Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[pandora-kernel.git] / drivers / scsi / lpfc / lpfc_init.c
index 295c7dd..b306579 100644 (file)
@@ -813,6 +813,7 @@ lpfc_hba_down_post_s3(struct lpfc_hba *phba)
 
        return 0;
 }
+
 /**
  * lpfc_hba_down_post_s4 - Perform lpfc uninitialization after HBA reset
  * @phba: pointer to lpfc HBA data structure.
@@ -2234,10 +2235,9 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
 void
 __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
 {
-       /* Clear pending FCF rediscovery wait and failover in progress flags */
-       phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND |
-                               FCF_DEAD_DISC |
-                               FCF_ACVL_DISC);
+       /* Clear pending FCF rediscovery wait flag */
+       phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
+
        /* Now, try to stop the timer */
        del_timer(&phba->fcf.redisc_wait);
 }
@@ -2261,6 +2261,8 @@ lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
                return;
        }
        __lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
+       /* Clear failover in progress flags */
+       phba->fcf.fcf_flag &= ~(FCF_DEAD_DISC | FCF_ACVL_DISC);
        spin_unlock_irq(&phba->hbalock);
 }
 
@@ -2935,8 +2937,7 @@ lpfc_sli4_fcf_redisc_wait_tmo(unsigned long ptr)
        phba->fcf.fcf_flag |= FCF_REDISC_EVT;
        spin_unlock_irq(&phba->hbalock);
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
-                       "2776 FCF rediscover wait timer expired, post "
-                       "a worker thread event for FCF table scan\n");
+                       "2776 FCF rediscover quiescent timer expired\n");
        /* wake up worker thread */
        lpfc_worker_wake_up(phba);
 }
@@ -3311,35 +3312,34 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                if (event_type == LPFC_FCOE_EVENT_TYPE_NEW_FCF)
                        lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2546 New FCF found event: "
-                                       "evt_tag:x%x, fcf_index:x%x\n",
+                                       "2546 New FCF event, evt_tag:x%x, "
+                                       "index:x%x\n",
                                        acqe_fcoe->event_tag,
                                        acqe_fcoe->index);
                else
                        lpfc_printf_log(phba, KERN_WARNING, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2788 FCF parameter modified event: "
-                                       "evt_tag:x%x, fcf_index:x%x\n",
+                                       "2788 FCF param modified event, "
+                                       "evt_tag:x%x, index:x%x\n",
                                        acqe_fcoe->event_tag,
                                        acqe_fcoe->index);
                if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
                        /*
                         * During period of FCF discovery, read the FCF
                         * table record indexed by the event to update
-                        * FCF round robin failover eligible FCF bmask.
+                        * FCF roundrobin failover eligible FCF bmask.
                         */
                        lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2779 Read new FCF record with "
-                                       "fcf_index:x%x for updating FCF "
-                                       "round robin failover bmask\n",
+                                       "2779 Read FCF (x%x) for updating "
+                                       "roundrobin FCF failover bmask\n",
                                        acqe_fcoe->index);
                        rc = lpfc_sli4_read_fcf_rec(phba, acqe_fcoe->index);
                }
 
                /* If the FCF discovery is in progress, do nothing. */
                spin_lock_irq(&phba->hbalock);
-               if (phba->hba_flag & FCF_DISC_INPROGRESS) {
+               if (phba->hba_flag & FCF_TS_INPROG) {
                        spin_unlock_irq(&phba->hbalock);
                        break;
                }
@@ -3358,15 +3358,15 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
 
                /* Otherwise, scan the entire FCF table and re-discover SAN */
                lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
-                               "2770 Start FCF table scan due to new FCF "
-                               "event: evt_tag:x%x, fcf_index:x%x\n",
+                               "2770 Start FCF table scan per async FCF "
+                               "event, evt_tag:x%x, index:x%x\n",
                                acqe_fcoe->event_tag, acqe_fcoe->index);
                rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba,
                                                     LPFC_FCOE_FCF_GET_FIRST);
                if (rc)
                        lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
                                        "2547 Issue FCF scan read FCF mailbox "
-                                       "command failed 0x%x\n", rc);
+                                       "command failed (x%x)\n", rc);
                break;
 
        case LPFC_FCOE_EVENT_TYPE_FCF_TABLE_FULL:
@@ -3378,9 +3378,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
 
        case LPFC_FCOE_EVENT_TYPE_FCF_DEAD:
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
-                       "2549 FCF disconnected from network index 0x%x"
-                       " tag 0x%x\n", acqe_fcoe->index,
-                       acqe_fcoe->event_tag);
+                       "2549 FCF (x%x) disconnected from network, "
+                       "tag:x%x\n", acqe_fcoe->index, acqe_fcoe->event_tag);
                /*
                 * If we are in the middle of FCF failover process, clear
                 * the corresponding FCF bit in the roundrobin bitmap.
@@ -3494,9 +3493,8 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
                        spin_unlock_irq(&phba->hbalock);
                        lpfc_printf_log(phba, KERN_INFO, LOG_FIP |
                                        LOG_DISCOVERY,
-                                       "2773 Start FCF fast failover due "
-                                       "to CVL event: evt_tag:x%x\n",
-                                       acqe_fcoe->event_tag);
+                                       "2773 Start FCF failover per CVL, "
+                                       "evt_tag:x%x\n", acqe_fcoe->event_tag);
                        rc = lpfc_sli4_redisc_fcf_table(phba);
                        if (rc) {
                                lpfc_printf_log(phba, KERN_ERR, LOG_FIP |
@@ -3646,8 +3644,7 @@ void lpfc_sli4_fcf_redisc_event_proc(struct lpfc_hba *phba)
 
        /* Scan FCF table from the first entry to re-discover SAN */
        lpfc_printf_log(phba, KERN_INFO, LOG_FIP | LOG_DISCOVERY,
-                       "2777 Start FCF table scan after FCF "
-                       "rediscovery quiescent period over\n");
+                       "2777 Start post-quiescent FCF table scan\n");
        rc = lpfc_sli4_fcf_scan_read_fcf_rec(phba, LPFC_FCOE_FCF_GET_FIRST);
        if (rc)
                lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
@@ -4165,7 +4162,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
                goto out_free_active_sgl;
        }
 
-       /* Allocate eligible FCF bmask memory for FCF round robin failover */
+       /* Allocate eligible FCF bmask memory for FCF roundrobin failover */
        longs = (LPFC_SLI4_FCF_TBL_INDX_MAX + BITS_PER_LONG - 1)/BITS_PER_LONG;
        phba->fcf.fcf_rr_bmask = kzalloc(longs * sizeof(unsigned long),
                                         GFP_KERNEL);
@@ -7270,6 +7267,51 @@ lpfc_sli4_unset_hba(struct lpfc_hba *phba)
        return;
 }
 
+/**
+ * lpfc_sli4_xri_exchange_busy_wait - Wait for device XRI exchange busy
+ * @phba: Pointer to HBA context object.
+ *
+ * This function is called in the SLI4 code path to wait for completion
+ * of device's XRIs exchange busy. It will check the XRI exchange busy
+ * on outstanding FCP and ELS I/Os every 10ms for up to 10 seconds; after
+ * that, it will check the XRI exchange busy on outstanding FCP and ELS
+ * I/Os every 30 seconds, log error message, and wait forever. Only when
+ * all XRI exchange busy complete, the driver unload shall proceed with
+ * invoking the function reset ioctl mailbox command to the CNA and the
+ * the rest of the driver unload resource release.
+ **/
+static void
+lpfc_sli4_xri_exchange_busy_wait(struct lpfc_hba *phba)
+{
+       int wait_time = 0;
+       int fcp_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_scsi_buf_list);
+       int els_xri_cmpl = list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);
+
+       while (!fcp_xri_cmpl || !els_xri_cmpl) {
+               if (wait_time > LPFC_XRI_EXCH_BUSY_WAIT_TMO) {
+                       if (!fcp_xri_cmpl)
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                               "2877 FCP XRI exchange busy "
+                                               "wait time: %d seconds.\n",
+                                               wait_time/1000);
+                       if (!els_xri_cmpl)
+                               lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+                                               "2878 ELS XRI exchange busy "
+                                               "wait time: %d seconds.\n",
+                                               wait_time/1000);
+                       msleep(LPFC_XRI_EXCH_BUSY_WAIT_T2);
+                       wait_time += LPFC_XRI_EXCH_BUSY_WAIT_T2;
+               } else {
+                       msleep(LPFC_XRI_EXCH_BUSY_WAIT_T1);
+                       wait_time += LPFC_XRI_EXCH_BUSY_WAIT_T1;
+               }
+               fcp_xri_cmpl =
+                       list_empty(&phba->sli4_hba.lpfc_abts_scsi_buf_list);
+               els_xri_cmpl =
+                       list_empty(&phba->sli4_hba.lpfc_abts_els_sgl_list);
+       }
+}
+
 /**
  * lpfc_sli4_hba_unset - Unset the fcoe hba
  * @phba: Pointer to HBA context object.
@@ -7315,6 +7357,12 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
                spin_unlock_irq(&phba->hbalock);
        }
 
+       /* Abort all iocbs associated with the hba */
+       lpfc_sli_hba_iocb_abort(phba);
+
+       /* Wait for completion of device XRI exchange busy */
+       lpfc_sli4_xri_exchange_busy_wait(phba);
+
        /* Disable PCI subsystem interrupt */
        lpfc_sli4_disable_intr(phba);