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