Add NPIV vport create and destroy handlers and register them with the
FC transport.

Signed-off-by: Chris Leech <[email protected]>
---

 drivers/scsi/fcoe/fcoe.c |   77 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 4cd95b9..2c98c17 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -81,6 +81,9 @@ static struct notifier_block fcoe_notifier = {
 static struct scsi_transport_template *fcoe_transport_template;
 static struct scsi_transport_template *fcoe_vport_template;
 
+static int fcoe_vport_destroy(struct fc_vport *vport);
+static int fcoe_vport_create(struct fc_vport *vport, bool disabled);
+
 struct fc_function_template fcoe_transport_function = {
        .show_host_node_name = 1,
        .show_host_port_name = 1,
@@ -112,6 +115,9 @@ struct fc_function_template fcoe_transport_function = {
        .issue_fc_host_lip = fcoe_reset,
 
        .terminate_rport_io = fc_rport_terminate_io,
+
+       .vport_create = fcoe_vport_create,
+       .vport_delete = fcoe_vport_destroy,
 };
 
 struct fc_function_template fcoe_vport_function = {
@@ -488,6 +494,10 @@ static int fcoe_shost_config(struct fc_lport *lp, struct 
Scsi_Host *shost,
                                "error on scsi_add_host\n");
                return rc;
        }
+
+       if (!lp->vn_port)
+               fc_host_max_npiv_vports(lp->host) = 256;
+
        sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
                FCOE_NAME, FCOE_VERSION,
                fcoe_netdev(lp)->name);
@@ -615,12 +625,13 @@ static struct libfc_function_template 
fcoe_libfc_fcn_templ = {
  * Returns : The allocated fc_lport or an error pointer
  */
 static struct fc_lport *fcoe_if_create(struct net_device *netdev,
-                                      struct device *parent)
+                                      struct device *parent, int npiv)
 {
        int rc;
        struct fc_lport *lp = NULL;
        struct fcoe_softc *fc;
        struct Scsi_Host *shost;
+       struct fc_vport *vport;
 
        FCOE_NETDEV_DBG(netdev, "Create Interface\n");
 
@@ -641,6 +652,15 @@ static struct fc_lport *fcoe_if_create(struct net_device 
*netdev,
                goto out_host_put;
        }
 
+       if (npiv) {
+               lp->vn_port = 1;
+               vport = dev_to_vport(parent);
+               FCOE_NETDEV_DBG(netdev, "Setting vport names, 0x%llX 0x%llX\n",
+                       vport->node_name, vport->port_name);
+               fc_set_wwnn(lp, vport->node_name);
+               fc_set_wwpn(lp, vport->port_name);
+       }
+
        /*
         * Initialize FIP.
         */
@@ -1676,7 +1696,7 @@ static int fcoe_create(const char *buffer, struct 
kernel_param *kp)
        }
        fcoe_ethdrv_get(netdev);
 
-       lport = fcoe_if_create(netdev, &netdev->dev);
+       lport = fcoe_if_create(netdev, &netdev->dev, 0);
        if (IS_ERR(lport)) {
                printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
                       netdev->name);
@@ -1955,3 +1975,56 @@ static void __exit fcoe_exit(void)
        fcoe_if_exit();
 }
 module_exit(fcoe_exit);
+
+/**
+ * fcoe_vport_create()
+ * @vport: fc_vport object to create a new fc_host for
+ * @disabled: start the new fc_host in a disabled state by default?
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_vport_create(struct fc_vport *vport, bool disabled)
+{
+       struct Scsi_Host *shost = vport_to_shost(vport);
+       struct fc_lport *pport = shost_priv(shost);
+       struct fcoe_softc *fc = lport_priv(pport);
+       struct net_device *netdev = fc->real_dev;
+       struct fc_lport *lport;
+       int rc;
+
+       dev_hold(netdev);
+       fcoe_ethdrv_get(netdev);
+
+       lport = fcoe_if_create(netdev, &vport->dev, 1);
+       if (IS_ERR(lport)) {
+               printk(KERN_ERR "fcoe: fcoe_vport_create(%s) failed\n",
+                      netdev->name);
+               fcoe_ethdrv_put(netdev);
+               rc = -EIO;
+               goto out_putdev;
+       }
+       vport->dd_data = lport;
+       rc = 0;
+out_putdev:
+       dev_put(netdev);
+       return rc;
+}
+
+/**
+ * fcoe_vport_destroy() - handles the destroy from sysfs
+ * @vport:
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_vport_destroy(struct fc_vport *vport)
+{
+       struct fc_lport *lport = vport->dd_data;
+       struct fcoe_softc *fc = lport_priv(lport);
+       struct net_device *netdev = fc->real_dev;
+
+       fcoe_if_destroy(lport);
+       fcoe_ethdrv_put(netdev);
+       dev_put(netdev);
+       return 0;
+}
+

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to