From 33693c7aab43958906941a98f3947d66f4277e03 Mon Sep 17 00:00:00 2001 From: Vikas Chaudhary Date: Wed, 22 Aug 2012 07:55:04 -0400 Subject: [PATCH] [SCSI] qla4xxx: Added new functions in isp_ops Signed-off-by: Poornima Vonti Signed-off-by: Vikas Chaudhary Reviewed-by: Mike Christie Signed-off-by: James Bottomley --- 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 | 277 +++++++++++++++++++------------- drivers/scsi/qla4xxx/ql4_nx.h | 34 ++++ drivers/scsi/qla4xxx/ql4_os.c | 108 +++++++------ 7 files changed, 343 insertions(+), 222 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_attr.c b/drivers/scsi/qla4xxx/ql4_attr.c index 71b44f087148..befe4f9fa629 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 82f70db08078..11271a2f551c 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 a9f651618c79..1010d717b7db 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 ea08e527faf7..73324fba64bc 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 84b039f9e9b5..13d8e4895f58 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,10 +421,36 @@ 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 + * 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; + *data = readl((void __iomem *)(off_value + CRB_INDIRECT_2M + + ha->nx_pcibase)); + } + return rval; +} + +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; off_value = off & 0xFFFF0000; writel(off_value, (void __iomem *)(CRB_WINDOW_2M + ha->nx_pcibase)); @@ -437,19 +462,13 @@ static int qla4_8xxx_md_rw_32(struct scsi_qla_host *ha, uint32_t off, 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; - } - - off_value = off & 0x0000FFFF; - - if (flag) + __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 16c5ae6d271a..1894de093f06 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 6aa508c5e4c6..ea8845ba0aaa 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);