diff options
author | James Smart <james.smart@emulex.com> | 2015-04-07 15:07:13 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-04-10 10:46:35 -0400 |
commit | ea4142f6b10585f271a40ee52eec2f55e48aeccf (patch) | |
tree | 553816bdcdf18b3c887c3d10fc3933b2a0d3c937 | |
parent | 85c0f177200b49cbed0f9c9ac67fe2656749f9cd (diff) |
lpfc: Fix host reset escalation killing all IOs.
Fix host reset escalation killing all IOs.
SLI-3 adapters will use a new host template. The template differs
from SLI-4 adapters in that it does not have an eh_host_reset_handler.
Lpfc has traditionally never had a host_reset. The host reset
handler was added when we ran into a stuck hardware condition on a
SLI-4 adapter. The host_reset will reset and reinit the pci function,
clearing the hardware condition.
Unfortunately, the host reset handler uses attach/detach code paths,
which makes scsi_add_host() and scsi_remove_host() calls. Meaning, a
host_reset will completely remove the scsi_host from the system. As a
new call to scsi_add_host() is made, the shost# changes, which results
in completely new scsi_devices and device names. All the older scsi
devices on the old shost# are now orphaned and unrecoverable.
We realize we need to re-implement the host_reset_handler so the scsi_host
stays registered across the host_reset, but that will be a rather
lengthy effort. In the short term, we had an immediate need to restore
the SLI-3 devices to their working behavior, with the easiest path being
to remove their host_reset handler.
Signed-off-by: Dick Kennedy <dick.kennedy@emulex.com>
Signed-off-by: James Smart <james.smart@emulex.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc_crtn.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 11 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_scsi.c | 25 |
3 files changed, 34 insertions, 3 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 00665a5d92fd..665c88cf6404 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
@@ -354,6 +354,7 @@ void lpfc_free_sysfs_attr(struct lpfc_vport *); | |||
354 | extern struct device_attribute *lpfc_hba_attrs[]; | 354 | extern struct device_attribute *lpfc_hba_attrs[]; |
355 | extern struct device_attribute *lpfc_vport_attrs[]; | 355 | extern struct device_attribute *lpfc_vport_attrs[]; |
356 | extern struct scsi_host_template lpfc_template; | 356 | extern struct scsi_host_template lpfc_template; |
357 | extern struct scsi_host_template lpfc_template_s3; | ||
357 | extern struct scsi_host_template lpfc_vport_template; | 358 | extern struct scsi_host_template lpfc_vport_template; |
358 | extern struct fc_function_template lpfc_transport_functions; | 359 | extern struct fc_function_template lpfc_transport_functions; |
359 | extern struct fc_function_template lpfc_vport_transport_functions; | 360 | extern struct fc_function_template lpfc_vport_transport_functions; |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 4ba91af11678..74672e0263ff 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -3257,12 +3257,17 @@ lpfc_create_port(struct lpfc_hba *phba, int instance, struct device *dev) | |||
3257 | struct Scsi_Host *shost; | 3257 | struct Scsi_Host *shost; |
3258 | int error = 0; | 3258 | int error = 0; |
3259 | 3259 | ||
3260 | if (dev != &phba->pcidev->dev) | 3260 | if (dev != &phba->pcidev->dev) { |
3261 | shost = scsi_host_alloc(&lpfc_vport_template, | 3261 | shost = scsi_host_alloc(&lpfc_vport_template, |
3262 | sizeof(struct lpfc_vport)); | 3262 | sizeof(struct lpfc_vport)); |
3263 | else | 3263 | } else { |
3264 | shost = scsi_host_alloc(&lpfc_template, | 3264 | if (phba->sli_rev == LPFC_SLI_REV4) |
3265 | shost = scsi_host_alloc(&lpfc_template, | ||
3265 | sizeof(struct lpfc_vport)); | 3266 | sizeof(struct lpfc_vport)); |
3267 | else | ||
3268 | shost = scsi_host_alloc(&lpfc_template_s3, | ||
3269 | sizeof(struct lpfc_vport)); | ||
3270 | } | ||
3266 | if (!shost) | 3271 | if (!shost) |
3267 | goto out; | 3272 | goto out; |
3268 | 3273 | ||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 4f9222eb2266..f6232991fb37 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -5857,6 +5857,31 @@ lpfc_disable_oas_lun(struct lpfc_hba *phba, struct lpfc_name *vport_wwpn, | |||
5857 | return false; | 5857 | return false; |
5858 | } | 5858 | } |
5859 | 5859 | ||
5860 | struct scsi_host_template lpfc_template_s3 = { | ||
5861 | .module = THIS_MODULE, | ||
5862 | .name = LPFC_DRIVER_NAME, | ||
5863 | .info = lpfc_info, | ||
5864 | .queuecommand = lpfc_queuecommand, | ||
5865 | .eh_abort_handler = lpfc_abort_handler, | ||
5866 | .eh_device_reset_handler = lpfc_device_reset_handler, | ||
5867 | .eh_target_reset_handler = lpfc_target_reset_handler, | ||
5868 | .eh_bus_reset_handler = lpfc_bus_reset_handler, | ||
5869 | .slave_alloc = lpfc_slave_alloc, | ||
5870 | .slave_configure = lpfc_slave_configure, | ||
5871 | .slave_destroy = lpfc_slave_destroy, | ||
5872 | .scan_finished = lpfc_scan_finished, | ||
5873 | .this_id = -1, | ||
5874 | .sg_tablesize = LPFC_DEFAULT_SG_SEG_CNT, | ||
5875 | .cmd_per_lun = LPFC_CMD_PER_LUN, | ||
5876 | .use_clustering = ENABLE_CLUSTERING, | ||
5877 | .shost_attrs = lpfc_hba_attrs, | ||
5878 | .max_sectors = 0xFFFF, | ||
5879 | .vendor_id = LPFC_NL_VENDOR_ID, | ||
5880 | .change_queue_depth = scsi_change_queue_depth, | ||
5881 | .use_blk_tags = 1, | ||
5882 | .track_queue_depth = 1, | ||
5883 | }; | ||
5884 | |||
5860 | struct scsi_host_template lpfc_template = { | 5885 | struct scsi_host_template lpfc_template = { |
5861 | .module = THIS_MODULE, | 5886 | .module = THIS_MODULE, |
5862 | .name = LPFC_DRIVER_NAME, | 5887 | .name = LPFC_DRIVER_NAME, |