aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 263325848462..8a7eb9f98a0c 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -700,23 +700,24 @@ static int srp_reconnect_target(struct srp_target_port *target)
700 struct Scsi_Host *shost = target->scsi_host; 700 struct Scsi_Host *shost = target->scsi_host;
701 int i, ret; 701 int i, ret;
702 702
703 if (target->state != SRP_TARGET_LIVE)
704 return -EAGAIN;
705
706 scsi_target_block(&shost->shost_gendev); 703 scsi_target_block(&shost->shost_gendev);
707 704
708 srp_disconnect_target(target); 705 srp_disconnect_target(target);
709 /* 706 /*
710 * Now get a new local CM ID so that we avoid confusing the 707 * Now get a new local CM ID so that we avoid confusing the target in
711 * target in case things are really fouled up. 708 * case things are really fouled up. Doing so also ensures that all CM
709 * callbacks will have finished before a new QP is allocated.
712 */ 710 */
713 ret = srp_new_cm_id(target); 711 ret = srp_new_cm_id(target);
714 if (ret) 712 /*
715 goto unblock; 713 * Whether or not creating a new CM ID succeeded, create a new
716 714 * QP. This guarantees that all completion callback function
717 ret = srp_create_target_ib(target); 715 * invocations have finished before request resetting starts.
718 if (ret) 716 */
719 goto unblock; 717 if (ret == 0)
718 ret = srp_create_target_ib(target);
719 else
720 srp_create_target_ib(target);
720 721
721 for (i = 0; i < SRP_CMD_SQ_SIZE; ++i) { 722 for (i = 0; i < SRP_CMD_SQ_SIZE; ++i) {
722 struct srp_request *req = &target->req_ring[i]; 723 struct srp_request *req = &target->req_ring[i];
@@ -728,9 +729,9 @@ static int srp_reconnect_target(struct srp_target_port *target)
728 for (i = 0; i < SRP_SQ_SIZE; ++i) 729 for (i = 0; i < SRP_SQ_SIZE; ++i)
729 list_add(&target->tx_ring[i]->list, &target->free_tx); 730 list_add(&target->tx_ring[i]->list, &target->free_tx);
730 731
731 ret = srp_connect_target(target); 732 if (ret == 0)
733 ret = srp_connect_target(target);
732 734
733unblock:
734 scsi_target_unblock(&shost->shost_gendev, ret == 0 ? SDEV_RUNNING : 735 scsi_target_unblock(&shost->shost_gendev, ret == 0 ? SDEV_RUNNING :
735 SDEV_TRANSPORT_OFFLINE); 736 SDEV_TRANSPORT_OFFLINE);
736 737
@@ -1739,7 +1740,7 @@ static int srp_abort(struct scsi_cmnd *scmnd)
1739 1740
1740 shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); 1741 shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n");
1741 1742
1742 if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd)) 1743 if (!req || !srp_claim_req(target, req, scmnd))
1743 return FAILED; 1744 return FAILED;
1744 srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, 1745 srp_send_tsk_mgmt(target, req->index, scmnd->device->lun,
1745 SRP_TSK_ABORT_TASK); 1746 SRP_TSK_ABORT_TASK);