diff options
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r-- | drivers/scsi/fcoe/fcoe.c | 271 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe.h | 10 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe_ctlr.c | 139 | ||||
-rw-r--r-- | drivers/scsi/fcoe/fcoe_transport.c | 88 |
4 files changed, 255 insertions, 253 deletions
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index bde6ee5333eb..155d7b9bdeae 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -137,6 +137,7 @@ static int fcoe_vport_create(struct fc_vport *, bool disabled); static int fcoe_vport_disable(struct fc_vport *, bool disable); static void fcoe_set_vport_symbolic_name(struct fc_vport *); static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *); +static int fcoe_validate_vport_create(struct fc_vport *); static struct libfc_function_template fcoe_libfc_fcn_templ = { .frame_send = fcoe_xmit, @@ -381,6 +382,42 @@ out: } /** + * fcoe_interface_release() - fcoe_port kref release function + * @kref: Embedded reference count in an fcoe_interface struct + */ +static void fcoe_interface_release(struct kref *kref) +{ + struct fcoe_interface *fcoe; + struct net_device *netdev; + + fcoe = container_of(kref, struct fcoe_interface, kref); + netdev = fcoe->netdev; + /* tear-down the FCoE controller */ + fcoe_ctlr_destroy(&fcoe->ctlr); + kfree(fcoe); + dev_put(netdev); + module_put(THIS_MODULE); +} + +/** + * fcoe_interface_get() - Get a reference to a FCoE interface + * @fcoe: The FCoE interface to be held + */ +static inline void fcoe_interface_get(struct fcoe_interface *fcoe) +{ + kref_get(&fcoe->kref); +} + +/** + * fcoe_interface_put() - Put a reference to a FCoE interface + * @fcoe: The FCoE interface to be released + */ +static inline void fcoe_interface_put(struct fcoe_interface *fcoe) +{ + kref_put(&fcoe->kref, fcoe_interface_release); +} + +/** * fcoe_interface_cleanup() - Clean up a FCoE interface * @fcoe: The FCoE interface to be cleaned up * @@ -392,6 +429,21 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) struct fcoe_ctlr *fip = &fcoe->ctlr; u8 flogi_maddr[ETH_ALEN]; const struct net_device_ops *ops; + struct fcoe_port *port = lport_priv(fcoe->ctlr.lp); + + FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); + + /* Logout of the fabric */ + fc_fabric_logoff(fcoe->ctlr.lp); + + /* Cleanup the fc_lport */ + fc_lport_destroy(fcoe->ctlr.lp); + + /* Stop the transmit retry timer */ + del_timer_sync(&port->timer); + + /* Free existing transmit skbs */ + fcoe_clean_pending_queue(fcoe->ctlr.lp); /* * Don't listen for Ethernet packets anymore. @@ -414,6 +466,9 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) } else dev_mc_del(netdev, FIP_ALL_ENODE_MACS); + if (!is_zero_ether_addr(port->data_src_addr)) + dev_uc_del(netdev, port->data_src_addr); + /* Tell the LLD we are done w/ FCoE */ ops = netdev->netdev_ops; if (ops->ndo_fcoe_disable) { @@ -421,42 +476,7 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe) FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE" " specific feature for LLD.\n"); } -} - -/** - * fcoe_interface_release() - fcoe_port kref release function - * @kref: Embedded reference count in an fcoe_interface struct - */ -static void fcoe_interface_release(struct kref *kref) -{ - struct fcoe_interface *fcoe; - struct net_device *netdev; - - fcoe = container_of(kref, struct fcoe_interface, kref); - netdev = fcoe->netdev; - /* tear-down the FCoE controller */ - fcoe_ctlr_destroy(&fcoe->ctlr); - kfree(fcoe); - dev_put(netdev); - module_put(THIS_MODULE); -} - -/** - * fcoe_interface_get() - Get a reference to a FCoE interface - * @fcoe: The FCoE interface to be held - */ -static inline void fcoe_interface_get(struct fcoe_interface *fcoe) -{ - kref_get(&fcoe->kref); -} - -/** - * fcoe_interface_put() - Put a reference to a FCoE interface - * @fcoe: The FCoE interface to be released - */ -static inline void fcoe_interface_put(struct fcoe_interface *fcoe) -{ - kref_put(&fcoe->kref, fcoe_interface_release); + fcoe_interface_put(fcoe); } /** @@ -821,39 +841,9 @@ skip_oem: * fcoe_if_destroy() - Tear down a SW FCoE instance * @lport: The local port to be destroyed * - * Locking: must be called with the RTNL mutex held and RTNL mutex - * needed to be dropped by this function since not dropping RTNL - * would cause circular locking warning on synchronous fip worker - * cancelling thru fcoe_interface_put invoked by this function. - * */ static void fcoe_if_destroy(struct fc_lport *lport) { - struct fcoe_port *port = lport_priv(lport); - struct fcoe_interface *fcoe = port->priv; - struct net_device *netdev = fcoe->netdev; - - FCOE_NETDEV_DBG(netdev, "Destroying interface\n"); - - /* Logout of the fabric */ - fc_fabric_logoff(lport); - - /* Cleanup the fc_lport */ - fc_lport_destroy(lport); - - /* Stop the transmit retry timer */ - del_timer_sync(&port->timer); - - /* Free existing transmit skbs */ - fcoe_clean_pending_queue(lport); - - if (!is_zero_ether_addr(port->data_src_addr)) - dev_uc_del(netdev, port->data_src_addr); - rtnl_unlock(); - - /* receives may not be stopped until after this */ - fcoe_interface_put(fcoe); - /* Free queued packets for the per-CPU receive threads */ fcoe_percpu_clean(lport); @@ -1783,23 +1773,8 @@ static int fcoe_disable(struct net_device *netdev) int rc = 0; mutex_lock(&fcoe_config_mutex); -#ifdef CONFIG_FCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module paramter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) { - rc = -ENODEV; - goto out_nodev; - } -#endif - - if (!rtnl_trylock()) { - mutex_unlock(&fcoe_config_mutex); - return -ERESTARTSYS; - } + rtnl_lock(); fcoe = fcoe_hostlist_lookup_port(netdev); rtnl_unlock(); @@ -1809,7 +1784,6 @@ static int fcoe_disable(struct net_device *netdev) } else rc = -ENODEV; -out_nodev: mutex_unlock(&fcoe_config_mutex); return rc; } @@ -1828,22 +1802,7 @@ static int fcoe_enable(struct net_device *netdev) int rc = 0; mutex_lock(&fcoe_config_mutex); -#ifdef CONFIG_FCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module paramter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) { - rc = -ENODEV; - goto out_nodev; - } -#endif - if (!rtnl_trylock()) { - mutex_unlock(&fcoe_config_mutex); - return -ERESTARTSYS; - } - + rtnl_lock(); fcoe = fcoe_hostlist_lookup_port(netdev); rtnl_unlock(); @@ -1852,7 +1811,6 @@ static int fcoe_enable(struct net_device *netdev) else if (!fcoe_link_ok(fcoe->ctlr.lp)) fcoe_ctlr_link_up(&fcoe->ctlr); -out_nodev: mutex_unlock(&fcoe_config_mutex); return rc; } @@ -1868,35 +1826,22 @@ out_nodev: static int fcoe_destroy(struct net_device *netdev) { struct fcoe_interface *fcoe; + struct fc_lport *lport; int rc = 0; mutex_lock(&fcoe_config_mutex); -#ifdef CONFIG_FCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module paramter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) { - rc = -ENODEV; - goto out_nodev; - } -#endif - if (!rtnl_trylock()) { - mutex_unlock(&fcoe_config_mutex); - return -ERESTARTSYS; - } - + rtnl_lock(); fcoe = fcoe_hostlist_lookup_port(netdev); if (!fcoe) { rtnl_unlock(); rc = -ENODEV; goto out_nodev; } - fcoe_interface_cleanup(fcoe); + lport = fcoe->ctlr.lp; list_del(&fcoe->list); - /* RTNL mutex is dropped by fcoe_if_destroy */ - fcoe_if_destroy(fcoe->ctlr.lp); + fcoe_interface_cleanup(fcoe); + rtnl_unlock(); + fcoe_if_destroy(lport); out_nodev: mutex_unlock(&fcoe_config_mutex); return rc; @@ -1912,8 +1857,6 @@ static void fcoe_destroy_work(struct work_struct *work) port = container_of(work, struct fcoe_port, destroy_work); mutex_lock(&fcoe_config_mutex); - rtnl_lock(); - /* RTNL mutex is dropped by fcoe_if_destroy */ fcoe_if_destroy(port->lport); mutex_unlock(&fcoe_config_mutex); } @@ -1948,23 +1891,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode) struct fc_lport *lport; mutex_lock(&fcoe_config_mutex); - - if (!rtnl_trylock()) { - mutex_unlock(&fcoe_config_mutex); - return -ERESTARTSYS; - } - -#ifdef CONFIG_FCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module paramter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) { - rc = -ENODEV; - goto out_nodev; - } -#endif + rtnl_lock(); /* look for existing lport */ if (fcoe_hostlist_lookup(netdev)) { @@ -2026,7 +1953,7 @@ out_nodev: int fcoe_link_speed_update(struct fc_lport *lport) { struct net_device *netdev = fcoe_netdev(lport); - struct ethtool_cmd ecmd = { ETHTOOL_GSET }; + struct ethtool_cmd ecmd; if (!dev_ethtool_get_settings(netdev, &ecmd)) { lport->link_supported_speeds &= @@ -2037,11 +1964,14 @@ int fcoe_link_speed_update(struct fc_lport *lport) if (ecmd.supported & SUPPORTED_10000baseT_Full) lport->link_supported_speeds |= FC_PORTSPEED_10GBIT; - if (ecmd.speed == SPEED_1000) + switch (ethtool_cmd_speed(&ecmd)) { + case SPEED_1000: lport->link_speed = FC_PORTSPEED_1GBIT; - if (ecmd.speed == SPEED_10000) + break; + case SPEED_10000: lport->link_speed = FC_PORTSPEED_10GBIT; - + break; + } return 0; } return -1; @@ -2422,6 +2352,17 @@ static int fcoe_vport_create(struct fc_vport *vport, bool disabled) struct fcoe_interface *fcoe = port->priv; struct net_device *netdev = fcoe->netdev; struct fc_lport *vn_port; + int rc; + char buf[32]; + + rc = fcoe_validate_vport_create(vport); + if (rc) { + wwn_to_str(vport->port_name, buf, sizeof(buf)); + printk(KERN_ERR "fcoe: Failed to create vport, " + "WWPN (0x%s) already exists\n", + buf); + return rc; + } mutex_lock(&fcoe_config_mutex); vn_port = fcoe_if_create(fcoe, &vport->dev, 1); @@ -2568,3 +2509,49 @@ static void fcoe_set_port_id(struct fc_lport *lport, if (fp && fc_frame_payload_op(fp) == ELS_FLOGI) fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp); } + +/** + * fcoe_validate_vport_create() - Validate a vport before creating it + * @vport: NPIV port to be created + * + * This routine is meant to add validation for a vport before creating it + * via fcoe_vport_create(). + * Current validations are: + * - WWPN supplied is unique for given lport + * + * +*/ +static int fcoe_validate_vport_create(struct fc_vport *vport) +{ + struct Scsi_Host *shost = vport_to_shost(vport); + struct fc_lport *n_port = shost_priv(shost); + struct fc_lport *vn_port; + int rc = 0; + char buf[32]; + + mutex_lock(&n_port->lp_mutex); + + wwn_to_str(vport->port_name, buf, sizeof(buf)); + /* Check if the wwpn is not same as that of the lport */ + if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) { + FCOE_DBG("vport WWPN 0x%s is same as that of the " + "base port WWPN\n", buf); + rc = -EINVAL; + goto out; + } + + /* Check if there is any existing vport with same wwpn */ + list_for_each_entry(vn_port, &n_port->vports, list) { + if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) { + FCOE_DBG("vport with given WWPN 0x%s already " + "exists\n", buf); + rc = -EINVAL; + break; + } + } + +out: + mutex_unlock(&n_port->lp_mutex); + + return rc; +} diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h index 408a6fd78fb4..c4a93993c0cf 100644 --- a/drivers/scsi/fcoe/fcoe.h +++ b/drivers/scsi/fcoe/fcoe.h @@ -99,4 +99,14 @@ static inline struct net_device *fcoe_netdev(const struct fc_lport *lport) ((struct fcoe_port *)lport_priv(lport))->priv)->netdev; } +static inline void wwn_to_str(u64 wwn, char *buf, int len) +{ + u8 wwpn[8]; + + u64_to_wwn(wwn, wwpn); + snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x", + wwpn[0], wwpn[1], wwpn[2], wwpn[3], + wwpn[4], wwpn[5], wwpn[6], wwpn[7]); +} + #endif /* _FCOE_H_ */ diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 9d38be2a41f9..c74c4b8e71ef 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -978,10 +978,8 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) * the FCF that answers multicast solicitations, not the others that * are sending periodic multicast advertisements. */ - if (mtu_valid) { - list_del(&fcf->list); - list_add(&fcf->list, &fip->fcfs); - } + if (mtu_valid) + list_move(&fcf->list, &fip->fcfs); /* * If this is the first validated FCF, note the time and @@ -1175,7 +1173,9 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, struct fc_lport *lport = fip->lp; struct fc_lport *vn_port = NULL; u32 desc_mask; - int is_vn_port = 0; + int num_vlink_desc; + int reset_phys_port = 0; + struct fip_vn_desc **vlink_desc_arr = NULL; LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n"); @@ -1185,70 +1185,73 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, /* * mask of required descriptors. Validating each one clears its bit. */ - desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) | BIT(FIP_DT_VN_ID); + desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME); rlen = ntohs(fh->fip_dl_len) * FIP_BPW; desc = (struct fip_desc *)(fh + 1); + + /* + * Actually need to subtract 'sizeof(*mp) - sizeof(*wp)' from 'rlen' + * before determining max Vx_Port descriptor but a buggy FCF could have + * omited either or both MAC Address and Name Identifier descriptors + */ + num_vlink_desc = rlen / sizeof(*vp); + if (num_vlink_desc) + vlink_desc_arr = kmalloc(sizeof(vp) * num_vlink_desc, + GFP_ATOMIC); + if (!vlink_desc_arr) + return; + num_vlink_desc = 0; + while (rlen >= sizeof(*desc)) { dlen = desc->fip_dlen * FIP_BPW; if (dlen > rlen) - return; + goto err; /* Drop CVL if there are duplicate critical descriptors */ if ((desc->fip_dtype < 32) && + (desc->fip_dtype != FIP_DT_VN_ID) && !(desc_mask & 1U << desc->fip_dtype)) { LIBFCOE_FIP_DBG(fip, "Duplicate Critical " "Descriptors in FIP CVL\n"); - return; + goto err; } switch (desc->fip_dtype) { case FIP_DT_MAC: mp = (struct fip_mac_desc *)desc; if (dlen < sizeof(*mp)) - return; + goto err; if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac)) - return; + goto err; desc_mask &= ~BIT(FIP_DT_MAC); break; case FIP_DT_NAME: wp = (struct fip_wwn_desc *)desc; if (dlen < sizeof(*wp)) - return; + goto err; if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name) - return; + goto err; desc_mask &= ~BIT(FIP_DT_NAME); break; case FIP_DT_VN_ID: vp = (struct fip_vn_desc *)desc; if (dlen < sizeof(*vp)) - return; - if (compare_ether_addr(vp->fd_mac, - fip->get_src_addr(lport)) == 0 && - get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn && - ntoh24(vp->fd_fc_id) == lport->port_id) { - desc_mask &= ~BIT(FIP_DT_VN_ID); - break; + goto err; + vlink_desc_arr[num_vlink_desc++] = vp; + vn_port = fc_vport_id_lookup(lport, + ntoh24(vp->fd_fc_id)); + if (vn_port && (vn_port == lport)) { + mutex_lock(&fip->ctlr_mutex); + per_cpu_ptr(lport->dev_stats, + get_cpu())->VLinkFailureCount++; + put_cpu(); + fcoe_ctlr_reset(fip); + mutex_unlock(&fip->ctlr_mutex); } - /* check if clr_vlink is for NPIV port */ - mutex_lock(&lport->lp_mutex); - list_for_each_entry(vn_port, &lport->vports, list) { - if (compare_ether_addr(vp->fd_mac, - fip->get_src_addr(vn_port)) == 0 && - (get_unaligned_be64(&vp->fd_wwpn) - == vn_port->wwpn) && - (ntoh24(vp->fd_fc_id) == - fc_host_port_id(vn_port->host))) { - desc_mask &= ~BIT(FIP_DT_VN_ID); - is_vn_port = 1; - break; - } - } - mutex_unlock(&lport->lp_mutex); - break; default: /* standard says ignore unknown descriptors >= 128 */ if (desc->fip_dtype < FIP_DT_VENDOR_BASE) - return; + goto err; break; } desc = (struct fip_desc *)((char *)desc + dlen); @@ -1258,26 +1261,68 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, /* * reset only if all required descriptors were present and valid. */ - if (desc_mask) { + if (desc_mask) LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n", desc_mask); + else if (!num_vlink_desc) { + LIBFCOE_FIP_DBG(fip, "CVL: no Vx_Port descriptor found\n"); + /* + * No Vx_Port description. Clear all NPIV ports, + * followed by physical port + */ + mutex_lock(&lport->lp_mutex); + list_for_each_entry(vn_port, &lport->vports, list) + fc_lport_reset(vn_port); + mutex_unlock(&lport->lp_mutex); + + mutex_lock(&fip->ctlr_mutex); + per_cpu_ptr(lport->dev_stats, + get_cpu())->VLinkFailureCount++; + put_cpu(); + fcoe_ctlr_reset(fip); + mutex_unlock(&fip->ctlr_mutex); + + fc_lport_reset(fip->lp); + fcoe_ctlr_solicit(fip, NULL); } else { - LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); + int i; - if (is_vn_port) - fc_lport_reset(vn_port); - else { - mutex_lock(&fip->ctlr_mutex); - per_cpu_ptr(lport->dev_stats, - get_cpu())->VLinkFailureCount++; - put_cpu(); - fcoe_ctlr_reset(fip); - mutex_unlock(&fip->ctlr_mutex); + LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n"); + for (i = 0; i < num_vlink_desc; i++) { + vp = vlink_desc_arr[i]; + vn_port = fc_vport_id_lookup(lport, + ntoh24(vp->fd_fc_id)); + if (!vn_port) + continue; + + /* + * 'port_id' is already validated, check MAC address and + * wwpn + */ + if (compare_ether_addr(fip->get_src_addr(vn_port), + vp->fd_mac) != 0 || + get_unaligned_be64(&vp->fd_wwpn) != + vn_port->wwpn) + continue; + + if (vn_port == lport) + /* + * Physical port, defer processing till all + * listed NPIV ports are cleared + */ + reset_phys_port = 1; + else /* NPIV port */ + fc_lport_reset(vn_port); + } + if (reset_phys_port) { fc_lport_reset(fip->lp); fcoe_ctlr_solicit(fip, NULL); } } + +err: + kfree(vlink_desc_arr); } /** diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index 258684101bfd..41068e8748e7 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -335,7 +335,7 @@ out_attach: EXPORT_SYMBOL(fcoe_transport_attach); /** - * fcoe_transport_attach - Detaches an FCoE transport + * fcoe_transport_detach - Detaches an FCoE transport * @ft: The fcoe transport to be attached * * Returns : 0 for success @@ -343,6 +343,7 @@ EXPORT_SYMBOL(fcoe_transport_attach); int fcoe_transport_detach(struct fcoe_transport *ft) { int rc = 0; + struct fcoe_netdev_mapping *nm = NULL, *tmp; mutex_lock(&ft_mutex); if (!ft->attached) { @@ -352,6 +353,19 @@ int fcoe_transport_detach(struct fcoe_transport *ft) goto out_attach; } + /* remove netdev mapping for this transport as it is going away */ + mutex_lock(&fn_mutex); + list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) { + if (nm->ft == ft) { + LIBFCOE_TRANSPORT_DBG("transport %s going away, " + "remove its netdev mapping for %s\n", + ft->name, nm->netdev->name); + list_del(&nm->list); + kfree(nm); + } + } + mutex_unlock(&fn_mutex); + list_del(&ft->list); ft->attached = false; LIBFCOE_TRANSPORT_DBG("detaching transport %s\n", ft->name); @@ -371,9 +385,9 @@ static int fcoe_transport_show(char *buffer, const struct kernel_param *kp) i = j = sprintf(buffer, "Attached FCoE transports:"); mutex_lock(&ft_mutex); list_for_each_entry(ft, &fcoe_transports, list) { - i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name); - if (i >= PAGE_SIZE) + if (i >= PAGE_SIZE - IFNAMSIZ) break; + i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name); } mutex_unlock(&ft_mutex); if (i == j) @@ -530,18 +544,7 @@ static int fcoe_transport_create(const char *buffer, struct kernel_param *kp) struct fcoe_transport *ft = NULL; enum fip_state fip_mode = (enum fip_state)(long)kp->arg; - if (!mutex_trylock(&ft_mutex)) - return restart_syscall(); - -#ifdef CONFIG_LIBFCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module parameter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) - goto out_nodev; -#endif + mutex_lock(&ft_mutex); netdev = fcoe_if_to_netdev(buffer); if (!netdev) { @@ -586,10 +589,7 @@ out_putdev: dev_put(netdev); out_nodev: mutex_unlock(&ft_mutex); - if (rc == -ERESTARTSYS) - return restart_syscall(); - else - return rc; + return rc; } /** @@ -608,18 +608,7 @@ static int fcoe_transport_destroy(const char *buffer, struct kernel_param *kp) struct net_device *netdev = NULL; struct fcoe_transport *ft = NULL; - if (!mutex_trylock(&ft_mutex)) - return restart_syscall(); - -#ifdef CONFIG_LIBFCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module parameter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) - goto out_nodev; -#endif + mutex_lock(&ft_mutex); netdev = fcoe_if_to_netdev(buffer); if (!netdev) { @@ -645,11 +634,7 @@ out_putdev: dev_put(netdev); out_nodev: mutex_unlock(&ft_mutex); - - if (rc == -ERESTARTSYS) - return restart_syscall(); - else - return rc; + return rc; } /** @@ -667,18 +652,7 @@ static int fcoe_transport_disable(const char *buffer, struct kernel_param *kp) struct net_device *netdev = NULL; struct fcoe_transport *ft = NULL; - if (!mutex_trylock(&ft_mutex)) - return restart_syscall(); - -#ifdef CONFIG_LIBFCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module parameter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) - goto out_nodev; -#endif + mutex_lock(&ft_mutex); netdev = fcoe_if_to_netdev(buffer); if (!netdev) @@ -716,18 +690,7 @@ static int fcoe_transport_enable(const char *buffer, struct kernel_param *kp) struct net_device *netdev = NULL; struct fcoe_transport *ft = NULL; - if (!mutex_trylock(&ft_mutex)) - return restart_syscall(); - -#ifdef CONFIG_LIBFCOE_MODULE - /* - * Make sure the module has been initialized, and is not about to be - * removed. Module parameter sysfs files are writable before the - * module_init function is called and after module_exit. - */ - if (THIS_MODULE->state != MODULE_STATE_LIVE) - goto out_nodev; -#endif + mutex_lock(&ft_mutex); netdev = fcoe_if_to_netdev(buffer); if (!netdev) @@ -743,10 +706,7 @@ out_putdev: dev_put(netdev); out_nodev: mutex_unlock(&ft_mutex); - if (rc == -ERESTARTSYS) - return restart_syscall(); - else - return rc; + return rc; } /** |