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 25 #include <scsi/fcoe_sysfs.h> 26 27 static atomic_t ctlr_num; 28 static atomic_t fcf_num; 29 30 /* 31 * fcoe_fcf_dev_loss_tmo: the default number of seconds that fcoe sysfs 32 * should insulate the loss of a fcf. 33 */ 34 static unsigned int fcoe_fcf_dev_loss_tmo = 1800; /* seconds */ 35 36 module_param_named(fcf_dev_loss_tmo, fcoe_fcf_dev_loss_tmo, 37 uint, S_IRUGO|S_IWUSR); 38 MODULE_PARM_DESC(fcf_dev_loss_tmo, 39 "Maximum number of seconds that libfcoe should" 40 " insulate the loss of a fcf. Once this value is" 41 " exceeded, the fcf is removed."); 42 43 /* 44 * These are used by the fcoe_*_show_function routines, they 45 * are intentionally placed in the .c file as they're not intended 46 * for use throughout the code. 47 */ 48 #define fcoe_ctlr_id(x) \ 49 ((x)->id) 50 #define fcoe_ctlr_work_q_name(x) \ 51 ((x)->work_q_name) 52 #define fcoe_ctlr_work_q(x) \ 53 ((x)->work_q) 54 #define fcoe_ctlr_devloss_work_q_name(x) \ 55 ((x)->devloss_work_q_name) 56 #define fcoe_ctlr_devloss_work_q(x) \ 57 ((x)->devloss_work_q) 58 #define fcoe_ctlr_mode(x) \ 59 ((x)->mode) 60 #define fcoe_ctlr_fcf_dev_loss_tmo(x) \ 61 ((x)->fcf_dev_loss_tmo) 62 #define fcoe_ctlr_link_fail(x) \ 63 ((x)->lesb.lesb_link_fail) 64 #define fcoe_ctlr_vlink_fail(x) \ 65 ((x)->lesb.lesb_vlink_fail) 66 #define fcoe_ctlr_miss_fka(x) \ 67 ((x)->lesb.lesb_miss_fka) 68 #define fcoe_ctlr_symb_err(x) \ 69 ((x)->lesb.lesb_symb_err) 70 #define fcoe_ctlr_err_block(x) \ 71 ((x)->lesb.lesb_err_block) 72 #define fcoe_ctlr_fcs_error(x) \ 73 ((x)->lesb.lesb_fcs_error) 74 #define fcoe_fcf_state(x) \ 75 ((x)->state) 76 #define fcoe_fcf_fabric_name(x) \ 77 ((x)->fabric_name) 78 #define fcoe_fcf_switch_name(x) \ 79 ((x)->switch_name) 80 #define fcoe_fcf_fc_map(x) \ 81 ((x)->fc_map) 82 #define fcoe_fcf_vfid(x) \ 83 ((x)->vfid) 84 #define fcoe_fcf_mac(x) \ 85 ((x)->mac) 86 #define fcoe_fcf_priority(x) \ 87 ((x)->priority) 88 #define fcoe_fcf_fka_period(x) \ 89 ((x)->fka_period) 90 #define fcoe_fcf_dev_loss_tmo(x) \ 91 ((x)->dev_loss_tmo) 92 #define fcoe_fcf_selected(x) \ 93 ((x)->selected) 94 #define fcoe_fcf_vlan_id(x) \ 95 ((x)->vlan_id) 96 97 /* 98 * dev_loss_tmo attribute 99 */ 100 static int fcoe_str_to_dev_loss(const char *buf, unsigned long *val) 101 { 102 int ret; 103 104 ret = kstrtoul(buf, 0, val); 105 if (ret) 106 return -EINVAL; 107 /* 108 * Check for overflow; dev_loss_tmo is u32 109 */ 110 if (*val > UINT_MAX) 111 return -EINVAL; 112 113 return 0; 114 } 115 116 static int fcoe_fcf_set_dev_loss_tmo(struct fcoe_fcf_device *fcf, 117 unsigned long val) 118 { 119 if ((fcf->state == FCOE_FCF_STATE_UNKNOWN) || 120 (fcf->state == FCOE_FCF_STATE_DISCONNECTED) || 121 (fcf->state == FCOE_FCF_STATE_DELETED)) 122 return -EBUSY; 123 /* 124 * Check for overflow; dev_loss_tmo is u32 125 */ 126 if (val > UINT_MAX) 127 return -EINVAL; 128 129 fcoe_fcf_dev_loss_tmo(fcf) = val; 130 return 0; 131 } 132 133 #define FCOE_DEVICE_ATTR(_prefix, _name, _mode, _show, _store) \ 134 struct device_attribute device_attr_fcoe_##_prefix##_##_name = \ 135 __ATTR(_name, _mode, _show, _store) 136 137 #define fcoe_ctlr_show_function(field, format_string, sz, cast) \ 138 static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ 139 struct device_attribute *attr, \ 140 char *buf) \ 141 { \ 142 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ 143 if (ctlr->f->get_fcoe_ctlr_##field) \ 144 ctlr->f->get_fcoe_ctlr_##field(ctlr); \ 145 return snprintf(buf, sz, format_string, \ 146 cast fcoe_ctlr_##field(ctlr)); \ 147 } 148 149 #define fcoe_fcf_show_function(field, format_string, sz, cast) \ 150 static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ 151 struct device_attribute *attr, \ 152 char *buf) \ 153 { \ 154 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ 155 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); \ 156 if (ctlr->f->get_fcoe_fcf_##field) \ 157 ctlr->f->get_fcoe_fcf_##field(fcf); \ 158 return snprintf(buf, sz, format_string, \ 159 cast fcoe_fcf_##field(fcf)); \ 160 } 161 162 #define fcoe_ctlr_private_show_function(field, format_string, sz, cast) \ 163 static ssize_t show_fcoe_ctlr_device_##field(struct device *dev, \ 164 struct device_attribute *attr, \ 165 char *buf) \ 166 { \ 167 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); \ 168 return snprintf(buf, sz, format_string, cast fcoe_ctlr_##field(ctlr)); \ 169 } 170 171 #define fcoe_fcf_private_show_function(field, format_string, sz, cast) \ 172 static ssize_t show_fcoe_fcf_device_##field(struct device *dev, \ 173 struct device_attribute *attr, \ 174 char *buf) \ 175 { \ 176 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); \ 177 return snprintf(buf, sz, format_string, cast fcoe_fcf_##field(fcf)); \ 178 } 179 180 #define fcoe_ctlr_private_rd_attr(field, format_string, sz) \ 181 fcoe_ctlr_private_show_function(field, format_string, sz, ) \ 182 static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 183 show_fcoe_ctlr_device_##field, NULL) 184 185 #define fcoe_ctlr_rd_attr(field, format_string, sz) \ 186 fcoe_ctlr_show_function(field, format_string, sz, ) \ 187 static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 188 show_fcoe_ctlr_device_##field, NULL) 189 190 #define fcoe_fcf_rd_attr(field, format_string, sz) \ 191 fcoe_fcf_show_function(field, format_string, sz, ) \ 192 static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 193 show_fcoe_fcf_device_##field, NULL) 194 195 #define fcoe_fcf_private_rd_attr(field, format_string, sz) \ 196 fcoe_fcf_private_show_function(field, format_string, sz, ) \ 197 static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 198 show_fcoe_fcf_device_##field, NULL) 199 200 #define fcoe_ctlr_private_rd_attr_cast(field, format_string, sz, cast) \ 201 fcoe_ctlr_private_show_function(field, format_string, sz, (cast)) \ 202 static FCOE_DEVICE_ATTR(ctlr, field, S_IRUGO, \ 203 show_fcoe_ctlr_device_##field, NULL) 204 205 #define fcoe_fcf_private_rd_attr_cast(field, format_string, sz, cast) \ 206 fcoe_fcf_private_show_function(field, format_string, sz, (cast)) \ 207 static FCOE_DEVICE_ATTR(fcf, field, S_IRUGO, \ 208 show_fcoe_fcf_device_##field, NULL) 209 210 #define fcoe_enum_name_search(title, table_type, table) \ 211 static const char *get_fcoe_##title##_name(enum table_type table_key) \ 212 { \ 213 int i; \ 214 char *name = NULL; \ 215 \ 216 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 217 if (table[i].value == table_key) { \ 218 name = table[i].name; \ 219 break; \ 220 } \ 221 } \ 222 return name; \ 223 } 224 225 static struct { 226 enum fcf_state value; 227 char *name; 228 } fcf_state_names[] = { 229 { FCOE_FCF_STATE_UNKNOWN, "Unknown" }, 230 { FCOE_FCF_STATE_DISCONNECTED, "Disconnected" }, 231 { FCOE_FCF_STATE_CONNECTED, "Connected" }, 232 }; 233 fcoe_enum_name_search(fcf_state, fcf_state, fcf_state_names) 234 #define FCOE_FCF_STATE_MAX_NAMELEN 50 235 236 static ssize_t show_fcf_state(struct device *dev, 237 struct device_attribute *attr, 238 char *buf) 239 { 240 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 241 const char *name; 242 name = get_fcoe_fcf_state_name(fcf->state); 243 if (!name) 244 return -EINVAL; 245 return snprintf(buf, FCOE_FCF_STATE_MAX_NAMELEN, "%s\n", name); 246 } 247 static FCOE_DEVICE_ATTR(fcf, state, S_IRUGO, show_fcf_state, NULL); 248 249 static struct { 250 enum fip_conn_type value; 251 char *name; 252 } fip_conn_type_names[] = { 253 { FIP_CONN_TYPE_UNKNOWN, "Unknown" }, 254 { FIP_CONN_TYPE_FABRIC, "Fabric" }, 255 { FIP_CONN_TYPE_VN2VN, "VN2VN" }, 256 }; 257 fcoe_enum_name_search(ctlr_mode, fip_conn_type, fip_conn_type_names) 258 #define FCOE_CTLR_MODE_MAX_NAMELEN 50 259 260 static ssize_t show_ctlr_mode(struct device *dev, 261 struct device_attribute *attr, 262 char *buf) 263 { 264 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 265 const char *name; 266 267 if (ctlr->f->get_fcoe_ctlr_mode) 268 ctlr->f->get_fcoe_ctlr_mode(ctlr); 269 270 name = get_fcoe_ctlr_mode_name(ctlr->mode); 271 if (!name) 272 return -EINVAL; 273 return snprintf(buf, FCOE_CTLR_MODE_MAX_NAMELEN, 274 "%s\n", name); 275 } 276 static FCOE_DEVICE_ATTR(ctlr, mode, S_IRUGO, 277 show_ctlr_mode, NULL); 278 279 static ssize_t 280 store_private_fcoe_ctlr_fcf_dev_loss_tmo(struct device *dev, 281 struct device_attribute *attr, 282 const char *buf, size_t count) 283 { 284 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 285 struct fcoe_fcf_device *fcf; 286 unsigned long val; 287 int rc; 288 289 rc = fcoe_str_to_dev_loss(buf, &val); 290 if (rc) 291 return rc; 292 293 fcoe_ctlr_fcf_dev_loss_tmo(ctlr) = val; 294 mutex_lock(&ctlr->lock); 295 list_for_each_entry(fcf, &ctlr->fcfs, peers) 296 fcoe_fcf_set_dev_loss_tmo(fcf, val); 297 mutex_unlock(&ctlr->lock); 298 return count; 299 } 300 fcoe_ctlr_private_show_function(fcf_dev_loss_tmo, "%d\n", 20, ); 301 static FCOE_DEVICE_ATTR(ctlr, fcf_dev_loss_tmo, S_IRUGO | S_IWUSR, 302 show_fcoe_ctlr_device_fcf_dev_loss_tmo, 303 store_private_fcoe_ctlr_fcf_dev_loss_tmo); 304 305 /* Link Error Status Block (LESB) */ 306 fcoe_ctlr_rd_attr(link_fail, "%u\n", 20); 307 fcoe_ctlr_rd_attr(vlink_fail, "%u\n", 20); 308 fcoe_ctlr_rd_attr(miss_fka, "%u\n", 20); 309 fcoe_ctlr_rd_attr(symb_err, "%u\n", 20); 310 fcoe_ctlr_rd_attr(err_block, "%u\n", 20); 311 fcoe_ctlr_rd_attr(fcs_error, "%u\n", 20); 312 313 fcoe_fcf_private_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 314 fcoe_fcf_private_rd_attr_cast(switch_name, "0x%llx\n", 20, unsigned long long); 315 fcoe_fcf_private_rd_attr(priority, "%u\n", 20); 316 fcoe_fcf_private_rd_attr(fc_map, "0x%x\n", 20); 317 fcoe_fcf_private_rd_attr(vfid, "%u\n", 20); 318 fcoe_fcf_private_rd_attr(mac, "%pM\n", 20); 319 fcoe_fcf_private_rd_attr(fka_period, "%u\n", 20); 320 fcoe_fcf_rd_attr(selected, "%u\n", 20); 321 fcoe_fcf_rd_attr(vlan_id, "%u\n", 20); 322 323 fcoe_fcf_private_show_function(dev_loss_tmo, "%d\n", 20, ) 324 static ssize_t 325 store_fcoe_fcf_dev_loss_tmo(struct device *dev, struct device_attribute *attr, 326 const char *buf, size_t count) 327 { 328 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 329 unsigned long val; 330 int rc; 331 332 rc = fcoe_str_to_dev_loss(buf, &val); 333 if (rc) 334 return rc; 335 336 rc = fcoe_fcf_set_dev_loss_tmo(fcf, val); 337 if (rc) 338 return rc; 339 return count; 340 } 341 static FCOE_DEVICE_ATTR(fcf, dev_loss_tmo, S_IRUGO | S_IWUSR, 342 show_fcoe_fcf_device_dev_loss_tmo, 343 store_fcoe_fcf_dev_loss_tmo); 344 345 static struct attribute *fcoe_ctlr_lesb_attrs[] = { 346 &device_attr_fcoe_ctlr_link_fail.attr, 347 &device_attr_fcoe_ctlr_vlink_fail.attr, 348 &device_attr_fcoe_ctlr_miss_fka.attr, 349 &device_attr_fcoe_ctlr_symb_err.attr, 350 &device_attr_fcoe_ctlr_err_block.attr, 351 &device_attr_fcoe_ctlr_fcs_error.attr, 352 NULL, 353 }; 354 355 static struct attribute_group fcoe_ctlr_lesb_attr_group = { 356 .name = "lesb", 357 .attrs = fcoe_ctlr_lesb_attrs, 358 }; 359 360 static struct attribute *fcoe_ctlr_attrs[] = { 361 &device_attr_fcoe_ctlr_fcf_dev_loss_tmo.attr, 362 &device_attr_fcoe_ctlr_mode.attr, 363 NULL, 364 }; 365 366 static struct attribute_group fcoe_ctlr_attr_group = { 367 .attrs = fcoe_ctlr_attrs, 368 }; 369 370 static const struct attribute_group *fcoe_ctlr_attr_groups[] = { 371 &fcoe_ctlr_attr_group, 372 &fcoe_ctlr_lesb_attr_group, 373 NULL, 374 }; 375 376 static struct attribute *fcoe_fcf_attrs[] = { 377 &device_attr_fcoe_fcf_fabric_name.attr, 378 &device_attr_fcoe_fcf_switch_name.attr, 379 &device_attr_fcoe_fcf_dev_loss_tmo.attr, 380 &device_attr_fcoe_fcf_fc_map.attr, 381 &device_attr_fcoe_fcf_vfid.attr, 382 &device_attr_fcoe_fcf_mac.attr, 383 &device_attr_fcoe_fcf_priority.attr, 384 &device_attr_fcoe_fcf_fka_period.attr, 385 &device_attr_fcoe_fcf_state.attr, 386 &device_attr_fcoe_fcf_selected.attr, 387 &device_attr_fcoe_fcf_vlan_id.attr, 388 NULL 389 }; 390 391 static struct attribute_group fcoe_fcf_attr_group = { 392 .attrs = fcoe_fcf_attrs, 393 }; 394 395 static const struct attribute_group *fcoe_fcf_attr_groups[] = { 396 &fcoe_fcf_attr_group, 397 NULL, 398 }; 399 400 struct bus_type fcoe_bus_type; 401 402 static int fcoe_bus_match(struct device *dev, 403 struct device_driver *drv) 404 { 405 if (dev->bus == &fcoe_bus_type) 406 return 1; 407 return 0; 408 } 409 410 /** 411 * fcoe_ctlr_device_release() - Release the FIP ctlr memory 412 * @dev: Pointer to the FIP ctlr's embedded device 413 * 414 * Called when the last FIP ctlr reference is released. 415 */ 416 static void fcoe_ctlr_device_release(struct device *dev) 417 { 418 struct fcoe_ctlr_device *ctlr = dev_to_ctlr(dev); 419 kfree(ctlr); 420 } 421 422 /** 423 * fcoe_fcf_device_release() - Release the FIP fcf memory 424 * @dev: Pointer to the fcf's embedded device 425 * 426 * Called when the last FIP fcf reference is released. 427 */ 428 static void fcoe_fcf_device_release(struct device *dev) 429 { 430 struct fcoe_fcf_device *fcf = dev_to_fcf(dev); 431 kfree(fcf); 432 } 433 434 struct device_type fcoe_ctlr_device_type = { 435 .name = "fcoe_ctlr", 436 .groups = fcoe_ctlr_attr_groups, 437 .release = fcoe_ctlr_device_release, 438 }; 439 440 struct device_type fcoe_fcf_device_type = { 441 .name = "fcoe_fcf", 442 .groups = fcoe_fcf_attr_groups, 443 .release = fcoe_fcf_device_release, 444 }; 445 446 struct bus_type fcoe_bus_type = { 447 .name = "fcoe", 448 .match = &fcoe_bus_match, 449 }; 450 451 /** 452 * fcoe_ctlr_device_flush_work() - Flush a FIP ctlr's workqueue 453 * @ctlr: Pointer to the FIP ctlr whose workqueue is to be flushed 454 */ 455 void fcoe_ctlr_device_flush_work(struct fcoe_ctlr_device *ctlr) 456 { 457 if (!fcoe_ctlr_work_q(ctlr)) { 458 printk(KERN_ERR 459 "ERROR: FIP Ctlr '%d' attempted to flush work, " 460 "when no workqueue created.\n", ctlr->id); 461 dump_stack(); 462 return; 463 } 464 465 flush_workqueue(fcoe_ctlr_work_q(ctlr)); 466 } 467 468 /** 469 * fcoe_ctlr_device_queue_work() - Schedule work for a FIP ctlr's workqueue 470 * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue 471 * @work: Work to queue for execution 472 * 473 * Return value: 474 * 1 on success / 0 already queued / < 0 for error 475 */ 476 int fcoe_ctlr_device_queue_work(struct fcoe_ctlr_device *ctlr, 477 struct work_struct *work) 478 { 479 if (unlikely(!fcoe_ctlr_work_q(ctlr))) { 480 printk(KERN_ERR 481 "ERROR: FIP Ctlr '%d' attempted to queue work, " 482 "when no workqueue created.\n", ctlr->id); 483 dump_stack(); 484 485 return -EINVAL; 486 } 487 488 return queue_work(fcoe_ctlr_work_q(ctlr), work); 489 } 490 491 /** 492 * fcoe_ctlr_device_flush_devloss() - Flush a FIP ctlr's devloss workqueue 493 * @ctlr: Pointer to FIP ctlr whose workqueue is to be flushed 494 */ 495 void fcoe_ctlr_device_flush_devloss(struct fcoe_ctlr_device *ctlr) 496 { 497 if (!fcoe_ctlr_devloss_work_q(ctlr)) { 498 printk(KERN_ERR 499 "ERROR: FIP Ctlr '%d' attempted to flush work, " 500 "when no workqueue created.\n", ctlr->id); 501 dump_stack(); 502 return; 503 } 504 505 flush_workqueue(fcoe_ctlr_devloss_work_q(ctlr)); 506 } 507 508 /** 509 * fcoe_ctlr_device_queue_devloss_work() - Schedule work for a FIP ctlr's devloss workqueue 510 * @ctlr: Pointer to the FIP ctlr who owns the devloss workqueue 511 * @work: Work to queue for execution 512 * @delay: jiffies to delay the work queuing 513 * 514 * Return value: 515 * 1 on success / 0 already queued / < 0 for error 516 */ 517 int fcoe_ctlr_device_queue_devloss_work(struct fcoe_ctlr_device *ctlr, 518 struct delayed_work *work, 519 unsigned long delay) 520 { 521 if (unlikely(!fcoe_ctlr_devloss_work_q(ctlr))) { 522 printk(KERN_ERR 523 "ERROR: FIP Ctlr '%d' attempted to queue work, " 524 "when no workqueue created.\n", ctlr->id); 525 dump_stack(); 526 527 return -EINVAL; 528 } 529 530 return queue_delayed_work(fcoe_ctlr_devloss_work_q(ctlr), work, delay); 531 } 532 533 static int fcoe_fcf_device_match(struct fcoe_fcf_device *new, 534 struct fcoe_fcf_device *old) 535 { 536 if (new->switch_name == old->switch_name && 537 new->fabric_name == old->fabric_name && 538 new->fc_map == old->fc_map && 539 compare_ether_addr(new->mac, old->mac) == 0) 540 return 1; 541 return 0; 542 } 543 544 /** 545 * fcoe_ctlr_device_add() - Add a FIP ctlr to sysfs 546 * @parent: The parent device to which the fcoe_ctlr instance 547 * should be attached 548 * @f: The LLD's FCoE sysfs function template pointer 549 * @priv_size: Size to be allocated with the fcoe_ctlr_device for the LLD 550 * 551 * This routine allocates a FIP ctlr object with some additional memory 552 * for the LLD. The FIP ctlr is initialized, added to sysfs and then 553 * attributes are added to it. 554 */ 555 struct fcoe_ctlr_device *fcoe_ctlr_device_add(struct device *parent, 556 struct fcoe_sysfs_function_template *f, 557 int priv_size) 558 { 559 struct fcoe_ctlr_device *ctlr; 560 int error = 0; 561 562 ctlr = kzalloc(sizeof(struct fcoe_ctlr_device) + priv_size, 563 GFP_KERNEL); 564 if (!ctlr) 565 goto out; 566 567 ctlr->id = atomic_inc_return(&ctlr_num) - 1; 568 ctlr->f = f; 569 INIT_LIST_HEAD(&ctlr->fcfs); 570 mutex_init(&ctlr->lock); 571 ctlr->dev.parent = parent; 572 ctlr->dev.bus = &fcoe_bus_type; 573 ctlr->dev.type = &fcoe_ctlr_device_type; 574 575 ctlr->fcf_dev_loss_tmo = fcoe_fcf_dev_loss_tmo; 576 577 snprintf(ctlr->work_q_name, sizeof(ctlr->work_q_name), 578 "ctlr_wq_%d", ctlr->id); 579 ctlr->work_q = create_singlethread_workqueue( 580 ctlr->work_q_name); 581 if (!ctlr->work_q) 582 goto out_del; 583 584 snprintf(ctlr->devloss_work_q_name, 585 sizeof(ctlr->devloss_work_q_name), 586 "ctlr_dl_wq_%d", ctlr->id); 587 ctlr->devloss_work_q = create_singlethread_workqueue( 588 ctlr->devloss_work_q_name); 589 if (!ctlr->devloss_work_q) 590 goto out_del_q; 591 592 dev_set_name(&ctlr->dev, "ctlr_%d", ctlr->id); 593 error = device_register(&ctlr->dev); 594 if (error) 595 goto out_del_q2; 596 597 return ctlr; 598 599 out_del_q2: 600 destroy_workqueue(ctlr->devloss_work_q); 601 ctlr->devloss_work_q = NULL; 602 out_del_q: 603 destroy_workqueue(ctlr->work_q); 604 ctlr->work_q = NULL; 605 out_del: 606 kfree(ctlr); 607 out: 608 return NULL; 609 } 610 EXPORT_SYMBOL_GPL(fcoe_ctlr_device_add); 611 612 /** 613 * fcoe_ctlr_device_delete() - Delete a FIP ctlr and its subtree from sysfs 614 * @ctlr: A pointer to the ctlr to be deleted 615 * 616 * Deletes a FIP ctlr and any fcfs attached 617 * to it. Deleting fcfs will cause their childen 618 * to be deleted as well. 619 * 620 * The ctlr is detached from sysfs and it's resources 621 * are freed (work q), but the memory is not freed 622 * until its last reference is released. 623 * 624 * This routine expects no locks to be held before 625 * calling. 626 * 627 * TODO: Currently there are no callbacks to clean up LLD data 628 * for a fcoe_fcf_device. LLDs must keep this in mind as they need 629 * to clean up each of their LLD data for all fcoe_fcf_device before 630 * calling fcoe_ctlr_device_delete. 631 */ 632 void fcoe_ctlr_device_delete(struct fcoe_ctlr_device *ctlr) 633 { 634 struct fcoe_fcf_device *fcf, *next; 635 /* Remove any attached fcfs */ 636 mutex_lock(&ctlr->lock); 637 list_for_each_entry_safe(fcf, next, 638 &ctlr->fcfs, peers) { 639 list_del(&fcf->peers); 640 fcf->state = FCOE_FCF_STATE_DELETED; 641 fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); 642 } 643 mutex_unlock(&ctlr->lock); 644 645 fcoe_ctlr_device_flush_work(ctlr); 646 647 destroy_workqueue(ctlr->devloss_work_q); 648 ctlr->devloss_work_q = NULL; 649 destroy_workqueue(ctlr->work_q); 650 ctlr->work_q = NULL; 651 652 device_unregister(&ctlr->dev); 653 } 654 EXPORT_SYMBOL_GPL(fcoe_ctlr_device_delete); 655 656 /** 657 * fcoe_fcf_device_final_delete() - Final delete routine 658 * @work: The FIP fcf's embedded work struct 659 * 660 * It is expected that the fcf has been removed from 661 * the FIP ctlr's list before calling this routine. 662 */ 663 static void fcoe_fcf_device_final_delete(struct work_struct *work) 664 { 665 struct fcoe_fcf_device *fcf = 666 container_of(work, struct fcoe_fcf_device, delete_work); 667 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 668 669 /* 670 * Cancel any outstanding timers. These should really exist 671 * only when rmmod'ing the LLDD and we're asking for 672 * immediate termination of the rports 673 */ 674 if (!cancel_delayed_work(&fcf->dev_loss_work)) 675 fcoe_ctlr_device_flush_devloss(ctlr); 676 677 device_unregister(&fcf->dev); 678 } 679 680 /** 681 * fip_timeout_deleted_fcf() - Delete a fcf when the devloss timer fires 682 * @work: The FIP fcf's embedded work struct 683 * 684 * Removes the fcf from the FIP ctlr's list of fcfs and 685 * queues the final deletion. 686 */ 687 static void fip_timeout_deleted_fcf(struct work_struct *work) 688 { 689 struct fcoe_fcf_device *fcf = 690 container_of(work, struct fcoe_fcf_device, dev_loss_work.work); 691 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 692 693 mutex_lock(&ctlr->lock); 694 695 /* 696 * If the fcf is deleted or reconnected before the timer 697 * fires the devloss queue will be flushed, but the state will 698 * either be CONNECTED or DELETED. If that is the case we 699 * cancel deleting the fcf. 700 */ 701 if (fcf->state != FCOE_FCF_STATE_DISCONNECTED) 702 goto out; 703 704 dev_printk(KERN_ERR, &fcf->dev, 705 "FIP fcf connection time out: removing fcf\n"); 706 707 list_del(&fcf->peers); 708 fcf->state = FCOE_FCF_STATE_DELETED; 709 fcoe_ctlr_device_queue_work(ctlr, &fcf->delete_work); 710 711 out: 712 mutex_unlock(&ctlr->lock); 713 } 714 715 /** 716 * fcoe_fcf_device_delete() - Delete a FIP fcf 717 * @fcf: Pointer to the fcf which is to be deleted 718 * 719 * Queues the FIP fcf on the devloss workqueue 720 * 721 * Expects the ctlr_attrs mutex to be held for fcf 722 * state change. 723 */ 724 void fcoe_fcf_device_delete(struct fcoe_fcf_device *fcf) 725 { 726 struct fcoe_ctlr_device *ctlr = fcoe_fcf_dev_to_ctlr_dev(fcf); 727 int timeout = fcf->dev_loss_tmo; 728 729 if (fcf->state != FCOE_FCF_STATE_CONNECTED) 730 return; 731 732 fcf->state = FCOE_FCF_STATE_DISCONNECTED; 733 734 /* 735 * FCF will only be re-connected by the LLD calling 736 * fcoe_fcf_device_add, and it should be setting up 737 * priv then. 738 */ 739 fcf->priv = NULL; 740 741 fcoe_ctlr_device_queue_devloss_work(ctlr, &fcf->dev_loss_work, 742 timeout * HZ); 743 } 744 EXPORT_SYMBOL_GPL(fcoe_fcf_device_delete); 745 746 /** 747 * fcoe_fcf_device_add() - Add a FCoE sysfs fcoe_fcf_device to the system 748 * @ctlr: The fcoe_ctlr_device that will be the fcoe_fcf_device parent 749 * @new_fcf: A temporary FCF used for lookups on the current list of fcfs 750 * 751 * Expects to be called with the ctlr->lock held 752 */ 753 struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr, 754 struct fcoe_fcf_device *new_fcf) 755 { 756 struct fcoe_fcf_device *fcf; 757 int error = 0; 758 759 list_for_each_entry(fcf, &ctlr->fcfs, peers) { 760 if (fcoe_fcf_device_match(new_fcf, fcf)) { 761 if (fcf->state == FCOE_FCF_STATE_CONNECTED) 762 return fcf; 763 764 fcf->state = FCOE_FCF_STATE_CONNECTED; 765 766 if (!cancel_delayed_work(&fcf->dev_loss_work)) 767 fcoe_ctlr_device_flush_devloss(ctlr); 768 769 return fcf; 770 } 771 } 772 773 fcf = kzalloc(sizeof(struct fcoe_fcf_device), GFP_ATOMIC); 774 if (unlikely(!fcf)) 775 goto out; 776 777 INIT_WORK(&fcf->delete_work, fcoe_fcf_device_final_delete); 778 INIT_DELAYED_WORK(&fcf->dev_loss_work, fip_timeout_deleted_fcf); 779 780 fcf->dev.parent = &ctlr->dev; 781 fcf->dev.bus = &fcoe_bus_type; 782 fcf->dev.type = &fcoe_fcf_device_type; 783 fcf->id = atomic_inc_return(&fcf_num) - 1; 784 fcf->state = FCOE_FCF_STATE_UNKNOWN; 785 786 fcf->dev_loss_tmo = ctlr->fcf_dev_loss_tmo; 787 788 dev_set_name(&fcf->dev, "fcf_%d", fcf->id); 789 790 fcf->fabric_name = new_fcf->fabric_name; 791 fcf->switch_name = new_fcf->switch_name; 792 fcf->fc_map = new_fcf->fc_map; 793 fcf->vfid = new_fcf->vfid; 794 memcpy(fcf->mac, new_fcf->mac, ETH_ALEN); 795 fcf->priority = new_fcf->priority; 796 fcf->fka_period = new_fcf->fka_period; 797 fcf->selected = new_fcf->selected; 798 799 error = device_register(&fcf->dev); 800 if (error) 801 goto out_del; 802 803 fcf->state = FCOE_FCF_STATE_CONNECTED; 804 list_add_tail(&fcf->peers, &ctlr->fcfs); 805 806 return fcf; 807 808 out_del: 809 kfree(fcf); 810 out: 811 return NULL; 812 } 813 EXPORT_SYMBOL_GPL(fcoe_fcf_device_add); 814 815 int __init fcoe_sysfs_setup(void) 816 { 817 int error; 818 819 atomic_set(&ctlr_num, 0); 820 atomic_set(&fcf_num, 0); 821 822 error = bus_register(&fcoe_bus_type); 823 if (error) 824 return error; 825 826 return 0; 827 } 828 829 void __exit fcoe_sysfs_teardown(void) 830 { 831 bus_unregister(&fcoe_bus_type); 832 } 833