aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_scsi.c
diff options
context:
space:
mode:
authorAndreas Herrmann <aherrman@de.ibm.com>2006-09-18 16:29:20 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-09-23 19:00:56 -0400
commit4eff4a36516d72e4f6ede901141214a7e05607e7 (patch)
treeb6a775ee5acbfdc91a349fc69580031e17276768 /drivers/s390/scsi/zfcp_scsi.c
parentdd52e0eaf891cd85bf2ca057c15ed6bfd76db4e6 (diff)
[SCSI] zfcp: fix: use correct req_id in eh_abort_handler
zfcp's eh_abort_handler used the wrong request ID to identify the request to be aborted. The bug was introduced with commit fea9d6c7bcd8ff1d60ff74f27ba483b3820b18a3 for improved management of request IDs. The bug is fixed with this patch. Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_scsi.c')
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c63
1 files changed, 27 insertions, 36 deletions
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 4857cccb1d5b..043ed7c0a7ed 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -378,16 +378,15 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, unsigned int id,
378 * will handle late commands. (Usually, the normal completion of late 378 * will handle late commands. (Usually, the normal completion of late
379 * commands is ignored with respect to the running abort operation.) 379 * commands is ignored with respect to the running abort operation.)
380 */ 380 */
381int 381int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
382zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
383{ 382{
384 struct Scsi_Host *scsi_host; 383 struct Scsi_Host *scsi_host;
385 struct zfcp_adapter *adapter; 384 struct zfcp_adapter *adapter;
386 struct zfcp_unit *unit; 385 struct zfcp_unit *unit;
387 int retval = SUCCESS; 386 struct zfcp_fsf_req *fsf_req;
388 struct zfcp_fsf_req *new_fsf_req = NULL;
389 struct zfcp_fsf_req *old_fsf_req;
390 unsigned long flags; 387 unsigned long flags;
388 unsigned long old_req_id;
389 int retval = SUCCESS;
391 390
392 scsi_host = scpnt->device->host; 391 scsi_host = scpnt->device->host;
393 adapter = (struct zfcp_adapter *) scsi_host->hostdata[0]; 392 adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
@@ -399,55 +398,47 @@ zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
399 /* avoid race condition between late normal completion and abort */ 398 /* avoid race condition between late normal completion and abort */
400 write_lock_irqsave(&adapter->abort_lock, flags); 399 write_lock_irqsave(&adapter->abort_lock, flags);
401 400
402 /* 401 /* Check whether corresponding fsf_req is still pending */
403 * Check whether command has just completed and can not be aborted. 402 spin_lock(&adapter->req_list_lock);
404 * Even if the command has just been completed late, we can access 403 fsf_req = zfcp_reqlist_ismember(adapter, (unsigned long)
405 * scpnt since the SCSI stack does not release it at least until 404 scpnt->host_scribble);
406 * this routine returns. (scpnt is parameter passed to this routine 405 spin_unlock(&adapter->req_list_lock);
407 * and must not disappear during abort even on late completion.) 406 if (!fsf_req) {
408 */
409 old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble;
410 if (!old_fsf_req) {
411 write_unlock_irqrestore(&adapter->abort_lock, flags); 407 write_unlock_irqrestore(&adapter->abort_lock, flags);
412 zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, NULL); 408 zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, NULL, 0);
413 retval = SUCCESS; 409 retval = SUCCESS;
414 goto out; 410 goto out;
415 } 411 }
416 old_fsf_req->data = 0; 412 fsf_req->data = 0;
417 old_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING; 413 fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;
414 old_req_id = fsf_req->req_id;
418 415
419 /* don't access old_fsf_req after releasing the abort_lock */ 416 /* don't access old fsf_req after releasing the abort_lock */
420 write_unlock_irqrestore(&adapter->abort_lock, flags); 417 write_unlock_irqrestore(&adapter->abort_lock, flags);
421 /* call FSF routine which does the abort */ 418
422 new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req, 419 fsf_req = zfcp_fsf_abort_fcp_command(old_req_id, adapter, unit, 0);
423 adapter, unit, 0); 420 if (!fsf_req) {
424 if (!new_fsf_req) {
425 ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n"); 421 ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n");
426 zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL, 422 zfcp_scsi_dbf_event_abort("nres", adapter, scpnt, NULL,
427 old_fsf_req); 423 old_req_id);
428 retval = FAILED; 424 retval = FAILED;
429 goto out; 425 goto out;
430 } 426 }
431 427
432 /* wait for completion of abort */ 428 __wait_event(fsf_req->completion_wq,
433 __wait_event(new_fsf_req->completion_wq, 429 fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
434 new_fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
435 430
436 /* status should be valid since signals were not permitted */ 431 if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {
437 if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) { 432 zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, fsf_req, 0);
438 zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req,
439 NULL);
440 retval = SUCCESS; 433 retval = SUCCESS;
441 } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) { 434 } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {
442 zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req, 435 zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, fsf_req, 0);
443 NULL);
444 retval = SUCCESS; 436 retval = SUCCESS;
445 } else { 437 } else {
446 zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req, 438 zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, fsf_req, 0);
447 NULL);
448 retval = FAILED; 439 retval = FAILED;
449 } 440 }
450 zfcp_fsf_req_free(new_fsf_req); 441 zfcp_fsf_req_free(fsf_req);
451 out: 442 out:
452 return retval; 443 return retval;
453} 444}