1 /* 2 * Copyright(c) 2011 - 2012 Intel Corporation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program; if not, write to the Free Software Foundation, Inc., 15 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 16 * 17 * Maintained at www.Open-FCoE.org 18 */ 19 20 #include <linux/module.h> 21 #include <linux/types.h> 22 #include <linux/kernel.h> 23 #include <linux/etherdevice.h> 24 #include <linux/ctype.h> 25 26 #include <scsi/fcoe_sysfs.h> 27 #include <scsi/libfcoe.h> 28 29 /* 30 * OK to include local libfcoe.h for debug_logging, but cannot include 31 * <scsi/libfcoe.h> otherwise non-netdev based fcoe solutions would have 32 * have to include more than fcoe_sysfs.h. 33 */ 34 #include "libfcoe.h" 35 36 static atomic_t ctlr_num; 37 static atomic_t fcf_num; 38 39 /* 40 * fcoe_fcf_dev_loss_tmo: the default number of seconds that fcoe sysfs 41 * should insulate the loss of a fcf. 42 */ 43 static unsigned int fcoe_fcf_dev_loss_tmo = 1800; /* seconds */ 44 45 module_param_named(fcf_dev_loss_tmo, fcoe_fcf_dev_loss_tmo, 46 uint, S_IRUGO|S_IWUSR); 47 MODULE_PARM_DESC(fcf_dev_loss_tmo, 48 "Maximum number of seconds that libfcoe should" 49 " insulate the loss of a fcf. Once this value is" 50 " exceeded, the fcf is removed."); 51 52 /* 53 * These are used by the fcoe_*_show_function routines, they 54 * are intentionally placed in the .c file as they're not intended 55 * for use throughout the code. 56 */ 57 #define fcoe_ctlr_id(x) \ 58 ((x)->id) 59 #define fcoe_ctlr_work_q_name(x) \ 60 ((x)->work_q_name) 61 #define fcoe_ctlr_work_q(x) \ 62 ((x)->work_q) 63 #define fcoe_ctlr_devloss_work_q_name(x) \ 64 ((x)->devloss_work_q_name) 65 #define fcoe_ctlr_devloss_work_q(x) \ 66 ((x)->devloss_work_q) 67 #define fcoe_ctlr_mode(x) \ 68 ((x)->mode) 69 #define fcoe_ctlr_fcf_dev_loss_tmo(x) \ 70 ((x)->fcf_dev_loss_tmo) 71 #define fcoe_ctlr_link_fail(x) \ 72 ((x)->lesb.lesb_link_fail) 73 #define fcoe_ctlr_vlink_fail(x) \ 74 ((x)->lesb.lesb_vlink_fail) 75 #define fcoe_ctlr_miss_fka(x) \ 76 ((x)->lesb.lesb_miss_fka) 77 #define fcoe_ctlr_symb_err(x) \ 78 ((x)->lesb.lesb_symb_err) 79 #define fcoe_ctlr_err_block(x) \ 80 ((x)->lesb.lesb_err_block) 81 #define fcoe_ctlr_fcs_error(x) \ 82 ((x)->lesb.lesb_fcs_error) 83 #define fcoe_ctlr_enabled(x) \ 84 ((x)->enabled) 85 #define fcoe_fcf_state(x) \ 86 ((x)->state) 87 #define fcoe_fcf_fabric_name(x) \ 88 ((x)->fabric_name) 89 #define fcoe_fcf_switch_name(x) \ 90 ((x)->switch_name) 91 #define fcoe_fcf_fc_map(x) \ 92 ((x)->fc_map) 93 #define fcoe_fcf_vfid(x) \ 94 ((x)->vfid) 95 #define fcoe_fcf_mac(x) \ 96 ((x)->mac) 97 #define fcoe_fcf_priority(x) \ 98 ((x)->priority) 99 #define fcoe_fcf_fka_period(x) \ 100 ((x)->fka_period) 101 #define fcoe_fcf_dev_loss_tmo(x) \ 102 ((x)->dev_loss_tmo) 103 #define fcoe_fcf_selected(x) \ 104 ((x)->selected) 105 #define fcoe_fcf_vlan_id(x) \ 106 ((x)->vlan_id) 107 108 /* 109 * dev_loss_tmo attribute 110 */ 111 static int fcoe_str_to_dev_loss(const char *buf, unsigned long *val) 112 { 113 int ret; 114 115 ret = kstrtoul(buf, 0, val); 116 if (ret) 117 return -EINVAL; 118 /* 119 * Check for overflow; dev_loss_tmo is u32 120 */ 121 if (*val > UINT_MAX) 122 return -EINVAL; 123 124 return 0; 125 } 126 127 static int fcoe_fcf_set_dev_loss_tmo(struct fcoe_fcf_device *fcf, 128 unsigned long val) 129 { 130 if ((fcf->state == FCOE_FCF_STATE_UNKNOWN) || 131 (fcf->state == FCOE_FCF_STATE_DISCONNECTED) || 132 (fcf->state == FCOE_FCF_STATE_DELETED)) 133 return -EBUSY; 134 /* 135 * Check for overflow; dev_loss_tmo is u32 136 */ 137 if (val > UINT_MAX) 138 return -EINVAL; 139 140 fcoe_fcf_dev_loss_tmo(fcf) = val; 141 return 0; 142 } 143 144 #define FCOE_DEVICE_ATTR(_prefix, _name, _mode, _show, _store) \ 145 struct device_attribute device_attr_fcoe_##_prefix##_##_name = \ 146 __ATTR(_name, _mode, _show, _store) 147 148 #define fcoe_ctlr_show_function(field, format_string, sz, cast) \ 149 static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ 150 struct device_attribute *attr, \ 151 char *buf) \ 152 { \ 153 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ 154 if (ctlr->f->get_fcoe_ctlr_##field) \ 155 ctlr->f->get_fcoe_ctlr_##field(ctlr); \ 156 return snprintf(buf, sz, format_string, \ 157 cast fcoe_ctlr_##field(ctlr)); \ 158 } 159 160 #define fcoe_fcf_show_function(field, format_string, sz, cast) \ 161 static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ 162 struct device_attribute *attr, \ 163 char *buf) \ 164 { \ 165 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ 166 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); \ 167 if (ctlr->f->get_fcoe_fcf_##field) \ 168 ctlr->f->get_fcoe_fcf_##field(fcf); \ 169 return snprintf(buf, sz, format_string, \ 170 cast fcoe_fcf_##field(fcf)); \ 171 } 172 173 #define fcoe_ctlr_private_show_function(field, format_string, sz, cast) \ 174 static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ 175 struct device_attribute *attr, \ 176 char *buf) \ 177 { \ 178 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ 179 return snprintf(buf, sz, format_string, cast fcoe_ctlr_##field(ctlr)); \ 180 } 181 182 #define fcoe_fcf_private_show_function(field, format_string, sz, cast) \ 183 static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ 184 struct device_attribute *attr, \ 185 char *buf) \ 186 { \ 187 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ 188 return snprintf(buf, sz, format_string, cast fcoe_fcf_##field(fcf)); \ 189 } 190 191 #define fcoe_ctlr_private_rd_attr(field, format_string, sz) \ 192 fcoe_ctlr_private_show_function(field, format_string, sz, ) \ 193 static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 194 show_fcoe_ctlr_device_##field, NULL) 195 196 #define fcoe_ctlr_rd_attr(field, format_string, sz) \ 197 fcoe_ctlr_show_function(field, format_string, sz, ) \ 198 static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 199 show_fcoe_ctlr_device_##field, NULL) 200 201 #define fcoe_fcf_rd_attr(field, format_string, sz) \ 202 fcoe_fcf_show_function(field, format_string, sz, ) \ 203 static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 204 show_fcoe_fcf_device_##field, NULL) 205 206 #define fcoe_fcf_private_rd_attr(field, format_string, sz) \ 207 fcoe_fcf_private_show_function(field, format_string, sz, ) \ 208 static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 209 show_fcoe_fcf_device_##field, NULL) 210 211 #define fcoe_ctlr_private_rd_attr_cast(field, format_string, sz, cast) \ 212 fcoe_ctlr_private_show_function(field, format_string, sz, (cast)) \ 213 static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 214 show_fcoe_ctlr_device_##field, NULL) 215 216 #define fcoe_fcf_private_rd_attr_cast(field, format_string, sz, cast) \ 217 fcoe_fcf_private_show_function(field, format_string, sz, (cast)) \ 218 static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 219 show_fcoe_fcf_device_##field, NULL) 220 221 #define fcoe_enum_name_search(title, table_type, table) \ 222 static const char *get_fcoe_##title##_name(enum table_type table_key) \ 223 { \ 224 if (table_key < 0 || table_key >= ARRAY_SIZE(table)) \ 225 return NULL; \ 226 return table[table_key]; \ 227 } 228 229 static char *fip_conn_type_names[] = { 230 [ FIP_CONN_TYPE_UNKNOWN ] = "Unknown", 231 [ FIP_CONN_TYPE_FABRIC ] = "Fabric", 232 [ FIP_CONN_TYPE_VN2VN ] = "VN2VN", 233 }; 234 fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names) 235 236 static enum fip_conn_type fcoe_parse_mode(const char *buf) 237 { 238 int i; 239 240 for (i = 0; i < ARRAY_SIZE(fip_conn_type_names); i++) { 241 if (strcasecmp(buf, fip_conn_type_names[i]) == 0) 242 return i; 243 } 244 245 return FIP_CONN_TYPE_UNKNOWN; 246 } 247 248 static char *fcf_state_names[] = { 249 [ FCOE_FCF_STATE_UNKNOWN ] = "Unknown", 250 [ FCOE_FCF_STATE_DISCONNECTED ] = "Disconnected", 251 [ FCOE_FCF_STATE_CONNECTED ] = "Connected", 252 }; 253 fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names) 254 #define FCOE_FCF_STATE_MAX_NAMELEN 50 255 256 static ssize_t show_fcf_state(struct device *dev, 257 struct device_attribute *attr, 258 char *buf) 259 { 260 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 261 const char *name; 262 name = get_fcoe_fcf_state_name(fcf->state); 263 if (!name) 264 return -EINVAL; 265 return snprintf(buf, FCOE_FCF_STATE_MAX_NAMELEN, "%s\n", name); 266 } 267 static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL); 268 269 #define FCOE_MAX_MODENAME_LEN 20 270 static ssize_t show_ctlr_mode(struct device *dev, 271 struct device_attribute *attr, 272 char *buf) 273 { 274 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 275 const char *name; 276 277 name = get_fcoe_ctlr_mode_name(ctlr->mode); 278 if (!name) 279 return -EINVAL; 280 return snprintf(buf, FCOE_MAX_MODENAME_LEN, 281 "%s\n", name); 282 } 283 284 static ssize_t store_ctlr_mode(struct device *dev, 285 struct device_attribute *attr, 286 const char *buf, size_t count) 287 { 288 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 289 char mode[FCOE_MAX_MODENAME_LEN + 1]; 290 291 if (count > FCOE_MAX_MODENAME_LEN) 292 return -EINVAL; 293 294 strncpy(mode, buf, count); 295 296 if (mode[count - 1] == '\n') 297 mode[count - 1] = '\0'; 298 else 299 mode[count] = '\0'; 300 301 switch (ctlr->enabled) { 302 case FCOE_CTLR_ENABLED: 303 LIBFCOE_SYSFS_DBG(ctlr, "Cannot change mode when enabled.\n"); 304 return -EBUSY; 305 case FCOE_CTLR_DISABLED: 306 if (!ctlr->f->set_fcoe_ctlr_mode) { 307 LIBFCOE_SYSFS_DBG(ctlr, 308 "Mode change not supported by LLD.\n"); 309 return -ENOTSUPP; 310 } 311 312 ctlr->mode = fcoe_parse_mode(mode); 313 if (ctlr->mode == FIP_CONN_TYPE_UNKNOWN) { 314 LIBFCOE_SYSFS_DBG(ctlr, "Unknown mode %s provided.\n", 315 buf); 316 return -EINVAL; 317 } 318 319 ctlr->f->set_fcoe_ctlr_mode(ctlr); 320 LIBFCOE_SYSFS_DBG(ctlr, "Mode changed to %s.\n", buf); 321 322 return count; 323 case FCOE_CTLR_UNUSED: 324 default: 325 LIBFCOE_SYSFS_DBG(ctlr, "Mode change not supported.\n"); 326 return -ENOTSUPP; 327 }; 328 } 329 330 static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO | S_IWUSR, 331 show_ctlr_mode, store_ctlr_mode); 332 333 static ssize_t store_ctlr_enabled(struct device *dev, 334 struct device_attribute *attr, 335 const char *buf, size_t count) 336 { 337 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 338 bool enabled; 339 int rc; 340 341 if (*buf == '1') 342 enabled = true; 343 else if (*buf == '0') 344 enabled = false; 345 else 346 return -EINVAL; 347 348 switch (ctlr->enabled) { 349 case FCOE_CTLR_ENABLED: 350 if (enabled) 351 return count; 352 ctlr->enabled = FCOE_CTLR_DISABLED; 353 break; 354 case FCOE_CTLR_DISABLED: 355 if (!enabled) 356 return count; 357 ctlr->enabled = FCOE_CTLR_ENABLED; 358 break; 359 case FCOE_CTLR_UNUSED: 360 return -ENOTSUPP; 361 }; 362 363 rc = ctlr->f->set_fcoe_ctlr_enabled(ctlr); 364 if (rc) 365 return rc; 366 367 return count; 368 } 369 370 static char *ctlr_enabled_state_names[] = { 371 [ FCOE_CTLR_ENABLED ] = "1", 372 [ FCOE_CTLR_DISABLED ] = "0", 373 }; 374 fcoe_enum_name_search(ctlr_enabled_state, ctlr_enabled_state, 375 ctlr_enabled_state_names) 376 #define FCOE_CTLR_ENABLED_MAX_NAMELEN 50 377 378 static ssize_t show_ctlr_enabled_state(struct device *dev, 379 struct device_attribute *attr, 380 char *buf) 381 { 382 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 383 const char *name; 384 385 name = get_fcoe_ctlr_enabled_state_name(ctlr->enabled); 386 if (!name) 387 return -EINVAL; 388 return snprintf(buf, FCOE_CTLR_ENABLED_MAX_NAMELEN, 389 "%s\n", name); 390 } 391 392 static FCOE_DEVICE_ATTR(ctlr, enabled, S_IRUGO | S_IWUSR, 393 show_ctlr_enabled_state, 394 store_ctlr_enabled); 395 396 static ssize_t store_ctlr_fip_resp(struct device *dev, 397 struct device_attribute *attr, 398 const char *buf, size_t count) 399 { 400 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 401 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr); 402 403 mutex_lock(&fip->ctlr_mutex); 404 if ((buf[1] == '\0') || ((buf[1] == '\n') && (buf[2] == '\0'))) { 405 if (buf[0] == '1') { 406 fip->fip_resp = 1; 407 mutex_unlock(&fip->ctlr_mutex); 408 return count; 409 } 410 if (buf[0] == '0') { 411 fip->fip_resp = 0; 412 mutex_unlock(&fip->ctlr_mutex); 413 return count; 414 } 415 } 416 mutex_unlock(&fip->ctlr_mutex); 417 return -EINVAL; 418 } 419 420 static ssize_t show_ctlr_fip_resp(struct device *dev, 421 struct device_attribute *attr, 422 char *buf) 423 { 424 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 425 struct fcoe_ctlr *fip = fcoe_ctlr_device_priv(ctlr); 426 427 return sprintf(buf, "%d\n", fip->fip_resp ? 1 : 0); 428 } 429 430 static FCOE_DEVICE_ATTR(ctlr, fip_vlan_responder, S_IRUGO | S_IWUSR, 431 show_ctlr_fip_resp, 432 store_ctlr_fip_resp); 433 434 static ssize_t 435 fcoe_ctlr_var_store(u32 *var, const char *buf, size_t count) 436 { 437 int err; 438 unsigned long v; 439 440 err = kstrtoul(buf, 10, &v); 441 if (err || v > UINT_MAX) 442 return -EINVAL; 443 444 *var = v; 445 446 return count; 447 } 448 449 static ssize_t store_ctlr_r_a_tov(struct device *dev, 450 struct device_attribute *attr, 451 const char *buf, size_t count) 452 { 453 struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev); 454 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 455 456 if (ctlr_dev->enabled == FCOE_CTLR_ENABLED) 457 return -EBUSY; 458 if (ctlr_dev->enabled == FCOE_CTLR_DISABLED) 459 return fcoe_ctlr_var_store(&ctlr->lp->r_a_tov, buf, count); 460 return -ENOTSUPP; 461 } 462 463 static ssize_t show_ctlr_r_a_tov(struct device *dev, 464 struct device_attribute *attr, 465 char *buf) 466 { 467 struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev); 468 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 469 470 return sprintf(buf, "%d\n", ctlr->lp->r_a_tov); 471 } 472 473 static FCOE_DEVICE_ATTR(ctlr, r_a_tov, S_IRUGO | S_IWUSR, 474 show_ctlr_r_a_tov, store_ctlr_r_a_tov); 475 476 static ssize_t store_ctlr_e_d_tov(struct device *dev, 477 struct device_attribute *attr, 478 const char *buf, size_t count) 479 { 480 struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev); 481 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 482 483 if (ctlr_dev->enabled == FCOE_CTLR_ENABLED) 484 return -EBUSY; 485 if (ctlr_dev->enabled == FCOE_CTLR_DISABLED) 486 return fcoe_ctlr_var_store(&ctlr->lp->e_d_tov, buf, count); 487 return -ENOTSUPP; 488 } 489 490 static ssize_t show_ctlr_e_d_tov(struct device *dev, 491 struct device_attribute *attr, 492 char *buf) 493 { 494 struct fcoe_ctlr_device *ctlr_dev = dev_to_ctlr(dev); 495 struct fcoe_ctlr *ctlr = fcoe_ctlr_device_priv(ctlr_dev); 496 497 return sprintf(buf, "%d\n", ctlr->lp->e_d_tov); 498 } 499 500 static FCOE_DEVICE_ATTR(ctlr, e_d_tov, S_IRUGO | S_IWUSR, 501 show_ctlr_e_d_tov, store_ctlr_e_d_tov); 502 503 static ssize_t 504 store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev, 505 struct device_attribute *attr, 506 const char *buf, size_t count) 507 { 508 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 509 struct fcoe_fcf_device *fcf; 510 unsigned long val; 511 int rc; 512 513 rc = fcoe_str_to_dev_loss(buf, &val); 514 if (rc) 515 return rc; 516 517 fcoe_ctlr_fcf_dev_loss_tmo(ctlr) = val; 518 mutex_lock(&ctlr->lock); 519 list_for_each_entry(fcf, &ctlr->fcfs, peers) 520 fcoe_fcf_set_dev_loss_tmo(fcf, val); 521 mutex_unlock(&ctlr->lock); 522 return count; 523 } 524 fcoe_ctlr_private_show_function(fcf_dev_loss_tmo, "%d\n", 20, ); 525 static FCOE_DEVICE_ATTR(ctlr, fcf_dev_loss_tmo, S_IRUGO | S_IWUSR, 526 show_fcoe_ctlr_device_fcf_dev_loss_tmo, 527 store_private_fcoe_ctlr_fcf_dev_loss_tmo); 528 529 /* Link Error Status Block (LESB) */ 530 fcoe_ctlr_rd_attr(link_fail, "%u\n", 20); 531 fcoe_ctlr_rd_attr(vlink_fail, "%u\n", 20); 532 fcoe_ctlr_rd_attr(miss_fka, "%u\n", 20); 533 fcoe_ctlr_rd_attr(symb_err, "%u\n", 20); 534 fcoe_ctlr_rd_attr(err_block, "%u\n", 20); 535 fcoe_ctlr_rd_attr(fcs_error, "%u\n", 20); 536 537 fcoe_fcf_private_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 538 fcoe_fcf_private_rd_attr_cast(switch_name, "0x%llx\n", 20, unsigned long long); 539 fcoe_fcf_private_rd_attr(priority, "%u\n", 20); 540 fcoe_fcf_private_rd_attr(fc_map, "0x%x\n", 20); 541 fcoe_fcf_private_rd_attr(vfid, "%u\n", 20); 542 fcoe_fcf_private_rd_attr(mac, "%pM\n", 20); 543 fcoe_fcf_private_rd_attr(fka_period, "%u\n", 20); 544 fcoe_fcf_rd_attr(selected, "%u\n", 20); 545 fcoe_fcf_rd_attr(vlan_id, "%u\n", 20); 546 547 fcoe_fcf_private_show_function(dev_loss_tmo, "%d\n", 20, ) 548 static ssize_t 549 store_fcoe_fcf_dev_loss_tmo(struct device *dev, struct device_attribute *attr, 550 const char *buf, size_t count) 551 { 552 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 553 unsigned long val; 554 int rc; 555 556 rc = fcoe_str_to_dev_loss(buf, &val); 557 if (rc) 558 return rc; 559 560 rc = fcoe_fcf_set_dev_loss_tmo(fcf, val); 561 if (rc) 562 return rc; 563 return count; 564 } 565 static FCOE_DEVICE_ATTR(fcf, dev_loss_tmo, S_IRUGO | S_IWUSR, 566 show_fcoe_fcf_device_dev_loss_tmo, 567 store_fcoe_fcf_dev_loss_tmo); 568 569 static struct attribute *fcoe_ctlr_lesb_attrs[] = { 570 &device_attr_fcoe_ctlr_link_fail.attr, 571 &device_attr_fcoe_ctlr_vlink_fail.attr, 572 &device_attr_fcoe_ctlr_miss_fka.attr, 573 &device_attr_fcoe_ctlr_symb_err.attr, 574 &device_attr_fcoe_ctlr_err_block.attr, 575 &device_attr_fcoe_ctlr_fcs_error.attr, 576 NULL, 577 }; 578 579 static struct attribute_group fcoe_ctlr_lesb_attr_group = { 580 .name = "lesb", 581 .attrs = fcoe_ctlr_lesb_attrs, 582 }; 583 584 static struct attribute *fcoe_ctlr_attrs[] = { 585 &device_attr_fcoe_ctlr_fip_vlan_responder.attr, 586 &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr, 587 &device_attr_fcoe_ctlr_r_a_tov.attr, 588 &device_attr_fcoe_ctlr_e_d_tov.attr, 589 &device_attr_fcoe_ctlr_enabled.attr, 590 &device_attr_fcoe_ctlr_mode.attr, 591 NULL, 592 }; 593 594 static struct attribute_group fcoe_ctlr_attr_group = { 595 .attrs = fcoe_ctlr_attrs, 596 }; 597 598 static const struct attribute_group *fcoe_ctlr_attr_groups[] = { 599 &fcoe_ctlr_attr_group, 600 &fcoe_ctlr_lesb_attr_group, 601 NULL, 602 }; 603 604 static struct attribute *fcoe_fcf_attrs[] = { 605 &device_attr_fcoe_fcf_fabric_name.attr, 606 &device_attr_fcoe_fcf_switch_name.attr, 607 &device_attr_fcoe_fcf_dev_loss_tmo.attr, 608 &device_attr_fcoe_fcf_fc_map.attr, 609 &device_attr_fcoe_fcf_vfid.attr, 610 &device_attr_fcoe_fcf_mac.attr, 611 &device_attr_fcoe_fcf_priority.attr, 612 &device_attr_fcoe_fcf_fka_period.attr, 613 &device_attr_fcoe_fcf_state.attr, 614 &device_attr_fcoe_fcf_selected.attr, 615 &device_attr_fcoe_fcf_vlan_id.attr, 616 NULL 617 }; 618 619 static struct attribute_group fcoe_fcf_attr_group = { 620 .attrs = fcoe_fcf_attrs, 621 }; 622 623 static const struct attribute_group *fcoe_fcf_attr_groups[] = { 624 &fcoe_fcf_attr_group, 625 NULL, 626 }; 627 628 static struct bus_type fcoe_bus_type; 629 630 static int fcoe_bus_match(struct device *dev, 631 struct device_driver *drv) 632 { 633 if (dev->bus == &fcoe_bus_type) 634 return 1; 635 return 0; 636 } 637 638 /** 639 * fcoe_ctlr_device_release() - Release the FIP ctlr memory 640 * @dev: Pointer to the FIP ctlr's embedded device 641 * 642 * Called when the last FIP ctlr reference is released. 643 */ 644 static void fcoe_ctlr_device_release(struct device *dev) 645 { 646 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 647 kfree(ctlr); 648 } 649 650 /** 651 * fcoe_fcf_device_release() - Release the FIP fcf memory 652 * @dev: Pointer to the fcf's embedded device 653 * 654 * Called when the last FIP fcf reference is released. 655 */ 656 static void fcoe_fcf_device_release(struct device *dev) 657 { 658 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 659 kfree(fcf); 660 } 661 662 static const struct device_type fcoe_ctlr_device_type = { 663 .name = "fcoe_ctlr", 664 .groups = fcoe_ctlr_attr_groups, 665 .release = fcoe_ctlr_device_release, 666 }; 667 668 static const struct device_type fcoe_fcf_device_type = { 669 .name = "fcoe_fcf", 670 .groups = fcoe_fcf_attr_groups, 671 .release = fcoe_fcf_device_release, 672 }; 673 674 static ssize_t ctlr_create_store(struct bus_type *bus, const char *buf, 675 size_t count) 676 { 677 return fcoe_ctlr_create_store(bus, buf, count); 678 } 679 static BUS_ATTR_WO(ctlr_create); 680 681 static ssize_t ctlr_destroy_store(struct bus_type *bus, const char *buf, 682 size_t count) 683 { 684 return fcoe_ctlr_destroy_store(bus, buf, count); 685 } 686 static BUS_ATTR_WO(ctlr_destroy); 687 688 static struct attribute *fcoe_bus_attrs[] = { 689 &bus_attr_ctlr_create.attr, 690 &bus_attr_ctlr_destroy.attr, 691 NULL, 692 }; 693 ATTRIBUTE_GROUPS(fcoe_bus); 694 695 static struct bus_type fcoe_bus_type = { 696 .name = "fcoe", 697 .match = &fcoe_bus_match, 698 .bus_groups = fcoe_bus_groups, 699 }; 700 701 /** 702 * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue 703 * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed 704 */ 705 static void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr) 706 { 707 if (!fcoe_ctlr_work_q(ctlr)) { 708 printk(KERN_ERR 709 "ERROR: FIP Ctlr '%d' attempted to flush work, " 710 "when no workqueue created.\n", ctlr->id); 711 dump_stack(); 712 return; 713 } 714 715 flush_workqueue(fcoe_ctlr_work_q(ctlr)); 716 } 717 718 /** 719 * fcoe_ctlr_device_queue_work() - Schedule work for a FIP ctlr's workqueue 720 * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue 721 * @work: Work to queue for execution 722 * 723 * Return value: 724 * 1 on success / 0 already queued / < 0 for error 725 */ 726 static int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr, 727 struct work_struct *work) 728 { 729 if (unlikely(!fcoe_ctlr_work_q(ctlr))) { 730 printk(KERN_ERR 731 "ERROR: FIP Ctlr '%d' attempted to queue work, " 732 "when no workqueue created.\n", ctlr->id); 733 dump_stack(); 734 735 return -EINVAL; 736 } 737 738 return queue_work(fcoe_ctlr_work_q(ctlr), work); 739 } 740 741 /** 742 * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue 743 * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed 744 */ 745 static void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr) 746 { 747 if (!fcoe_ctlr_devloss_work_q(ctlr)) { 748 printk(KERN_ERR 749 "ERROR: FIP Ctlr '%d' attempted to flush work, " 750 "when no workqueue created.\n", ctlr->id); 751 dump_stack(); 752 return; 753 } 754 755 flush_workqueue(fcoe_ctlr_devloss_work_q(ctlr)); 756 } 757 758 /** 759 * fcoe_ctlr_device_queue_devloss_work() - Schedule work for a FIP ctlr's devloss workqueue 760 * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue 761 * @work: Work to queue for execution 762 * @delay: jiffies to delay the work queuing 763 * 764 * Return value: 765 * 1 on success / 0 already queued / < 0 for error 766 */ 767 static int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr, 768 struct delayed_work *work, 769 unsigned long delay) 770 { 771 if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) { 772 printk(KERN_ERR 773 "ERROR: FIP Ctlr '%d' attempted to queue work, " 774 "when no workqueue created.\n", ctlr->id); 775 dump_stack(); 776 777 return -EINVAL; 778 } 779 780 return queue_delayed_work(fcoe_ctlr_devloss_work_q(ctlr), work, delay); 781 } 782 783 static int fcoe_fcf_device_match(struct fcoe_fcf_device *new, 784 struct fcoe_fcf_device *old) 785 { 786 if (new->switch_name == old->switch_name && 787 new->fabric_name == old->fabric_name && 788 new->fc_map == old->fc_map && 789 ether_addr_equal(new->mac, old->mac)) 790 return 1; 791 return 0; 792 } 793 794 /** 795 * fcoe_ctlr_device_add() - Add a FIP ctlr to sysfs 796 * @parent: The parent device to which the fcoe_ctlr instance 797 * should be attached 798 * @f: The LLD's FCoE sysfs function template pointer 799 * @priv_size: Size to be allocated with the fcoe_ctlr_device for the LLD 800 * 801 * This routine allocates a FIP ctlr object with some additional memory 802 * for the LLD. The FIP ctlr is initialized, added to sysfs and then 803 * attributes are added to it. 804 */ 805 struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, 806 struct fcoe_sysfs_function_template *f, 807 int priv_size) 808 { 809 struct fcoe_ctlr_device *ctlr; 810 int error = 0; 811 812 ctlr = kzalloc(sizeof(struct fcoe_ctlr_device) + priv_size, 813 GFP_KERNEL); 814 if (!ctlr) 815 goto out; 816 817 ctlr->id = atomic_inc_return(&ctlr_num) - 1; 818 ctlr->f = f; 819 ctlr->mode = FIP_CONN_TYPE_FABRIC; 820 INIT_LIST_HEAD(&ctlr->fcfs); 821 mutex_init(&ctlr->lock); 822 ctlr->dev.parent = parent; 823 ctlr->dev.bus = &fcoe_bus_type; 824 ctlr->dev.type = &fcoe_ctlr_device_type; 825 826 ctlr->fcf_dev_loss_tmo = fcoe_fcf_dev_loss_tmo; 827 828 snprintf(ctlr->work_q_name, sizeof(ctlr->work_q_name), 829 "ctlr_wq_%d", ctlr->id); 830 ctlr->work_q = create_singlethread_workqueue( 831 ctlr->work_q_name); 832 if (!ctlr->work_q) 833 goto out_del; 834 835 snprintf(ctlr->devloss_work_q_name, 836 sizeof(ctlr->devloss_work_q_name), 837 "ctlr_dl_wq_%d", ctlr->id); 838 ctlr->devloss_work_q = create_singlethread_workqueue( 839 ctlr->devloss_work_q_name); 840 if (!ctlr->devloss_work_q) 841 goto out_del_q; 842 843 dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id); 844 error = device_register(&ctlr->dev); 845 if (error) 846 goto out_del_q2; 847 848 return ctlr; 849 850 out_del_q2: 851 destroy_workqueue(ctlr->devloss_work_q); 852 ctlr->devloss_work_q = NULL; 853 out_del_q: 854 destroy_workqueue(ctlr->work_q); 855 ctlr->work_q = NULL; 856 out_del: 857 kfree(ctlr); 858 out: 859 return NULL; 860 } 861 EXPORT_SYMBOL_GPL(fcoe_ctlr_device_add); 862 863 /** 864 * fcoe_ctlr_device_delete() - Delete a FIP ctlr and its subtree from sysfs 865 * @ctlr: A pointer to the ctlr to be deleted 866 * 867 * Deletes a FIP ctlr and any fcfs attached 868 * to it. Deleting fcfs will cause their childen 869 * to be deleted as well. 870 * 871 * The ctlr is detached from sysfs and it's resources 872 * are freed (work q), but the memory is not freed 873 * until its last reference is released. 874 * 875 * This routine expects no locks to be held before 876 * calling. 877 * 878 * TODO: Currently there are no callbacks to clean up LLD data 879 * for a fcoe_fcf_device. LLDs must keep this in mind as they need 880 * to clean up each of their LLD data for all fcoe_fcf_device before 881 * calling fcoe_ctlr_device_delete. 882 */ 883 void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *ctlr) 884 { 885 struct fcoe_fcf_device *fcf, *next; 886 /* Remove any attached fcfs */ 887 mutex_lock(&ctlr->lock); 888 list_for_each_entry_safe(fcf, next, 889 &ctlr->fcfs, peers) { 890 list_del(&fcf->peers); 891 fcf->state = FCOE_FCF_STATE_DELETED; 892 fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); 893 } 894 mutex_unlock(&ctlr->lock); 895 896 fcoe_ctlr_device_flush_work(ctlr); 897 898 destroy_workqueue(ctlr->devloss_work_q); 899 ctlr->devloss_work_q = NULL; 900 destroy_workqueue(ctlr->work_q); 901 ctlr->work_q = NULL; 902 903 device_unregister(&ctlr->dev); 904 } 905 EXPORT_SYMBOL_GPL(fcoe_ctlr_device_delete); 906 907 /** 908 * fcoe_fcf_device_final_delete() - Final delete routine 909 * @work: The FIP fcf's embedded work struct 910 * 911 * It is expected that the fcf has been removed from 912 * the FIP ctlr's list before calling this routine. 913 */ 914 static void fcoe_fcf_device_final_delete(struct work_struct *work) 915 { 916 struct fcoe_fcf_device *fcf = 917 container_of(work, struct fcoe_fcf_device, delete_work); 918 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 919 920 /* 921 * Cancel any outstanding timers. These should really exist 922 * only when rmmod'ing the LLDD and we're asking for 923 * immediate termination of the rports 924 */ 925 if (!cancel_delayed_work(&fcf->dev_loss_work)) 926 fcoe_ctlr_device_flush_devloss(ctlr); 927 928 device_unregister(&fcf->dev); 929 } 930 931 /** 932 * fip_timeout_deleted_fcf() - Delete a fcf when the devloss timer fires 933 * @work: The FIP fcf's embedded work struct 934 * 935 * Removes the fcf from the FIP ctlr's list of fcfs and 936 * queues the final deletion. 937 */ 938 static void fip_timeout_deleted_fcf(struct work_struct *work) 939 { 940 struct fcoe_fcf_device *fcf = 941 container_of(work, struct fcoe_fcf_device, dev_loss_work.work); 942 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 943 944 mutex_lock(&ctlr->lock); 945 946 /* 947 * If the fcf is deleted or reconnected before the timer 948 * fires the devloss queue will be flushed, but the state will 949 * either be CONNECTED or DELETED. If that is the case we 950 * cancel deleting the fcf. 951 */ 952 if (fcf->state != FCOE_FCF_STATE_DISCONNECTED) 953 goto out; 954 955 dev_printk(KERN_ERR, &fcf->dev, 956 "FIP fcf connection time out: removing fcf\n"); 957 958 list_del(&fcf->peers); 959 fcf->state = FCOE_FCF_STATE_DELETED; 960 fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); 961 962 out: 963 mutex_unlock(&ctlr->lock); 964 } 965 966 /** 967 * fcoe_fcf_device_delete() - Delete a FIP fcf 968 * @fcf: Pointer to the fcf which is to be deleted 969 * 970 * Queues the FIP fcf on the devloss workqueue 971 * 972 * Expects the ctlr_attrs mutex to be held for fcf 973 * state change. 974 */ 975 void fcoe_fcf_device_delete(struct fcoe_fcf_device *fcf) 976 { 977 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 978 int timeout = fcf->dev_loss_tmo; 979 980 if (fcf->state != FCOE_FCF_STATE_CONNECTED) 981 return; 982 983 fcf->state = FCOE_FCF_STATE_DISCONNECTED; 984 985 /* 986 * FCF will only be re-connected by the LLD calling 987 * fcoe_fcf_device_add, and it should be setting up 988 * priv then. 989 */ 990 fcf->priv = NULL; 991 992 fcoe_ctlr_device_queue_devloss_work(ctlr, &fcf->dev_loss_work, 993 timeout * HZ); 994 } 995 EXPORT_SYMBOL_GPL(fcoe_fcf_device_delete); 996 997 /** 998 * fcoe_fcf_device_add() - Add a FCoE sysfs fcoe_fcf_device to the system 999 * @ctlr: The fcoe_ctlr_device that will be the fcoe_fcf_device parent 1000 * @new_fcf: A temporary FCF used for lookups on the current list of fcfs 1001 * 1002 * Expects to be called with the ctlr->lock held 1003 */ 1004 struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr, 1005 struct fcoe_fcf_device *new_fcf) 1006 { 1007 struct fcoe_fcf_device *fcf; 1008 int error = 0; 1009 1010 list_for_each_entry(fcf, &ctlr->fcfs, peers) { 1011 if (fcoe_fcf_device_match(new_fcf, fcf)) { 1012 if (fcf->state == FCOE_FCF_STATE_CONNECTED) 1013 return fcf; 1014 1015 fcf->state = FCOE_FCF_STATE_CONNECTED; 1016 1017 if (!cancel_delayed_work(&fcf->dev_loss_work)) 1018 fcoe_ctlr_device_flush_devloss(ctlr); 1019 1020 return fcf; 1021 } 1022 } 1023 1024 fcf = kzalloc(sizeof(struct fcoe_fcf_device), GFP_ATOMIC); 1025 if (unlikely(!fcf)) 1026 goto out; 1027 1028 INIT_WORK(&fcf->delete_work, fcoe_fcf_device_final_delete); 1029 INIT_DELAYED_WORK(&fcf->dev_loss_work, fip_timeout_deleted_fcf); 1030 1031 fcf->dev.parent = &ctlr->dev; 1032 fcf->dev.bus = &fcoe_bus_type; 1033 fcf->dev.type = &fcoe_fcf_device_type; 1034 fcf->id = atomic_inc_return(&fcf_num) - 1; 1035 fcf->state = FCOE_FCF_STATE_UNKNOWN; 1036 1037 fcf->dev_loss_tmo = ctlr->fcf_dev_loss_tmo; 1038 1039 dev_set_name(&fcf->dev, "fcf_%d", fcf->id); 1040 1041 fcf->fabric_name = new_fcf->fabric_name; 1042 fcf->switch_name = new_fcf->switch_name; 1043 fcf->fc_map = new_fcf->fc_map; 1044 fcf->vfid = new_fcf->vfid; 1045 memcpy(fcf->mac, new_fcf->mac, ETH_ALEN); 1046 fcf->priority = new_fcf->priority; 1047 fcf->fka_period = new_fcf->fka_period; 1048 fcf->selected = new_fcf->selected; 1049 1050 error = device_register(&fcf->dev); 1051 if (error) 1052 goto out_del; 1053 1054 fcf->state = FCOE_FCF_STATE_CONNECTED; 1055 list_add_tail(&fcf->peers, &ctlr->fcfs); 1056 1057 return fcf; 1058 1059 out_del: 1060 kfree(fcf); 1061 out: 1062 return NULL; 1063 } 1064 EXPORT_SYMBOL_GPL(fcoe_fcf_device_add); 1065 1066 int __init fcoe_sysfs_setup(void) 1067 { 1068 int error; 1069 1070 atomic_set(&ctlr_num, 0); 1071 atomic_set(&fcf_num, 0); 1072 1073 error = bus_register(&fcoe_bus_type); 1074 if (error) 1075 return error; 1076 1077 return 0; 1078 } 1079 1080 void __exit fcoe_sysfs_teardown(void) 1081 { 1082 bus_unregister(&fcoe_bus_type); 1083 } 1084