aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2015-04-07 15:07:13 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-04-10 10:46:35 -0400
commitea4142f6b10585f271a40ee52eec2f55e48aeccf (patch)
tree553816bdcdf18b3c887c3d10fc3933b2a0d3c937
parent85c0f177200b49cbed0f9c9ac67fe2656749f9cd (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.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c11
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c25
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 *);
354extern struct device_attribute *lpfc_hba_attrs[]; 354extern struct device_attribute *lpfc_hba_attrs[];
355extern struct device_attribute *lpfc_vport_attrs[]; 355extern struct device_attribute *lpfc_vport_attrs[];
356extern struct scsi_host_template lpfc_template; 356extern struct scsi_host_template lpfc_template;
357extern struct scsi_host_template lpfc_template_s3;
357extern struct scsi_host_template lpfc_vport_template; 358extern struct scsi_host_template lpfc_vport_template;
358extern struct fc_function_template lpfc_transport_functions; 359extern struct fc_function_template lpfc_transport_functions;
359extern struct fc_function_template lpfc_vport_transport_functions; 360extern 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
5860struct 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
5860struct scsi_host_template lpfc_template = { 5885struct scsi_host_template lpfc_template = {
5861 .module = THIS_MODULE, 5886 .module = THIS_MODULE,
5862 .name = LPFC_DRIVER_NAME, 5887 .name = LPFC_DRIVER_NAME,