diff options
Diffstat (limited to 'drivers/infiniband/ulp/srp/ib_srp.c')
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 9909022dc6c3..3db9a659719b 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -488,7 +488,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch) | |||
488 | struct ib_qp *qp; | 488 | struct ib_qp *qp; |
489 | struct ib_fmr_pool *fmr_pool = NULL; | 489 | struct ib_fmr_pool *fmr_pool = NULL; |
490 | struct srp_fr_pool *fr_pool = NULL; | 490 | struct srp_fr_pool *fr_pool = NULL; |
491 | const int m = 1 + dev->use_fast_reg; | 491 | const int m = dev->use_fast_reg ? 3 : 1; |
492 | struct ib_cq_init_attr cq_attr = {}; | 492 | struct ib_cq_init_attr cq_attr = {}; |
493 | int ret; | 493 | int ret; |
494 | 494 | ||
@@ -994,16 +994,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich) | |||
994 | 994 | ||
995 | ret = srp_lookup_path(ch); | 995 | ret = srp_lookup_path(ch); |
996 | if (ret) | 996 | if (ret) |
997 | return ret; | 997 | goto out; |
998 | 998 | ||
999 | while (1) { | 999 | while (1) { |
1000 | init_completion(&ch->done); | 1000 | init_completion(&ch->done); |
1001 | ret = srp_send_req(ch, multich); | 1001 | ret = srp_send_req(ch, multich); |
1002 | if (ret) | 1002 | if (ret) |
1003 | return ret; | 1003 | goto out; |
1004 | ret = wait_for_completion_interruptible(&ch->done); | 1004 | ret = wait_for_completion_interruptible(&ch->done); |
1005 | if (ret < 0) | 1005 | if (ret < 0) |
1006 | return ret; | 1006 | goto out; |
1007 | 1007 | ||
1008 | /* | 1008 | /* |
1009 | * The CM event handling code will set status to | 1009 | * The CM event handling code will set status to |
@@ -1011,15 +1011,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich) | |||
1011 | * back, or SRP_DLID_REDIRECT if we get a lid/qp | 1011 | * back, or SRP_DLID_REDIRECT if we get a lid/qp |
1012 | * redirect REJ back. | 1012 | * redirect REJ back. |
1013 | */ | 1013 | */ |
1014 | switch (ch->status) { | 1014 | ret = ch->status; |
1015 | switch (ret) { | ||
1015 | case 0: | 1016 | case 0: |
1016 | ch->connected = true; | 1017 | ch->connected = true; |
1017 | return 0; | 1018 | goto out; |
1018 | 1019 | ||
1019 | case SRP_PORT_REDIRECT: | 1020 | case SRP_PORT_REDIRECT: |
1020 | ret = srp_lookup_path(ch); | 1021 | ret = srp_lookup_path(ch); |
1021 | if (ret) | 1022 | if (ret) |
1022 | return ret; | 1023 | goto out; |
1023 | break; | 1024 | break; |
1024 | 1025 | ||
1025 | case SRP_DLID_REDIRECT: | 1026 | case SRP_DLID_REDIRECT: |
@@ -1028,13 +1029,16 @@ static int srp_connect_ch(struct srp_rdma_ch *ch, bool multich) | |||
1028 | case SRP_STALE_CONN: | 1029 | case SRP_STALE_CONN: |
1029 | shost_printk(KERN_ERR, target->scsi_host, PFX | 1030 | shost_printk(KERN_ERR, target->scsi_host, PFX |
1030 | "giving up on stale connection\n"); | 1031 | "giving up on stale connection\n"); |
1031 | ch->status = -ECONNRESET; | 1032 | ret = -ECONNRESET; |
1032 | return ch->status; | 1033 | goto out; |
1033 | 1034 | ||
1034 | default: | 1035 | default: |
1035 | return ch->status; | 1036 | goto out; |
1036 | } | 1037 | } |
1037 | } | 1038 | } |
1039 | |||
1040 | out: | ||
1041 | return ret <= 0 ? ret : -ENODEV; | ||
1038 | } | 1042 | } |
1039 | 1043 | ||
1040 | static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey) | 1044 | static int srp_inv_rkey(struct srp_rdma_ch *ch, u32 rkey) |
@@ -1309,7 +1313,7 @@ reset_state: | |||
1309 | } | 1313 | } |
1310 | 1314 | ||
1311 | static int srp_map_finish_fr(struct srp_map_state *state, | 1315 | static int srp_map_finish_fr(struct srp_map_state *state, |
1312 | struct srp_rdma_ch *ch) | 1316 | struct srp_rdma_ch *ch, int sg_nents) |
1313 | { | 1317 | { |
1314 | struct srp_target_port *target = ch->target; | 1318 | struct srp_target_port *target = ch->target; |
1315 | struct srp_device *dev = target->srp_host->srp_dev; | 1319 | struct srp_device *dev = target->srp_host->srp_dev; |
@@ -1324,10 +1328,10 @@ static int srp_map_finish_fr(struct srp_map_state *state, | |||
1324 | 1328 | ||
1325 | WARN_ON_ONCE(!dev->use_fast_reg); | 1329 | WARN_ON_ONCE(!dev->use_fast_reg); |
1326 | 1330 | ||
1327 | if (state->sg_nents == 0) | 1331 | if (sg_nents == 0) |
1328 | return 0; | 1332 | return 0; |
1329 | 1333 | ||
1330 | if (state->sg_nents == 1 && target->global_mr) { | 1334 | if (sg_nents == 1 && target->global_mr) { |
1331 | srp_map_desc(state, sg_dma_address(state->sg), | 1335 | srp_map_desc(state, sg_dma_address(state->sg), |
1332 | sg_dma_len(state->sg), | 1336 | sg_dma_len(state->sg), |
1333 | target->global_mr->rkey); | 1337 | target->global_mr->rkey); |
@@ -1341,8 +1345,7 @@ static int srp_map_finish_fr(struct srp_map_state *state, | |||
1341 | rkey = ib_inc_rkey(desc->mr->rkey); | 1345 | rkey = ib_inc_rkey(desc->mr->rkey); |
1342 | ib_update_fast_reg_key(desc->mr, rkey); | 1346 | ib_update_fast_reg_key(desc->mr, rkey); |
1343 | 1347 | ||
1344 | n = ib_map_mr_sg(desc->mr, state->sg, state->sg_nents, | 1348 | n = ib_map_mr_sg(desc->mr, state->sg, sg_nents, dev->mr_page_size); |
1345 | dev->mr_page_size); | ||
1346 | if (unlikely(n < 0)) | 1349 | if (unlikely(n < 0)) |
1347 | return n; | 1350 | return n; |
1348 | 1351 | ||
@@ -1448,16 +1451,15 @@ static int srp_map_sg_fr(struct srp_map_state *state, struct srp_rdma_ch *ch, | |||
1448 | state->fr.next = req->fr_list; | 1451 | state->fr.next = req->fr_list; |
1449 | state->fr.end = req->fr_list + ch->target->cmd_sg_cnt; | 1452 | state->fr.end = req->fr_list + ch->target->cmd_sg_cnt; |
1450 | state->sg = scat; | 1453 | state->sg = scat; |
1451 | state->sg_nents = scsi_sg_count(req->scmnd); | ||
1452 | 1454 | ||
1453 | while (state->sg_nents) { | 1455 | while (count) { |
1454 | int i, n; | 1456 | int i, n; |
1455 | 1457 | ||
1456 | n = srp_map_finish_fr(state, ch); | 1458 | n = srp_map_finish_fr(state, ch, count); |
1457 | if (unlikely(n < 0)) | 1459 | if (unlikely(n < 0)) |
1458 | return n; | 1460 | return n; |
1459 | 1461 | ||
1460 | state->sg_nents -= n; | 1462 | count -= n; |
1461 | for (i = 0; i < n; i++) | 1463 | for (i = 0; i < n; i++) |
1462 | state->sg = sg_next(state->sg); | 1464 | state->sg = sg_next(state->sg); |
1463 | } | 1465 | } |
@@ -1517,10 +1519,12 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req, | |||
1517 | 1519 | ||
1518 | if (dev->use_fast_reg) { | 1520 | if (dev->use_fast_reg) { |
1519 | state.sg = idb_sg; | 1521 | state.sg = idb_sg; |
1520 | state.sg_nents = 1; | ||
1521 | sg_set_buf(idb_sg, req->indirect_desc, idb_len); | 1522 | sg_set_buf(idb_sg, req->indirect_desc, idb_len); |
1522 | idb_sg->dma_address = req->indirect_dma_addr; /* hack! */ | 1523 | idb_sg->dma_address = req->indirect_dma_addr; /* hack! */ |
1523 | ret = srp_map_finish_fr(&state, ch); | 1524 | #ifdef CONFIG_NEED_SG_DMA_LENGTH |
1525 | idb_sg->dma_length = idb_sg->length; /* hack^2 */ | ||
1526 | #endif | ||
1527 | ret = srp_map_finish_fr(&state, ch, 1); | ||
1524 | if (ret < 0) | 1528 | if (ret < 0) |
1525 | return ret; | 1529 | return ret; |
1526 | } else if (dev->use_fmr) { | 1530 | } else if (dev->use_fmr) { |
@@ -1655,7 +1659,7 @@ static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_rdma_ch *ch, | |||
1655 | return ret; | 1659 | return ret; |
1656 | req->nmdesc++; | 1660 | req->nmdesc++; |
1657 | } else { | 1661 | } else { |
1658 | idb_rkey = target->global_mr->rkey; | 1662 | idb_rkey = cpu_to_be32(target->global_mr->rkey); |
1659 | } | 1663 | } |
1660 | 1664 | ||
1661 | indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr); | 1665 | indirect_hdr->table_desc.va = cpu_to_be64(req->indirect_dma_addr); |