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
