diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_init.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_init.c | 75 |
1 files changed, 63 insertions, 12 deletions
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 5bb57c5282c9..285cb204f300 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -1121,7 +1121,7 @@ qla81xx_reset_mpi(scsi_qla_host_t *vha) * * Returns 0 on success. */ -static inline void +static inline int qla24xx_reset_risc(scsi_qla_host_t *vha) { unsigned long flags = 0; @@ -1130,6 +1130,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) uint32_t cnt, d2; uint16_t wd; static int abts_cnt; /* ISP abort retry counts */ + int rval = QLA_SUCCESS; spin_lock_irqsave(&ha->hardware_lock, flags); @@ -1142,26 +1143,57 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) udelay(10); } + if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE)) + set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017e, + "HCCR: 0x%x, Control Status %x, DMA active status:0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_DWORD(®->ctrl_status), + (RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE)); + WRT_REG_DWORD(®->ctrl_status, CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); udelay(100); + /* Wait for firmware to complete NVRAM accesses. */ d2 = (uint32_t) RD_REG_WORD(®->mailbox0); - for (cnt = 10000 ; cnt && d2; cnt--) { - udelay(5); - d2 = (uint32_t) RD_REG_WORD(®->mailbox0); + for (cnt = 10000; RD_REG_WORD(®->mailbox0) != 0 && + rval == QLA_SUCCESS; cnt--) { barrier(); + if (cnt) + udelay(5); + else + rval = QLA_FUNCTION_TIMEOUT; } + if (rval == QLA_SUCCESS) + set_bit(ISP_MBX_RDY, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x017f, + "HCCR: 0x%x, MailBox0 Status 0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_DWORD(®->mailbox0)); + /* Wait for soft-reset to complete. */ d2 = RD_REG_DWORD(®->ctrl_status); - for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) { - udelay(5); - d2 = RD_REG_DWORD(®->ctrl_status); + for (cnt = 0; cnt < 6000000; cnt++) { barrier(); + if ((RD_REG_DWORD(®->ctrl_status) & + CSRX_ISP_SOFT_RESET) == 0) + break; + + udelay(5); } + if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_ISP_SOFT_RESET)) + set_bit(ISP_SOFT_RESET_CMPL, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015d, + "HCCR: 0x%x, Soft Reset status: 0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_DWORD(®->ctrl_status)); /* If required, do an MPI FW reset now */ if (test_and_clear_bit(MPI_RESET_NEEDED, &vha->dpc_flags)) { @@ -1190,16 +1222,32 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) RD_REG_DWORD(®->hccr); d2 = (uint32_t) RD_REG_WORD(®->mailbox0); - for (cnt = 6000000 ; cnt && d2; cnt--) { - udelay(5); - d2 = (uint32_t) RD_REG_WORD(®->mailbox0); + for (cnt = 6000000; RD_REG_WORD(®->mailbox0) != 0 && + rval == QLA_SUCCESS; cnt--) { barrier(); + if (cnt) + udelay(5); + else + rval = QLA_FUNCTION_TIMEOUT; } + if (rval == QLA_SUCCESS) + set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); + + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015e, + "Host Risc 0x%x, mailbox0 0x%x\n", + RD_REG_DWORD(®->hccr), + RD_REG_WORD(®->mailbox0)); spin_unlock_irqrestore(&ha->hardware_lock, flags); + ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x015f, + "Driver in %s mode\n", + IS_NOPOLLING_TYPE(ha) ? "Interrupt" : "Polling"); + if (IS_NOPOLLING_TYPE(ha)) ha->isp_ops->enable_intrs(ha); + + return rval; } static void @@ -2243,8 +2291,11 @@ qla2x00_fw_ready(scsi_qla_host_t *vha) rval = QLA_SUCCESS; - /* 20 seconds for loop down. */ - min_wait = 20; + /* Time to wait for loop down */ + if (IS_P3P_TYPE(ha)) + min_wait = 30; + else + min_wait = 20; /* * Firmware should take at most one RATOV to login, plus 5 seconds for |