[PATCH 5/5] zfcp: convert zfcp to use target reset and device reset handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mike Christie <michaelc@xxxxxxxxxxx>

zfcp uses the device reset handler to try and send a lun reset.
If that fails it then does a target reset. This patch has it
do a lun reset in the target reset handler like other drivers,
then do a target reset in the target reset handler. scsi_error.c
will escalate from device reset to target reset for the driver.

This patch is only compile tested since suprisingly I could find
a s390 box, but I could not hook storage into the the zfcp adapter
(box was remote).
Signed-off-by: Mike Christie <michaelc@xxxxxxxxxxx>
---
 drivers/s390/scsi/zfcp_scsi.c |   67 +++++++++++++++++++++++++----------------
 1 files changed, 41 insertions(+), 26 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index b9daf5c..13dceec 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 *,
 				  void (*done) (struct scsi_cmnd *));
 static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
 static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
+static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *);
 static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
 static int zfcp_task_management_function(struct zfcp_unit *, u8,
 					 struct scsi_cmnd *);
@@ -51,6 +52,7 @@ struct zfcp_data zfcp_data = {
 		.queuecommand		= zfcp_scsi_queuecommand,
 		.eh_abort_handler	= zfcp_scsi_eh_abort_handler,
 		.eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler,
+		.eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler,
 		.eh_host_reset_handler	= zfcp_scsi_eh_host_reset_handler,
 		.can_queue		= 4096,
 		.this_id		= -1,
@@ -457,33 +459,46 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
 			unit->fcp_lun, unit->port->wwpn,
 			zfcp_get_busid_by_adapter(unit->port->adapter));
 
-	/*
-	 * If we do not know whether the unit supports 'logical unit reset'
-	 * then try 'logical unit reset' and proceed with 'target reset'
-	 * if 'logical unit reset' fails.
-	 * If the unit is known not to support 'logical unit reset' then
-	 * skip 'logical unit reset' and try 'target reset' immediately.
-	 */
-	if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
-			      &unit->status)) {
-		retval = zfcp_task_management_function(unit,
-						       FCP_LOGICAL_UNIT_RESET,
-						       scpnt);
-		if (retval) {
-			ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);
-			if (retval == -ENOTSUPP)
-				atomic_set_mask
-				    (ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
-				     &unit->status);
-			/* fall through and try 'target reset' next */
-		} else {
-			ZFCP_LOG_DEBUG("unit reset succeeded (unit=%p)\n",
-				       unit);
-			/* avoid 'target reset' */
-			retval = SUCCESS;
-			goto out;
-		}
+	if (atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
+			     &unit->status)) {
+		ZFCP_LOG_DEBUG("unit reset not supported (unit=%p)\n", unit);
+		retval = FAILED;
+		goto out;
+	}
+
+	retval = zfcp_task_management_function(unit,
+					       FCP_LOGICAL_UNIT_RESET,
+					       scpnt);
+	if (retval) {
+		ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);
+		if (retval == -ENOTSUPP)
+			atomic_set_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
+					&unit->status);
+		retval = FAILED;
+	} else {
+		ZFCP_LOG_DEBUG("unit reset succeeded (unit=%p)\n", unit);
+		retval = SUCCESS;
+	}
+ out:
+	return retval;
+}
+
+static int
+zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
+{
+	int retval;
+	struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
+
+	if (!unit) {
+		ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n");
+		retval = SUCCESS;
+		goto out;
 	}
+
+	ZFCP_LOG_NORMAL("resetting target 0x%016Lx on port 0x%016Lx, adapter %s\n",
+			unit->fcp_lun, unit->port->wwpn,
+			zfcp_get_busid_by_adapter(unit->port->adapter));
+
 	retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt);
 	if (retval) {
 		ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);
-- 
1.5.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux