summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_init.c')
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c136
1 files changed, 95 insertions, 41 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 4a332c32d71..539546df037 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -11,8 +11,8 @@
#include "ql4_dbg.h"
#include "ql4_inline.h"
-static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
- uint32_t fw_ddb_index);
+static struct ddb_entry *qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
+ uint32_t fw_ddb_index);
static void ql4xxx_set_mac_number(struct scsi_qla_host *ha)
{
@@ -51,8 +51,8 @@ static void ql4xxx_set_mac_number(struct scsi_qla_host *ha)
* This routine deallocates and unlinks the specified ddb_entry from the
* adapter's
**/
-static void qla4xxx_free_ddb(struct scsi_qla_host *ha,
- struct ddb_entry *ddb_entry)
+void qla4xxx_free_ddb(struct scsi_qla_host *ha,
+ struct ddb_entry *ddb_entry)
{
/* Remove device entry from list */
list_del_init(&ddb_entry->list);
@@ -86,6 +86,25 @@ void qla4xxx_free_ddb_list(struct scsi_qla_host *ha)
}
/**
+ * qla4xxx_init_response_q_entries() - Initializes response queue entries.
+ * @ha: HA context
+ *
+ * Beginning of request ring has initialization control block already built
+ * by nvram config routine.
+ **/
+static void qla4xxx_init_response_q_entries(struct scsi_qla_host *ha)
+{
+ uint16_t cnt;
+ struct response *pkt;
+
+ pkt = (struct response *)ha->response_ptr;
+ for (cnt = 0; cnt < RESPONSE_QUEUE_DEPTH; cnt++) {
+ pkt->signature = RESPONSE_PROCESSED;
+ pkt++;
+ }
+}
+
+/**
* qla4xxx_init_rings - initialize hw queues
* @ha: pointer to host adapter structure.
*
@@ -109,19 +128,31 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha)
ha->response_out = 0;
ha->response_ptr = &ha->response_ring[ha->response_out];
- /*
- * Initialize DMA Shadow registers. The firmware is really supposed to
- * take care of this, but on some uniprocessor systems, the shadow
- * registers aren't cleared-- causing the interrupt_handler to think
- * there are responses to be processed when there aren't.
- */
- ha->shadow_regs->req_q_out = __constant_cpu_to_le32(0);
- ha->shadow_regs->rsp_q_in = __constant_cpu_to_le32(0);
- wmb();
+ if (is_qla8022(ha)) {
+ writel(0,
+ (unsigned long __iomem *)&ha->qla4_8xxx_reg->req_q_out);
+ writel(0,
+ (unsigned long __iomem *)&ha->qla4_8xxx_reg->rsp_q_in);
+ writel(0,
+ (unsigned long __iomem *)&ha->qla4_8xxx_reg->rsp_q_out);
+ } else {
+ /*
+ * Initialize DMA Shadow registers. The firmware is really
+ * supposed to take care of this, but on some uniprocessor
+ * systems, the shadow registers aren't cleared-- causing
+ * the interrupt_handler to think there are responses to be
+ * processed when there aren't.
+ */
+ ha->shadow_regs->req_q_out = __constant_cpu_to_le32(0);
+ ha->shadow_regs->rsp_q_in = __constant_cpu_to_le32(0);
+ wmb();
- writel(0, &ha->reg->req_q_in);
- writel(0, &ha->reg->rsp_q_out);
- readl(&ha->reg->rsp_q_out);
+ writel(0, &ha->reg->req_q_in);
+ writel(0, &ha->reg->rsp_q_out);
+ readl(&ha->reg->rsp_q_out);
+ }
+
+ qla4xxx_init_response_q_entries(ha);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -129,11 +160,11 @@ int qla4xxx_init_rings(struct scsi_qla_host *ha)
}
/**
- * qla4xxx_validate_mac_address - validate adapter MAC address(es)
+ * qla4xxx_get_sys_info - validate adapter MAC address(es)
* @ha: pointer to host adapter structure.
*
**/
-static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha)
+int qla4xxx_get_sys_info(struct scsi_qla_host *ha)
{
struct flash_sys_info *sys_info;
dma_addr_t sys_info_dma;
@@ -145,7 +176,7 @@ static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha)
DEBUG2(printk("scsi%ld: %s: Unable to allocate dma buffer.\n",
ha->host_no, __func__));
- goto exit_validate_mac_no_free;
+ goto exit_get_sys_info_no_free;
}
memset(sys_info, 0, sizeof(*sys_info));
@@ -155,7 +186,7 @@ static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha)
DEBUG2(printk("scsi%ld: %s: get_flash FLASH_OFFSET_SYS_INFO "
"failed\n", ha->host_no, __func__));
- goto exit_validate_mac;
+ goto exit_get_sys_info;
}
/* Save M.A.C. address & serial_number */
@@ -168,11 +199,11 @@ static int qla4xxx_validate_mac_address(struct scsi_qla_host *ha)
status = QLA_SUCCESS;
- exit_validate_mac:
+exit_get_sys_info:
dma_free_coherent(&ha->pdev->dev, sizeof(*sys_info), sys_info,
sys_info_dma);
- exit_validate_mac_no_free:
+exit_get_sys_info_no_free:
return status;
}
@@ -584,21 +615,19 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
min(sizeof(ddb_entry->link_local_ipv6_addr),
sizeof(fw_ddb_entry->link_local_ipv6_addr)));
- DEBUG2(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d "
- "State %04x ConnErr %08x IP %pI6 "
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB[%d] State %04x"
+ " ConnErr %08x IP %pI6 "
":%04d \"%s\"\n",
__func__, fw_ddb_index,
- ddb_entry->os_target_id,
ddb_entry->fw_ddb_device_state,
conn_err, fw_ddb_entry->ip_addr,
le16_to_cpu(fw_ddb_entry->port),
fw_ddb_entry->iscsi_name));
} else
- DEBUG2(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d "
- "State %04x ConnErr %08x IP %pI4 "
+ DEBUG2(ql4_printk(KERN_INFO, ha, "%s: DDB[%d] State %04x"
+ " ConnErr %08x IP %pI4 "
":%04d \"%s\"\n",
__func__, fw_ddb_index,
- ddb_entry->os_target_id,
ddb_entry->fw_ddb_device_state,
conn_err, fw_ddb_entry->ip_addr,
le16_to_cpu(fw_ddb_entry->port),
@@ -984,7 +1013,7 @@ static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha)
}
/**
- * qla4xxx_update_ddb_list - update the driver ddb list
+ * qla4xxx_reinitialize_ddb_list - update the driver ddb list
* @ha: pointer to host adapter structure.
*
* This routine obtains device information from the F/W database after
@@ -1028,7 +1057,7 @@ int qla4xxx_relogin_device(struct scsi_qla_host *ha,
(uint16_t)RELOGIN_TOV);
atomic_set(&ddb_entry->relogin_timer, relogin_timer);
- DEBUG2(printk("scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no,
+ DEBUG2(printk("scsi%ld: Relogin ddb [%d]. TOV=%d\n", ha->host_no,
ddb_entry->fw_ddb_index, relogin_timer));
qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index, 0);
@@ -1085,7 +1114,16 @@ static int qla4xxx_config_nvram(struct scsi_qla_host *ha)
return QLA_SUCCESS;
}
-static void qla4x00_pci_config(struct scsi_qla_host *ha)
+/**
+ * qla4_8xxx_pci_config() - Setup ISP82xx PCI configuration registers.
+ * @ha: HA context
+ */
+void qla4_8xxx_pci_config(struct scsi_qla_host *ha)
+{
+ pci_set_master(ha->pdev);
+}
+
+void qla4xxx_pci_config(struct scsi_qla_host *ha)
{
uint16_t w;
int status;
@@ -1216,7 +1254,7 @@ int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a)
* This routine performs the necessary steps to start the firmware for
* the QLA4010 adapter.
**/
-static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
+int qla4xxx_start_firmware(struct scsi_qla_host *ha)
{
unsigned long flags = 0;
uint32_t mbox_status;
@@ -1295,7 +1333,8 @@ static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
if (soft_reset) {
DEBUG(printk("scsi%ld: %s: Issue Soft Reset\n", ha->host_no,
__func__));
- status = qla4xxx_soft_reset(ha);
+ status = qla4xxx_soft_reset(ha); /* NOTE: acquires drvr
+ * lock again, but ok */
if (status == QLA_ERROR) {
DEBUG(printk("scsi%d: %s: Soft Reset failed!\n",
ha->host_no, __func__));
@@ -1316,7 +1355,6 @@ static int qla4xxx_start_firmware(struct scsi_qla_host *ha)
ql4xxx_unlock_drvr(ha);
if (status == QLA_SUCCESS) {
- qla4xxx_get_fw_version(ha);
if (test_and_clear_bit(AF_GET_CRASH_RECORD, &ha->flags))
qla4xxx_get_crash_record(ha);
} else {
@@ -1343,18 +1381,21 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
int status = QLA_ERROR;
int8_t ip_address[IP_ADDR_LEN] = {0} ;
- clear_bit(AF_ONLINE, &ha->flags);
ha->eeprom_cmd_data = 0;
- qla4x00_pci_config(ha);
+ ql4_printk(KERN_INFO, ha, "Configuring PCI space...\n");
+ ha->isp_ops->pci_config(ha);
- qla4xxx_disable_intrs(ha);
+ ha->isp_ops->disable_intrs(ha);
/* Initialize the Host adapter request/response queues and firmware */
- if (qla4xxx_start_firmware(ha) == QLA_ERROR)
+ if (ha->isp_ops->start_firmware(ha) == QLA_ERROR)
+ goto exit_init_hba;
+
+ if (qla4xxx_get_fw_version(ha) == QLA_ERROR)
goto exit_init_hba;
- if (qla4xxx_validate_mac_address(ha) == QLA_ERROR)
+ if (ha->isp_ops->get_sys_info(ha) == QLA_ERROR)
goto exit_init_hba;
if (qla4xxx_init_local_data(ha) == QLA_ERROR)
@@ -1407,6 +1448,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha,
exit_init_online:
set_bit(AF_ONLINE, &ha->flags);
exit_init_hba:
+ DEBUG2(printk("scsi%ld: initialize adapter: %s\n", ha->host_no,
+ status == QLA_ERROR ? "FAILED" : "SUCCEDED"));
return status;
}
@@ -1558,9 +1601,20 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
atomic_set(&ddb_entry->relogin_timer, 0);
atomic_set(&ddb_entry->retry_relogin_timer,
ddb_entry->default_time2wait + 4);
+ DEBUG(printk("scsi%ld: %s: ddb[%d] "
+ "initiate relogin after %d seconds\n",
+ ha->host_no, __func__,
+ ddb_entry->fw_ddb_index,
+ ddb_entry->default_time2wait + 4));
+ } else {
+ DEBUG(printk("scsi%ld: %s: ddb[%d] "
+ "relogin not initiated, state = %d, "
+ "ddb_entry->flags = 0x%lx\n",
+ ha->host_no, __func__,
+ ddb_entry->fw_ddb_index,
+ ddb_entry->fw_ddb_device_state,
+ ddb_entry->flags));
}
}
-
return QLA_SUCCESS;
}
-