Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright(c) 2011 - 2012 Intel Corporation. All rights reserved.
0004  *
0005  * Maintained at www.Open-FCoE.org
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/types.h>
0010 #include <linux/kernel.h>
0011 #include <linux/etherdevice.h>
0012 #include <linux/ctype.h>
0013 
0014 #include <scsi/fcoe_sysfs.h>
0015 #include <scsi/libfcoe.h>
0016 
0017 /*
0018  * OK to include local libfcoe.h for debug_logging, but cannot include
0019  * <scsi/libfcoe.h> otherwise non-netdev based fcoe solutions would have
0020  * have to include more than fcoe_sysfs.h.
0021  */
0022 #include "libfcoe.h"
0023 
0024 static atomic_t ctlr_num;
0025 static atomic_t fcf_num;
0026 
0027 /*
0028  * fcoe_fcf_dev_loss_tmo: the default number of seconds that fcoe sysfs
0029  * should insulate the loss of a fcf.
0030  */
0031 static unsigned int fcoe_fcf_dev_loss_tmo = 1800;  /* seconds */
0032 
0033 module_param_named(fcf_dev_loss_tmo, fcoe_fcf_dev_loss_tmo,
0034            uint, S_IRUGO|S_IWUSR);
0035 MODULE_PARM_DESC(fcf_dev_loss_tmo,
0036          "Maximum number of seconds that libfcoe should"
0037          " insulate the loss of a fcf. Once this value is"
0038          " exceeded, the fcf is removed.");
0039 
0040 /*
0041  * These are used by the fcoe_*_show_function routines, they
0042  * are intentionally placed in the .c file as they're not intended
0043  * for use throughout the code.
0044  */
0045 #define fcoe_ctlr_id(x)             \
0046     ((x)->id)
0047 #define fcoe_ctlr_work_q_name(x)        \
0048     ((x)->work_q_name)
0049 #define fcoe_ctlr_work_q(x)         \
0050     ((x)->work_q)
0051 #define fcoe_ctlr_devloss_work_q_name(x)    \
0052     ((x)->devloss_work_q_name)
0053 #define fcoe_ctlr_devloss_work_q(x)     \
0054     ((x)->devloss_work_q)
0055 #define fcoe_ctlr_mode(x)           \
0056     ((x)->mode)
0057 #define fcoe_ctlr_fcf_dev_loss_tmo(x)       \
0058     ((x)->fcf_dev_loss_tmo)
0059 #define fcoe_ctlr_link_fail(x)          \
0060     ((x)->lesb.lesb_link_fail)
0061 #define fcoe_ctlr_vlink_fail(x)         \
0062     ((x)->lesb.lesb_vlink_fail)
0063 #define fcoe_ctlr_miss_fka(x)           \
0064     ((x)->lesb.lesb_miss_fka)
0065 #define fcoe_ctlr_symb_err(x)           \
0066     ((x)->lesb.lesb_symb_err)
0067 #define fcoe_ctlr_err_block(x)          \
0068     ((x)->lesb.lesb_err_block)
0069 #define fcoe_ctlr_fcs_error(x)          \
0070     ((x)->lesb.lesb_fcs_error)
0071 #define fcoe_ctlr_enabled(x)            \
0072     ((x)->enabled)
0073 #define fcoe_fcf_state(x)           \
0074     ((x)->state)
0075 #define fcoe_fcf_fabric_name(x)         \
0076     ((x)->fabric_name)
0077 #define fcoe_fcf_switch_name(x)         \
0078     ((x)->switch_name)
0079 #define fcoe_fcf_fc_map(x)          \
0080     ((x)->fc_map)
0081 #define fcoe_fcf_vfid(x)            \
0082     ((x)->vfid)
0083 #define fcoe_fcf_mac(x)             \
0084     ((x)->mac)
0085 #define fcoe_fcf_priority(x)            \
0086     ((x)->priority)
0087 #define fcoe_fcf_fka_period(x)          \
0088     ((x)->fka_period)
0089 #define fcoe_fcf_dev_loss_tmo(x)        \
0090     ((x)->dev_loss_tmo)
0091 #define fcoe_fcf_selected(x)            \
0092     ((x)->selected)
0093 #define fcoe_fcf_vlan_id(x)         \
0094     ((x)->vlan_id)
0095 
0096 /*
0097  * dev_loss_tmo attribute
0098  */
0099 static int fcoe_str_to_dev_loss(const char *buf, unsigned long *val)
0100 {
0101     int ret;
0102 
0103     ret = kstrtoul(buf, 0, val);
0104     if (ret)
0105         return -EINVAL;
0106     /*
0107      * Check for overflow; dev_loss_tmo is u32
0108      */
0109     if (*val > UINT_MAX)
0110         return -EINVAL;
0111 
0112     return 0;
0113 }
0114 
0115 static int fcoe_fcf_set_dev_loss_tmo(struct fcoe_fcf_device *fcf,
0116                      unsigned long val)
0117 {
0118     if ((fcf->state == FCOE_FCF_STATE_UNKNOWN) ||
0119         (fcf->state == FCOE_FCF_STATE_DISCONNECTED) ||
0120         (fcf->state == FCOE_FCF_STATE_DELETED))
0121         return -EBUSY;
0122     /*
0123      * Check for overflow; dev_loss_tmo is u32
0124      */
0125     if (val > UINT_MAX)
0126         return -EINVAL;
0127 
0128     fcoe_fcf_dev_loss_tmo(fcf) = val;
0129     return 0;
0130 }
0131 
0132 #define FCOE_DEVICE_ATTR(_prefix, _name, _mode, _show, _store)  \
0133 struct device_attribute device_attr_fcoe_##_prefix##_##_name =  \
0134     __ATTR(_name, _mode, _show, _store)
0135 
0136 #define fcoe_ctlr_show_function(field, format_string, sz, cast) \
0137 static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \
0138                         struct device_attribute *attr, \
0139                         char *buf)          \
0140 {                                   \
0141     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);       \
0142     if (ctlr->f->get_fcoe_ctlr_##field)             \
0143         ctlr->f->get_fcoe_ctlr_##field(ctlr);           \
0144     return snprintf(buf, sz, format_string,             \
0145             cast fcoe_ctlr_##field(ctlr));          \
0146 }
0147 
0148 #define fcoe_fcf_show_function(field, format_string, sz, cast)  \
0149 static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \
0150                        struct device_attribute *attr, \
0151                        char *buf)           \
0152 {                                   \
0153     struct fcoe_fcf_device *fcf = dev_to_fcf(dev);          \
0154     struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);  \
0155     if (ctlr->f->get_fcoe_fcf_##field)              \
0156         ctlr->f->get_fcoe_fcf_##field(fcf);         \
0157     return snprintf(buf, sz, format_string,             \
0158             cast fcoe_fcf_##field(fcf));            \
0159 }
0160 
0161 #define fcoe_ctlr_private_show_function(field, format_string, sz, cast) \
0162 static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \
0163                         struct device_attribute *attr, \
0164                         char *buf)          \
0165 {                                   \
0166     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);       \
0167     return snprintf(buf, sz, format_string, cast fcoe_ctlr_##field(ctlr)); \
0168 }
0169 
0170 #define fcoe_fcf_private_show_function(field, format_string, sz, cast)  \
0171 static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \
0172                        struct device_attribute *attr, \
0173                        char *buf)           \
0174 {                               \
0175     struct fcoe_fcf_device *fcf = dev_to_fcf(dev);          \
0176     return snprintf(buf, sz, format_string, cast fcoe_fcf_##field(fcf)); \
0177 }
0178 
0179 #define fcoe_ctlr_private_rd_attr(field, format_string, sz)     \
0180     fcoe_ctlr_private_show_function(field, format_string, sz, ) \
0181     static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO,           \
0182                 show_fcoe_ctlr_device_##field, NULL)
0183 
0184 #define fcoe_ctlr_rd_attr(field, format_string, sz)         \
0185     fcoe_ctlr_show_function(field, format_string, sz, )     \
0186     static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO,           \
0187                 show_fcoe_ctlr_device_##field, NULL)
0188 
0189 #define fcoe_fcf_rd_attr(field, format_string, sz)          \
0190     fcoe_fcf_show_function(field, format_string, sz, )      \
0191     static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO,            \
0192                 show_fcoe_fcf_device_##field, NULL)
0193 
0194 #define fcoe_fcf_private_rd_attr(field, format_string, sz)      \
0195     fcoe_fcf_private_show_function(field, format_string, sz, )  \
0196     static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO,            \
0197                 show_fcoe_fcf_device_##field, NULL)
0198 
0199 #define fcoe_ctlr_private_rd_attr_cast(field, format_string, sz, cast)  \
0200     fcoe_ctlr_private_show_function(field, format_string, sz, (cast)) \
0201     static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO,           \
0202                 show_fcoe_ctlr_device_##field, NULL)
0203 
0204 #define fcoe_fcf_private_rd_attr_cast(field, format_string, sz, cast)   \
0205     fcoe_fcf_private_show_function(field, format_string, sz, (cast)) \
0206     static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO,            \
0207                 show_fcoe_fcf_device_##field, NULL)
0208 
0209 #define fcoe_enum_name_search(title, table_type, table)         \
0210 static const char *get_fcoe_##title##_name(enum table_type table_key)   \
0211 {                                   \
0212     if (table_key < 0 || table_key >= ARRAY_SIZE(table))        \
0213         return NULL;                        \
0214     return table[table_key];                    \
0215 }
0216 
0217 static char *fip_conn_type_names[] = {
0218     [ FIP_CONN_TYPE_UNKNOWN ] = "Unknown",
0219     [ FIP_CONN_TYPE_FABRIC ]  = "Fabric",
0220     [ FIP_CONN_TYPE_VN2VN ]   = "VN2VN",
0221 };
0222 fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names)
0223 
0224 static enum fip_conn_type fcoe_parse_mode(const char *buf)
0225 {
0226     int i;
0227 
0228     for (i = 0; i < ARRAY_SIZE(fip_conn_type_names); i++) {
0229         if (strcasecmp(buf, fip_conn_type_names[i]) == 0)
0230             return i;
0231     }
0232 
0233     return FIP_CONN_TYPE_UNKNOWN;
0234 }
0235 
0236 static char *fcf_state_names[] = {
0237     [ FCOE_FCF_STATE_UNKNOWN ]      = "Unknown",
0238     [ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected",
0239     [ FCOE_FCF_STATE_CONNECTED ]    = "Connected",
0240 };
0241 fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names)
0242 #define FCOE_FCF_STATE_MAX_NAMELEN 50
0243 
0244 static ssize_t show_fcf_state(struct device *dev,
0245                   struct device_attribute *attr,
0246                   char *buf)
0247 {
0248     struct fcoe_fcf_device *fcf = dev_to_fcf(dev);
0249     const char *name;
0250     name = get_fcoe_fcf_state_name(fcf->state);
0251     if (!name)
0252         return -EINVAL;
0253     return snprintf(buf, FCOE_FCF_STATE_MAX_NAMELEN, "%s\n", name);
0254 }
0255 static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL);
0256 
0257 #define FCOE_MAX_MODENAME_LEN 20
0258 static ssize_t show_ctlr_mode(struct device *dev,
0259                   struct device_attribute *attr,
0260                   char *buf)
0261 {
0262     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0263     const char *name;
0264 
0265     name = get_fcoe_ctlr_mode_name(ctlr->mode);
0266     if (!name)
0267         return -EINVAL;
0268     return snprintf(buf, FCOE_MAX_MODENAME_LEN,
0269             "%s\n", name);
0270 }
0271 
0272 static ssize_t store_ctlr_mode(struct device *dev,
0273                    struct device_attribute *attr,
0274                    const char *buf, size_t count)
0275 {
0276     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0277     char mode[FCOE_MAX_MODENAME_LEN + 1];
0278 
0279     if (count > FCOE_MAX_MODENAME_LEN)
0280         return -EINVAL;
0281 
0282     strncpy(mode, buf, count);
0283 
0284     if (mode[count - 1] == '\n')
0285         mode[count - 1] = '\0';
0286     else
0287         mode[count] = '\0';
0288 
0289     switch (ctlr->enabled) {
0290     case FCOE_CTLR_ENABLED:
0291         LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.\n");
0292         return -EBUSY;
0293     case FCOE_CTLR_DISABLED:
0294         if (!ctlr->f->set_fcoe_ctlr_mode) {
0295             LIBFCOE_SYSFS_DBG(ctlr,
0296                       "Mode change not supported by LLD.\n");
0297             return -ENOTSUPP;
0298         }
0299 
0300         ctlr->mode = fcoe_parse_mode(mode);
0301         if (ctlr->mode == FIP_CONN_TYPE_UNKNOWN) {
0302             LIBFCOE_SYSFS_DBG(ctlr, "Unknown mode %s provided.\n",
0303                       buf);
0304             return -EINVAL;
0305         }
0306 
0307         ctlr->f->set_fcoe_ctlr_mode(ctlr);
0308         LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.\n", buf);
0309 
0310         return count;
0311     case FCOE_CTLR_UNUSED:
0312     default:
0313         LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.\n");
0314         return -ENOTSUPP;
0315     }
0316 }
0317 
0318 static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO | S_IWUSR,
0319             show_ctlr_mode, store_ctlr_mode);
0320 
0321 static ssize_t store_ctlr_enabled(struct device *dev,
0322                   struct device_attribute *attr,
0323                   const char *buf, size_t count)
0324 {
0325     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0326     bool enabled;
0327     int rc;
0328 
0329     if (*buf == '1')
0330         enabled = true;
0331     else if (*buf == '0')
0332         enabled = false;
0333     else
0334         return -EINVAL;
0335 
0336     switch (ctlr->enabled) {
0337     case FCOE_CTLR_ENABLED:
0338         if (enabled)
0339             return count;
0340         ctlr->enabled = FCOE_CTLR_DISABLED;
0341         break;
0342     case FCOE_CTLR_DISABLED:
0343         if (!enabled)
0344             return count;
0345         ctlr->enabled = FCOE_CTLR_ENABLED;
0346         break;
0347     case FCOE_CTLR_UNUSED:
0348         return -ENOTSUPP;
0349     }
0350 
0351     rc = ctlr->f->set_fcoe_ctlr_enabled(ctlr);
0352     if (rc)
0353         return rc;
0354 
0355     return count;
0356 }
0357 
0358 static char *ctlr_enabled_state_names[] = {
0359     [ FCOE_CTLR_ENABLED ]  = "1",
0360     [ FCOE_CTLR_DISABLED ] = "0",
0361 };
0362 fcoe_enum_name_search(ctlr_enabled_state, ctlr_enabled_state,
0363               ctlr_enabled_state_names)
0364 #define FCOE_CTLR_ENABLED_MAX_NAMELEN 50
0365 
0366 static ssize_t show_ctlr_enabled_state(struct device *dev,
0367                        struct device_attribute *attr,
0368                        char *buf)
0369 {
0370     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0371     const char *name;
0372 
0373     name = get_fcoe_ctlr_enabled_state_name(ctlr->enabled);
0374     if (!name)
0375         return -EINVAL;
0376     return snprintf(buf, FCOE_CTLR_ENABLED_MAX_NAMELEN,
0377             "%s\n", name);
0378 }
0379 
0380 static FCOE_DEVICE_ATTR(ctlr, enabled, S_IRUGO | S_IWUSR,
0381             show_ctlr_enabled_state,
0382             store_ctlr_enabled);
0383 
0384 static ssize_t store_ctlr_fip_resp(struct device *dev,
0385                   struct device_attribute *attr,
0386                   const char *buf, size_t count)
0387 {
0388     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0389     struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr);
0390 
0391     mutex_lock(&fip->ctlr_mutex);
0392     if ((buf[1] == '\0') || ((buf[1] == '\n') && (buf[2] == '\0'))) {
0393         if (buf[0] == '1') {
0394             fip->fip_resp = 1;
0395             mutex_unlock(&fip->ctlr_mutex);
0396             return count;
0397         }
0398         if (buf[0] == '0') {
0399             fip->fip_resp = 0;
0400             mutex_unlock(&fip->ctlr_mutex);
0401             return count;
0402         }
0403     }
0404     mutex_unlock(&fip->ctlr_mutex);
0405     return -EINVAL;
0406 }
0407 
0408 static ssize_t show_ctlr_fip_resp(struct device *dev,
0409                   struct device_attribute *attr,
0410                   char *buf)
0411 {
0412     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0413     struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr);
0414 
0415     return sprintf(buf, "%d\n", fip->fip_resp ? 1 : 0);
0416 }
0417 
0418 static FCOE_DEVICE_ATTR(ctlr, fip_vlan_responder, S_IRUGO | S_IWUSR,
0419             show_ctlr_fip_resp,
0420             store_ctlr_fip_resp);
0421 
0422 static ssize_t
0423 fcoe_ctlr_var_store(u32 *var, const char *buf, size_t count)
0424 {
0425     int err;
0426     unsigned long v;
0427 
0428     err = kstrtoul(buf, 10, &v);
0429     if (err || v > UINT_MAX)
0430         return -EINVAL;
0431 
0432     *var = v;
0433 
0434     return count;
0435 }
0436 
0437 static ssize_t store_ctlr_r_a_tov(struct device *dev,
0438                   struct device_attribute *attr,
0439                   const char *buf, size_t count)
0440 {
0441     struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
0442     struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
0443 
0444     if (ctlr_dev->enabled == FCOE_CTLR_ENABLED)
0445         return -EBUSY;
0446     if (ctlr_dev->enabled == FCOE_CTLR_DISABLED)
0447         return fcoe_ctlr_var_store(&ctlr->lp->r_a_tov, buf, count);
0448     return -ENOTSUPP;
0449 }
0450 
0451 static ssize_t show_ctlr_r_a_tov(struct device *dev,
0452                  struct device_attribute *attr,
0453                  char *buf)
0454 {
0455     struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
0456     struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
0457 
0458     return sprintf(buf, "%d\n", ctlr->lp->r_a_tov);
0459 }
0460 
0461 static FCOE_DEVICE_ATTR(ctlr, r_a_tov, S_IRUGO | S_IWUSR,
0462             show_ctlr_r_a_tov, store_ctlr_r_a_tov);
0463 
0464 static ssize_t store_ctlr_e_d_tov(struct device *dev,
0465                   struct device_attribute *attr,
0466                   const char *buf, size_t count)
0467 {
0468     struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
0469     struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
0470 
0471     if (ctlr_dev->enabled == FCOE_CTLR_ENABLED)
0472         return -EBUSY;
0473     if (ctlr_dev->enabled == FCOE_CTLR_DISABLED)
0474         return fcoe_ctlr_var_store(&ctlr->lp->e_d_tov, buf, count);
0475     return -ENOTSUPP;
0476 }
0477 
0478 static ssize_t show_ctlr_e_d_tov(struct device *dev,
0479                  struct device_attribute *attr,
0480                  char *buf)
0481 {
0482     struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev);
0483     struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev);
0484 
0485     return sprintf(buf, "%d\n", ctlr->lp->e_d_tov);
0486 }
0487 
0488 static FCOE_DEVICE_ATTR(ctlr, e_d_tov, S_IRUGO | S_IWUSR,
0489             show_ctlr_e_d_tov, store_ctlr_e_d_tov);
0490 
0491 static ssize_t
0492 store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev,
0493                      struct device_attribute *attr,
0494                      const char *buf, size_t count)
0495 {
0496     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0497     struct fcoe_fcf_device *fcf;
0498     unsigned long val;
0499     int rc;
0500 
0501     rc = fcoe_str_to_dev_loss(buf, &val);
0502     if (rc)
0503         return rc;
0504 
0505     fcoe_ctlr_fcf_dev_loss_tmo(ctlr) = val;
0506     mutex_lock(&ctlr->lock);
0507     list_for_each_entry(fcf, &ctlr->fcfs, peers)
0508         fcoe_fcf_set_dev_loss_tmo(fcf, val);
0509     mutex_unlock(&ctlr->lock);
0510     return count;
0511 }
0512 fcoe_ctlr_private_show_function(fcf_dev_loss_tmo, "%d\n", 20, );
0513 static FCOE_DEVICE_ATTR(ctlr, fcf_dev_loss_tmo, S_IRUGO | S_IWUSR,
0514             show_fcoe_ctlr_device_fcf_dev_loss_tmo,
0515             store_private_fcoe_ctlr_fcf_dev_loss_tmo);
0516 
0517 /* Link Error Status Block (LESB) */
0518 fcoe_ctlr_rd_attr(link_fail, "%u\n", 20);
0519 fcoe_ctlr_rd_attr(vlink_fail, "%u\n", 20);
0520 fcoe_ctlr_rd_attr(miss_fka, "%u\n", 20);
0521 fcoe_ctlr_rd_attr(symb_err, "%u\n", 20);
0522 fcoe_ctlr_rd_attr(err_block, "%u\n", 20);
0523 fcoe_ctlr_rd_attr(fcs_error, "%u\n", 20);
0524 
0525 fcoe_fcf_private_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long);
0526 fcoe_fcf_private_rd_attr_cast(switch_name, "0x%llx\n", 20, unsigned long long);
0527 fcoe_fcf_private_rd_attr(priority, "%u\n", 20);
0528 fcoe_fcf_private_rd_attr(fc_map, "0x%x\n", 20);
0529 fcoe_fcf_private_rd_attr(vfid, "%u\n", 20);
0530 fcoe_fcf_private_rd_attr(mac, "%pM\n", 20);
0531 fcoe_fcf_private_rd_attr(fka_period, "%u\n", 20);
0532 fcoe_fcf_rd_attr(selected, "%u\n", 20);
0533 fcoe_fcf_rd_attr(vlan_id, "%u\n", 20);
0534 
0535 fcoe_fcf_private_show_function(dev_loss_tmo, "%d\n", 20, )
0536 static ssize_t
0537 store_fcoe_fcf_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
0538                 const char *buf, size_t count)
0539 {
0540     struct fcoe_fcf_device *fcf = dev_to_fcf(dev);
0541     unsigned long val;
0542     int rc;
0543 
0544     rc = fcoe_str_to_dev_loss(buf, &val);
0545     if (rc)
0546         return rc;
0547 
0548     rc = fcoe_fcf_set_dev_loss_tmo(fcf, val);
0549     if (rc)
0550         return rc;
0551     return count;
0552 }
0553 static FCOE_DEVICE_ATTR(fcf, dev_loss_tmo, S_IRUGO | S_IWUSR,
0554             show_fcoe_fcf_device_dev_loss_tmo,
0555             store_fcoe_fcf_dev_loss_tmo);
0556 
0557 static struct attribute *fcoe_ctlr_lesb_attrs[] = {
0558     &device_attr_fcoe_ctlr_link_fail.attr,
0559     &device_attr_fcoe_ctlr_vlink_fail.attr,
0560     &device_attr_fcoe_ctlr_miss_fka.attr,
0561     &device_attr_fcoe_ctlr_symb_err.attr,
0562     &device_attr_fcoe_ctlr_err_block.attr,
0563     &device_attr_fcoe_ctlr_fcs_error.attr,
0564     NULL,
0565 };
0566 
0567 static struct attribute_group fcoe_ctlr_lesb_attr_group = {
0568     .name = "lesb",
0569     .attrs = fcoe_ctlr_lesb_attrs,
0570 };
0571 
0572 static struct attribute *fcoe_ctlr_attrs[] = {
0573     &device_attr_fcoe_ctlr_fip_vlan_responder.attr,
0574     &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr,
0575     &device_attr_fcoe_ctlr_r_a_tov.attr,
0576     &device_attr_fcoe_ctlr_e_d_tov.attr,
0577     &device_attr_fcoe_ctlr_enabled.attr,
0578     &device_attr_fcoe_ctlr_mode.attr,
0579     NULL,
0580 };
0581 
0582 static struct attribute_group fcoe_ctlr_attr_group = {
0583     .attrs = fcoe_ctlr_attrs,
0584 };
0585 
0586 static const struct attribute_group *fcoe_ctlr_attr_groups[] = {
0587     &fcoe_ctlr_attr_group,
0588     &fcoe_ctlr_lesb_attr_group,
0589     NULL,
0590 };
0591 
0592 static struct attribute *fcoe_fcf_attrs[] = {
0593     &device_attr_fcoe_fcf_fabric_name.attr,
0594     &device_attr_fcoe_fcf_switch_name.attr,
0595     &device_attr_fcoe_fcf_dev_loss_tmo.attr,
0596     &device_attr_fcoe_fcf_fc_map.attr,
0597     &device_attr_fcoe_fcf_vfid.attr,
0598     &device_attr_fcoe_fcf_mac.attr,
0599     &device_attr_fcoe_fcf_priority.attr,
0600     &device_attr_fcoe_fcf_fka_period.attr,
0601     &device_attr_fcoe_fcf_state.attr,
0602     &device_attr_fcoe_fcf_selected.attr,
0603     &device_attr_fcoe_fcf_vlan_id.attr,
0604     NULL
0605 };
0606 
0607 static struct attribute_group fcoe_fcf_attr_group = {
0608     .attrs = fcoe_fcf_attrs,
0609 };
0610 
0611 static const struct attribute_group *fcoe_fcf_attr_groups[] = {
0612     &fcoe_fcf_attr_group,
0613     NULL,
0614 };
0615 
0616 static struct bus_type fcoe_bus_type;
0617 
0618 static int fcoe_bus_match(struct device *dev,
0619               struct device_driver *drv)
0620 {
0621     if (dev->bus == &fcoe_bus_type)
0622         return 1;
0623     return 0;
0624 }
0625 
0626 /**
0627  * fcoe_ctlr_device_release() - Release the FIP ctlr memory
0628  * @dev: Pointer to the FIP ctlr's embedded device
0629  *
0630  * Called when the last FIP ctlr reference is released.
0631  */
0632 static void fcoe_ctlr_device_release(struct device *dev)
0633 {
0634     struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev);
0635     kfree(ctlr);
0636 }
0637 
0638 /**
0639  * fcoe_fcf_device_release() - Release the FIP fcf memory
0640  * @dev: Pointer to the fcf's embedded device
0641  *
0642  * Called when the last FIP fcf reference is released.
0643  */
0644 static void fcoe_fcf_device_release(struct device *dev)
0645 {
0646     struct fcoe_fcf_device *fcf = dev_to_fcf(dev);
0647     kfree(fcf);
0648 }
0649 
0650 static const struct device_type fcoe_ctlr_device_type = {
0651     .name = "fcoe_ctlr",
0652     .groups = fcoe_ctlr_attr_groups,
0653     .release = fcoe_ctlr_device_release,
0654 };
0655 
0656 static const struct device_type fcoe_fcf_device_type = {
0657     .name = "fcoe_fcf",
0658     .groups = fcoe_fcf_attr_groups,
0659     .release = fcoe_fcf_device_release,
0660 };
0661 
0662 static ssize_t ctlr_create_store(struct bus_type *bus, const char *buf,
0663                  size_t count)
0664 {
0665     return fcoe_ctlr_create_store(bus, buf, count);
0666 }
0667 static BUS_ATTR_WO(ctlr_create);
0668 
0669 static ssize_t ctlr_destroy_store(struct bus_type *bus, const char *buf,
0670                   size_t count)
0671 {
0672     return fcoe_ctlr_destroy_store(bus, buf, count);
0673 }
0674 static BUS_ATTR_WO(ctlr_destroy);
0675 
0676 static struct attribute *fcoe_bus_attrs[] = {
0677     &bus_attr_ctlr_create.attr,
0678     &bus_attr_ctlr_destroy.attr,
0679     NULL,
0680 };
0681 ATTRIBUTE_GROUPS(fcoe_bus);
0682 
0683 static struct bus_type fcoe_bus_type = {
0684     .name = "fcoe",
0685     .match = &fcoe_bus_match,
0686     .bus_groups = fcoe_bus_groups,
0687 };
0688 
0689 /**
0690  * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue
0691  * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed
0692  */
0693 static void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr)
0694 {
0695     if (!fcoe_ctlr_work_q(ctlr)) {
0696         printk(KERN_ERR
0697                "ERROR: FIP Ctlr '%d' attempted to flush work, "
0698                "when no workqueue created.\n", ctlr->id);
0699         dump_stack();
0700         return;
0701     }
0702 
0703     flush_workqueue(fcoe_ctlr_work_q(ctlr));
0704 }
0705 
0706 /**
0707  * fcoe_ctlr_device_queue_work() - Schedule work for a FIP ctlr's workqueue
0708  * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue
0709  * @work:   Work to queue for execution
0710  *
0711  * Return value:
0712  *  1 on success / 0 already queued / < 0 for error
0713  */
0714 static int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr,
0715                        struct work_struct *work)
0716 {
0717     if (unlikely(!fcoe_ctlr_work_q(ctlr))) {
0718         printk(KERN_ERR
0719                "ERROR: FIP Ctlr '%d' attempted to queue work, "
0720                "when no workqueue created.\n", ctlr->id);
0721         dump_stack();
0722 
0723         return -EINVAL;
0724     }
0725 
0726     return queue_work(fcoe_ctlr_work_q(ctlr), work);
0727 }
0728 
0729 /**
0730  * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue
0731  * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed
0732  */
0733 static void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr)
0734 {
0735     if (!fcoe_ctlr_devloss_work_q(ctlr)) {
0736         printk(KERN_ERR
0737                "ERROR: FIP Ctlr '%d' attempted to flush work, "
0738                "when no workqueue created.\n", ctlr->id);
0739         dump_stack();
0740         return;
0741     }
0742 
0743     flush_workqueue(fcoe_ctlr_devloss_work_q(ctlr));
0744 }
0745 
0746 /**
0747  * fcoe_ctlr_device_queue_devloss_work() - Schedule work for a FIP ctlr's devloss workqueue
0748  * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue
0749  * @work:   Work to queue for execution
0750  * @delay:  jiffies to delay the work queuing
0751  *
0752  * Return value:
0753  *  1 on success / 0 already queued / < 0 for error
0754  */
0755 static int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr,
0756                            struct delayed_work *work,
0757                            unsigned long delay)
0758 {
0759     if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) {
0760         printk(KERN_ERR
0761                "ERROR: FIP Ctlr '%d' attempted to queue work, "
0762                "when no workqueue created.\n", ctlr->id);
0763         dump_stack();
0764 
0765         return -EINVAL;
0766     }
0767 
0768     return queue_delayed_work(fcoe_ctlr_devloss_work_q(ctlr), work, delay);
0769 }
0770 
0771 static int fcoe_fcf_device_match(struct fcoe_fcf_device *new,
0772                  struct fcoe_fcf_device *old)
0773 {
0774     if (new->switch_name == old->switch_name &&
0775         new->fabric_name == old->fabric_name &&
0776         new->fc_map == old->fc_map &&
0777         ether_addr_equal(new->mac, old->mac))
0778         return 1;
0779     return 0;
0780 }
0781 
0782 /**
0783  * fcoe_ctlr_device_add() - Add a FIP ctlr to sysfs
0784  * @parent:    The parent device to which the fcoe_ctlr instance
0785  *             should be attached
0786  * @f:         The LLD's FCoE sysfs function template pointer
0787  * @priv_size: Size to be allocated with the fcoe_ctlr_device for the LLD
0788  *
0789  * This routine allocates a FIP ctlr object with some additional memory
0790  * for the LLD. The FIP ctlr is initialized, added to sysfs and then
0791  * attributes are added to it.
0792  */
0793 struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent,
0794                     struct fcoe_sysfs_function_template *f,
0795                     int priv_size)
0796 {
0797     struct fcoe_ctlr_device *ctlr;
0798     int error = 0;
0799 
0800     ctlr = kzalloc(sizeof(struct fcoe_ctlr_device) + priv_size,
0801                GFP_KERNEL);
0802     if (!ctlr)
0803         goto out;
0804 
0805     ctlr->id = atomic_inc_return(&ctlr_num) - 1;
0806     ctlr->f = f;
0807     ctlr->mode = FIP_CONN_TYPE_FABRIC;
0808     INIT_LIST_HEAD(&ctlr->fcfs);
0809     mutex_init(&ctlr->lock);
0810     ctlr->dev.parent = parent;
0811     ctlr->dev.bus = &fcoe_bus_type;
0812     ctlr->dev.type = &fcoe_ctlr_device_type;
0813 
0814     ctlr->fcf_dev_loss_tmo = fcoe_fcf_dev_loss_tmo;
0815 
0816     snprintf(ctlr->work_q_name, sizeof(ctlr->work_q_name),
0817          "ctlr_wq_%d", ctlr->id);
0818     ctlr->work_q = create_singlethread_workqueue(
0819         ctlr->work_q_name);
0820     if (!ctlr->work_q)
0821         goto out_del;
0822 
0823     snprintf(ctlr->devloss_work_q_name,
0824          sizeof(ctlr->devloss_work_q_name),
0825          "ctlr_dl_wq_%d", ctlr->id);
0826     ctlr->devloss_work_q = create_singlethread_workqueue(
0827         ctlr->devloss_work_q_name);
0828     if (!ctlr->devloss_work_q)
0829         goto out_del_q;
0830 
0831     dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id);
0832     error = device_register(&ctlr->dev);
0833     if (error)
0834         goto out_del_q2;
0835 
0836     return ctlr;
0837 
0838 out_del_q2:
0839     destroy_workqueue(ctlr->devloss_work_q);
0840     ctlr->devloss_work_q = NULL;
0841 out_del_q:
0842     destroy_workqueue(ctlr->work_q);
0843     ctlr->work_q = NULL;
0844 out_del:
0845     kfree(ctlr);
0846 out:
0847     return NULL;
0848 }
0849 EXPORT_SYMBOL_GPL(fcoe_ctlr_device_add);
0850 
0851 /**
0852  * fcoe_ctlr_device_delete() - Delete a FIP ctlr and its subtree from sysfs
0853  * @ctlr: A pointer to the ctlr to be deleted
0854  *
0855  * Deletes a FIP ctlr and any fcfs attached
0856  * to it. Deleting fcfs will cause their childen
0857  * to be deleted as well.
0858  *
0859  * The ctlr is detached from sysfs and it's resources
0860  * are freed (work q), but the memory is not freed
0861  * until its last reference is released.
0862  *
0863  * This routine expects no locks to be held before
0864  * calling.
0865  *
0866  * TODO: Currently there are no callbacks to clean up LLD data
0867  * for a fcoe_fcf_device. LLDs must keep this in mind as they need
0868  * to clean up each of their LLD data for all fcoe_fcf_device before
0869  * calling fcoe_ctlr_device_delete.
0870  */
0871 void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *ctlr)
0872 {
0873     struct fcoe_fcf_device *fcf, *next;
0874     /* Remove any attached fcfs */
0875     mutex_lock(&ctlr->lock);
0876     list_for_each_entry_safe(fcf, next,
0877                  &ctlr->fcfs, peers) {
0878         list_del(&fcf->peers);
0879         fcf->state = FCOE_FCF_STATE_DELETED;
0880         fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work);
0881     }
0882     mutex_unlock(&ctlr->lock);
0883 
0884     fcoe_ctlr_device_flush_work(ctlr);
0885 
0886     destroy_workqueue(ctlr->devloss_work_q);
0887     ctlr->devloss_work_q = NULL;
0888     destroy_workqueue(ctlr->work_q);
0889     ctlr->work_q = NULL;
0890 
0891     device_unregister(&ctlr->dev);
0892 }
0893 EXPORT_SYMBOL_GPL(fcoe_ctlr_device_delete);
0894 
0895 /**
0896  * fcoe_fcf_device_final_delete() - Final delete routine
0897  * @work: The FIP fcf's embedded work struct
0898  *
0899  * It is expected that the fcf has been removed from
0900  * the FIP ctlr's list before calling this routine.
0901  */
0902 static void fcoe_fcf_device_final_delete(struct work_struct *work)
0903 {
0904     struct fcoe_fcf_device *fcf =
0905         container_of(work, struct fcoe_fcf_device, delete_work);
0906     struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);
0907 
0908     /*
0909      * Cancel any outstanding timers. These should really exist
0910      * only when rmmod'ing the LLDD and we're asking for
0911      * immediate termination of the rports
0912      */
0913     if (!cancel_delayed_work(&fcf->dev_loss_work))
0914         fcoe_ctlr_device_flush_devloss(ctlr);
0915 
0916     device_unregister(&fcf->dev);
0917 }
0918 
0919 /**
0920  * fip_timeout_deleted_fcf() - Delete a fcf when the devloss timer fires
0921  * @work: The FIP fcf's embedded work struct
0922  *
0923  * Removes the fcf from the FIP ctlr's list of fcfs and
0924  * queues the final deletion.
0925  */
0926 static void fip_timeout_deleted_fcf(struct work_struct *work)
0927 {
0928     struct fcoe_fcf_device *fcf =
0929         container_of(work, struct fcoe_fcf_device, dev_loss_work.work);
0930     struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);
0931 
0932     mutex_lock(&ctlr->lock);
0933 
0934     /*
0935      * If the fcf is deleted or reconnected before the timer
0936      * fires the devloss queue will be flushed, but the state will
0937      * either be CONNECTED or DELETED. If that is the case we
0938      * cancel deleting the fcf.
0939      */
0940     if (fcf->state != FCOE_FCF_STATE_DISCONNECTED)
0941         goto out;
0942 
0943     dev_printk(KERN_ERR, &fcf->dev,
0944            "FIP fcf connection time out: removing fcf\n");
0945 
0946     list_del(&fcf->peers);
0947     fcf->state = FCOE_FCF_STATE_DELETED;
0948     fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work);
0949 
0950 out:
0951     mutex_unlock(&ctlr->lock);
0952 }
0953 
0954 /**
0955  * fcoe_fcf_device_delete() - Delete a FIP fcf
0956  * @fcf: Pointer to the fcf which is to be deleted
0957  *
0958  * Queues the FIP fcf on the devloss workqueue
0959  *
0960  * Expects the ctlr_attrs mutex to be held for fcf
0961  * state change.
0962  */
0963 void fcoe_fcf_device_delete(struct fcoe_fcf_device *fcf)
0964 {
0965     struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf);
0966     int timeout = fcf->dev_loss_tmo;
0967 
0968     if (fcf->state != FCOE_FCF_STATE_CONNECTED)
0969         return;
0970 
0971     fcf->state = FCOE_FCF_STATE_DISCONNECTED;
0972 
0973     /*
0974      * FCF will only be re-connected by the LLD calling
0975      * fcoe_fcf_device_add, and it should be setting up
0976      * priv then.
0977      */
0978     fcf->priv = NULL;
0979 
0980     fcoe_ctlr_device_queue_devloss_work(ctlr, &fcf->dev_loss_work,
0981                        timeout * HZ);
0982 }
0983 EXPORT_SYMBOL_GPL(fcoe_fcf_device_delete);
0984 
0985 /**
0986  * fcoe_fcf_device_add() - Add a FCoE sysfs fcoe_fcf_device to the system
0987  * @ctlr:    The fcoe_ctlr_device that will be the fcoe_fcf_device parent
0988  * @new_fcf: A temporary FCF used for lookups on the current list of fcfs
0989  *
0990  * Expects to be called with the ctlr->lock held
0991  */
0992 struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr,
0993                         struct fcoe_fcf_device *new_fcf)
0994 {
0995     struct fcoe_fcf_device *fcf;
0996     int error = 0;
0997 
0998     list_for_each_entry(fcf, &ctlr->fcfs, peers) {
0999         if (fcoe_fcf_device_match(new_fcf, fcf)) {
1000             if (fcf->state == FCOE_FCF_STATE_CONNECTED)
1001                 return fcf;
1002 
1003             fcf->state = FCOE_FCF_STATE_CONNECTED;
1004 
1005             if (!cancel_delayed_work(&fcf->dev_loss_work))
1006                 fcoe_ctlr_device_flush_devloss(ctlr);
1007 
1008             return fcf;
1009         }
1010     }
1011 
1012     fcf = kzalloc(sizeof(struct fcoe_fcf_device), GFP_ATOMIC);
1013     if (unlikely(!fcf))
1014         goto out;
1015 
1016     INIT_WORK(&fcf->delete_work, fcoe_fcf_device_final_delete);
1017     INIT_DELAYED_WORK(&fcf->dev_loss_work, fip_timeout_deleted_fcf);
1018 
1019     fcf->dev.parent = &ctlr->dev;
1020     fcf->dev.bus = &fcoe_bus_type;
1021     fcf->dev.type = &fcoe_fcf_device_type;
1022     fcf->id = atomic_inc_return(&fcf_num) - 1;
1023     fcf->state = FCOE_FCF_STATE_UNKNOWN;
1024 
1025     fcf->dev_loss_tmo = ctlr->fcf_dev_loss_tmo;
1026 
1027     dev_set_name(&fcf->dev, "fcf_%d", fcf->id);
1028 
1029     fcf->fabric_name = new_fcf->fabric_name;
1030     fcf->switch_name = new_fcf->switch_name;
1031     fcf->fc_map = new_fcf->fc_map;
1032     fcf->vfid = new_fcf->vfid;
1033     memcpy(fcf->mac, new_fcf->mac, ETH_ALEN);
1034     fcf->priority = new_fcf->priority;
1035     fcf->fka_period = new_fcf->fka_period;
1036     fcf->selected = new_fcf->selected;
1037 
1038     error = device_register(&fcf->dev);
1039     if (error)
1040         goto out_del;
1041 
1042     fcf->state = FCOE_FCF_STATE_CONNECTED;
1043     list_add_tail(&fcf->peers, &ctlr->fcfs);
1044 
1045     return fcf;
1046 
1047 out_del:
1048     kfree(fcf);
1049 out:
1050     return NULL;
1051 }
1052 EXPORT_SYMBOL_GPL(fcoe_fcf_device_add);
1053 
1054 int __init fcoe_sysfs_setup(void)
1055 {
1056     atomic_set(&ctlr_num, 0);
1057     atomic_set(&fcf_num, 0);
1058 
1059     return bus_register(&fcoe_bus_type);
1060 }
1061 
1062 void __exit fcoe_sysfs_teardown(void)
1063 {
1064     bus_unregister(&fcoe_bus_type);
1065 }