]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi/lpfc: Fixed system crash due to not providing SCSI error-handling host reset...
authorVaios Papadimitriou <vaios.papadimitriou@emulex.com>
Tue, 28 Aug 2012 22:50:32 +0000 (15:50 -0700)
committerJerry Snitselaar <jerry.snitselaar@oracle.com>
Wed, 5 Sep 2012 19:25:45 +0000 (12:25 -0700)
commit id: 27b01b821f136e657c28078007a865a307816c1a

Signed-off-by: Jerry Snitselaar <jerry.snitselaar@oracle.com>
drivers/scsi/lpfc/lpfc_scsi.c
drivers/scsi/lpfc/lpfc_sli.c

index 148f250cffcd4f35a8428c7b4c904e9c94a7843b..a7155527295689498466d7cc88d6dc5ecae0e3ec 100644 (file)
@@ -4932,6 +4932,43 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
        return ret;
 }
 
+/**
+ * lpfc_host_reset_handler - scsi_host_template eh_host_reset_handler entry pt
+ * @cmnd: Pointer to scsi_cmnd data structure.
+ *
+ * This routine does host reset to the adaptor port. It brings the HBA
+ * offline, performs a board restart, and then brings the board back online.
+ * The lpfc_offline calls lpfc_sli_hba_down which will abort and local
+ * reject all outstanding SCSI commands to the host and error returned
+ * back to SCSI mid-level. As this will be SCSI mid-level's last resort
+ * of error handling, it will only return error if resetting of the adapter
+ * is not successful; in all other cases, will return success.
+ *
+ * Return code :
+ *  0x2003 - Error
+ *  0x2002 - Success
+ **/
+static int
+lpfc_host_reset_handler(struct scsi_cmnd *cmnd)
+{
+       struct Scsi_Host *shost = cmnd->device->host;
+       struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+       struct lpfc_hba *phba = vport->phba;
+       int rc, ret = SUCCESS;
+
+       lpfc_offline_prep(phba);
+       lpfc_offline(phba);
+       rc = lpfc_sli_brdrestart(phba);
+       if (rc)
+               ret = FAILED;
+       lpfc_online(phba);
+       lpfc_unblock_mgmt_io(phba);
+
+       lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
+                       "3172 SCSI layer issued Host Reset Data: x%x\n", ret);
+       return ret;
+}
+
 /**
  * lpfc_slave_alloc - scsi_host_template slave_alloc entry point
  * @sdev: Pointer to scsi_device.
@@ -5074,6 +5111,7 @@ struct scsi_host_template lpfc_template = {
        .eh_device_reset_handler = lpfc_device_reset_handler,
        .eh_target_reset_handler = lpfc_target_reset_handler,
        .eh_bus_reset_handler   = lpfc_bus_reset_handler,
+       .eh_host_reset_handler  = lpfc_host_reset_handler,
        .slave_alloc            = lpfc_slave_alloc,
        .slave_configure        = lpfc_slave_configure,
        .slave_destroy          = lpfc_slave_destroy,
index 048183d4fb109840a1d11a8b4293a70a9211da1d..c74f15e8ed365b4b2eff6a9ea0052c2f0f9190c1 100644 (file)
@@ -3882,6 +3882,7 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
 {
        struct lpfc_sli *psli = &phba->sli;
        uint16_t cfg_value;
+       int rc;
 
        /* Reset HBA */
        lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
@@ -3910,12 +3911,12 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
 
        /* Perform FCoE PCI function reset */
        lpfc_sli4_queue_destroy(phba);
-       lpfc_pci_function_reset(phba);
+       rc = lpfc_pci_function_reset(phba);
 
        /* Restore PCI cmd register */
        pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
 
-       return 0;
+       return rc;
 }
 
 /**
@@ -4007,6 +4008,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
 {
        struct lpfc_sli *psli = &phba->sli;
        uint32_t hba_aer_enabled;
+       int rc;
 
        /* Restart HBA */
        lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
@@ -4016,7 +4018,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
        /* Take PCIe device Advanced Error Reporting (AER) state */
        hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED;
 
-       lpfc_sli4_brdreset(phba);
+       rc = lpfc_sli4_brdreset(phba);
 
        spin_lock_irq(&phba->hbalock);
        phba->pport->stopped = 0;
@@ -4033,7 +4035,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
 
        lpfc_hba_down_post(phba);
 
-       return 0;
+       return rc;
 }
 
 /**