By passing in the parent device instead of assuming the netdev is what should be used, fcoe_if_create becomes usable for NPIV vports as well. You still need a netdev, because that's how FCoE works. Also removed some duplicate checks from fcoe_if_create that are already in fcoe_create.
fcoe_if_destroy needs to take an lport as it's only argument, not a netdev. That removes the 1:1 netdev:lport assumption from the destroy path. Signed-off-by: Chris Leech <[email protected]> --- drivers/scsi/fcoe/fcoe.c | 61 ++++++++++++++++------------------------------ 1 files changed, 21 insertions(+), 40 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 9394c8c..381e4e2 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -436,25 +436,15 @@ static inline int fcoe_em_config(struct fc_lport *lp) /** * fcoe_if_destroy() - FCoE software HBA tear-down function - * @netdev: ptr to the associated net_device - * - * Returns: 0 if link is OK for use by FCoE. + * @lp: fc_lport to destroy */ -static int fcoe_if_destroy(struct net_device *netdev) +static void fcoe_if_destroy(struct fc_lport *lp) { - struct fc_lport *lp = NULL; - struct fcoe_softc *fc; - - BUG_ON(!netdev); + struct fcoe_softc *fc = lport_priv(lp); + struct net_device *netdev = fc->real_dev; FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); - lp = fcoe_hostlist_lookup(netdev); - if (!lp) - return -ENODEV; - - fc = lport_priv(lp); - /* Logout of the fabric */ fc_fabric_logoff(lp); @@ -494,8 +484,6 @@ static int fcoe_if_destroy(struct net_device *netdev) /* Release the net_device and Scsi_Host */ dev_put(fc->real_dev); scsi_host_put(lp->host); - - return 0; } /* @@ -543,32 +531,28 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = { /** * fcoe_if_create() - this function creates the fcoe interface * @netdev: pointer the associated netdevice + * @parent: device pointer to be the parent in sysfs for the SCSI host * * Creates fc_lport struct and scsi_host for lport, configures lport * and starts fabric login. * - * Returns : 0 on success + * Returns : The allocated fc_lport or an error pointer */ -static int fcoe_if_create(struct net_device *netdev) +static struct fc_lport *fcoe_if_create(struct net_device *netdev, + struct device *parent) { int rc; struct fc_lport *lp = NULL; struct fcoe_softc *fc; struct Scsi_Host *shost; - BUG_ON(!netdev); - FCOE_NETDEV_DBG(netdev, "Create Interface\n"); - lp = fcoe_hostlist_lookup(netdev); - if (lp) - return -EEXIST; - shost = libfc_host_alloc(&fcoe_shost_template, sizeof(struct fcoe_softc)); if (!shost) { FCOE_NETDEV_DBG(netdev, "Could not allocate host structure\n"); - return -ENOMEM; + return ERR_PTR(-ENOMEM); } lp = shost_priv(shost); fc = lport_priv(lp); @@ -597,7 +581,7 @@ static int fcoe_if_create(struct net_device *netdev) } /* configure lport scsi host properties */ - rc = fcoe_shost_config(lp, shost, &netdev->dev); + rc = fcoe_shost_config(lp, shost, parent); if (rc) { FCOE_NETDEV_DBG(netdev, "Could not configure shost for the " "interface\n"); @@ -632,7 +616,7 @@ static int fcoe_if_create(struct net_device *netdev) dev_hold(netdev); - return rc; + return lp; out_lp_destroy: fc_exch_mgr_free(lp->emp); /* Free the EM */ @@ -640,7 +624,7 @@ out_netdev_cleanup: fcoe_netdev_cleanup(fc); out_host_put: scsi_host_put(lp->host); - return rc; + return ERR_PTR(rc); } /** @@ -1543,8 +1527,9 @@ static int fcoe_ethdrv_put(const struct net_device *netdev) */ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) { - int rc; struct net_device *netdev; + struct fc_lport *lport; + int rc; netdev = fcoe_if_to_netdev(buffer); if (!netdev) { @@ -1552,17 +1537,12 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp) goto out_nodev; } /* look for existing lport */ - if (!fcoe_hostlist_lookup(netdev)) { + lport = fcoe_hostlist_lookup(netdev); + if (!lport) { rc = -ENODEV; goto out_putdev; } - rc = fcoe_if_destroy(netdev); - if (rc) { - printk(KERN_ERR "fcoe: Failed to destroy interface (%s)\n", - netdev->name); - rc = -EIO; - goto out_putdev; - } + fcoe_if_destroy(lport); fcoe_ethdrv_put(netdev); rc = 0; out_putdev: @@ -1581,6 +1561,7 @@ out_nodev: static int fcoe_create(const char *buffer, struct kernel_param *kp) { int rc; + struct fc_lport *lport; struct net_device *netdev; netdev = fcoe_if_to_netdev(buffer); @@ -1595,8 +1576,8 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp) } fcoe_ethdrv_get(netdev); - rc = fcoe_if_create(netdev); - if (rc) { + lport = fcoe_if_create(netdev, &netdev->dev); + if (IS_ERR(lport)) { printk(KERN_ERR "fcoe: Failed to create interface (%s)\n", netdev->name); fcoe_ethdrv_put(netdev); @@ -1858,7 +1839,7 @@ static void __exit fcoe_exit(void) /* releases the associated fcoe hosts */ list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list) - fcoe_if_destroy(fc->real_dev); + fcoe_if_destroy(fc->ctlr.lp); unregister_hotcpu_notifier(&fcoe_cpu_notifier); _______________________________________________ devel mailing list [email protected] http://www.open-fcoe.org/mailman/listinfo/devel
