scsi: storvsc: Add support for FC rport.
[linux-2.6-block.git] / drivers / scsi / storvsc_drv.c
index 585e54f6512cdd773342a7a040a203045ea65f26..b2183415b9ee564a439ad47b4a84a13b8d667992 100644 (file)
@@ -280,7 +280,7 @@ static const struct vmstor_protocol vmstor_protocols[] = {
 
 
 /*
- * This structure is sent during the intialization phase to get the different
+ * This structure is sent during the initialization phase to get the different
  * properties of the channel.
  */
 
@@ -478,6 +478,9 @@ struct storvsc_device {
         */
        u64 node_name;
        u64 port_name;
+#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
+       struct fc_rport *rport;
+#endif
 };
 
 struct hv_host_device {
@@ -866,7 +869,7 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc)
         * We will however populate all the slots to evenly distribute
         * the load.
         */
-       stor_device->stor_chns = kzalloc(sizeof(void *) * num_possible_cpus(),
+       stor_device->stor_chns = kcalloc(num_possible_cpus(), sizeof(void *),
                                         GFP_KERNEL);
        if (stor_device->stor_chns == NULL)
                return -ENOMEM;
@@ -1191,8 +1194,6 @@ static void storvsc_on_channel_callback(void *context)
                        break;
                }
        } while (1);
-
-       return;
 }
 
 static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size,
@@ -1816,19 +1817,27 @@ static int storvsc_probe(struct hv_device *device,
                target = (device->dev_instance.b[5] << 8 |
                         device->dev_instance.b[4]);
                ret = scsi_add_device(host, 0, target, 0);
-               if (ret) {
-                       scsi_remove_host(host);
-                       goto err_out2;
-               }
+               if (ret)
+                       goto err_out3;
        }
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
        if (host->transportt == fc_transport_template) {
+               struct fc_rport_identifiers ids = {
+                       .roles = FC_PORT_ROLE_FCP_DUMMY_INITIATOR,
+               };
+
                fc_host_node_name(host) = stor_device->node_name;
                fc_host_port_name(host) = stor_device->port_name;
+               stor_device->rport = fc_remote_port_add(host, 0, &ids);
+               if (!stor_device->rport)
+                       goto err_out3;
        }
 #endif
        return 0;
 
+err_out3:
+       scsi_remove_host(host);
+
 err_out2:
        /*
         * Once we have connected with the host, we would need to
@@ -1854,8 +1863,10 @@ static int storvsc_remove(struct hv_device *dev)
        struct Scsi_Host *host = stor_device->host;
 
 #if IS_ENABLED(CONFIG_SCSI_FC_ATTRS)
-       if (host->transportt == fc_transport_template)
+       if (host->transportt == fc_transport_template) {
+               fc_remote_port_delete(stor_device->rport);
                fc_remove_host(host);
+       }
 #endif
        scsi_remove_host(host);
        storvsc_dev_remove(dev);