qla2xxx: Check the QLA8044_CRB_DRV_ACTIVE_INDEX register when we are not the owner...
authorHiral Patel <hiral.patel@qlogic.com>
Fri, 11 Apr 2014 20:54:34 +0000 (16:54 -0400)
committerChristoph Hellwig <hch@lst.de>
Mon, 19 May 2014 11:31:04 +0000 (13:31 +0200)
Signed-off-by: Hiral Patel <hiral.patel@qlogic.com>
Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_nx2.c
drivers/scsi/qla2xxx/qla_nx2.h

index e48084f2fb248fcf2f8e448096df61d8604d8223..85646820af3287c858195d88150226c7e522987d 100644 (file)
@@ -51,6 +51,7 @@
  * | Virtual Port                 |       0xa007       |               |
  * | ISP82XX Specific             |       0xb157       | 0xb002,0xb024  |
  * |                              |                    | 0xb09e,0xb0ae  |
+ * |                             |                    | 0xb0c3,0xb0c6  |
  * |                              |                    | 0xb0e0-0xb0ef  |
  * |                              |                    | 0xb085,0xb0dc  |
  * |                              |                    | 0xb107,0xb108  |
index e5b4a409289324812301fc13d0ddebf87130047e..da9e3902f2190b6a61d7f06200dbe5806f15dced 100644 (file)
@@ -1633,7 +1633,7 @@ static void
 qla8044_need_reset_handler(struct scsi_qla_host *vha)
 {
        uint32_t dev_state = 0, drv_state, drv_active;
-       unsigned long reset_timeout, dev_init_timeout;
+       unsigned long reset_timeout;
        struct qla_hw_data *ha = vha->hw;
 
        ql_log(ql_log_fatal, vha, 0xb0c2,
@@ -1647,84 +1647,78 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha)
                qla8044_idc_lock(ha);
        }
 
+       dev_state = qla8044_rd_direct(vha,
+           QLA8044_CRB_DEV_STATE_INDEX);
        drv_state = qla8044_rd_direct(vha,
            QLA8044_CRB_DRV_STATE_INDEX);
        drv_active = qla8044_rd_direct(vha,
            QLA8044_CRB_DRV_ACTIVE_INDEX);
 
        ql_log(ql_log_info, vha, 0xb0c5,
-           "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n",
-           __func__, vha->host_no, drv_state, drv_active);
+           "%s(%ld): drv_state = 0x%x, drv_active = 0x%x dev_state = 0x%x\n",
+           __func__, vha->host_no, drv_state, drv_active, dev_state);
 
-       if (!ha->flags.nic_core_reset_owner) {
-               ql_dbg(ql_dbg_p3p, vha, 0xb0c3,
-                   "%s(%ld): reset acknowledged\n",
-                   __func__, vha->host_no);
-               qla8044_set_rst_ready(vha);
+       qla8044_set_rst_ready(vha);
 
-               /* Non-reset owners ACK Reset and wait for device INIT state
-                * as part of Reset Recovery by Reset Owner
-                */
-               dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
+       /* wait for 10 seconds for reset ack from all functions */
+       reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
 
-               do {
-                       if (time_after_eq(jiffies, dev_init_timeout)) {
-                               ql_log(ql_log_info, vha, 0xb0c4,
-                                   "%s: Non Reset owner: Reset Ack Timeout!\n",
-                                   __func__);
-                               break;
-                       }
+       do {
+               if (time_after_eq(jiffies, reset_timeout)) {
+                       ql_log(ql_log_info, vha, 0xb0c4,
+                           "%s: Function %d: Reset Ack Timeout!, drv_state: 0x%08x, drv_active: 0x%08x\n",
+                           __func__, ha->portnum, drv_state, drv_active);
+                       break;
+               }
 
-                       qla8044_idc_unlock(ha);
-                       msleep(1000);
-                       qla8044_idc_lock(ha);
+               qla8044_idc_unlock(ha);
+               msleep(1000);
+               qla8044_idc_lock(ha);
 
-                       dev_state = qla8044_rd_direct(vha,
-                                       QLA8044_CRB_DEV_STATE_INDEX);
-               } while (((drv_state & drv_active) != drv_active) &&
-                   (dev_state == QLA8XXX_DEV_NEED_RESET));
+               dev_state = qla8044_rd_direct(vha,
+                   QLA8044_CRB_DEV_STATE_INDEX);
+               drv_state = qla8044_rd_direct(vha,
+                   QLA8044_CRB_DRV_STATE_INDEX);
+               drv_active = qla8044_rd_direct(vha,
+                   QLA8044_CRB_DRV_ACTIVE_INDEX);
+       } while (((drv_state & drv_active) != drv_active) &&
+           (dev_state == QLA8XXX_DEV_NEED_RESET));
+
+       /* Remove IDC participation of functions not acknowledging */
+       if (drv_state != drv_active) {
+               ql_log(ql_log_info, vha, 0xb0c7,
+                   "%s(%ld): Function %d turning off drv_active of non-acking function 0x%x\n",
+                   __func__, vha->host_no, ha->portnum,
+                   (drv_active ^ drv_state));
+               drv_active = drv_active & drv_state;
+               qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
+                   drv_active);
        } else {
-               qla8044_set_rst_ready(vha);
-
-               /* wait for 10 seconds for reset ack from all functions */
-               reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
-
-               while ((drv_state & drv_active) != drv_active) {
-                       if (time_after_eq(jiffies, reset_timeout)) {
-                               ql_log(ql_log_info, vha, 0xb0c6,
-                                   "%s: RESET TIMEOUT!"
-                                   "drv_state: 0x%08x, drv_active: 0x%08x\n",
-                                   QLA2XXX_DRIVER_NAME, drv_state, drv_active);
-                               break;
-                       }
-
-                       qla8044_idc_unlock(ha);
-                       msleep(1000);
-                       qla8044_idc_lock(ha);
-
-                       drv_state = qla8044_rd_direct(vha,
-                           QLA8044_CRB_DRV_STATE_INDEX);
-                       drv_active = qla8044_rd_direct(vha,
-                           QLA8044_CRB_DRV_ACTIVE_INDEX);
-               }
-
-               if (drv_state != drv_active) {
-                       ql_log(ql_log_info, vha, 0xb0c7,
-                           "%s(%ld): Reset_owner turning off drv_active "
-                           "of non-acking function 0x%x\n", __func__,
-                           vha->host_no, (drv_active ^ drv_state));
-                       drv_active = drv_active & drv_state;
-                       qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX,
-                           drv_active);
+               /*
+                * Reset owner should execute reset recovery,
+                * if all functions acknowledged
+                */
+               if ((ha->flags.nic_core_reset_owner) &&
+                   (dev_state == QLA8XXX_DEV_NEED_RESET)) {
+                       ha->flags.nic_core_reset_owner = 0;
+                       qla8044_device_bootstrap(vha);
+                       return;
                }
+       }
 
-               /*
-               * Clear RESET OWNER, will be set at next reset
-               * by next RST_OWNER
-               */
+       /* Exit if non active function */
+       if (!(drv_active & (1 << ha->portnum))) {
                ha->flags.nic_core_reset_owner = 0;
+               return;
+       }
 
-               /* Start Reset Recovery */
+       /*
+        * Execute Reset Recovery if Reset Owner or Function 7
+        * is the only active function
+        */
+       if (ha->flags.nic_core_reset_owner ||
+           ((drv_state & drv_active) == QLA8044_FUN7_ACTIVE_INDEX)) {
+               ha->flags.nic_core_reset_owner = 0;
                qla8044_device_bootstrap(vha);
        }
 }
index c9ff2cbf5008207c977fa572cd0b46b7ff2a4d92..ada36057d7cde4727653cf783b165d707d752e86 100644 (file)
 #define QLA8044_LINK_SPEED(f)          (0x36E0+(((f) >> 2) * 4))
 #define QLA8044_MAX_LINK_SPEED(f)       (0x36F0+(((f) / 4) * 4))
 #define QLA8044_LINK_SPEED_FACTOR      10
+#define QLA8044_FUN7_ACTIVE_INDEX      0x80
 
 /* FLASH API Defines */
 #define QLA8044_FLASH_MAX_WAIT_USEC    100