aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c64
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 *));
32static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *); 32static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
33static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *); 33static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
34static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *);
34static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *); 35static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
35static int zfcp_task_management_function(struct zfcp_unit *, u8, 36static 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
445static int 447static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
446zfcp_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 /* 462static 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
499static int 475static int