[SCSI] qla4xxx: Added support for ISP82XX

Signed-off-by: Vikas Chaudhary <Vikas Chaudhary@qlogic.com>
Signed-off-by: Karen Higgins <karen.higgins@qlogic.com>
Signed-off-by: Ravi Anand <ravi.anand@qlogic.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 4a332c3..539546df 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 @@
  * 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 @@
 }
 
 /**
+ * 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 @@
 	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 @@
 }
 
 /**
- * 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 @@
 		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 @@
 		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 @@
 
 	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 @@
 			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 @@
 }
 
 /**
- * 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 @@
 			    (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 @@
 	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 @@
  * 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 @@
 	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 @@
 
 	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 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_validate_mac_address(ha) == QLA_ERROR)
+	if (qla4xxx_get_fw_version(ha) == QLA_ERROR)
+		goto exit_init_hba;
+
+	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 @@
 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 @@
 			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;
 }
-