Merge ../linux-2.6-watchdog-mm
[linux-drm-fsl-dcu.git] / drivers / infiniband / ulp / srp / ib_srp.c
index 44b9e5be6687941757e62ac0a7fd9be231dcda68..4b09147f438f5d44a93d46eba3ccf6de6ed345bc 100644 (file)
@@ -343,29 +343,32 @@ static int srp_send_req(struct srp_target_port *target)
         */
        if (target->io_class == SRP_REV10_IB_IO_CLASS) {
                memcpy(req->priv.initiator_port_id,
-                      target->srp_host->initiator_port_id + 8, 8);
+                      &target->path.sgid.global.interface_id, 8);
                memcpy(req->priv.initiator_port_id + 8,
-                      target->srp_host->initiator_port_id, 8);
+                      &target->initiator_ext, 8);
                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.initiator_port_id,
-                      target->srp_host->initiator_port_id, 16);
+                      &target->initiator_ext, 8);
+               memcpy(req->priv.initiator_port_id + 8,
+                      &target->path.sgid.global.interface_id, 8);
                memcpy(req->priv.target_port_id,     &target->id_ext, 8);
                memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
        }
 
        /*
         * 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
-        * use that anyway.
+        * zero out the first 8 bytes of our initiator port ID and set
+        * the second 8 bytes to the local node GUID.
         */
        if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) {
                printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround "
                       "activated for target GUID %016llx\n",
                       (unsigned long long) be64_to_cpu(target->ioc_guid));
                memset(req->priv.initiator_port_id, 0, 8);
+               memcpy(req->priv.initiator_port_id + 8,
+                      &target->srp_host->dev->dev->node_guid, 8);
        }
 
        status = ib_send_cm_req(target->cm_id, &req->param);
@@ -1553,6 +1556,7 @@ enum {
        SRP_OPT_MAX_SECT        = 1 << 5,
        SRP_OPT_MAX_CMD_PER_LUN = 1 << 6,
        SRP_OPT_IO_CLASS        = 1 << 7,
+       SRP_OPT_INITIATOR_EXT   = 1 << 8,
        SRP_OPT_ALL             = (SRP_OPT_ID_EXT       |
                                   SRP_OPT_IOC_GUID     |
                                   SRP_OPT_DGID         |
@@ -1569,6 +1573,7 @@ static match_table_t srp_opt_tokens = {
        { 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_INITIATOR_EXT,        "initiator_ext=%s"      },
        { SRP_OPT_ERR,                  NULL                    }
 };
 
@@ -1668,6 +1673,12 @@ static int srp_parse_options(const char *buf, struct srp_target_port *target)
                        target->io_class = token;
                        break;
 
+               case SRP_OPT_INITIATOR_EXT:
+                       p = match_strdup(args);
+                       target->initiator_ext = cpu_to_be64(simple_strtoull(p, NULL, 16));
+                       kfree(p);
+                       break;
+
                default:
                        printk(KERN_WARNING PFX "unknown parameter or missing value "
                               "'%s' in target creation request\n", p);
@@ -1708,7 +1719,6 @@ static ssize_t srp_create_target(struct class_device *class_dev,
        target_host->max_lun = SRP_MAX_LUN;
 
        target = host_to_target(target_host);
-       memset(target, 0, sizeof *target);
 
        target->io_class   = SRP_REV16A_IB_IO_CLASS;
        target->scsi_host  = target_host;
@@ -1815,9 +1825,6 @@ static struct srp_host *srp_add_port(struct srp_device *device, u8 port)
        host->dev  = device;
        host->port = port;
 
-       host->initiator_port_id[7] = port;
-       memcpy(host->initiator_port_id + 8, &device->dev->node_guid, 8);
-
        host->class_dev.class = &srp_class;
        host->class_dev.dev   = device->dev->dma_device;
        snprintf(host->class_dev.class_id, BUS_ID_SIZE, "srp-%s-%d",