Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-block.git] / drivers / scsi / qla2xxx / qla_init.c
index e59f25bff7abbb49a9f2478b8e1cf59e9d8fe399..285cb204f30051897ad08582c4e329eb2f359fa1 100644 (file)
@@ -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(&reg->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(&reg->hccr),
+           RD_REG_DWORD(&reg->ctrl_status),
+           (RD_REG_DWORD(&reg->ctrl_status) & CSRX_DMA_ACTIVE));
+
        WRT_REG_DWORD(&reg->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(&reg->mailbox0);
-       for (cnt = 10000 ; cnt && d2; cnt--) {
-               udelay(5);
-               d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+       for (cnt = 10000; RD_REG_WORD(&reg->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(&reg->hccr),
+           RD_REG_DWORD(&reg->mailbox0));
+
        /* Wait for soft-reset to complete. */
        d2 = RD_REG_DWORD(&reg->ctrl_status);
-       for (cnt = 6000000 ; cnt && (d2 & CSRX_ISP_SOFT_RESET); cnt--) {
-               udelay(5);
-               d2 = RD_REG_DWORD(&reg->ctrl_status);
+       for (cnt = 0; cnt < 6000000; cnt++) {
                barrier();
+               if ((RD_REG_DWORD(&reg->ctrl_status) &
+                   CSRX_ISP_SOFT_RESET) == 0)
+                       break;
+
+               udelay(5);
        }
+       if (!(RD_REG_DWORD(&reg->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(&reg->hccr),
+           RD_REG_DWORD(&reg->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(&reg->hccr);
 
        d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
-       for (cnt = 6000000 ; cnt && d2; cnt--) {
-               udelay(5);
-               d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
+       for (cnt = 6000000; RD_REG_WORD(&reg->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(&reg->hccr),
+            RD_REG_WORD(&reg->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
@@ -5364,7 +5415,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr)
        blob = qla2x00_request_firmware(vha);
        if (!blob) {
                ql_log(ql_log_info, vha, 0x0083,
-                   "Fimware image unavailable.\n");
+                   "Firmware image unavailable.\n");
                ql_log(ql_log_info, vha, 0x0084,
                    "Firmware images can be retrieved from: "QLA_FW_URL ".\n");
                return QLA_FUNCTION_FAILED;
@@ -5467,7 +5518,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr)
        blob = qla2x00_request_firmware(vha);
        if (!blob) {
                ql_log(ql_log_warn, vha, 0x0090,
-                   "Fimware image unavailable.\n");
+                   "Firmware image unavailable.\n");
                ql_log(ql_log_warn, vha, 0x0091,
                    "Firmware images can be retrieved from: "
                    QLA_FW_URL ".\n");