aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2012-05-09 21:19:44 -0400
committerJames Bottomley <JBottomley@Parallels.com>2012-05-17 06:17:18 -0400
commit27b01b821f136e657c28078007a865a307816c1a (patch)
treee2f3faf40148b02bcf65c751ce3fa6efdb500874 /drivers/scsi/lpfc
parent93d1379e6924daef1968779d97c46ba2e0915fd2 (diff)
[SCSI] lpfc 8.3.31: Fixed system crash due to not providing SCSI error-handling host reset handler
Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c38
-rw-r--r--drivers/scsi/lpfc/lpfc_sli.c10
2 files changed, 44 insertions, 4 deletions
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index b410555f3a83..66e09069f281 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -4959,6 +4959,43 @@ lpfc_bus_reset_handler(struct scsi_cmnd *cmnd)
4959} 4959}
4960 4960
4961/** 4961/**
4962 * lpfc_host_reset_handler - scsi_host_template eh_host_reset_handler entry pt
4963 * @cmnd: Pointer to scsi_cmnd data structure.
4964 *
4965 * This routine does host reset to the adaptor port. It brings the HBA
4966 * offline, performs a board restart, and then brings the board back online.
4967 * The lpfc_offline calls lpfc_sli_hba_down which will abort and local
4968 * reject all outstanding SCSI commands to the host and error returned
4969 * back to SCSI mid-level. As this will be SCSI mid-level's last resort
4970 * of error handling, it will only return error if resetting of the adapter
4971 * is not successful; in all other cases, will return success.
4972 *
4973 * Return code :
4974 * 0x2003 - Error
4975 * 0x2002 - Success
4976 **/
4977static int
4978lpfc_host_reset_handler(struct scsi_cmnd *cmnd)
4979{
4980 struct Scsi_Host *shost = cmnd->device->host;
4981 struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
4982 struct lpfc_hba *phba = vport->phba;
4983 int rc, ret = SUCCESS;
4984
4985 lpfc_offline_prep(phba);
4986 lpfc_offline(phba);
4987 rc = lpfc_sli_brdrestart(phba);
4988 if (rc)
4989 ret = FAILED;
4990 lpfc_online(phba);
4991 lpfc_unblock_mgmt_io(phba);
4992
4993 lpfc_printf_log(phba, KERN_ERR, LOG_FCP,
4994 "3172 SCSI layer issued Host Reset Data: x%x\n", ret);
4995 return ret;
4996}
4997
4998/**
4962 * lpfc_slave_alloc - scsi_host_template slave_alloc entry point 4999 * lpfc_slave_alloc - scsi_host_template slave_alloc entry point
4963 * @sdev: Pointer to scsi_device. 5000 * @sdev: Pointer to scsi_device.
4964 * 5001 *
@@ -5090,6 +5127,7 @@ struct scsi_host_template lpfc_template = {
5090 .eh_device_reset_handler = lpfc_device_reset_handler, 5127 .eh_device_reset_handler = lpfc_device_reset_handler,
5091 .eh_target_reset_handler = lpfc_target_reset_handler, 5128 .eh_target_reset_handler = lpfc_target_reset_handler,
5092 .eh_bus_reset_handler = lpfc_bus_reset_handler, 5129 .eh_bus_reset_handler = lpfc_bus_reset_handler,
5130 .eh_host_reset_handler = lpfc_host_reset_handler,
5093 .slave_alloc = lpfc_slave_alloc, 5131 .slave_alloc = lpfc_slave_alloc,
5094 .slave_configure = lpfc_slave_configure, 5132 .slave_configure = lpfc_slave_configure,
5095 .slave_destroy = lpfc_slave_destroy, 5133 .slave_destroy = lpfc_slave_destroy,
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
index 832899410306..b4720a109817 100644
--- a/drivers/scsi/lpfc/lpfc_sli.c
+++ b/drivers/scsi/lpfc/lpfc_sli.c
@@ -3885,6 +3885,7 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
3885{ 3885{
3886 struct lpfc_sli *psli = &phba->sli; 3886 struct lpfc_sli *psli = &phba->sli;
3887 uint16_t cfg_value; 3887 uint16_t cfg_value;
3888 int rc;
3888 3889
3889 /* Reset HBA */ 3890 /* Reset HBA */
3890 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 3891 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
@@ -3913,12 +3914,12 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba)
3913 3914
3914 /* Perform FCoE PCI function reset */ 3915 /* Perform FCoE PCI function reset */
3915 lpfc_sli4_queue_destroy(phba); 3916 lpfc_sli4_queue_destroy(phba);
3916 lpfc_pci_function_reset(phba); 3917 rc = lpfc_pci_function_reset(phba);
3917 3918
3918 /* Restore PCI cmd register */ 3919 /* Restore PCI cmd register */
3919 pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value); 3920 pci_write_config_word(phba->pcidev, PCI_COMMAND, cfg_value);
3920 3921
3921 return 0; 3922 return rc;
3922} 3923}
3923 3924
3924/** 3925/**
@@ -4010,6 +4011,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
4010{ 4011{
4011 struct lpfc_sli *psli = &phba->sli; 4012 struct lpfc_sli *psli = &phba->sli;
4012 uint32_t hba_aer_enabled; 4013 uint32_t hba_aer_enabled;
4014 int rc;
4013 4015
4014 /* Restart HBA */ 4016 /* Restart HBA */
4015 lpfc_printf_log(phba, KERN_INFO, LOG_SLI, 4017 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
@@ -4019,7 +4021,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
4019 /* Take PCIe device Advanced Error Reporting (AER) state */ 4021 /* Take PCIe device Advanced Error Reporting (AER) state */
4020 hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED; 4022 hba_aer_enabled = phba->hba_flag & HBA_AER_ENABLED;
4021 4023
4022 lpfc_sli4_brdreset(phba); 4024 rc = lpfc_sli4_brdreset(phba);
4023 4025
4024 spin_lock_irq(&phba->hbalock); 4026 spin_lock_irq(&phba->hbalock);
4025 phba->pport->stopped = 0; 4027 phba->pport->stopped = 0;
@@ -4036,7 +4038,7 @@ lpfc_sli_brdrestart_s4(struct lpfc_hba *phba)
4036 4038
4037 lpfc_hba_down_post(phba); 4039 lpfc_hba_down_post(phba);
4038 4040
4039 return 0; 4041 return rc;
4040} 4042}
4041 4043
4042/** 4044/**