Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 360280
b: refs/heads/master
c: 6a891b0
h: refs/heads/master
v: v3
  • Loading branch information
Robert Love committed Dec 14, 2012
1 parent 3b72590 commit 7ed4ae7
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3993de6183885a099163b9562a2ea9c07b994a0e
refs/heads/master: 6a891b071b640e1de44c4a5117fa2c974dcfa84a
41 changes: 40 additions & 1 deletion trunk/Documentation/ABI/testing/sysfs-bus-fcoe
Original file line number Diff line number Diff line change
@@ -1,14 +1,53 @@
What: /sys/bus/fcoe/
Date: August 2012
KernelVersion: TBD
Contact: Robert Love <robert.w.love@intel.com>, devel@open-fcoe.org
Description: The FCoE bus. Attributes in this directory are control interfaces.
Attributes:

ctlr_create: 'FCoE Controller' instance creation interface. Writing an
<ifname> to this file will allocate and populate sysfs with a
fcoe_ctlr_device (ctlr_X). The user can then configure any
per-port settings and finally write to the fcoe_ctlr_device's
'start' attribute to begin the kernel's discovery and login
process.

ctlr_destroy: 'FCoE Controller' instance removal interface. Writing a
fcoe_ctlr_device's sysfs name to this file will log the
fcoe_ctlr_device out of the fabric or otherwise connected
FCoE devices. It will also free all kernel memory allocated
for this fcoe_ctlr_device and any structures associated
with it, this includes the scsi_host.

What: /sys/bus/fcoe/devices/ctlr_X
Date: March 2012
KernelVersion: TBD
Contact: Robert Love <robert.w.love@intel.com>, devel@open-fcoe.org
Description: 'FCoE Controller' instances on the fcoe bus
Description: 'FCoE Controller' instances on the fcoe bus.
The FCoE Controller now has a three stage creation process.
1) Write interface name to ctlr_create 2) Configure the FCoE
Controller (ctlr_X) 3) Enable the FCoE Controller to begin
discovery and login. The FCoE Controller is destroyed by
writing it's name, i.e. ctlr_X to the ctlr_delete file.

Attributes:

fcf_dev_loss_tmo: Device loss timeout peroid (see below). Changing
this value will change the dev_loss_tmo for all
FCFs discovered by this controller.

mode: Display or change the FCoE Controller's mode. Possible
modes are 'Fabric' and 'VN2VN'. If a FCoE Controller
is started in 'Fabric' mode then FIP FCF discovery is
initiated and ultimately a fabric login is attempted.
If a FCoE Controller is started in 'VN2VN' mode then
FIP VN2VN discovery and login is performed. A FCoE
Controller only supports one mode at a time.

enabled: Whether an FCoE controller is enabled or disabled.
0 if disabled, 1 if enabled. Writing either 0 or 1
to this file will enable or disable the FCoE controller.

lesb/link_fail: Link Error Status Block (LESB) link failure count.

lesb/vlink_fail: Link Error Status Block (LESB) virtual link
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -2555,7 +2555,6 @@ module_init(bnx2fc_mod_init);
module_exit(bnx2fc_mod_exit);

static struct fcoe_sysfs_function_template bnx2fc_fcoe_sysfs_templ = {
.get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
.get_fcoe_ctlr_link_fail = bnx2fc_ctlr_get_lesb,
.get_fcoe_ctlr_vlink_fail = bnx2fc_ctlr_get_lesb,
.get_fcoe_ctlr_miss_fka = bnx2fc_ctlr_get_lesb,
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/scsi/fcoe/fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ static void fcoe_ctlr_get_lesb(struct fcoe_ctlr_device *);
static void fcoe_fcf_get_vlan_id(struct fcoe_fcf_device *);

static struct fcoe_sysfs_function_template fcoe_sysfs_templ = {
.get_fcoe_ctlr_mode = fcoe_ctlr_get_fip_mode,
.get_fcoe_ctlr_link_fail = fcoe_ctlr_get_lesb,
.get_fcoe_ctlr_vlink_fail = fcoe_ctlr_get_lesb,
.get_fcoe_ctlr_miss_fka = fcoe_ctlr_get_lesb,
Expand Down
137 changes: 130 additions & 7 deletions trunk/drivers/scsi/fcoe/fcoe_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/etherdevice.h>
#include <linux/ctype.h>

#include <scsi/fcoe_sysfs.h>
#include <scsi/libfcoe.h>

/*
* OK to include local libfcoe.h for debug_logging, but cannot include
Expand Down Expand Up @@ -78,6 +80,8 @@ MODULE_PARM_DESC(fcf_dev_loss_tmo,
((x)->lesb.lesb_err_block)
#define fcoe_ctlr_fcs_error(x) \
((x)->lesb.lesb_fcs_error)
#define fcoe_ctlr_enabled(x) \
((x)->enabled)
#define fcoe_fcf_state(x) \
((x)->state)
#define fcoe_fcf_fabric_name(x) \
Expand Down Expand Up @@ -228,7 +232,18 @@ static char *fip_conn_type_names[] = {
[ FIP_CONN_TYPE_VN2VN ] = "VN2VN",
};
fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
#define FCOE_CTLR_MODE_MAX_NAMELEN 50

static enum fip_conn_type fcoe_parse_mode(const char *buf)
{
int i;

for (i = 0; i < ARRAY_SIZE(fip_conn_type_names); i++) {
if (strcasecmp(buf, fip_conn_type_names[i]) == 0)
return i;
}

return FIP_CONN_TYPE_UNKNOWN;
}

static char *fcf_state_names[] = {
[ FCOE_FCF_STATE_UNKNOWN ] = "Unknown",
Expand Down Expand Up @@ -259,17 +274,116 @@ static ssize_t show_ctlr_mode(struct device *dev,
struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
const char *name;

if (ctlr->f->get_fcoe_ctlr_mode)
ctlr->f->get_fcoe_ctlr_mode(ctlr);

name = get_fcoe_ctlr_mode_name(ctlr->mode);
if (!name)
return -EINVAL;
return snprintf(buf, FCOE_CTLR_MODE_MAX_NAMELEN,
return snprintf(buf, FCOE_MAX_MODENAME_LEN,
"%s\n", name);
}
static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO,
show_ctlr_mode, NULL);

static ssize_t store_ctlr_mode(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
char mode[FCOE_MAX_MODENAME_LEN + 1];

if (count > FCOE_MAX_MODENAME_LEN)
return -EINVAL;

strncpy(mode, buf, count);

if (mode[count - 1] == '\n')
mode[count - 1] = '\0';
else
mode[count] = '\0';

switch (ctlr->enabled) {
case FCOE_CTLR_ENABLED:
LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.");
return -EBUSY;
case FCOE_CTLR_DISABLED:
if (!ctlr->f->set_fcoe_ctlr_mode) {
LIBFCOE_SYSFS_DBG(ctlr,
"Mode change not supported by LLD.");
return -ENOTSUPP;
}

ctlr->mode = fcoe_parse_mode(mode);
if (ctlr->mode == FIP_CONN_TYPE_UNKNOWN) {
LIBFCOE_SYSFS_DBG(ctlr,
"Unknown mode %s provided.", buf);
return -EINVAL;
}

ctlr->f->set_fcoe_ctlr_mode(ctlr);
LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.", buf);

return count;
case FCOE_CTLR_UNUSED:
default:
LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.");
return -ENOTSUPP;
};
}

static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO | S_IWUSR,
show_ctlr_mode, store_ctlr_mode);

static ssize_t store_ctlr_enabled(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
int rc;

switch (ctlr->enabled) {
case FCOE_CTLR_ENABLED:
if (*buf == '1')
return count;
ctlr->enabled = FCOE_CTLR_DISABLED;
break;
case FCOE_CTLR_DISABLED:
if (*buf == '0')
return count;
ctlr->enabled = FCOE_CTLR_ENABLED;
break;
case FCOE_CTLR_UNUSED:
return -ENOTSUPP;
};

rc = ctlr->f->set_fcoe_ctlr_enabled(ctlr);
if (rc)
return rc;

return count;
}

static char *ctlr_enabled_state_names[] = {
[ FCOE_CTLR_ENABLED ] = "1",
[ FCOE_CTLR_DISABLED ] = "0",
};
fcoe_enum_name_search(ctlr_enabled_state, ctlr_enabled_state,
ctlr_enabled_state_names)
#define FCOE_CTLR_ENABLED_MAX_NAMELEN 50

static ssize_t show_ctlr_enabled_state(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
const char *name;

name = get_fcoe_ctlr_enabled_state_name(ctlr->enabled);
if (!name)
return -EINVAL;
return snprintf(buf, FCOE_CTLR_ENABLED_MAX_NAMELEN,
"%s\n", name);
}

static FCOE_DEVICE_ATTR(ctlr, enabled, S_IRUGO | S_IWUSR,
show_ctlr_enabled_state,
store_ctlr_enabled);

static ssize_t
store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev,
Expand Down Expand Up @@ -354,6 +468,7 @@ static struct attribute_group fcoe_ctlr_lesb_attr_group = {

static struct attribute *fcoe_ctlr_attrs[] = {
&device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr,
&device_attr_fcoe_ctlr_enabled.attr,
&device_attr_fcoe_ctlr_mode.attr,
NULL,
};
Expand Down Expand Up @@ -438,9 +553,16 @@ struct device_type fcoe_fcf_device_type = {
.release = fcoe_fcf_device_release,
};

struct bus_attribute fcoe_bus_attr_group[] = {
__ATTR(ctlr_create, S_IWUSR, NULL, fcoe_ctlr_create_store),
__ATTR(ctlr_destroy, S_IWUSR, NULL, fcoe_ctlr_destroy_store),
__ATTR_NULL
};

struct bus_type fcoe_bus_type = {
.name = "fcoe",
.match = &fcoe_bus_match,
.bus_attrs = fcoe_bus_attr_group,
};

/**
Expand Down Expand Up @@ -561,6 +683,7 @@ struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,

ctlr->id = atomic_inc_return(&ctlr_num) - 1;
ctlr->f = f;
ctlr->mode = FIP_CONN_TYPE_FABRIC;
INIT_LIST_HEAD(&ctlr->fcfs);
mutex_init(&ctlr->lock);
ctlr->dev.parent = parent;
Expand Down
104 changes: 104 additions & 0 deletions trunk/drivers/scsi/fcoe/fcoe_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,110 @@ static int libfcoe_device_notification(struct notifier_block *notifier,
return NOTIFY_OK;
}

ssize_t fcoe_ctlr_create_store(struct bus_type *bus,
const char *buf, size_t count)
{
struct net_device *netdev = NULL;
struct fcoe_transport *ft = NULL;
struct fcoe_ctlr_device *ctlr_dev = NULL;
int rc = 0;
int err;

mutex_lock(&ft_mutex);

netdev = fcoe_if_to_netdev(buf);
if (!netdev) {
LIBFCOE_TRANSPORT_DBG("Invalid device %s.\n", buf);
rc = -ENODEV;
goto out_nodev;
}

ft = fcoe_netdev_map_lookup(netdev);
if (ft) {
LIBFCOE_TRANSPORT_DBG("transport %s already has existing "
"FCoE instance on %s.\n",
ft->name, netdev->name);
rc = -EEXIST;
goto out_putdev;
}

ft = fcoe_transport_lookup(netdev);
if (!ft) {
LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
netdev->name);
rc = -ENODEV;
goto out_putdev;
}

/* pass to transport create */
err = ft->alloc ? ft->alloc(netdev) : -ENODEV;
if (err) {
fcoe_del_netdev_mapping(netdev);
rc = -ENOMEM;
goto out_putdev;
}

err = fcoe_add_netdev_mapping(netdev, ft);
if (err) {
LIBFCOE_TRANSPORT_DBG("failed to add new netdev mapping "
"for FCoE transport %s for %s.\n",
ft->name, netdev->name);
rc = -ENODEV;
goto out_putdev;
}

LIBFCOE_TRANSPORT_DBG("transport %s %s to create fcoe on %s.\n",
ft->name, (ctlr_dev) ? "succeeded" : "failed",
netdev->name);

out_putdev:
dev_put(netdev);
out_nodev:
mutex_unlock(&ft_mutex);
if (rc)
return rc;
return count;
}

ssize_t fcoe_ctlr_destroy_store(struct bus_type *bus,
const char *buf, size_t count)
{
int rc = -ENODEV;
struct net_device *netdev = NULL;
struct fcoe_transport *ft = NULL;

mutex_lock(&ft_mutex);

netdev = fcoe_if_to_netdev(buf);
if (!netdev) {
LIBFCOE_TRANSPORT_DBG("invalid device %s.\n", buf);
goto out_nodev;
}

ft = fcoe_netdev_map_lookup(netdev);
if (!ft) {
LIBFCOE_TRANSPORT_DBG("no FCoE transport found for %s.\n",
netdev->name);
goto out_putdev;
}

/* pass to transport destroy */
rc = ft->destroy(netdev);
if (rc)
goto out_putdev;

fcoe_del_netdev_mapping(netdev);
LIBFCOE_TRANSPORT_DBG("transport %s %s to destroy fcoe on %s.\n",
ft->name, (rc) ? "failed" : "succeeded",
netdev->name);
rc = count; /* required for successful return */
out_putdev:
dev_put(netdev);
out_nodev:
mutex_unlock(&ft_mutex);
return rc;
}
EXPORT_SYMBOL(fcoe_ctlr_destroy_store);

/**
* fcoe_transport_create() - Create a fcoe interface
Expand Down
Loading

0 comments on commit 7ed4ae7

Please sign in to comment.