diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2008-03-03 06:19:28 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-07 13:15:43 -0400 |
commit | 74b2e047ecda7a82c3327a0d0bb45ee2ccf301ca (patch) | |
tree | da3466200e3b5c56702c98a420d64de1a8877907 /drivers | |
parent | ce5450392fa3ab54f0a84aa3b7589f8d6f2a58af (diff) |
[SCSI] zfcp: convert zfcp to use target reset and device reset handler
[based on proposal from Mike Christie <michaelc@cs.wisc.edu>, this
patch adds some simplifications to the handler functions]
With the new target reset handler callback in the SCSI midlayer, the
device reset handler in zfcp can be split in two parts. Now, zfcp does
not have to track anymore whether the device supports LUN resets, so
remove this flag and let the SCSI midlayer decide what to do.
The device reset handler simply issues a LUN reset and the target
reset handler a target reset.
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_scsi.c | 64 |
2 files changed, 20 insertions, 45 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 9e9f6c1e4e5d..662c70f537ec 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -634,7 +634,6 @@ do { \ | |||
634 | ZFCP_STATUS_PORT_NO_SCSI_ID) | 634 | ZFCP_STATUS_PORT_NO_SCSI_ID) |
635 | 635 | ||
636 | /* logical unit status */ | 636 | /* logical unit status */ |
637 | #define ZFCP_STATUS_UNIT_NOTSUPPUNITRESET 0x00000001 | ||
638 | #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 | 637 | #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 |
639 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 | 638 | #define ZFCP_STATUS_UNIT_SHARED 0x00000004 |
640 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 | 639 | #define ZFCP_STATUS_UNIT_READONLY 0x00000008 |
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index b9daf5c05862..ff97a61ad964 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -31,6 +31,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *, | |||
31 | void (*done) (struct scsi_cmnd *)); | 31 | void (*done) (struct scsi_cmnd *)); |
32 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); | 32 | static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); |
33 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); | 33 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); |
34 | static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *); | ||
34 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); | 35 | static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); |
35 | static int zfcp_task_management_function(struct zfcp_unit *, u8, | 36 | static int zfcp_task_management_function(struct zfcp_unit *, u8, |
36 | struct scsi_cmnd *); | 37 | struct scsi_cmnd *); |
@@ -51,6 +52,7 @@ struct zfcp_data zfcp_data = { | |||
51 | .queuecommand = zfcp_scsi_queuecommand, | 52 | .queuecommand = zfcp_scsi_queuecommand, |
52 | .eh_abort_handler = zfcp_scsi_eh_abort_handler, | 53 | .eh_abort_handler = zfcp_scsi_eh_abort_handler, |
53 | .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, | 54 | .eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler, |
55 | .eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler, | ||
54 | .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, | 56 | .eh_host_reset_handler = zfcp_scsi_eh_host_reset_handler, |
55 | .can_queue = 4096, | 57 | .can_queue = 4096, |
56 | .this_id = -1, | 58 | .this_id = -1, |
@@ -442,58 +444,32 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt) | |||
442 | return retval; | 444 | return retval; |
443 | } | 445 | } |
444 | 446 | ||
445 | static int | 447 | static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) |
446 | zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | ||
447 | { | 448 | { |
448 | int retval; | 449 | int retval; |
449 | struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata; | 450 | struct zfcp_unit *unit = scpnt->device->hostdata; |
450 | 451 | ||
451 | if (!unit) { | 452 | if (!unit) { |
452 | ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n"); | 453 | WARN_ON(1); |
453 | retval = SUCCESS; | 454 | return SUCCESS; |
454 | goto out; | ||
455 | } | 455 | } |
456 | ZFCP_LOG_NORMAL("resetting unit 0x%016Lx on port 0x%016Lx, adapter %s\n", | 456 | retval = zfcp_task_management_function(unit, |
457 | unit->fcp_lun, unit->port->wwpn, | 457 | FCP_LOGICAL_UNIT_RESET, |
458 | zfcp_get_busid_by_adapter(unit->port->adapter)); | 458 | scpnt); |
459 | return retval ? FAILED : SUCCESS; | ||
460 | } | ||
459 | 461 | ||
460 | /* | 462 | static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt) |
461 | * If we do not know whether the unit supports 'logical unit reset' | 463 | { |
462 | * then try 'logical unit reset' and proceed with 'target reset' | 464 | int retval; |
463 | * if 'logical unit reset' fails. | 465 | struct zfcp_unit *unit = scpnt->device->hostdata; |
464 | * If the unit is known not to support 'logical unit reset' then | 466 | |
465 | * skip 'logical unit reset' and try 'target reset' immediately. | 467 | if (!unit) { |
466 | */ | 468 | WARN_ON(1); |
467 | if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET, | 469 | return SUCCESS; |
468 | &unit->status)) { | ||
469 | retval = zfcp_task_management_function(unit, | ||
470 | FCP_LOGICAL_UNIT_RESET, | ||
471 | scpnt); | ||
472 | if (retval) { | ||
473 | ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit); | ||
474 | if (retval == -ENOTSUPP) | ||
475 | atomic_set_mask | ||
476 | (ZFCP_STATUS_UNIT_NOTSUPPUNITRESET, | ||
477 | &unit->status); | ||
478 | /* fall through and try 'target reset' next */ | ||
479 | } else { | ||
480 | ZFCP_LOG_DEBUG("unit reset succeeded (unit=%p)\n", | ||
481 | unit); | ||
482 | /* avoid 'target reset' */ | ||
483 | retval = SUCCESS; | ||
484 | goto out; | ||
485 | } | ||
486 | } | 470 | } |
487 | retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt); | 471 | retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt); |
488 | if (retval) { | 472 | return retval ? FAILED : SUCCESS; |
489 | ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit); | ||
490 | retval = FAILED; | ||
491 | } else { | ||
492 | ZFCP_LOG_DEBUG("target reset succeeded (unit=%p)\n", unit); | ||
493 | retval = SUCCESS; | ||
494 | } | ||
495 | out: | ||
496 | return retval; | ||
497 | } | 473 | } |
498 | 474 | ||
499 | static int | 475 | static int |