aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIshai Rabinovitz <ishai@mellanox.co.il>2006-10-04 09:28:56 -0400
committerRoland Dreier <rolandd@cisco.com>2006-10-10 15:49:05 -0400
commit01cb9bcbd34b7ba768a7f05375faf43becdb8a60 (patch)
tree58eeaa0d602c3f858fced07e53ca4c44041c5a45 /drivers
parent9b0af401aae336975e620fccdd294bb763424f3f (diff)
IB/srp: Enable multiple connections to the same target
Enable multiple concurrent connections to the same SRP target: 1) Use port GUID instead of node GUID in the initiator port identifier. This allows connections to be made from multiple HCA ports at the same time. 2) Let the user specify the identifier extention when adding the device. This allows userspace to make multiple connections even from the same port, if it wants too. Without this, only one connection can be made from any given HCA, even if it has multiple ports, because we don't use multi-channel mode, so targets will only allow one connection from a given initiator port ID. Signed-off-by: Ishai Rabinovitz <ishai@mellanox.co.il> Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c26
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h2
2 files changed, 18 insertions, 10 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index f1b7a0f2beed..4b09147f438f 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -343,29 +343,32 @@ static int srp_send_req(struct srp_target_port *target)
343 */ 343 */
344 if (target->io_class == SRP_REV10_IB_IO_CLASS) { 344 if (target->io_class == SRP_REV10_IB_IO_CLASS) {
345 memcpy(req->priv.initiator_port_id, 345 memcpy(req->priv.initiator_port_id,
346 target->srp_host->initiator_port_id + 8, 8); 346 &target->path.sgid.global.interface_id, 8);
347 memcpy(req->priv.initiator_port_id + 8, 347 memcpy(req->priv.initiator_port_id + 8,
348 target->srp_host->initiator_port_id, 8); 348 &target->initiator_ext, 8);
349 memcpy(req->priv.target_port_id, &target->ioc_guid, 8); 349 memcpy(req->priv.target_port_id, &target->ioc_guid, 8);
350 memcpy(req->priv.target_port_id + 8, &target->id_ext, 8); 350 memcpy(req->priv.target_port_id + 8, &target->id_ext, 8);
351 } else { 351 } else {
352 memcpy(req->priv.initiator_port_id, 352 memcpy(req->priv.initiator_port_id,
353 target->srp_host->initiator_port_id, 16); 353 &target->initiator_ext, 8);
354 memcpy(req->priv.initiator_port_id + 8,
355 &target->path.sgid.global.interface_id, 8);
354 memcpy(req->priv.target_port_id, &target->id_ext, 8); 356 memcpy(req->priv.target_port_id, &target->id_ext, 8);
355 memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8); 357 memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
356 } 358 }
357 359
358 /* 360 /*
359 * Topspin/Cisco SRP targets will reject our login unless we 361 * Topspin/Cisco SRP targets will reject our login unless we
360 * zero out the first 8 bytes of our initiator port ID. The 362 * zero out the first 8 bytes of our initiator port ID and set
361 * second 8 bytes must be our local node GUID, but we always 363 * the second 8 bytes to the local node GUID.
362 * use that anyway.
363 */ 364 */
364 if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { 365 if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) {
365 printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " 366 printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround "
366 "activated for target GUID %016llx\n", 367 "activated for target GUID %016llx\n",
367 (unsigned long long) be64_to_cpu(target->ioc_guid)); 368 (unsigned long long) be64_to_cpu(target->ioc_guid));
368 memset(req->priv.initiator_port_id, 0, 8); 369 memset(req->priv.initiator_port_id, 0, 8);
370 memcpy(req->priv.initiator_port_id + 8,
371 &target->srp_host->dev->dev->node_guid, 8);
369 } 372 }
370 373
371 status = ib_send_cm_req(target->cm_id, &req->param); 374 status = ib_send_cm_req(target->cm_id, &req->param);
@@ -1553,6 +1556,7 @@ enum {
1553 SRP_OPT_MAX_SECT = 1 << 5, 1556 SRP_OPT_MAX_SECT = 1 << 5,
1554 SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, 1557 SRP_OPT_MAX_CMD_PER_LUN = 1 << 6,
1555 SRP_OPT_IO_CLASS = 1 << 7, 1558 SRP_OPT_IO_CLASS = 1 << 7,
1559 SRP_OPT_INITIATOR_EXT = 1 << 8,
1556 SRP_OPT_ALL = (SRP_OPT_ID_EXT | 1560 SRP_OPT_ALL = (SRP_OPT_ID_EXT |
1557 SRP_OPT_IOC_GUID | 1561 SRP_OPT_IOC_GUID |
1558 SRP_OPT_DGID | 1562 SRP_OPT_DGID |
@@ -1569,6 +1573,7 @@ static match_table_t srp_opt_tokens = {
1569 { SRP_OPT_MAX_SECT, "max_sect=%d" }, 1573 { SRP_OPT_MAX_SECT, "max_sect=%d" },
1570 { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, 1574 { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" },
1571 { SRP_OPT_IO_CLASS, "io_class=%x" }, 1575 { SRP_OPT_IO_CLASS, "io_class=%x" },
1576 { SRP_OPT_INITIATOR_EXT, "initiator_ext=%s" },
1572 { SRP_OPT_ERR, NULL } 1577 { SRP_OPT_ERR, NULL }
1573}; 1578};
1574 1579
@@ -1668,6 +1673,12 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
1668 target->io_class = token; 1673 target->io_class = token;
1669 break; 1674 break;
1670 1675
1676 case SRP_OPT_INITIATOR_EXT:
1677 p = match_strdup(args);
1678 target->initiator_ext = cpu_to_be64(simple_strtoull(p, NULL, 16));
1679 kfree(p);
1680 break;
1681
1671 default: 1682 default:
1672 printk(KERN_WARNING PFX "unknown parameter or missing value " 1683 printk(KERN_WARNING PFX "unknown parameter or missing value "
1673 "'%s' in target creation request\n", p); 1684 "'%s' in target creation request\n", p);
@@ -1814,9 +1825,6 @@ static struct srp_host *srp_add_port(struct srp_device *device, u8 port)
1814 host->dev = device; 1825 host->dev = device;
1815 host->port = port; 1826 host->port = port;
1816 1827
1817 host->initiator_port_id[7] = port;
1818 memcpy(host->initiator_port_id + 8, &device->dev->node_guid, 8);
1819
1820 host->class_dev.class = &srp_class; 1828 host->class_dev.class = &srp_class;
1821 host->class_dev.dev = device->dev->dma_device; 1829 host->class_dev.dev = device->dev->dma_device;
1822 snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d", 1830 snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d",
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index 5b581fb8eb0d..d4e35ef51374 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -91,7 +91,6 @@ struct srp_device {
91}; 91};
92 92
93struct srp_host { 93struct srp_host {
94 u8 initiator_port_id[16];
95 struct srp_device *dev; 94 struct srp_device *dev;
96 u8 port; 95 u8 port;
97 struct class_device class_dev; 96 struct class_device class_dev;
@@ -122,6 +121,7 @@ struct srp_target_port {
122 __be64 id_ext; 121 __be64 id_ext;
123 __be64 ioc_guid; 122 __be64 ioc_guid;
124 __be64 service_id; 123 __be64 service_id;
124 __be64 initiator_ext;
125 u16 io_class; 125 u16 io_class;
126 struct srp_host *srp_host; 126 struct srp_host *srp_host;
127 struct Scsi_Host *scsi_host; 127 struct Scsi_Host *scsi_host;