aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2012-03-17 13:18:54 -0400
committerRoland Dreier <roland@purestorage.com>2012-11-30 20:40:29 -0500
commit09be70a238005cc33f2a52b0aeae52f117e81582 (patch)
tree503bc827e108bf820cd55aa605a6e6d36f8ac00d /drivers/infiniband
parentc9b03c1ae55decc721310b79d8f50d44fbb37dc7 (diff)
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.c25
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
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 5aa70e96ec9..a2261995c55 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
646 646
647static int srp_reconnect_target(struct srp_target_port *target) 647static int srp_reconnect_target(struct srp_target_port *target)
648{ 648{
649 struct Scsi_Host *shost = target->scsi_host;
649 struct ib_qp_attr qp_attr; 650 struct ib_qp_attr qp_attr;
650 struct ib_wc wc; 651 struct ib_wc wc;
651 int i, ret; 652 int i, ret;
652 653
653 if (!srp_change_state(target, SRP_TARGET_LIVE, SRP_TARGET_CONNECTING)) 654 if (target->state != SRP_TARGET_LIVE)
654 return -EAGAIN; 655 return -EAGAIN;
655 656
657 scsi_target_block(&shost->shost_gendev);
658
656 srp_disconnect_target(target); 659 srp_disconnect_target(target);
657 /* 660 /*
658 * Now get a new local CM ID so that we avoid confusing the 661 * 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)
660 */ 663 */
661 ret = srp_new_cm_id(target); 664 ret = srp_new_cm_id(target);
662 if (ret) 665 if (ret)
663 goto err; 666 goto unblock;
664 667
665 qp_attr.qp_state = IB_QPS_RESET; 668 qp_attr.qp_state = IB_QPS_RESET;
666 ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE); 669 ret = ib_modify_qp(target->qp, &qp_attr, IB_QP_STATE);
667 if (ret) 670 if (ret)
668 goto err; 671 goto unblock;
669 672
670 ret = srp_init_qp(target, target->qp); 673 ret = srp_init_qp(target, target->qp);
671 if (ret) 674 if (ret)
672 goto err; 675 goto unblock;
673 676
674 while (ib_poll_cq(target->recv_cq, 1, &wc) > 0) 677 while (ib_poll_cq(target->recv_cq, 1, &wc) > 0)
675 ; /* nothing */ 678 ; /* nothing */
@@ -688,11 +691,15 @@ static int srp_reconnect_target(struct srp_target_port *target)
688 691
689 target->qp_in_error = 0; 692 target->qp_in_error = 0;
690 ret = srp_connect_target(target); 693 ret = srp_connect_target(target);
694
695unblock:
696 scsi_target_unblock(&shost->shost_gendev, ret == 0 ? SDEV_RUNNING :
697 SDEV_TRANSPORT_OFFLINE);
698
691 if (ret) 699 if (ret)
692 goto err; 700 goto err;
693 701
694 if (!srp_change_state(target, SRP_TARGET_CONNECTING, SRP_TARGET_LIVE)) 702 shost_printk(KERN_INFO, target->scsi_host, PFX "reconnect succeeded\n");
695 ret = -EAGAIN;
696 703
697 return ret; 704 return ret;
698 705
@@ -710,7 +717,7 @@ err:
710 * the flush_scheduled_work() in srp_remove_one(). 717 * the flush_scheduled_work() in srp_remove_one().
711 */ 718 */
712 spin_lock_irq(&target->lock); 719 spin_lock_irq(&target->lock);
713 if (target->state == SRP_TARGET_CONNECTING) { 720 if (target->state == SRP_TARGET_LIVE) {
714 target->state = SRP_TARGET_DEAD; 721 target->state = SRP_TARGET_DEAD;
715 INIT_WORK(&target->work, srp_remove_work); 722 INIT_WORK(&target->work, srp_remove_work);
716 queue_work(ib_wq, &target->work); 723 queue_work(ib_wq, &target->work);
@@ -1311,9 +1318,6 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd)
1311 unsigned long flags; 1318 unsigned long flags;
1312 int len; 1319 int len;
1313 1320
1314 if (target->state == SRP_TARGET_CONNECTING)
1315 goto err;
1316
1317 if (target->state == SRP_TARGET_DEAD || 1321 if (target->state == SRP_TARGET_DEAD ||
1318 target->state == SRP_TARGET_REMOVED) { 1322 target->state == SRP_TARGET_REMOVED) {
1319 scmnd->result = DID_BAD_TARGET << 16; 1323 scmnd->result = DID_BAD_TARGET << 16;
@@ -1377,7 +1381,6 @@ err_iu:
1377err_unlock: 1381err_unlock:
1378 spin_unlock_irqrestore(&target->lock, flags); 1382 spin_unlock_irqrestore(&target->lock, flags);
1379 1383
1380err:
1381 return SCSI_MLQUEUE_HOST_BUSY; 1384 return SCSI_MLQUEUE_HOST_BUSY;
1382} 1385}
1383 1386
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index e3a6304ba87..8b436cee46a 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -80,7 +80,6 @@ enum {
80 80
81enum srp_target_state { 81enum srp_target_state {
82 SRP_TARGET_LIVE, 82 SRP_TARGET_LIVE,
83 SRP_TARGET_CONNECTING,
84 SRP_TARGET_DEAD, 83 SRP_TARGET_DEAD,
85 SRP_TARGET_REMOVED 84 SRP_TARGET_REMOVED
86}; 85};