diff options
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 38 | ||||
| -rw-r--r-- | drivers/scsi/lpfc/lpfc_sli.c | 10 |
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 | **/ | ||
| 4977 | static int | ||
| 4978 | lpfc_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 | /** |
