aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorRamachandra K <rkuchimanchi@silverstorm.com>2006-06-17 23:37:38 -0400
committerRoland Dreier <rolandd@cisco.com>2006-06-17 23:37:38 -0400
commit0c0450db31481aa01a04e7faecc93ee6841972d6 (patch)
treec7a1ed2896345d022011831f8a9aaa21e8d8ff00 /drivers/infiniband
parent73c0996b1ca60338fa50e42acfcebd32b7636a8b (diff)
IB/srp: Support SRP rev. 10 targets
There has been a change in the format of port identifiers between revision 10 of the SRP specification and the current revision 16A. Revision 10 specifies port identifier format as lower 8 bytes : GUID upper 8 bytes : Extension Whereas revision 16A specifies it as lower 8 bytes : Extension upper 8 bytes : GUID There are older targets (e.g. SilverStorm Virtual Fibre Channel Bridge) which conform to revision 10 of the SRP specification. The I/O class of revision 10 is 0xFF00 and the I/O class of revision 16A is 0x0100. For supporting older targets, this patch: 1) Adds a new optional target creation parameter "io_class". Default value of io_class is 0x0100 (i.e. revision 16A) 2) Uses the correct port identifier format for targets with IO class of 0xFF00 (i.e. conforming to revision 10) Signed-off-by: Ramachandra K <rkuchimanchi@silverstorm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c44
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.h1
2 files changed, 42 insertions, 3 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index f1401e1f2f97..e7fa8b680cb6 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -321,7 +321,29 @@ static int srp_send_req(struct srp_target_port *target)
321 req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len); 321 req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len);
322 req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | 322 req->priv.req_buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
323 SRP_BUF_FORMAT_INDIRECT); 323 SRP_BUF_FORMAT_INDIRECT);
324 memcpy(req->priv.initiator_port_id, target->srp_host->initiator_port_id, 16); 324 /*
325 * In the published SRP specification (draft rev. 16a), the
326 * port identifier format is 8 bytes of ID extension followed
327 * by 8 bytes of GUID. Older drafts put the two halves in the
328 * opposite order, so that the GUID comes first.
329 *
330 * Targets conforming to these obsolete drafts can be
331 * recognized by the I/O Class they report.
332 */
333 if (target->io_class == SRP_REV10_IB_IO_CLASS) {
334 memcpy(req->priv.initiator_port_id,
335 target->srp_host->initiator_port_id + 8, 8);
336 memcpy(req->priv.initiator_port_id + 8,
337 target->srp_host->initiator_port_id, 8);
338 memcpy(req->priv.target_port_id, &target->ioc_guid, 8);
339 memcpy(req->priv.target_port_id + 8, &target->id_ext, 8);
340 } else {
341 memcpy(req->priv.initiator_port_id,
342 target->srp_host->initiator_port_id, 16);
343 memcpy(req->priv.target_port_id, &target->id_ext, 8);
344 memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
345 }
346
325 /* 347 /*
326 * Topspin/Cisco SRP targets will reject our login unless we 348 * Topspin/Cisco SRP targets will reject our login unless we
327 * zero out the first 8 bytes of our initiator port ID. The 349 * zero out the first 8 bytes of our initiator port ID. The
@@ -334,8 +356,6 @@ static int srp_send_req(struct srp_target_port *target)
334 (unsigned long long) be64_to_cpu(target->ioc_guid)); 356 (unsigned long long) be64_to_cpu(target->ioc_guid));
335 memset(req->priv.initiator_port_id, 0, 8); 357 memset(req->priv.initiator_port_id, 0, 8);
336 } 358 }
337 memcpy(req->priv.target_port_id, &target->id_ext, 8);
338 memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
339 359
340 status = ib_send_cm_req(target->cm_id, &req->param); 360 status = ib_send_cm_req(target->cm_id, &req->param);
341 361
@@ -1511,6 +1531,7 @@ enum {
1511 SRP_OPT_SERVICE_ID = 1 << 4, 1531 SRP_OPT_SERVICE_ID = 1 << 4,
1512 SRP_OPT_MAX_SECT = 1 << 5, 1532 SRP_OPT_MAX_SECT = 1 << 5,
1513 SRP_OPT_MAX_CMD_PER_LUN = 1 << 6, 1533 SRP_OPT_MAX_CMD_PER_LUN = 1 << 6,
1534 SRP_OPT_IO_CLASS = 1 << 7,
1514 SRP_OPT_ALL = (SRP_OPT_ID_EXT | 1535 SRP_OPT_ALL = (SRP_OPT_ID_EXT |
1515 SRP_OPT_IOC_GUID | 1536 SRP_OPT_IOC_GUID |
1516 SRP_OPT_DGID | 1537 SRP_OPT_DGID |
@@ -1526,6 +1547,7 @@ static match_table_t srp_opt_tokens = {
1526 { SRP_OPT_SERVICE_ID, "service_id=%s" }, 1547 { SRP_OPT_SERVICE_ID, "service_id=%s" },
1527 { SRP_OPT_MAX_SECT, "max_sect=%d" }, 1548 { SRP_OPT_MAX_SECT, "max_sect=%d" },
1528 { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" }, 1549 { SRP_OPT_MAX_CMD_PER_LUN, "max_cmd_per_lun=%d" },
1550 { SRP_OPT_IO_CLASS, "io_class=%x" },
1529 { SRP_OPT_ERR, NULL } 1551 { SRP_OPT_ERR, NULL }
1530}; 1552};
1531 1553
@@ -1610,6 +1632,21 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
1610 target->scsi_host->cmd_per_lun = min(token, SRP_SQ_SIZE); 1632 target->scsi_host->cmd_per_lun = min(token, SRP_SQ_SIZE);
1611 break; 1633 break;
1612 1634
1635 case SRP_OPT_IO_CLASS:
1636 if (match_hex(args, &token)) {
1637 printk(KERN_WARNING PFX "bad IO class parameter '%s' \n", p);
1638 goto out;
1639 }
1640 if (token != SRP_REV10_IB_IO_CLASS &&
1641 token != SRP_REV16A_IB_IO_CLASS) {
1642 printk(KERN_WARNING PFX "unknown IO class parameter value"
1643 " %x specified (use %x or %x).\n",
1644 token, SRP_REV10_IB_IO_CLASS, SRP_REV16A_IB_IO_CLASS);
1645 goto out;
1646 }
1647 target->io_class = token;
1648 break;
1649
1613 default: 1650 default:
1614 printk(KERN_WARNING PFX "unknown parameter or missing value " 1651 printk(KERN_WARNING PFX "unknown parameter or missing value "
1615 "'%s' in target creation request\n", p); 1652 "'%s' in target creation request\n", p);
@@ -1652,6 +1689,7 @@ static ssize_t srp_create_target(struct class_device *class_dev,
1652 target = host_to_target(target_host); 1689 target = host_to_target(target_host);
1653 memset(target, 0, sizeof *target); 1690 memset(target, 0, sizeof *target);
1654 1691
1692 target->io_class = SRP_REV16A_IB_IO_CLASS;
1655 target->scsi_host = target_host; 1693 target->scsi_host = target_host;
1656 target->srp_host = host; 1694 target->srp_host = host;
1657 1695
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h
index ad45e4856e1c..5b581fb8eb0d 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.h
+++ b/drivers/infiniband/ulp/srp/ib_srp.h
@@ -122,6 +122,7 @@ struct srp_target_port {
122 __be64 id_ext; 122 __be64 id_ext;
123 __be64 ioc_guid; 123 __be64 ioc_guid;
124 __be64 service_id; 124 __be64 service_id;
125 u16 io_class;
125 struct srp_host *srp_host; 126 struct srp_host *srp_host;
126 struct Scsi_Host *scsi_host; 127 struct Scsi_Host *scsi_host;
127 char target_name[32]; 128 char target_name[32];