aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/ulp/srp/ib_srp.c')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 5f0f4fc58f43..e397f1b0af09 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -1787,17 +1787,24 @@ static void srp_process_rsp(struct srp_rdma_ch *ch, struct srp_rsp *rsp)
1787 if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) { 1787 if (unlikely(rsp->tag & SRP_TAG_TSK_MGMT)) {
1788 spin_lock_irqsave(&ch->lock, flags); 1788 spin_lock_irqsave(&ch->lock, flags);
1789 ch->req_lim += be32_to_cpu(rsp->req_lim_delta); 1789 ch->req_lim += be32_to_cpu(rsp->req_lim_delta);
1790 if (rsp->tag == ch->tsk_mgmt_tag) {
1791 ch->tsk_mgmt_status = -1;
1792 if (be32_to_cpu(rsp->resp_data_len) >= 4)
1793 ch->tsk_mgmt_status = rsp->data[3];
1794 complete(&ch->tsk_mgmt_done);
1795 } else {
1796 shost_printk(KERN_ERR, target->scsi_host,
1797 "Received tsk mgmt response too late for tag %#llx\n",
1798 rsp->tag);
1799 }
1790 spin_unlock_irqrestore(&ch->lock, flags); 1800 spin_unlock_irqrestore(&ch->lock, flags);
1791
1792 ch->tsk_mgmt_status = -1;
1793 if (be32_to_cpu(rsp->resp_data_len) >= 4)
1794 ch->tsk_mgmt_status = rsp->data[3];
1795 complete(&ch->tsk_mgmt_done);
1796 } else { 1801 } else {
1797 scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag); 1802 scmnd = scsi_host_find_tag(target->scsi_host, rsp->tag);
1798 if (scmnd) { 1803 if (scmnd && scmnd->host_scribble) {
1799 req = (void *)scmnd->host_scribble; 1804 req = (void *)scmnd->host_scribble;
1800 scmnd = srp_claim_req(ch, req, NULL, scmnd); 1805 scmnd = srp_claim_req(ch, req, NULL, scmnd);
1806 } else {
1807 scmnd = NULL;
1801 } 1808 }
1802 if (!scmnd) { 1809 if (!scmnd) {
1803 shost_printk(KERN_ERR, target->scsi_host, 1810 shost_printk(KERN_ERR, target->scsi_host,
@@ -2469,19 +2476,18 @@ srp_change_queue_depth(struct scsi_device *sdev, int qdepth)
2469} 2476}
2470 2477
2471static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun, 2478static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
2472 u8 func) 2479 u8 func, u8 *status)
2473{ 2480{
2474 struct srp_target_port *target = ch->target; 2481 struct srp_target_port *target = ch->target;
2475 struct srp_rport *rport = target->rport; 2482 struct srp_rport *rport = target->rport;
2476 struct ib_device *dev = target->srp_host->srp_dev->dev; 2483 struct ib_device *dev = target->srp_host->srp_dev->dev;
2477 struct srp_iu *iu; 2484 struct srp_iu *iu;
2478 struct srp_tsk_mgmt *tsk_mgmt; 2485 struct srp_tsk_mgmt *tsk_mgmt;
2486 int res;
2479 2487
2480 if (!ch->connected || target->qp_in_error) 2488 if (!ch->connected || target->qp_in_error)
2481 return -1; 2489 return -1;
2482 2490
2483 init_completion(&ch->tsk_mgmt_done);
2484
2485 /* 2491 /*
2486 * Lock the rport mutex to avoid that srp_create_ch_ib() is 2492 * Lock the rport mutex to avoid that srp_create_ch_ib() is
2487 * invoked while a task management function is being sent. 2493 * invoked while a task management function is being sent.
@@ -2504,10 +2510,16 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
2504 2510
2505 tsk_mgmt->opcode = SRP_TSK_MGMT; 2511 tsk_mgmt->opcode = SRP_TSK_MGMT;
2506 int_to_scsilun(lun, &tsk_mgmt->lun); 2512 int_to_scsilun(lun, &tsk_mgmt->lun);
2507 tsk_mgmt->tag = req_tag | SRP_TAG_TSK_MGMT;
2508 tsk_mgmt->tsk_mgmt_func = func; 2513 tsk_mgmt->tsk_mgmt_func = func;
2509 tsk_mgmt->task_tag = req_tag; 2514 tsk_mgmt->task_tag = req_tag;
2510 2515
2516 spin_lock_irq(&ch->lock);
2517 ch->tsk_mgmt_tag = (ch->tsk_mgmt_tag + 1) | SRP_TAG_TSK_MGMT;
2518 tsk_mgmt->tag = ch->tsk_mgmt_tag;
2519 spin_unlock_irq(&ch->lock);
2520
2521 init_completion(&ch->tsk_mgmt_done);
2522
2511 ib_dma_sync_single_for_device(dev, iu->dma, sizeof *tsk_mgmt, 2523 ib_dma_sync_single_for_device(dev, iu->dma, sizeof *tsk_mgmt,
2512 DMA_TO_DEVICE); 2524 DMA_TO_DEVICE);
2513 if (srp_post_send(ch, iu, sizeof(*tsk_mgmt))) { 2525 if (srp_post_send(ch, iu, sizeof(*tsk_mgmt))) {
@@ -2516,13 +2528,15 @@ static int srp_send_tsk_mgmt(struct srp_rdma_ch *ch, u64 req_tag, u64 lun,
2516 2528
2517 return -1; 2529 return -1;
2518 } 2530 }
2531 res = wait_for_completion_timeout(&ch->tsk_mgmt_done,
2532 msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS));
2533 if (res > 0 && status)
2534 *status = ch->tsk_mgmt_status;
2519 mutex_unlock(&rport->mutex); 2535 mutex_unlock(&rport->mutex);
2520 2536
2521 if (!wait_for_completion_timeout(&ch->tsk_mgmt_done, 2537 WARN_ON_ONCE(res < 0);
2522 msecs_to_jiffies(SRP_ABORT_TIMEOUT_MS)))
2523 return -1;
2524 2538
2525 return 0; 2539 return res > 0 ? 0 : -1;
2526} 2540}
2527 2541
2528static int srp_abort(struct scsi_cmnd *scmnd) 2542static int srp_abort(struct scsi_cmnd *scmnd)
@@ -2548,7 +2562,7 @@ static int srp_abort(struct scsi_cmnd *scmnd)
2548 shost_printk(KERN_ERR, target->scsi_host, 2562 shost_printk(KERN_ERR, target->scsi_host,
2549 "Sending SRP abort for tag %#x\n", tag); 2563 "Sending SRP abort for tag %#x\n", tag);
2550 if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun, 2564 if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun,
2551 SRP_TSK_ABORT_TASK) == 0) 2565 SRP_TSK_ABORT_TASK, NULL) == 0)
2552 ret = SUCCESS; 2566 ret = SUCCESS;
2553 else if (target->rport->state == SRP_RPORT_LOST) 2567 else if (target->rport->state == SRP_RPORT_LOST)
2554 ret = FAST_IO_FAIL; 2568 ret = FAST_IO_FAIL;
@@ -2566,14 +2580,15 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
2566 struct srp_target_port *target = host_to_target(scmnd->device->host); 2580 struct srp_target_port *target = host_to_target(scmnd->device->host);
2567 struct srp_rdma_ch *ch; 2581 struct srp_rdma_ch *ch;
2568 int i; 2582 int i;
2583 u8 status;
2569 2584
2570 shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); 2585 shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n");
2571 2586
2572 ch = &target->ch[0]; 2587 ch = &target->ch[0];
2573 if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, scmnd->device->lun, 2588 if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, scmnd->device->lun,
2574 SRP_TSK_LUN_RESET)) 2589 SRP_TSK_LUN_RESET, &status))
2575 return FAILED; 2590 return FAILED;
2576 if (ch->tsk_mgmt_status) 2591 if (status)
2577 return FAILED; 2592 return FAILED;
2578 2593
2579 for (i = 0; i < target->ch_count; i++) { 2594 for (i = 0; i < target->ch_count; i++) {