summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Herrmann <aherrman@de.ibm.com>2006-03-10 00:56:16 +0100
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-03-09 19:11:03 -0500
commitad58f7dbeb6f5ea82679962f18985f16b660a2d9 (patch)
tree3951a1d5a27d2e10c55c7d6662cf8e726ffeed87
parentad139a2f56e5789aa8a9f74e3600a7f854a38de9 (diff)
[SCSI] zfcp: fix device registration issues
The patch fixes following issues: (1) Replace scsi_add_device with scsi_scan_target. (Thus the rport instead of the scsi_host becomes parent of a scsi_target again.) (2) Avoid scsi_device allocation during registration of an remote port. (Would be done during fc_scsi_scan_rport.) (3) Fix queuecommand behaviour when an zfcp unit is blocked. (Call scsi_done with DID_NO_CONNECT instead of returning SCSI_MLQUEUE_DEVICE_BUSY otherwise we might end up waiting for completion in blk_execute_rq for ever.) Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_erp.c11
-rw-r--r--drivers/s390/scsi/zfcp_scsi.c6
3 files changed, 12 insertions, 6 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 7f551d66f47f..6eba56cd89ba 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -664,6 +664,7 @@ do { \
#define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002
#define ZFCP_STATUS_UNIT_SHARED 0x00000004
#define ZFCP_STATUS_UNIT_READONLY 0x00000008
+#define ZFCP_STATUS_UNIT_REGISTERED 0x00000010
/* FSF request status (this does not have a common part) */
#define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
index e3c4bdd29a60..57cb628a05aa 100644
--- a/drivers/s390/scsi/zfcp_erp.c
+++ b/drivers/s390/scsi/zfcp_erp.c
@@ -3391,10 +3391,13 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter,
&& (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY,
&unit->status))
&& !unit->device
- && port->rport)
- scsi_add_device(port->adapter->scsi_host, 0,
- port->rport->scsi_target_id,
- unit->scsi_lun);
+ && port->rport) {
+ atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED,
+ &unit->status);
+ scsi_scan_target(&port->rport->dev, 0,
+ port->rport->scsi_target_id,
+ unit->scsi_lun, 0);
+ }
zfcp_unit_put(unit);
break;
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index a2de3c9afe49..9e6d07d7b3c8 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -183,7 +183,8 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp)
read_lock_irqsave(&zfcp_data.config_lock, flags);
unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun);
- if (unit) {
+ if (unit && atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED,
+ &unit->status)) {
sdp->hostdata = unit;
unit->device = sdp;
zfcp_unit_get(unit);
@@ -208,6 +209,7 @@ zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
if (unit) {
+ atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
sdpnt->hostdata = NULL;
unit->device = NULL;
zfcp_unit_put(unit);
@@ -291,7 +293,7 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit,
"on port 0x%016Lx in recovery\n",
zfcp_get_busid_by_unit(unit),
unit->fcp_lun, unit->port->wwpn);
- retval = SCSI_MLQUEUE_DEVICE_BUSY;
+ zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT);
goto out;
}