diff options
author | Bart Van Assche <bvanassche@acm.org> | 2012-03-17 13:18:54 -0400 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2012-11-30 20:40:29 -0500 |
commit | 09be70a238005cc33f2a52b0aeae52f117e81582 (patch) | |
tree | 503bc827e108bf820cd55aa605a6e6d36f8ac00d /drivers/infiniband | |
parent | c9b03c1ae55decc721310b79d8f50d44fbb37dc7 (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.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 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 | ||
647 | static int srp_reconnect_target(struct srp_target_port *target) | 647 | static 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 | |||
695 | unblock: | ||
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: | |||
1377 | err_unlock: | 1381 | err_unlock: |
1378 | spin_unlock_irqrestore(&target->lock, flags); | 1382 | spin_unlock_irqrestore(&target->lock, flags); |
1379 | 1383 | ||
1380 | err: | ||
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 | ||
81 | enum srp_target_state { | 81 | enum 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 | }; |