[PATCH 06/12] qla4xxx: Added new functions in isp_ops

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Vikas Chaudhary <vikas.chaudhary@xxxxxxxxxx>

Signed-off-by: Poornima Vonti <poornima.vonti@xxxxxxxxxx>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@xxxxxxxxxx>
---
 drivers/scsi/qla4xxx/ql4_attr.c |   10 +-
 drivers/scsi/qla4xxx/ql4_def.h  |   27 ++++
 drivers/scsi/qla4xxx/ql4_glbl.h |   13 ++-
 drivers/scsi/qla4xxx/ql4_mbx.c  |   96 ++++++---------
 drivers/scsi/qla4xxx/ql4_nx.c   |  273 +++++++++++++++++++++++----------------
 drivers/scsi/qla4xxx/ql4_nx.h   |   34 +++++
 drivers/scsi/qla4xxx/ql4_os.c   |  108 +++++++++-------
 7 files changed, 341 insertions(+), 220 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_attr.c b/drivers/scsi/qla4xxx/ql4_attr.c
index 71b44f0..befe4f9 100644
--- a/drivers/scsi/qla4xxx/ql4_attr.c
+++ b/drivers/scsi/qla4xxx/ql4_attr.c
@@ -75,21 +75,21 @@ qla4_8xxx_sysfs_write_fw_dump(struct file *filep, struct kobject *kobj,
 		break;
 	case 2:
 		/* Reset HBA */
-		qla4_82xx_idc_lock(ha);
-		dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+		ha->isp_ops->idc_lock(ha);
+		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
 		if (dev_state == QLA8XXX_DEV_READY) {
 			ql4_printk(KERN_INFO, ha,
 				   "%s: Setting Need reset, reset_owner is 0x%x.\n",
 				   __func__, ha->func_num);
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-					QLA8XXX_DEV_NEED_RESET);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+					    QLA8XXX_DEV_NEED_RESET);
 			set_bit(AF_8XXX_RST_OWNER, &ha->flags);
 		} else
 			ql4_printk(KERN_INFO, ha,
 				   "%s: Reset not performed as device state is 0x%x\n",
 				   __func__, dev_state);
 
-		qla4_82xx_idc_unlock(ha);
+		ha->isp_ops->idc_unlock(ha);
 		break;
 	default:
 		/* do nothing */
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 82f70db..11271a2 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -388,8 +388,10 @@ struct isp_operations {
 	void (*disable_intrs) (struct scsi_qla_host *);
 	void (*enable_intrs) (struct scsi_qla_host *);
 	int (*start_firmware) (struct scsi_qla_host *);
+	int (*restart_firmware) (struct scsi_qla_host *);
 	irqreturn_t (*intr_handler) (int , void *);
 	void (*interrupt_service_routine) (struct scsi_qla_host *, uint32_t);
+	int (*need_reset) (struct scsi_qla_host *);
 	int (*reset_chip) (struct scsi_qla_host *);
 	int (*reset_firmware) (struct scsi_qla_host *);
 	void (*queue_iocb) (struct scsi_qla_host *);
@@ -397,6 +399,15 @@ struct isp_operations {
 	uint16_t (*rd_shdw_req_q_out) (struct scsi_qla_host *);
 	uint16_t (*rd_shdw_rsp_q_in) (struct scsi_qla_host *);
 	int (*get_sys_info) (struct scsi_qla_host *);
+	uint32_t (*rd_reg_direct) (struct scsi_qla_host *, ulong);
+	void (*wr_reg_direct) (struct scsi_qla_host *, ulong, uint32_t);
+	int (*rd_reg_indirect) (struct scsi_qla_host *, uint32_t, uint32_t *);
+	int (*wr_reg_indirect) (struct scsi_qla_host *, uint32_t, uint32_t);
+	int (*idc_lock) (struct scsi_qla_host *);
+	void (*idc_unlock) (struct scsi_qla_host *);
+	void (*rom_lock_recovery) (struct scsi_qla_host *);
+	void (*queue_mailbox_command) (struct scsi_qla_host *, uint32_t *, int);
+	void (*process_mailbox_interrupt) (struct scsi_qla_host *, int);
 };
 
 struct ql4_mdump_size_table {
@@ -733,6 +744,8 @@ struct scsi_qla_host {
 #define MAX_MRB		128
 	struct mrb *active_mrb_array[MAX_MRB];
 	uint32_t mrb_index;
+
+	uint32_t *reg_tbl;
 };
 
 struct ql4_task_data {
@@ -942,6 +955,20 @@ static inline int ql4xxx_reset_active(struct scsi_qla_host *ha)
 	       test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags);
 
 }
+
+static inline int qla4_8xxx_rd_direct(struct scsi_qla_host *ha,
+				      const uint32_t crb_reg)
+{
+	return ha->isp_ops->rd_reg_direct(ha, ha->reg_tbl[crb_reg]);
+}
+
+static inline void qla4_8xxx_wr_direct(struct scsi_qla_host *ha,
+				       const uint32_t crb_reg,
+				       const uint32_t value)
+{
+	ha->isp_ops->wr_reg_direct(ha, ha->reg_tbl[crb_reg], value);
+}
+
 /*---------------------------------------------------------------------------*/
 
 /* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index a9f6516..1010d71 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -117,7 +117,7 @@ int qla4_82xx_crb_win_lock(struct scsi_qla_host *);
 void qla4_82xx_crb_win_unlock(struct scsi_qla_host *);
 int qla4_82xx_pci_get_crb_addr_2M(struct scsi_qla_host *, ulong *);
 void qla4_82xx_wr_32(struct scsi_qla_host *, ulong, u32);
-int qla4_82xx_rd_32(struct scsi_qla_host *, ulong);
+uint32_t qla4_82xx_rd_32(struct scsi_qla_host *, ulong);
 int qla4_82xx_pci_mem_read_2M(struct scsi_qla_host *, u64, void *, int);
 int qla4_82xx_pci_mem_write_2M(struct scsi_qla_host *ha, u64, void *, int);
 int qla4_82xx_isp_reset(struct scsi_qla_host *ha);
@@ -203,6 +203,17 @@ int qla4xxx_req_template_size(struct scsi_qla_host *ha);
 void qla4_8xxx_alloc_sysfs_attr(struct scsi_qla_host *ha);
 void qla4_8xxx_free_sysfs_attr(struct scsi_qla_host *ha);
 void qla4xxx_alloc_fw_dump(struct scsi_qla_host *ha);
+int qla4_82xx_try_start_fw(struct scsi_qla_host *ha);
+int qla4_8xxx_need_reset(struct scsi_qla_host *ha);
+int qla4_82xx_md_rd_32(struct scsi_qla_host *ha, uint32_t off, uint32_t *data);
+int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data);
+void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha);
+void qla4_82xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+			      int incount);
+void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
+void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+			    int incount);
+void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int outcount);
 
 extern int ql4xextended_error_logging;
 extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index ea08e52..73324fb 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -10,6 +10,37 @@
 #include "ql4_dbg.h"
 #include "ql4_inline.h"
 
+void qla4xxx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+			    int in_count)
+{
+	int i;
+
+	/* Load all mailbox registers, except mailbox 0. */
+	for (i = 1; i < in_count; i++)
+		writel(mbx_cmd[i], &ha->reg->mailbox[i]);
+
+	/* Wakeup firmware  */
+	writel(mbx_cmd[0], &ha->reg->mailbox[0]);
+	readl(&ha->reg->mailbox[0]);
+	writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
+	readl(&ha->reg->ctrl_status);
+}
+
+void qla4xxx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
+{
+	int intr_status;
+
+	intr_status = readl(&ha->reg->ctrl_status);
+	if (intr_status & INTR_PENDING) {
+		/*
+		 * Service the interrupt.
+		 * The ISR will save the mailbox status registers
+		 * to a temporary storage location in the adapter structure.
+		 */
+		ha->mbox_status_count = out_count;
+		ha->isp_ops->interrupt_service_routine(ha, intr_status);
+	}
+}
 
 /**
  * qla4xxx_mailbox_command - issues mailbox commands
@@ -30,7 +61,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 	int status = QLA_ERROR;
 	uint8_t i;
 	u_long wait_count;
-	uint32_t intr_status;
 	unsigned long flags = 0;
 	uint32_t dev_state;
 
@@ -85,9 +115,9 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 			goto mbox_exit;
 		}
 		/* Do not send any mbx cmd if h/w is in failed state*/
-		qla4_82xx_idc_lock(ha);
-		dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
-		qla4_82xx_idc_unlock(ha);
+		ha->isp_ops->idc_lock(ha);
+		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
+		ha->isp_ops->idc_unlock(ha);
 		if (dev_state == QLA8XXX_DEV_FAILED) {
 			ql4_printk(KERN_WARNING, ha,
 				   "scsi%ld: %s: H/W is in failed state, do not send any mailbox commands\n",
@@ -102,30 +132,8 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 	for (i = 0; i < outCount; i++)
 		ha->mbox_status[i] = 0;
 
-	if (is_qla8022(ha)) {
-		/* Load all mailbox registers, except mailbox 0. */
-		DEBUG5(
-		    printk("scsi%ld: %s: Cmd ", ha->host_no, __func__);
-		    for (i = 0; i < inCount; i++)
-			printk("mb%d=%04x ", i, mbx_cmd[i]);
-		    printk("\n"));
-
-		for (i = 1; i < inCount; i++)
-			writel(mbx_cmd[i], &ha->qla4_82xx_reg->mailbox_in[i]);
-		writel(mbx_cmd[0], &ha->qla4_82xx_reg->mailbox_in[0]);
-		readl(&ha->qla4_82xx_reg->mailbox_in[0]);
-		writel(HINT_MBX_INT_PENDING, &ha->qla4_82xx_reg->hint);
-	} else {
-		/* Load all mailbox registers, except mailbox 0. */
-		for (i = 1; i < inCount; i++)
-			writel(mbx_cmd[i], &ha->reg->mailbox[i]);
-
-		/* Wakeup firmware  */
-		writel(mbx_cmd[0], &ha->reg->mailbox[0]);
-		readl(&ha->reg->mailbox[0]);
-		writel(set_rmask(CSR_INTR_RISC), &ha->reg->ctrl_status);
-		readl(&ha->reg->ctrl_status);
-	}
+	/* Queue the mailbox command to the firmware */
+	ha->isp_ops->queue_mailbox_command(ha, mbx_cmd, inCount);
 
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
 
@@ -167,37 +175,7 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
 			 */
 
 			spin_lock_irqsave(&ha->hardware_lock, flags);
-			if (is_qla8022(ha)) {
-				intr_status =
-				    readl(&ha->qla4_82xx_reg->host_int);
-				if (intr_status & ISRX_82XX_RISC_INT) {
-					ha->mbox_status_count = outCount;
-					intr_status =
-					 readl(&ha->qla4_82xx_reg->host_status);
-					ha->isp_ops->interrupt_service_routine(
-					    ha, intr_status);
-					if (test_bit(AF_INTERRUPTS_ON,
-					    &ha->flags) &&
-					    test_bit(AF_INTx_ENABLED,
-					    &ha->flags))
-						qla4_82xx_wr_32(ha,
-						ha->nx_legacy_intr.tgt_mask_reg,
-						0xfbff);
-				}
-			} else {
-				intr_status = readl(&ha->reg->ctrl_status);
-				if (intr_status & INTR_PENDING) {
-					/*
-					 * Service the interrupt.
-					 * The ISR will save the mailbox status
-					 * registers to a temporary storage
-					 * location in the adapter structure.
-					 */
-					ha->mbox_status_count = outCount;
-					ha->isp_ops->interrupt_service_routine(
-					    ha, intr_status);
-				}
-			}
+			ha->isp_ops->process_mailbox_interrupt(ha, outCount);
 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
 			msleep(10);
 		}
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 84b039f..13d8e48 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -396,8 +396,7 @@ qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data)
 	}
 }
 
-int
-qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
+uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
 {
 	unsigned long flags = 0;
 	int rv;
@@ -422,34 +421,54 @@ qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off)
 }
 
 /* Minidump related functions */
-static int qla4_8xxx_md_rw_32(struct scsi_qla_host *ha, uint32_t off,
-			      u32 data, uint8_t flag)
+int qla4_82xx_md_rd_32(struct scsi_qla_host *ha, uint32_t off, uint32_t *data)
 {
-	uint32_t win_read, off_value, rval = QLA_SUCCESS;
+	uint32_t win_read, off_value;
+	int rval = QLA_SUCCESS;
 
 	off_value  = off & 0xFFFF0000;
 	writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
 
-	/* Read back value to make sure write has gone through before trying
+	/*
+	 * Read back value to make sure write has gone through before trying
 	 * to use it.
 	 */
 	win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
 	if (win_read != off_value) {
 		DEBUG2(ql4_printk(KERN_INFO, ha,
 				  "%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
-				   __func__, off_value, win_read, off));
-		return QLA_ERROR;
+				  __func__, off_value, win_read, off));
+		rval = QLA_ERROR;
+	} else {
+		off_value  = off & 0x0000FFFF;
+		*data = readl((void __iomem *)(off_value + CRB_INDIRECT_2M +
+					       ha->nx_pcibase));
 	}
+	return rval;
+}
 
-	off_value  = off & 0x0000FFFF;
+int qla4_82xx_md_wr_32(struct scsi_qla_host *ha, uint32_t off, uint32_t data)
+{
+	uint32_t win_read, off_value;
+	int rval = QLA_SUCCESS;
 
-	if (flag)
+	off_value  = off & 0xFFFF0000;
+	writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
+
+	/* Read back value to make sure write has gone through before trying
+	 * to use it.
+	 */
+	win_read = readl((void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase));
+	if (win_read != off_value) {
+		DEBUG2(ql4_printk(KERN_INFO, ha,
+				  "%s: Written (0x%x) != Read (0x%x), off=0x%x\n",
+				  __func__, off_value, win_read, off));
+		rval = QLA_ERROR;
+	} else {
+		off_value  = off & 0x0000FFFF;
 		writel(data, (void __iomem *)(off_value + CRB_INDIRECT_2M +
 					      ha->nx_pcibase));
-	else
-		rval = readl((void __iomem *)(off_value + CRB_INDIRECT_2M +
-					      ha->nx_pcibase));
-
+	}
 	return rval;
 }
 
@@ -1491,11 +1510,11 @@ qla4_8xxx_set_drv_active(struct scsi_qla_host *ha)
 {
 	uint32_t drv_active;
 
-	drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
 	drv_active |= (1 << (ha->func_num * 4));
 	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
 		   __func__, ha->host_no, drv_active);
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
 }
 
 void
@@ -1503,21 +1522,20 @@ qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha)
 {
 	uint32_t drv_active;
 
-	drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
+	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
 	drv_active &= ~(1 << (ha->func_num * 4));
 	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_active: 0x%08x\n",
 		   __func__, ha->host_no, drv_active);
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_ACTIVE, drv_active);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_ACTIVE, drv_active);
 }
 
-static inline int
-qla4_8xxx_need_reset(struct scsi_qla_host *ha)
+inline int qla4_8xxx_need_reset(struct scsi_qla_host *ha)
 {
 	uint32_t drv_state, drv_active;
 	int rval;
 
-	drv_active = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
-	drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+	drv_active = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_ACTIVE);
+	drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
 	rval = drv_state & (1 << (ha->func_num * 4));
 	if ((test_bit(AF_EEH_BUSY, &ha->flags)) && drv_active)
 		rval = 1;
@@ -1530,11 +1548,11 @@ qla4_8xxx_set_rst_ready(struct scsi_qla_host *ha)
 {
 	uint32_t drv_state;
 
-	drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+	drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
 	drv_state |= (1 << (ha->func_num * 4));
 	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
 		   __func__, ha->host_no, drv_state);
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
 }
 
 static inline void
@@ -1542,11 +1560,11 @@ qla4_8xxx_clear_rst_ready(struct scsi_qla_host *ha)
 {
 	uint32_t drv_state;
 
-	drv_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+	drv_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
 	drv_state &= ~(1 << (ha->func_num * 4));
 	ql4_printk(KERN_INFO, ha, "%s(%ld): drv_state: 0x%08x\n",
 		   __func__, ha->host_no, drv_state);
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, drv_state);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, drv_state);
 }
 
 static inline void
@@ -1554,9 +1572,9 @@ qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha)
 {
 	uint32_t qsnt_state;
 
-	qsnt_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DRV_STATE);
+	qsnt_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DRV_STATE);
 	qsnt_state |= (2 << (ha->func_num * 4));
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, qsnt_state);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, qsnt_state);
 }
 
 
@@ -1595,8 +1613,7 @@ qla4_82xx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start)
 	return qla4_82xx_rcvpeg_ready(ha);
 }
 
-static int
-qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
+int qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
 {
 	int rval = QLA_ERROR;
 
@@ -1625,7 +1642,7 @@ qla4_82xx_try_start_fw(struct scsi_qla_host *ha)
 	return rval;
 }
 
-static void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha)
+void qla4_82xx_rom_lock_recovery(struct scsi_qla_host *ha)
 {
 	if (qla4_82xx_rom_lock(ha)) {
 		/* Someone else is holding the lock. */
@@ -1655,7 +1672,7 @@ static void qla4_8xxx_minidump_process_rdcrb(struct scsi_qla_host *ha,
 	loop_cnt = crb_hdr->op_count;
 
 	for (i = 0; i < loop_cnt; i++) {
-		r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
+		ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
 		*data_ptr++ = cpu_to_le32(r_addr);
 		*data_ptr++ = cpu_to_le32(r_value);
 		r_addr += r_stride;
@@ -1690,16 +1707,16 @@ static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
 	p_mask = cache_hdr->cache_ctrl.poll_mask;
 
 	for (i = 0; i < loop_count; i++) {
-		qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1);
+		ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
 
 		if (c_value_w)
-			qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1);
+			ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
 
 		if (p_mask) {
 			w_time = jiffies + p_wait;
 			do {
-				c_value_r = qla4_8xxx_md_rw_32(ha, c_addr,
-								0, 0);
+				ha->isp_ops->rd_reg_indirect(ha, c_addr,
+							     &c_value_r);
 				if ((c_value_r & p_mask) == 0) {
 					break;
 				} else if (time_after_eq(jiffies, w_time)) {
@@ -1711,7 +1728,7 @@ static int qla4_8xxx_minidump_process_l2tag(struct scsi_qla_host *ha,
 
 		addr = r_addr;
 		for (k = 0; k < r_cnt; k++) {
-			r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
 			*data_ptr++ = cpu_to_le32(r_value);
 			addr += cache_hdr->read_ctrl.read_addr_stride;
 		}
@@ -1741,47 +1758,48 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
 	for (i = 0; i < crb_entry->op_count; i++) {
 		opcode = crb_entry->crb_ctrl.opcode;
 		if (opcode & QLA8XXX_DBG_OPCODE_WR) {
-			qla4_8xxx_md_rw_32(ha, crb_addr,
-					   crb_entry->value_1, 1);
+			ha->isp_ops->wr_reg_indirect(ha, crb_addr,
+						     crb_entry->value_1);
 			opcode &= ~QLA8XXX_DBG_OPCODE_WR;
 		}
 		if (opcode & QLA8XXX_DBG_OPCODE_RW) {
-			read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
-			qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
+			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
+			ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
 			opcode &= ~QLA8XXX_DBG_OPCODE_RW;
 		}
 		if (opcode & QLA8XXX_DBG_OPCODE_AND) {
-			read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
 			read_value &= crb_entry->value_2;
 			opcode &= ~QLA8XXX_DBG_OPCODE_AND;
 			if (opcode & QLA8XXX_DBG_OPCODE_OR) {
 				read_value |= crb_entry->value_3;
 				opcode &= ~QLA8XXX_DBG_OPCODE_OR;
 			}
-			qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
+			ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
 		}
 		if (opcode & QLA8XXX_DBG_OPCODE_OR) {
-			read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
 			read_value |= crb_entry->value_3;
-			qla4_8xxx_md_rw_32(ha, crb_addr, read_value, 1);
+			ha->isp_ops->wr_reg_indirect(ha, crb_addr, read_value);
 			opcode &= ~QLA8XXX_DBG_OPCODE_OR;
 		}
 		if (opcode & QLA8XXX_DBG_OPCODE_POLL) {
 			poll_time = crb_entry->crb_strd.poll_timeout;
 			wtime = jiffies + poll_time;
-			read_value = qla4_8xxx_md_rw_32(ha, crb_addr, 0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, crb_addr, &read_value);
 
 			do {
 				if ((read_value & crb_entry->value_2) ==
-				    crb_entry->value_1)
+				    crb_entry->value_1) {
 					break;
-				else if (time_after_eq(jiffies, wtime)) {
+				} else if (time_after_eq(jiffies, wtime)) {
 					/* capturing dump failed */
 					rval = QLA_ERROR;
 					break;
-				} else
-					read_value = qla4_8xxx_md_rw_32(ha,
-								crb_addr, 0, 0);
+				} else {
+					ha->isp_ops->rd_reg_indirect(ha,
+							crb_addr, &read_value);
+				}
 			} while (1);
 			opcode &= ~QLA8XXX_DBG_OPCODE_POLL;
 		}
@@ -1794,7 +1812,7 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
 				addr = crb_addr;
 			}
 
-			read_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, addr, &read_value);
 			index = crb_entry->crb_ctrl.state_index_v;
 			tmplt_hdr->saved_state_array[index] = read_value;
 			opcode &= ~QLA8XXX_DBG_OPCODE_RDSTATE;
@@ -1816,7 +1834,7 @@ static int qla4_8xxx_minidump_process_control(struct scsi_qla_host *ha,
 				read_value = crb_entry->value_1;
 			}
 
-			qla4_8xxx_md_rw_32(ha, addr, read_value, 1);
+			ha->isp_ops->wr_reg_indirect(ha, addr, read_value);
 			opcode &= ~QLA8XXX_DBG_OPCODE_WRSTATE;
 		}
 
@@ -1883,8 +1901,8 @@ static void qla4_8xxx_minidump_process_rdmux(struct scsi_qla_host *ha,
 	loop_cnt = mux_hdr->op_count;
 
 	for (i = 0; i < loop_cnt; i++) {
-		qla4_8xxx_md_rw_32(ha, s_addr, s_value, 1);
-		r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
+		ha->isp_ops->wr_reg_indirect(ha, s_addr, s_value);
+		ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
 		*data_ptr++ = cpu_to_le32(s_value);
 		*data_ptr++ = cpu_to_le32(r_value);
 		s_value += s_stride;
@@ -1913,11 +1931,11 @@ static void qla4_8xxx_minidump_process_l1cache(struct scsi_qla_host *ha,
 	r_cnt = cache_hdr->read_ctrl.read_addr_cnt;
 
 	for (i = 0; i < loop_count; i++) {
-		qla4_8xxx_md_rw_32(ha, t_r_addr, t_value, 1);
-		qla4_8xxx_md_rw_32(ha, c_addr, c_value_w, 1);
+		ha->isp_ops->wr_reg_indirect(ha, t_r_addr, t_value);
+		ha->isp_ops->wr_reg_indirect(ha, c_addr, c_value_w);
 		addr = r_addr;
 		for (k = 0; k < r_cnt; k++) {
-			r_value = qla4_8xxx_md_rw_32(ha, addr, 0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, addr, &r_value);
 			*data_ptr++ = cpu_to_le32(r_value);
 			addr += cache_hdr->read_ctrl.read_addr_stride;
 		}
@@ -1944,10 +1962,10 @@ static void qla4_8xxx_minidump_process_queue(struct scsi_qla_host *ha,
 	loop_cnt = q_hdr->op_count;
 
 	for (i = 0; i < loop_cnt; i++) {
-		qla4_8xxx_md_rw_32(ha, s_addr, qid, 1);
+		ha->isp_ops->wr_reg_indirect(ha, s_addr, qid);
 		r_addr = q_hdr->read_addr;
 		for (k = 0; k < r_cnt; k++) {
-			r_value = qla4_8xxx_md_rw_32(ha, r_addr, 0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, r_addr, &r_value);
 			*data_ptr++ = cpu_to_le32(r_value);
 			r_addr += r_stride;
 		}
@@ -1978,11 +1996,11 @@ static void qla4_82xx_minidump_process_rdrom(struct scsi_qla_host *ha,
 			   __func__, r_addr, loop_cnt));
 
 	for (i = 0; i < loop_cnt; i++) {
-		qla4_8xxx_md_rw_32(ha, MD_DIRECT_ROM_WINDOW,
-				   (r_addr & 0xFFFF0000), 1);
-		r_value = qla4_8xxx_md_rw_32(ha,
-					     MD_DIRECT_ROM_READ_BASE +
-					     (r_addr & 0x0000FFFF), 0, 0);
+		ha->isp_ops->wr_reg_indirect(ha, MD_DIRECT_ROM_WINDOW,
+					     (r_addr & 0xFFFF0000));
+		ha->isp_ops->rd_reg_indirect(ha,
+				MD_DIRECT_ROM_READ_BASE + (r_addr & 0x0000FFFF),
+				&r_value);
 		*data_ptr++ = cpu_to_le32(r_value);
 		r_addr += sizeof(uint32_t);
 	}
@@ -2032,17 +2050,19 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
 
 	write_lock_irqsave(&ha->hw_lock, flags);
 	for (i = 0; i < loop_cnt; i++) {
-		qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_LO, r_addr, 1);
+		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_LO,
+					     r_addr);
 		r_value = 0;
-		qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_ADDR_HI, r_value, 1);
+		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_ADDR_HI,
+					     r_value);
 		r_value = MIU_TA_CTL_ENABLE;
-		qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);
+		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
 		r_value = MIU_TA_CTL_START_ENABLE;
-		qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL, r_value, 1);
+		ha->isp_ops->wr_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL, r_value);
 
 		for (j = 0; j < MAX_CTL_CHECK; j++) {
-			r_value = qla4_8xxx_md_rw_32(ha, MD_MIU_TEST_AGT_CTRL,
-						     0, 0);
+			ha->isp_ops->rd_reg_indirect(ha, MD_MIU_TEST_AGT_CTRL,
+						     &r_value);
 			if ((r_value & MIU_TA_CTL_BUSY) == 0)
 				break;
 		}
@@ -2056,9 +2076,9 @@ static int qla4_8xxx_minidump_process_rdmem(struct scsi_qla_host *ha,
 		}
 
 		for (j = 0; j < 4; j++) {
-			r_data = qla4_8xxx_md_rw_32(ha,
-						    MD_MIU_TEST_AGT_RDDATA[j],
-						    0, 0);
+			ha->isp_ops->rd_reg_indirect(ha,
+						     MD_MIU_TEST_AGT_RDDATA[j],
+						     &r_data);
 			*data_ptr++ = cpu_to_le32(r_data);
 		}
 
@@ -2277,19 +2297,18 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
 	uint32_t old_count, count;
 	int need_reset = 0, peg_stuck = 1;
 
-	need_reset = qla4_8xxx_need_reset(ha);
-
-	old_count = qla4_82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
+	need_reset = ha->isp_ops->need_reset(ha);
+	old_count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
 
 	for (i = 0; i < 10; i++) {
 		timeout = msleep_interruptible(200);
 		if (timeout) {
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-			   QLA8XXX_DEV_FAILED);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+					    QLA8XXX_DEV_FAILED);
 			return rval;
 		}
 
-		count = qla4_82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
+		count = qla4_8xxx_rd_direct(ha, QLA8XXX_PEG_ALIVE_COUNTER);
 		if (count != old_count)
 			peg_stuck = 0;
 	}
@@ -2297,13 +2316,13 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
 	if (need_reset) {
 		/* We are trying to perform a recovery here. */
 		if (peg_stuck)
-			qla4_82xx_rom_lock_recovery(ha);
+			ha->isp_ops->rom_lock_recovery(ha);
 		goto dev_initialize;
 	} else  {
 		/* Start of day for this ha context. */
 		if (peg_stuck) {
 			/* Either we are the first or recovery in progress. */
-			qla4_82xx_rom_lock_recovery(ha);
+			ha->isp_ops->rom_lock_recovery(ha);
 			goto dev_initialize;
 		} else {
 			/* Firmware already running. */
@@ -2315,12 +2334,14 @@ qla4_8xxx_device_bootstrap(struct scsi_qla_host *ha)
 dev_initialize:
 	/* set to DEV_INITIALIZING */
 	ql4_printk(KERN_INFO, ha, "HW State: INITIALIZING\n");
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_INITIALIZING);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+			    QLA8XXX_DEV_INITIALIZING);
 
 	/* Driver that sets device state to initializating sets IDC version */
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION, QLA82XX_IDC_VERSION);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION,
+			    QLA82XX_IDC_VERSION);
 
-	qla4_82xx_idc_unlock(ha);
+	ha->isp_ops->idc_unlock(ha);
 	if (ql4xenablemd && test_bit(AF_FW_RECOVERY, &ha->flags) &&
 	    !test_and_set_bit(AF_82XX_FW_DUMPED, &ha->flags)) {
 		if (!qla4_8xxx_collect_md_data(ha)) {
@@ -2330,19 +2351,20 @@ dev_initialize:
 			clear_bit(AF_82XX_FW_DUMPED, &ha->flags);
 		}
 	}
-	rval = qla4_82xx_try_start_fw(ha);
-	qla4_82xx_idc_lock(ha);
+	rval = ha->isp_ops->restart_firmware(ha);
+	ha->isp_ops->idc_lock(ha);
 
 	if (rval != QLA_SUCCESS) {
 		ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
 		qla4_8xxx_clear_drv_active(ha);
-		qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_FAILED);
+		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+				    QLA8XXX_DEV_FAILED);
 		return rval;
 	}
 
 dev_ready:
 	ql4_printk(KERN_INFO, ha, "HW State: READY\n");
-	qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
+	qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE, QLA8XXX_DEV_READY);
 
 	return rval;
 }
@@ -2436,9 +2458,9 @@ qla4_82xx_need_reset_handler(struct scsi_qla_host *ha)
 void
 qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha)
 {
-	qla4_82xx_idc_lock(ha);
+	ha->isp_ops->idc_lock(ha);
 	qla4_8xxx_set_qsnt_ready(ha);
-	qla4_82xx_idc_unlock(ha);
+	ha->isp_ops->idc_unlock(ha);
 }
 
 /**
@@ -2454,12 +2476,12 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
 	unsigned long dev_init_timeout;
 
 	if (!test_bit(AF_INIT_DONE, &ha->flags)) {
-		qla4_82xx_idc_lock(ha);
+		ha->isp_ops->idc_lock(ha);
 		qla4_8xxx_set_drv_active(ha);
-		qla4_82xx_idc_unlock(ha);
+		ha->isp_ops->idc_unlock(ha);
 	}
 
-	dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+	dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
 	DEBUG2(ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
 			  dev_state, dev_state < MAX_STATES ?
 			  qdev_state[dev_state] : "Unknown"));
@@ -2467,7 +2489,7 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
 	/* wait for 30 seconds for device to go ready */
 	dev_init_timeout = jiffies + (ha->nx_dev_init_timeout * HZ);
 
-	qla4_82xx_idc_lock(ha);
+	ha->isp_ops->idc_lock(ha);
 	while (1) {
 
 		if (time_after_eq(jiffies, dev_init_timeout)) {
@@ -2476,11 +2498,11 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
 				   DRIVER_NAME,
 				   dev_state, dev_state < MAX_STATES ?
 				   qdev_state[dev_state] : "Unknown");
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-				QLA8XXX_DEV_FAILED);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+					    QLA8XXX_DEV_FAILED);
 		}
 
-		dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
 		ql4_printk(KERN_INFO, ha, "Device state is 0x%x = %s\n",
 			   dev_state, dev_state < MAX_STATES ?
 			   qdev_state[dev_state] : "Unknown");
@@ -2493,9 +2515,9 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
 			rval = qla4_8xxx_device_bootstrap(ha);
 			goto exit;
 		case QLA8XXX_DEV_INITIALIZING:
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_unlock(ha);
 			msleep(1000);
-			qla4_82xx_idc_lock(ha);
+			ha->isp_ops->idc_lock(ha);
 			break;
 		case QLA8XXX_DEV_NEED_RESET:
 			if (!ql4xdontresethba) {
@@ -2505,9 +2527,9 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
 				dev_init_timeout = jiffies +
 					(ha->nx_dev_init_timeout * HZ);
 			} else {
-				qla4_82xx_idc_unlock(ha);
+				ha->isp_ops->idc_unlock(ha);
 				msleep(1000);
-				qla4_82xx_idc_lock(ha);
+				ha->isp_ops->idc_lock(ha);
 			}
 			break;
 		case QLA8XXX_DEV_NEED_QUIESCENT:
@@ -2515,26 +2537,26 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha)
 			qla4_8xxx_need_qsnt_handler(ha);
 			break;
 		case QLA8XXX_DEV_QUIESCENT:
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_unlock(ha);
 			msleep(1000);
-			qla4_82xx_idc_lock(ha);
+			ha->isp_ops->idc_lock(ha);
 			break;
 		case QLA8XXX_DEV_FAILED:
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_unlock(ha);
 			qla4xxx_dead_adapter_cleanup(ha);
 			rval = QLA_ERROR;
-			qla4_82xx_idc_lock(ha);
+			ha->isp_ops->idc_lock(ha);
 			goto exit;
 		default:
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_unlock(ha);
 			qla4xxx_dead_adapter_cleanup(ha);
 			rval = QLA_ERROR;
-			qla4_82xx_idc_lock(ha);
+			ha->isp_ops->idc_lock(ha);
 			goto exit;
 		}
 	}
 exit:
-	qla4_82xx_idc_unlock(ha);
+	ha->isp_ops->idc_unlock(ha);
 	return rval;
 }
 
@@ -2822,6 +2844,39 @@ qla4_82xx_get_idc_param(struct scsi_qla_host *ha)
 	return;
 }
 
+void qla4_82xx_queue_mbox_cmd(struct scsi_qla_host *ha, uint32_t *mbx_cmd,
+			      int in_count)
+{
+	int i;
+
+	/* Load all mailbox registers, except mailbox 0. */
+	for (i = 1; i < in_count; i++)
+		writel(mbx_cmd[i], &ha->qla4_82xx_reg->mailbox_in[i]);
+
+	/* Wakeup firmware  */
+	writel(mbx_cmd[0], &ha->qla4_82xx_reg->mailbox_in[0]);
+	readl(&ha->qla4_82xx_reg->mailbox_in[0]);
+	writel(HINT_MBX_INT_PENDING, &ha->qla4_82xx_reg->hint);
+	readl(&ha->qla4_82xx_reg->hint);
+}
+
+void qla4_82xx_process_mbox_intr(struct scsi_qla_host *ha, int out_count)
+{
+	int intr_status;
+
+	intr_status = readl(&ha->qla4_82xx_reg->host_int);
+	if (intr_status & ISRX_82XX_RISC_INT) {
+		ha->mbox_status_count = out_count;
+		intr_status = readl(&ha->qla4_82xx_reg->host_status);
+		ha->isp_ops->interrupt_service_routine(ha, intr_status);
+
+		if (test_bit(AF_INTERRUPTS_ON, &ha->flags) &&
+		    test_bit(AF_INTx_ENABLED, &ha->flags))
+			qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
+					0xfbff);
+	}
+}
+
 int
 qla4_8xxx_get_flash_info(struct scsi_qla_host *ha)
 {
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h
index 16c5ae6..1894de0 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.h
+++ b/drivers/scsi/qla4xxx/ql4_nx.h
@@ -579,6 +579,40 @@ enum {
 #define QLA82XX_CRB_DEV_PART_INFO	(QLA82XX_CAM_RAM(0x14c))
 #define QLA82XX_CRB_DRV_IDC_VERSION	(QLA82XX_CAM_RAM(0x174))
 
+enum qla_regs {
+	QLA8XXX_PEG_HALT_STATUS1 = 0,
+	QLA8XXX_PEG_HALT_STATUS2,
+	QLA8XXX_PEG_ALIVE_COUNTER,
+	QLA8XXX_CRB_DRV_ACTIVE,
+	QLA8XXX_CRB_DEV_STATE,
+	QLA8XXX_CRB_DRV_STATE,
+	QLA8XXX_CRB_DRV_SCRATCH,
+	QLA8XXX_CRB_DEV_PART_INFO,
+	QLA8XXX_CRB_DRV_IDC_VERSION,
+	QLA8XXX_FW_VERSION_MAJOR,
+	QLA8XXX_FW_VERSION_MINOR,
+	QLA8XXX_FW_VERSION_SUB,
+	QLA8XXX_CRB_CMDPEG_STATE,
+	QLA8XXX_CRB_TEMP_STATE,
+};
+
+static const uint32_t qla4_82xx_reg_tbl[] = {
+	QLA82XX_PEG_HALT_STATUS1,
+	QLA82XX_PEG_HALT_STATUS2,
+	QLA82XX_PEG_ALIVE_COUNTER,
+	QLA82XX_CRB_DRV_ACTIVE,
+	QLA82XX_CRB_DEV_STATE,
+	QLA82XX_CRB_DRV_STATE,
+	QLA82XX_CRB_DRV_SCRATCH,
+	QLA82XX_CRB_DEV_PART_INFO,
+	QLA82XX_CRB_DRV_IDC_VERSION,
+	QLA82XX_FW_VERSION_MAJOR,
+	QLA82XX_FW_VERSION_MINOR,
+	QLA82XX_FW_VERSION_SUB,
+	CRB_CMDPEG_STATE,
+	CRB_TEMP_STATE,
+};
+
 /* Every driver should use these Device State */
 #define QLA8XXX_DEV_COLD		1
 #define QLA8XXX_DEV_INITIALIZING	2
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 6aa508c..ea8845b 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -2420,7 +2420,7 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha)
 	uint32_t temp, temp_state, temp_val;
 	int status = QLA_SUCCESS;
 
-	temp = qla4_82xx_rd_32(ha, CRB_TEMP_STATE);
+	temp = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_TEMP_STATE);
 
 	temp_state = qla82xx_get_temp_state(temp);
 	temp_val = qla82xx_get_temp_val(temp);
@@ -2454,9 +2454,11 @@ static int qla4_8xxx_check_temp(struct scsi_qla_host *ha)
 static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
 {
 	uint32_t fw_heartbeat_counter;
+	uint32_t halt_status1, halt_status2;
 	int status = QLA_SUCCESS;
 
-	fw_heartbeat_counter = qla4_82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER);
+	fw_heartbeat_counter = qla4_8xxx_rd_direct(ha,
+						   QLA8XXX_PEG_ALIVE_COUNTER);
 	/* If PEG_ALIVE_COUNTER is 0xffffffff, AER/EEH is in progress, ignore */
 	if (fw_heartbeat_counter == 0xffffffff) {
 		DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Device in frozen "
@@ -2470,18 +2472,18 @@ static int qla4_8xxx_check_fw_alive(struct scsi_qla_host *ha)
 		/* FW not alive after 2 seconds */
 		if (ha->seconds_since_last_heartbeat == 2) {
 			ha->seconds_since_last_heartbeat = 0;
+			halt_status1 = qla4_8xxx_rd_direct(ha,
+						QLA8XXX_PEG_HALT_STATUS1);
+			halt_status2 = qla4_8xxx_rd_direct(ha,
+						QLA8XXX_PEG_HALT_STATUS2);
 
 			ql4_printk(KERN_INFO, ha,
 				   "scsi(%ld): %s, Dumping hw/fw registers:\n "
 				   " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:"
 				   " 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:"
 				   " 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:"
-				   " 0x%x,\n PEG_NET_4_PC: 0x%x\n",
-				   ha->host_no, __func__,
-				   qla4_82xx_rd_32(ha,
-						   QLA82XX_PEG_HALT_STATUS1),
-				   qla4_82xx_rd_32(ha,
-						   QLA82XX_PEG_HALT_STATUS2),
+				   " 0x%x,\n PEG_NET_4_PC: 0x%x\n", ha->host_no,
+				   __func__, halt_status1, halt_status2,
 				   qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 +
 						   0x3c),
 				   qla4_82xx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 +
@@ -2515,7 +2517,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
 	if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
 	    test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
 	    test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) {
-		dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+		dev_state = qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE);
 
 		if (qla4_8xxx_check_temp(ha)) {
 			ql4_printk(KERN_INFO, ha, "disabling pause"
@@ -2547,8 +2549,8 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
 				qla4_82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x98,
 						CRB_NIU_XG_PAUSE_CTL_P0 |
 						CRB_NIU_XG_PAUSE_CTL_P1);
-				halt_status = qla4_82xx_rd_32(ha,
-						QLA82XX_PEG_HALT_STATUS1);
+				halt_status = qla4_8xxx_rd_direct(ha,
+						   QLA8XXX_PEG_HALT_STATUS1);
 
 				if (QLA82XX_FWERROR_CODE(halt_status) == 0x67)
 					ql4_printk(KERN_ERR, ha, "%s:"
@@ -3040,9 +3042,10 @@ recover_ha_init_adapter:
 		 * with multiple resets in the same thread,
 		 * utilize DPC to retry */
 		if (is_qla8022(ha)) {
-			qla4_82xx_idc_lock(ha);
-			dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_lock(ha);
+			dev_state = qla4_8xxx_rd_direct(ha,
+							QLA8XXX_CRB_DEV_STATE);
+			ha->isp_ops->idc_unlock(ha);
 			if (dev_state == QLA8XXX_DEV_FAILED) {
 				ql4_printk(KERN_INFO, ha, "%s: don't retry "
 					   "recover adapter. H/W is in Failed "
@@ -3385,10 +3388,10 @@ static void qla4xxx_do_dpc(struct work_struct *work)
 
 	if (is_qla8022(ha)) {
 		if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
-			qla4_82xx_idc_lock(ha);
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-			    QLA8XXX_DEV_FAILED);
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_lock(ha);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+					    QLA8XXX_DEV_FAILED);
+			ha->isp_ops->idc_unlock(ha);
 			ql4_printk(KERN_INFO, ha, "HW State: FAILED\n");
 			qla4_8xxx_device_state_handler(ha);
 		}
@@ -3512,9 +3515,9 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
 	ha->isp_ops->reset_firmware(ha);
 
 	if (is_qla8022(ha)) {
-		qla4_82xx_idc_lock(ha);
+		ha->isp_ops->idc_lock(ha);
 		qla4_8xxx_clear_drv_active(ha);
-		qla4_82xx_idc_unlock(ha);
+		ha->isp_ops->idc_unlock(ha);
 	}
 
 	/* Detach interrupts */
@@ -3658,6 +3661,8 @@ static struct isp_operations qla4xxx_isp_ops = {
 	.rd_shdw_req_q_out      = qla4xxx_rd_shdw_req_q_out,
 	.rd_shdw_rsp_q_in       = qla4xxx_rd_shdw_rsp_q_in,
 	.get_sys_info           = qla4xxx_get_sys_info,
+	.queue_mailbox_command	= qla4xxx_queue_mbox_cmd,
+	.process_mailbox_interrupt = qla4xxx_process_mbox_intr,
 };
 
 static struct isp_operations qla4_82xx_isp_ops = {
@@ -3666,8 +3671,10 @@ static struct isp_operations qla4_82xx_isp_ops = {
 	.disable_intrs          = qla4_82xx_disable_intrs,
 	.enable_intrs           = qla4_82xx_enable_intrs,
 	.start_firmware         = qla4_8xxx_load_risc,
+	.restart_firmware	= qla4_82xx_try_start_fw,
 	.intr_handler           = qla4_82xx_intr_handler,
 	.interrupt_service_routine = qla4_82xx_interrupt_service_routine,
+	.need_reset		= qla4_8xxx_need_reset,
 	.reset_chip             = qla4_82xx_isp_reset,
 	.reset_firmware         = qla4_8xxx_stop_firmware,
 	.queue_iocb             = qla4_82xx_queue_iocb,
@@ -3675,6 +3682,15 @@ static struct isp_operations qla4_82xx_isp_ops = {
 	.rd_shdw_req_q_out      = qla4_82xx_rd_shdw_req_q_out,
 	.rd_shdw_rsp_q_in       = qla4_82xx_rd_shdw_rsp_q_in,
 	.get_sys_info           = qla4_8xxx_get_sys_info,
+	.rd_reg_direct		= qla4_82xx_rd_32,
+	.wr_reg_direct		= qla4_82xx_wr_32,
+	.rd_reg_indirect	= qla4_82xx_md_rd_32,
+	.wr_reg_indirect	= qla4_82xx_md_wr_32,
+	.idc_lock		= qla4_82xx_idc_lock,
+	.idc_unlock		= qla4_82xx_idc_unlock,
+	.rom_lock_recovery	= qla4_82xx_rom_lock_recovery,
+	.queue_mailbox_command	= qla4_82xx_queue_mbox_cmd,
+	.process_mailbox_interrupt = qla4_82xx_process_mbox_intr,
 };
 
 uint16_t qla4xxx_rd_shdw_req_q_out(struct scsi_qla_host *ha)
@@ -5075,6 +5091,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
 	/* Setup Runtime configurable options */
 	if (is_qla8022(ha)) {
 		ha->isp_ops = &qla4_82xx_isp_ops;
+		ha->reg_tbl = (uint32_t *) qla4_82xx_reg_tbl;
 		rwlock_init(&ha->hw_lock);
 		ha->qdr_sn_window = -1;
 		ha->ddr_mn_window = -1;
@@ -5161,9 +5178,10 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
 	    init_retry_count++ < MAX_INIT_RETRIES) {
 
 		if (is_qla8022(ha)) {
-			qla4_82xx_idc_lock(ha);
-			dev_state = qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_lock(ha);
+			dev_state = qla4_8xxx_rd_direct(ha,
+							QLA82XX_CRB_DEV_STATE);
+			ha->isp_ops->idc_unlock(ha);
 			if (dev_state == QLA8XXX_DEV_FAILED) {
 				ql4_printk(KERN_WARNING, ha, "%s: don't retry "
 				    "initialize adapter. H/W is in failed state\n",
@@ -5186,10 +5204,10 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
 		if (is_qla8022(ha) && ql4xdontresethba) {
 			/* Put the device in failed state. */
 			DEBUG2(printk(KERN_ERR "HW STATE: FAILED\n"));
-			qla4_82xx_idc_lock(ha);
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-			    QLA8XXX_DEV_FAILED);
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_lock(ha);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+					    QLA8XXX_DEV_FAILED);
+			ha->isp_ops->idc_unlock(ha);
 		}
 		ret = -ENODEV;
 		goto remove_host;
@@ -6033,31 +6051,29 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
 		    "0x%x is the owner\n", ha->host_no, __func__,
 		    ha->pdev->devfn);
 
-		qla4_82xx_idc_lock(ha);
-		qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-		    QLA8XXX_DEV_COLD);
-
-		qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
-		    QLA82XX_IDC_VERSION);
-
-		qla4_82xx_idc_unlock(ha);
+		ha->isp_ops->idc_lock(ha);
+		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+				    QLA8XXX_DEV_COLD);
+		qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_IDC_VERSION,
+				    QLA82XX_IDC_VERSION);
+		ha->isp_ops->idc_unlock(ha);
 		clear_bit(AF_FW_RECOVERY, &ha->flags);
 		rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
-		qla4_82xx_idc_lock(ha);
+		ha->isp_ops->idc_lock(ha);
 
 		if (rval != QLA_SUCCESS) {
 			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
 			    "FAILED\n", ha->host_no, __func__);
 			qla4_8xxx_clear_drv_active(ha);
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-			    QLA8XXX_DEV_FAILED);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+					    QLA8XXX_DEV_FAILED);
 		} else {
 			ql4_printk(KERN_INFO, ha, "scsi%ld: %s: HW State: "
 			    "READY\n", ha->host_no, __func__);
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
-			    QLA8XXX_DEV_READY);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DEV_STATE,
+					    QLA8XXX_DEV_READY);
 			/* Clear driver state register */
-			qla4_82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
+			qla4_8xxx_wr_direct(ha, QLA8XXX_CRB_DRV_STATE, 0);
 			qla4_8xxx_set_drv_active(ha);
 			ret = qla4xxx_request_irqs(ha);
 			if (ret) {
@@ -6070,13 +6086,13 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
 				rval = QLA_SUCCESS;
 			}
 		}
-		qla4_82xx_idc_unlock(ha);
+		ha->isp_ops->idc_unlock(ha);
 	} else {
 		ql4_printk(KERN_INFO, ha, "scsi%ld: %s: devfn 0x%x is not "
 		    "the reset owner\n", ha->host_no, __func__,
 		    ha->pdev->devfn);
-		if ((qla4_82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
-		    QLA8XXX_DEV_READY)) {
+		if ((qla4_8xxx_rd_direct(ha, QLA8XXX_CRB_DEV_STATE) ==
+		     QLA8XXX_DEV_READY)) {
 			clear_bit(AF_FW_RECOVERY, &ha->flags);
 			rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
 			if (rval == QLA_SUCCESS) {
@@ -6091,9 +6107,9 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
 					rval = QLA_SUCCESS;
 				}
 			}
-			qla4_82xx_idc_lock(ha);
+			ha->isp_ops->idc_lock(ha);
 			qla4_8xxx_set_drv_active(ha);
-			qla4_82xx_idc_unlock(ha);
+			ha->isp_ops->idc_unlock(ha);
 		}
 	}
 	clear_bit(DPC_RESET_ACTIVE, &ha->dpc_flags);
-- 
1.7.8.GIT

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux