Skip to content

Commit

Permalink
[SCSI] fcoe, libfc: adds enable/disable for fcoe interface
Browse files Browse the repository at this point in the history
This is to allow fcoemon util to enable or disable a fcoe interface
according to DCB link state change.

Adds sysfs module param enable and disable for this and also
updates existing other module param description to be consistent
and more accurate since older description had double "fcoe" word
with less meaningful netdev reference to user space.

Adds code to ignore redundant fc_lport_enter_reset handling for a
already disabled fcoe interface by checking LPORT_ST_DISABLED
or LPORT_ST_LOGO states, this also prevents lport state transition
on link flap on a disabled interface.

Above changes required lport state transition to get out of
disabled or logo state on call to fc_fabric_login.

Signed-off-by: Vasu Dev <vasu.dev@intel.com>
Signed-off-by: Robert Love <robert.w.love@intel.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Vasu Dev authored and James Bottomley committed Dec 12, 2009
1 parent c1ecb90 commit 55a66d3
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 3 deletions.
110 changes: 108 additions & 2 deletions drivers/scsi/fcoe/fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ static int fcoe_cpu_callback(struct notifier_block *, unsigned long, void *);

static int fcoe_create(const char *, struct kernel_param *);
static int fcoe_destroy(const char *, struct kernel_param *);
static int fcoe_enable(const char *, struct kernel_param *);
static int fcoe_disable(const char *, struct kernel_param *);

static struct fc_seq *fcoe_elsct_send(struct fc_lport *,
u32 did, struct fc_frame *,
Expand All @@ -115,10 +117,16 @@ static void fcoe_get_lesb(struct fc_lport *, struct fc_els_lesb *);

module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
__MODULE_PARM_TYPE(create, "string");
MODULE_PARM_DESC(create, "Create fcoe fcoe using net device passed in.");
MODULE_PARM_DESC(create, " Creates fcoe instance on a ethernet interface");
module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
__MODULE_PARM_TYPE(destroy, "string");
MODULE_PARM_DESC(destroy, "Destroy fcoe fcoe");
MODULE_PARM_DESC(destroy, " Destroys fcoe instance on a ethernet interface");
module_param_call(enable, fcoe_enable, NULL, NULL, S_IWUSR);
__MODULE_PARM_TYPE(enable, "string");
MODULE_PARM_DESC(enable, " Enables fcoe on a ethernet interface.");
module_param_call(disable, fcoe_disable, NULL, NULL, S_IWUSR);
__MODULE_PARM_TYPE(disable, "string");
MODULE_PARM_DESC(disable, " Disables fcoe on a ethernet interface.");

/* notification function for packets from net device */
static struct notifier_block fcoe_notifier = {
Expand Down Expand Up @@ -1858,6 +1866,104 @@ static struct net_device *fcoe_if_to_netdev(const char *buffer)
return NULL;
}

/**
* fcoe_disable() - Disables a FCoE interface
* @buffer: The name of the Ethernet interface to be disabled
* @kp: The associated kernel parameter
*
* Called from sysfs.
*
* Returns: 0 for success
*/
static int fcoe_disable(const char *buffer, struct kernel_param *kp)
{
struct fcoe_interface *fcoe;
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

netdev = fcoe_if_to_netdev(buffer);
if (!netdev) {
rc = -ENODEV;
goto out_nodev;
}

rtnl_lock();
fcoe = fcoe_hostlist_lookup_port(netdev);
rtnl_unlock();

if (fcoe)
fc_fabric_logoff(fcoe->ctlr.lp);
else
rc = -ENODEV;

dev_put(netdev);
out_nodev:
mutex_unlock(&fcoe_config_mutex);
return rc;
}

/**
* fcoe_enable() - Enables a FCoE interface
* @buffer: The name of the Ethernet interface to be enabled
* @kp: The associated kernel parameter
*
* Called from sysfs.
*
* Returns: 0 for success
*/
static int fcoe_enable(const char *buffer, struct kernel_param *kp)
{
struct fcoe_interface *fcoe;
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

netdev = fcoe_if_to_netdev(buffer);
if (!netdev) {
rc = -ENODEV;
goto out_nodev;
}

rtnl_lock();
fcoe = fcoe_hostlist_lookup_port(netdev);
rtnl_unlock();

if (fcoe)
rc = fc_fabric_login(fcoe->ctlr.lp);
else
rc = -ENODEV;

dev_put(netdev);
out_nodev:
mutex_unlock(&fcoe_config_mutex);
return rc;
}

/**
* fcoe_destroy() - Destroy a FCoE interface
* @buffer: The name of the Ethernet interface to be destroyed
Expand Down
7 changes: 6 additions & 1 deletion drivers/scsi/libfc/fc_lport.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,9 @@ int fc_fabric_login(struct fc_lport *lport)
int rc = -1;

mutex_lock(&lport->lp_mutex);
if (lport->state == LPORT_ST_DISABLED) {
if (lport->state == LPORT_ST_DISABLED ||
lport->state == LPORT_ST_LOGO) {
fc_lport_state_enter(lport, LPORT_ST_RESET);
fc_lport_enter_reset(lport);
rc = 0;
}
Expand Down Expand Up @@ -967,6 +969,9 @@ static void fc_lport_enter_reset(struct fc_lport *lport)
FC_LPORT_DBG(lport, "Entered RESET state from %s state\n",
fc_lport_state(lport));

if (lport->state == LPORT_ST_DISABLED || lport->state == LPORT_ST_LOGO)
return;

if (lport->vport) {
if (lport->link_up)
fc_vport_set_state(lport->vport, FC_VPORT_INITIALIZING);
Expand Down

0 comments on commit 55a66d3

Please sign in to comment.