diff options
author | Bart Van Assche <bvanassche@acm.org> | 2012-03-17 21:18:54 +0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-12-01 05:40:29 +0400 |
commit | 09be70a238005cc33f2a52b0aeae52f117e81582 (patch) | |
tree | 503bc827e108bf820cd55aa605a6e6d36f8ac00d /drivers/infiniband | |
parent | c9b03c1ae55decc721310b79d8f50d44fbb37dc7 (diff) | |
download | linux-09be70a238005cc33f2a52b0aeae52f117e81582.tar.xz |
IB/srp: Eliminate state SRP_TARGET_CONNECTING
Block the SCSI host while reconnecting instead of representing the
reconnection activity as a distinct SRP target state. This allows us
to eliminate the target state SRP_TARGET_CONNECTING.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: David Dillow <dillowda@ornl.gov>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 25 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 1 |
2 files changed, 14 insertions, 12 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 5aa70e96ec90..a2261995c550 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -646,13 +646,16 @@ static void srp_reset_req(struct srp_target_port *target, struct srp_request *re static int srp_reconnect_target(struct srp_target_port *target) { + struct Scsi_Host *shost = target->scsi_host; struct ib_qp_attr qp_attr; struct ib_wc wc; int i, ret; - if (!srp_change_state(target, SRP_TARGET_LIVE, SRP_TARGET_CONNECTING)) + if (target->state != SRP_TARGET_LIVE) return -EAGAIN; + scsi_target_block(&shost->shost_gendev); + srp_disconnect_target(target); /* * Now get a new local CM ID so that we avoid confusing the @@ -660,16 +663,16 @@ static int srp_reconnect_target(struct srp_target_port *target) */ ret = srp_new_cm_id(target); if (ret) - goto err; + goto unblock; qp_attr.qp_state = IB_QPS_RESET; ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE); if (ret) - goto err; + goto unblock; ret = srp_init_qp(target, target->qp); if (ret) - goto err; + goto unblock; while (ib_poll_cq(target->recv_cq, 1, &wc) > 0) ; /* nothing */ @@ -688,11 +691,15 @@ static int srp_reconnect_target(struct srp_target_port *target) target->qp_in_error = 0; ret = srp_connect_target(target); + +unblock: + scsi_target_unblock(&shost->shost_gendev, ret == 0 ? SDEV_RUNNING : + SDEV_TRANSPORT_OFFLINE); + if (ret) goto err; - if (!srp_change_state(target, SRP_TARGET_CONNECTING, SRP_TARGET_LIVE)) - ret = -EAGAIN; + shost_printk(KERN_INFO, target->scsi_host, PFX "reconnect succeeded\n"); return ret; @@ -710,7 +717,7 @@ err: * the flush_scheduled_work() in srp_remove_one(). */ spin_lock_irq(&target->lock); - if (target->state == SRP_TARGET_CONNECTING) { + if (target->state == SRP_TARGET_LIVE) { target->state = SRP_TARGET_DEAD; INIT_WORK(&target->work, srp_remove_work); queue_work(ib_wq, &target->work); @@ -1311,9 +1318,6 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) unsigned long flags; int len; - if (target->state == SRP_TARGET_CONNECTING) - goto err; - if (target->state == SRP_TARGET_DEAD || target->state == SRP_TARGET_REMOVED) { scmnd->result = DID_BAD_TARGET << 16; @@ -1377,7 +1381,6 @@ err_iu: err_unlock: spin_unlock_irqrestore(&target->lock, flags); -err: return SCSI_MLQUEUE_HOST_BUSY; } diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index e3a6304ba87b..8b436cee46ad 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h @@ -80,7 +80,6 @@ enum { enum srp_target_state { SRP_TARGET_LIVE, - SRP_TARGET_CONNECTING, SRP_TARGET_DEAD, SRP_TARGET_REMOVED }; |