Hi Roland,

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

Where as 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 IO class of revision 10 is 0xFF00 and the IO 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)


Regards,
Ram


Signed-off-by: Ramachandra K ([EMAIL PROTECTED])

Index: infiniband/ulp/srp/ib_srp.c
===================================================================
--- infiniband/ulp/srp/ib_srp.c (revision 7460)
+++ infiniband/ulp/srp/ib_srp.c (working copy)
@@ -321,8 +321,34 @@
        req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len);
        req->priv.req_buf_fmt   = cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
                                              SRP_BUF_FORMAT_INDIRECT);
-       memcpy(req->priv.initiator_port_id, 
target->srp_host->initiator_port_id, 16);
        /*
+        * Older targets conforming to Rev 10 of the SRP specification
+        * use the port identifier format which is
+        *
+        * lower 8 bytes :  GUID
+        * upper 8 bytes :  extension
+        *
+        * Where as according to the new SRP specification (Rev 16a), the 
+        * port identifier format is
+        *
+        * lower 8 bytes :  extension
+        * upper 8 bytes :  GUID
+        *
+        * So check the IO class of the target to decide which format to use.
+        */
+
+       /* If its Rev 10, flip the initiator port id fields */
+       if (target->io_class == SRP_REV10_IO_CLASS) {
+               memcpy(req->priv.initiator_port_id,
+                       target->srp_host->initiator_port_id + 8 , 8);
+               memcpy(req->priv.initiator_port_id + 8,
+                       target->srp_host->initiator_port_id, 8);
+       }
+       else {  
+               memcpy(req->priv.initiator_port_id,
+                        target->srp_host->initiator_port_id, 16);
+       }
+       /*
         * Topspin/Cisco SRP targets will reject our login unless we
         * zero out the first 8 bytes of our initiator port ID.  The
         * second 8 bytes must be our local node GUID, but we always
@@ -334,8 +360,14 @@
                       (unsigned long long) be64_to_cpu(target->ioc_guid));
                memset(req->priv.initiator_port_id, 0, 8);
        }
-       memcpy(req->priv.target_port_id,     &target->id_ext, 8);
-       memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
+       if (target->io_class == SRP_REV10_IO_CLASS) {
+               memcpy(req->priv.target_port_id,     &target->ioc_guid, 8);
+               memcpy(req->priv.target_port_id + 8, &target->id_ext, 8);
+       }
+       else {
+               memcpy(req->priv.target_port_id,     &target->id_ext, 8);
+               memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
+       }
 
        status = ib_send_cm_req(target->cm_id, &req->param);
 
@@ -1513,6 +1545,7 @@
        SRP_OPT_SERVICE_ID      = 1 << 4,
        SRP_OPT_MAX_SECT        = 1 << 5,
        SRP_OPT_MAX_CMD_PER_LUN = 1 << 6,
+       SRP_OPT_IO_CLASS        = 1 << 7,
        SRP_OPT_ALL             = (SRP_OPT_ID_EXT       |
                                   SRP_OPT_IOC_GUID     |
                                   SRP_OPT_DGID         |
@@ -1528,6 +1561,7 @@
        { SRP_OPT_SERVICE_ID,           "service_id=%s"         },
        { SRP_OPT_MAX_SECT,             "max_sect=%d"           },
        { SRP_OPT_MAX_CMD_PER_LUN,      "max_cmd_per_lun=%d"    },
+       { SRP_OPT_IO_CLASS,             "io_class=%x"   },
        { SRP_OPT_ERR,                  NULL                    }
 };
 
@@ -1611,7 +1645,19 @@
                        }
                        target->scsi_host->cmd_per_lun = min(token, 
SRP_SQ_SIZE);
                        break;
-
+               case SRP_OPT_IO_CLASS:
+                       if (match_hex(args, &token)) {
+                               printk(KERN_WARNING PFX "bad  IO class 
parameter '%s' \n", p);
+                               goto out;
+                       }
+                       if (token == SRP_REV10_IO_CLASS || token == 
SRP_REV16A_IO_CLASS)
+                               target->io_class = (unsigned short)(token);
+                       else
+                               printk(KERN_WARNING PFX "unknown IO class 
parameter value"
+                                  " %x specified. Use %x or %x. Defaulting to 
IO class %x\n",
+                                  token, SRP_REV10_IO_CLASS, 
SRP_REV16A_IO_CLASS,
+                                  SRP_REV16A_IO_CLASS);
+                       break;
                default:
                        printk(KERN_WARNING PFX "unknown parameter or missing 
value "
                               "'%s' in target creation request\n", p);
@@ -1654,6 +1700,8 @@
        target = host_to_target(target_host);
        memset(target, 0, sizeof *target);
 
+       /*Set default IO class of target to Rev 16A*/
+       target->io_class   = SRP_REV16A_IO_CLASS;
        target->scsi_host  = target_host;
        target->srp_host   = host;
 
Index: infiniband/ulp/srp/ib_srp.h
===================================================================
--- infiniband/ulp/srp/ib_srp.h (revision 7460)
+++ infiniband/ulp/srp/ib_srp.h (working copy)
@@ -48,6 +48,9 @@
 #include <rdma/ib_cm.h>
 #include <rdma/ib_fmr_pool.h>
 
+#define SRP_REV10_IO_CLASS   0xFF00
+#define SRP_REV16A_IO_CLASS  0x0100
+
 enum {
        SRP_PATH_REC_TIMEOUT_MS = 1000,
        SRP_ABORT_TIMEOUT_MS    = 5000,
@@ -122,6 +125,7 @@
        __be64                  id_ext;
        __be64                  ioc_guid;
        __be64                  service_id;
+       __be16                  io_class;
        struct srp_host        *srp_host;
        struct Scsi_Host       *scsi_host;
        char                    target_name[32];


_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to