diff options
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 4 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | 19 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 14 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iscsi_iser.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_memory.c | 9 | ||||
-rw-r--r-- | drivers/infiniband/ulp/iser/iser_verbs.c | 8 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 42 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 1 |
8 files changed, 72 insertions, 27 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 07ca6fd5546b..eb71aaa26a9a 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -117,6 +117,8 @@ enum { | |||
117 | #define IPOIB_OP_CM (0) | 117 | #define IPOIB_OP_CM (0) |
118 | #endif | 118 | #endif |
119 | 119 | ||
120 | #define IPOIB_QPN_MASK ((__force u32) cpu_to_be32(0xFFFFFF)) | ||
121 | |||
120 | /* structs */ | 122 | /* structs */ |
121 | 123 | ||
122 | struct ipoib_header { | 124 | struct ipoib_header { |
@@ -760,4 +762,6 @@ extern int ipoib_debug_level; | |||
760 | 762 | ||
761 | #define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff) | 763 | #define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff) |
762 | 764 | ||
765 | extern const char ipoib_driver_version[]; | ||
766 | |||
763 | #endif /* _IPOIB_H */ | 767 | #endif /* _IPOIB_H */ |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c index 29bc7b5724ac..c4b3940845e6 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c | |||
@@ -39,7 +39,24 @@ | |||
39 | static void ipoib_get_drvinfo(struct net_device *netdev, | 39 | static void ipoib_get_drvinfo(struct net_device *netdev, |
40 | struct ethtool_drvinfo *drvinfo) | 40 | struct ethtool_drvinfo *drvinfo) |
41 | { | 41 | { |
42 | strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1); | 42 | struct ipoib_dev_priv *priv = netdev_priv(netdev); |
43 | struct ib_device_attr *attr; | ||
44 | |||
45 | attr = kmalloc(sizeof(*attr), GFP_KERNEL); | ||
46 | if (attr && !ib_query_device(priv->ca, attr)) | ||
47 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), | ||
48 | "%d.%d.%d", (int)(attr->fw_ver >> 32), | ||
49 | (int)(attr->fw_ver >> 16) & 0xffff, | ||
50 | (int)attr->fw_ver & 0xffff); | ||
51 | kfree(attr); | ||
52 | |||
53 | strlcpy(drvinfo->bus_info, dev_name(priv->ca->dma_device), | ||
54 | sizeof(drvinfo->bus_info)); | ||
55 | |||
56 | strlcpy(drvinfo->version, ipoib_driver_version, | ||
57 | sizeof(drvinfo->version)); | ||
58 | |||
59 | strlcpy(drvinfo->driver, "ib_ipoib", sizeof(drvinfo->driver)); | ||
43 | } | 60 | } |
44 | 61 | ||
45 | static int ipoib_get_coalesce(struct net_device *dev, | 62 | static int ipoib_get_coalesce(struct net_device *dev, |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 6fdc9e78da0d..8534afd04e7c 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -49,9 +49,14 @@ | |||
49 | #include <linux/jhash.h> | 49 | #include <linux/jhash.h> |
50 | #include <net/arp.h> | 50 | #include <net/arp.h> |
51 | 51 | ||
52 | #define DRV_VERSION "1.0.0" | ||
53 | |||
54 | const char ipoib_driver_version[] = DRV_VERSION; | ||
55 | |||
52 | MODULE_AUTHOR("Roland Dreier"); | 56 | MODULE_AUTHOR("Roland Dreier"); |
53 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); | 57 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); |
54 | MODULE_LICENSE("Dual BSD/GPL"); | 58 | MODULE_LICENSE("Dual BSD/GPL"); |
59 | MODULE_VERSION(DRV_VERSION); | ||
55 | 60 | ||
56 | int ipoib_sendq_size __read_mostly = IPOIB_TX_RING_SIZE; | 61 | int ipoib_sendq_size __read_mostly = IPOIB_TX_RING_SIZE; |
57 | int ipoib_recvq_size __read_mostly = IPOIB_RX_RING_SIZE; | 62 | int ipoib_recvq_size __read_mostly = IPOIB_RX_RING_SIZE; |
@@ -505,6 +510,9 @@ static void path_rec_completion(int status, | |||
505 | 510 | ||
506 | spin_unlock_irqrestore(&priv->lock, flags); | 511 | spin_unlock_irqrestore(&priv->lock, flags); |
507 | 512 | ||
513 | if (IS_ERR_OR_NULL(ah)) | ||
514 | ipoib_del_neighs_by_gid(dev, path->pathrec.dgid.raw); | ||
515 | |||
508 | if (old_ah) | 516 | if (old_ah) |
509 | ipoib_put_ah(old_ah); | 517 | ipoib_put_ah(old_ah); |
510 | 518 | ||
@@ -844,10 +852,10 @@ static u32 ipoib_addr_hash(struct ipoib_neigh_hash *htbl, u8 *daddr) | |||
844 | * different subnets. | 852 | * different subnets. |
845 | */ | 853 | */ |
846 | /* qpn octets[1:4) & port GUID octets[12:20) */ | 854 | /* qpn octets[1:4) & port GUID octets[12:20) */ |
847 | u32 *daddr_32 = (u32 *) daddr; | 855 | u32 *d32 = (u32 *) daddr; |
848 | u32 hv; | 856 | u32 hv; |
849 | 857 | ||
850 | hv = jhash_3words(daddr_32[3], daddr_32[4], 0xFFFFFF & daddr_32[0], 0); | 858 | hv = jhash_3words(d32[3], d32[4], IPOIB_QPN_MASK & d32[0], 0); |
851 | return hv & htbl->mask; | 859 | return hv & htbl->mask; |
852 | } | 860 | } |
853 | 861 | ||
@@ -1688,6 +1696,8 @@ static void ipoib_remove_one(struct ib_device *device) | |||
1688 | return; | 1696 | return; |
1689 | 1697 | ||
1690 | dev_list = ib_get_client_data(device, &ipoib_client); | 1698 | dev_list = ib_get_client_data(device, &ipoib_client); |
1699 | if (!dev_list) | ||
1700 | return; | ||
1691 | 1701 | ||
1692 | list_for_each_entry_safe(priv, tmp, dev_list, list) { | 1702 | list_for_each_entry_safe(priv, tmp, dev_list, list) { |
1693 | ib_unregister_event_handler(&priv->event_handler); | 1703 | ib_unregister_event_handler(&priv->event_handler); |
diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.h b/drivers/infiniband/ulp/iser/iscsi_iser.h index ef7d3be46c31..5babdb35bda7 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.h +++ b/drivers/infiniband/ulp/iser/iscsi_iser.h | |||
@@ -94,7 +94,7 @@ | |||
94 | 94 | ||
95 | /* support up to 512KB in one RDMA */ | 95 | /* support up to 512KB in one RDMA */ |
96 | #define ISCSI_ISER_SG_TABLESIZE (0x80000 >> SHIFT_4K) | 96 | #define ISCSI_ISER_SG_TABLESIZE (0x80000 >> SHIFT_4K) |
97 | #define ISER_DEF_CMD_PER_LUN 128 | 97 | #define ISER_DEF_CMD_PER_LUN ISCSI_DEF_XMIT_CMDS_MAX |
98 | 98 | ||
99 | /* QP settings */ | 99 | /* QP settings */ |
100 | /* Maximal bounds on received asynchronous PDUs */ | 100 | /* Maximal bounds on received asynchronous PDUs */ |
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c index 2033a928d34d..be1edb04b085 100644 --- a/drivers/infiniband/ulp/iser/iser_memory.c +++ b/drivers/infiniband/ulp/iser/iser_memory.c | |||
@@ -369,10 +369,11 @@ int iser_reg_rdma_mem(struct iscsi_iser_task *iser_task, | |||
369 | regd_buf = &iser_task->rdma_regd[cmd_dir]; | 369 | regd_buf = &iser_task->rdma_regd[cmd_dir]; |
370 | 370 | ||
371 | aligned_len = iser_data_buf_aligned_len(mem, ibdev); | 371 | aligned_len = iser_data_buf_aligned_len(mem, ibdev); |
372 | if (aligned_len != mem->dma_nents) { | 372 | if (aligned_len != mem->dma_nents || |
373 | (!ib_conn->fmr_pool && mem->dma_nents > 1)) { | ||
373 | iscsi_conn->fmr_unalign_cnt++; | 374 | iscsi_conn->fmr_unalign_cnt++; |
374 | iser_warn("rdma alignment violation %d/%d aligned\n", | 375 | iser_warn("rdma alignment violation (%d/%d aligned) or FMR not supported\n", |
375 | aligned_len, mem->size); | 376 | aligned_len, mem->size); |
376 | iser_data_buf_dump(mem, ibdev); | 377 | iser_data_buf_dump(mem, ibdev); |
377 | 378 | ||
378 | /* unmap the command data before accessing it */ | 379 | /* unmap the command data before accessing it */ |
@@ -404,7 +405,7 @@ int iser_reg_rdma_mem(struct iscsi_iser_task *iser_task, | |||
404 | } else { /* use FMR for multiple dma entries */ | 405 | } else { /* use FMR for multiple dma entries */ |
405 | iser_page_vec_build(mem, ib_conn->page_vec, ibdev); | 406 | iser_page_vec_build(mem, ib_conn->page_vec, ibdev); |
406 | err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, ®d_buf->reg); | 407 | err = iser_reg_page_vec(ib_conn, ib_conn->page_vec, ®d_buf->reg); |
407 | if (err) { | 408 | if (err && err != -EAGAIN) { |
408 | iser_data_buf_dump(mem, ibdev); | 409 | iser_data_buf_dump(mem, ibdev); |
409 | iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", | 410 | iser_err("mem->dma_nents = %d (dlength = 0x%x)\n", |
410 | mem->dma_nents, | 411 | mem->dma_nents, |
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 95a49affee44..4debadc53106 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c | |||
@@ -242,10 +242,14 @@ static int iser_create_ib_conn_res(struct iser_conn *ib_conn) | |||
242 | IB_ACCESS_REMOTE_READ); | 242 | IB_ACCESS_REMOTE_READ); |
243 | 243 | ||
244 | ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, ¶ms); | 244 | ib_conn->fmr_pool = ib_create_fmr_pool(device->pd, ¶ms); |
245 | if (IS_ERR(ib_conn->fmr_pool)) { | 245 | ret = PTR_ERR(ib_conn->fmr_pool); |
246 | ret = PTR_ERR(ib_conn->fmr_pool); | 246 | if (IS_ERR(ib_conn->fmr_pool) && ret != -ENOSYS) { |
247 | ib_conn->fmr_pool = NULL; | 247 | ib_conn->fmr_pool = NULL; |
248 | goto out_err; | 248 | goto out_err; |
249 | } else if (ret == -ENOSYS) { | ||
250 | ib_conn->fmr_pool = NULL; | ||
251 | iser_warn("FMRs are not supported, using unaligned mode\n"); | ||
252 | ret = 0; | ||
249 | } | 253 | } |
250 | 254 | ||
251 | memset(&init_attr, 0, sizeof init_attr); | 255 | memset(&init_attr, 0, sizeof init_attr); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index d5088ce78290..7ccf3284dda3 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,11 +729,12 @@ 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 | ||
733 | unblock: | ||
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); |
737 | target->transport_offline = !!ret; | ||
736 | 738 | ||
737 | if (ret) | 739 | if (ret) |
738 | goto err; | 740 | goto err; |
@@ -1352,6 +1354,12 @@ static int srp_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd) | |||
1352 | unsigned long flags; | 1354 | unsigned long flags; |
1353 | int len; | 1355 | int len; |
1354 | 1356 | ||
1357 | if (unlikely(target->transport_offline)) { | ||
1358 | scmnd->result = DID_NO_CONNECT << 16; | ||
1359 | scmnd->scsi_done(scmnd); | ||
1360 | return 0; | ||
1361 | } | ||
1362 | |||
1355 | spin_lock_irqsave(&target->lock, flags); | 1363 | spin_lock_irqsave(&target->lock, flags); |
1356 | iu = __srp_get_tx_iu(target, SRP_IU_CMD); | 1364 | iu = __srp_get_tx_iu(target, SRP_IU_CMD); |
1357 | if (!iu) | 1365 | if (!iu) |
@@ -1695,6 +1703,9 @@ static int srp_send_tsk_mgmt(struct srp_target_port *target, | |||
1695 | struct srp_iu *iu; | 1703 | struct srp_iu *iu; |
1696 | struct srp_tsk_mgmt *tsk_mgmt; | 1704 | struct srp_tsk_mgmt *tsk_mgmt; |
1697 | 1705 | ||
1706 | if (!target->connected || target->qp_in_error) | ||
1707 | return -1; | ||
1708 | |||
1698 | init_completion(&target->tsk_mgmt_done); | 1709 | init_completion(&target->tsk_mgmt_done); |
1699 | 1710 | ||
1700 | spin_lock_irq(&target->lock); | 1711 | spin_lock_irq(&target->lock); |
@@ -1736,7 +1747,7 @@ static int srp_abort(struct scsi_cmnd *scmnd) | |||
1736 | 1747 | ||
1737 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); | 1748 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); |
1738 | 1749 | ||
1739 | if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd)) | 1750 | if (!req || !srp_claim_req(target, req, scmnd)) |
1740 | return FAILED; | 1751 | return FAILED; |
1741 | srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, | 1752 | srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, |
1742 | SRP_TSK_ABORT_TASK); | 1753 | SRP_TSK_ABORT_TASK); |
@@ -1754,8 +1765,6 @@ static int srp_reset_device(struct scsi_cmnd *scmnd) | |||
1754 | 1765 | ||
1755 | shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); | 1766 | shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n"); |
1756 | 1767 | ||
1757 | if (target->qp_in_error) | ||
1758 | return FAILED; | ||
1759 | if (srp_send_tsk_mgmt(target, SRP_TAG_NO_REQ, scmnd->device->lun, | 1768 | if (srp_send_tsk_mgmt(target, SRP_TAG_NO_REQ, scmnd->device->lun, |
1760 | SRP_TSK_LUN_RESET)) | 1769 | SRP_TSK_LUN_RESET)) |
1761 | return FAILED; | 1770 | return FAILED; |
@@ -1972,7 +1981,6 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target) | |||
1972 | spin_unlock(&host->target_lock); | 1981 | spin_unlock(&host->target_lock); |
1973 | 1982 | ||
1974 | target->state = SRP_TARGET_LIVE; | 1983 | target->state = SRP_TARGET_LIVE; |
1975 | target->connected = false; | ||
1976 | 1984 | ||
1977 | scsi_scan_target(&target->scsi_host->shost_gendev, | 1985 | scsi_scan_target(&target->scsi_host->shost_gendev, |
1978 | 0, target->scsi_id, SCAN_WILD_CARD, 0); | 1986 | 0, target->scsi_id, SCAN_WILD_CARD, 0); |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index de2d0b3c0bfe..66fbedda4571 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
@@ -140,6 +140,7 @@ struct srp_target_port { | |||
140 | unsigned int cmd_sg_cnt; | 140 | unsigned int cmd_sg_cnt; |
141 | unsigned int indirect_size; | 141 | unsigned int indirect_size; |
142 | bool allow_ext_sg; | 142 | bool allow_ext_sg; |
143 | bool transport_offline; | ||
143 | 144 | ||
144 | /* Everything above this point is used in the hot path of | 145 | /* Everything above this point is used in the hot path of |
145 | * command processing. Try to keep them packed into cachelines. | 146 | * command processing. Try to keep them packed into cachelines. |