diff options
author | Brian King <brking@linux.vnet.ibm.com> | 2012-08-24 17:50:59 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-09-24 04:10:58 -0400 |
commit | a077c7faf3cb3e28303ba431148a85f613f4e955 (patch) | |
tree | c60145d43096534a189c3ce948e51f5812c9f9f6 /drivers/scsi/ibmvscsi | |
parent | 7731e6bb312ec8bb7892c465401dbc7119aea785 (diff) |
[SCSI] ibmvfc: Fix double completion on abort timeout
If an abort request times out to the virtual fibre channel adapter,
the ibmvfc driver will kick off a reset of the adapter. This
patch ensures we wait for the both the abort request and the
request being aborted to be completed prior to exiting the
eh_abort handler. This fixes a bug where the ibmvfc driver
was erroneously returning success to the eh_abort handler
then later sending back a response to the same command.
Signed-off-by: Brian King <brking@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/ibmvscsi')
-rw-r--r-- | drivers/scsi/ibmvscsi/ibmvfc.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 134a0ae85bb7..4f73daccc9f1 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c | |||
@@ -2242,6 +2242,21 @@ static int ibmvfc_match_key(struct ibmvfc_event *evt, void *key) | |||
2242 | } | 2242 | } |
2243 | 2243 | ||
2244 | /** | 2244 | /** |
2245 | * ibmvfc_match_evt - Match function for specified event | ||
2246 | * @evt: ibmvfc event struct | ||
2247 | * @match: event to match | ||
2248 | * | ||
2249 | * Returns: | ||
2250 | * 1 if event matches key / 0 if event does not match key | ||
2251 | **/ | ||
2252 | static int ibmvfc_match_evt(struct ibmvfc_event *evt, void *match) | ||
2253 | { | ||
2254 | if (evt == match) | ||
2255 | return 1; | ||
2256 | return 0; | ||
2257 | } | ||
2258 | |||
2259 | /** | ||
2245 | * ibmvfc_abort_task_set - Abort outstanding commands to the device | 2260 | * ibmvfc_abort_task_set - Abort outstanding commands to the device |
2246 | * @sdev: scsi device to abort commands | 2261 | * @sdev: scsi device to abort commands |
2247 | * | 2262 | * |
@@ -2322,7 +2337,20 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) | |||
2322 | if (rc) { | 2337 | if (rc) { |
2323 | sdev_printk(KERN_INFO, sdev, "Cancel failed, resetting host\n"); | 2338 | sdev_printk(KERN_INFO, sdev, "Cancel failed, resetting host\n"); |
2324 | ibmvfc_reset_host(vhost); | 2339 | ibmvfc_reset_host(vhost); |
2325 | rsp_rc = 0; | 2340 | rsp_rc = -EIO; |
2341 | rc = ibmvfc_wait_for_ops(vhost, sdev->hostdata, ibmvfc_match_key); | ||
2342 | |||
2343 | if (rc == SUCCESS) | ||
2344 | rsp_rc = 0; | ||
2345 | |||
2346 | rc = ibmvfc_wait_for_ops(vhost, evt, ibmvfc_match_evt); | ||
2347 | if (rc != SUCCESS) { | ||
2348 | spin_lock_irqsave(vhost->host->host_lock, flags); | ||
2349 | ibmvfc_hard_reset_host(vhost); | ||
2350 | spin_unlock_irqrestore(vhost->host->host_lock, flags); | ||
2351 | rsp_rc = 0; | ||
2352 | } | ||
2353 | |||
2326 | goto out; | 2354 | goto out; |
2327 | } | 2355 | } |
2328 | } | 2356 | } |