1 /* 2 * FiberChannel transport specific attributes exported to sysfs. 3 * 4 * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 * ======== 21 * 22 * Copyright (C) 2004-2005 James Smart, Emulex Corporation 23 * Rewrite for host, target, device, and remote port attributes, 24 * statistics, and service functions... 25 * 26 */ 27 #include <linux/module.h> 28 #include <linux/init.h> 29 #include <scsi/scsi_device.h> 30 #include <scsi/scsi_host.h> 31 #include <scsi/scsi_transport.h> 32 #include <scsi/scsi_transport_fc.h> 33 #include "scsi_priv.h" 34 35 #define FC_PRINTK(x, l, f, a...) printk(l "scsi(%d:%d:%d:%d): " f, (x)->host->host_no, (x)->channel, (x)->id, (x)->lun , ##a) 36 37 /* 38 * Redefine so that we can have same named attributes in the 39 * sdev/starget/host objects. 40 */ 41 #define FC_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \ 42 struct class_device_attribute class_device_attr_##_prefix##_##_name = \ 43 __ATTR(_name,_mode,_show,_store) 44 45 #define fc_enum_name_search(title, table_type, table) \ 46 static const char *get_fc_##title##_name(enum table_type table_key) \ 47 { \ 48 int i; \ 49 char *name = NULL; \ 50 \ 51 for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ 52 if (table[i].value == table_key) { \ 53 name = table[i].name; \ 54 break; \ 55 } \ 56 } \ 57 return name; \ 58 } 59 60 #define fc_enum_name_match(title, table_type, table) \ 61 static int get_fc_##title##_match(const char *table_key, \ 62 enum table_type *value) \ 63 { \ 64 int i; \ 65 \ 66 for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ 67 if (strncmp(table_key, table[i].name, \ 68 table[i].matchlen) == 0) { \ 69 *value = table[i].value; \ 70 return 0; /* success */ \ 71 } \ 72 } \ 73 return 1; /* failure */ \ 74 } 75 76 77 /* Convert fc_port_type values to ascii string name */ 78 static struct { 79 enum fc_port_type value; 80 char *name; 81 } fc_port_type_names[] = { 82 { FC_PORTTYPE_UNKNOWN, "Unknown" }, 83 { FC_PORTTYPE_OTHER, "Other" }, 84 { FC_PORTTYPE_NOTPRESENT, "Not Present" }, 85 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" }, 86 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" }, 87 { FC_PORTTYPE_LPORT, "LPort (private loop)" }, 88 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection" }, 89 }; 90 fc_enum_name_search(port_type, fc_port_type, fc_port_type_names) 91 #define FC_PORTTYPE_MAX_NAMELEN 50 92 93 94 /* Convert fc_port_state values to ascii string name */ 95 static struct { 96 enum fc_port_state value; 97 char *name; 98 } fc_port_state_names[] = { 99 { FC_PORTSTATE_UNKNOWN, "Unknown" }, 100 { FC_PORTSTATE_NOTPRESENT, "Not Present" }, 101 { FC_PORTSTATE_ONLINE, "Online" }, 102 { FC_PORTSTATE_OFFLINE, "Offline" }, 103 { FC_PORTSTATE_BLOCKED, "Blocked" }, 104 { FC_PORTSTATE_BYPASSED, "Bypassed" }, 105 { FC_PORTSTATE_DIAGNOSTICS, "Diagnostics" }, 106 { FC_PORTSTATE_LINKDOWN, "Linkdown" }, 107 { FC_PORTSTATE_ERROR, "Error" }, 108 { FC_PORTSTATE_LOOPBACK, "Loopback" }, 109 }; 110 fc_enum_name_search(port_state, fc_port_state, fc_port_state_names) 111 #define FC_PORTSTATE_MAX_NAMELEN 20 112 113 114 /* Convert fc_tgtid_binding_type values to ascii string name */ 115 static struct { 116 enum fc_tgtid_binding_type value; 117 char *name; 118 int matchlen; 119 } fc_tgtid_binding_type_names[] = { 120 { FC_TGTID_BIND_NONE, "none", 4 }, 121 { FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 }, 122 { FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 }, 123 { FC_TGTID_BIND_BY_ID, "port_id (FC Address)", 7 }, 124 }; 125 fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type, 126 fc_tgtid_binding_type_names) 127 fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type, 128 fc_tgtid_binding_type_names) 129 #define FC_BINDTYPE_MAX_NAMELEN 30 130 131 132 #define fc_bitfield_name_search(title, table) \ 133 static ssize_t \ 134 get_fc_##title##_names(u32 table_key, char *buf) \ 135 { \ 136 char *prefix = ""; \ 137 ssize_t len = 0; \ 138 int i; \ 139 \ 140 for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ 141 if (table[i].value & table_key) { \ 142 len += sprintf(buf + len, "%s%s", \ 143 prefix, table[i].name); \ 144 prefix = ", "; \ 145 } \ 146 } \ 147 len += sprintf(buf + len, "\n"); \ 148 return len; \ 149 } 150 151 152 /* Convert FC_COS bit values to ascii string name */ 153 static struct { 154 u32 value; 155 char *name; 156 } fc_cos_names[] = { 157 { FC_COS_CLASS1, "Class 1" }, 158 { FC_COS_CLASS2, "Class 2" }, 159 { FC_COS_CLASS3, "Class 3" }, 160 { FC_COS_CLASS4, "Class 4" }, 161 { FC_COS_CLASS6, "Class 6" }, 162 }; 163 fc_bitfield_name_search(cos, fc_cos_names) 164 165 166 /* Convert FC_PORTSPEED bit values to ascii string name */ 167 static struct { 168 u32 value; 169 char *name; 170 } fc_port_speed_names[] = { 171 { FC_PORTSPEED_1GBIT, "1 Gbit" }, 172 { FC_PORTSPEED_2GBIT, "2 Gbit" }, 173 { FC_PORTSPEED_4GBIT, "4 Gbit" }, 174 { FC_PORTSPEED_10GBIT, "10 Gbit" }, 175 { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" }, 176 }; 177 fc_bitfield_name_search(port_speed, fc_port_speed_names) 178 179 180 static int 181 show_fc_fc4s (char *buf, u8 *fc4_list) 182 { 183 int i, len=0; 184 185 for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++) 186 len += sprintf(buf + len , "0x%02x ", *fc4_list); 187 len += sprintf(buf + len, "\n"); 188 return len; 189 } 190 191 192 /* Convert FC_RPORT_ROLE bit values to ascii string name */ 193 static struct { 194 u32 value; 195 char *name; 196 } fc_remote_port_role_names[] = { 197 { FC_RPORT_ROLE_FCP_TARGET, "FCP Target" }, 198 { FC_RPORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, 199 { FC_RPORT_ROLE_IP_PORT, "IP Port" }, 200 }; 201 fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) 202 203 /* 204 * Define roles that are specific to port_id. Values are relative to ROLE_MASK. 205 */ 206 #define FC_WELLKNOWN_PORTID_MASK 0xfffff0 207 #define FC_WELLKNOWN_ROLE_MASK 0x00000f 208 #define FC_FPORT_PORTID 0x00000e 209 #define FC_FABCTLR_PORTID 0x00000d 210 #define FC_DIRSRVR_PORTID 0x00000c 211 #define FC_TIMESRVR_PORTID 0x00000b 212 #define FC_MGMTSRVR_PORTID 0x00000a 213 214 215 static void fc_timeout_blocked_rport(void *data); 216 static void fc_scsi_scan_rport(void *data); 217 static void fc_rport_terminate(struct fc_rport *rport); 218 219 /* 220 * Attribute counts pre object type... 221 * Increase these values if you add attributes 222 */ 223 #define FC_STARGET_NUM_ATTRS 3 224 #define FC_RPORT_NUM_ATTRS 9 225 #define FC_HOST_NUM_ATTRS 15 226 227 struct fc_internal { 228 struct scsi_transport_template t; 229 struct fc_function_template *f; 230 231 /* 232 * For attributes : each object has : 233 * An array of the actual attributes structures 234 * An array of null-terminated pointers to the attribute 235 * structures - used for mid-layer interaction. 236 * 237 * The attribute containers for the starget and host are are 238 * part of the midlayer. As the remote port is specific to the 239 * fc transport, we must provide the attribute container. 240 */ 241 struct class_device_attribute private_starget_attrs[ 242 FC_STARGET_NUM_ATTRS]; 243 struct class_device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1]; 244 245 struct class_device_attribute private_host_attrs[FC_HOST_NUM_ATTRS]; 246 struct class_device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1]; 247 248 struct transport_container rport_attr_cont; 249 struct class_device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS]; 250 struct class_device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1]; 251 }; 252 253 #define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t) 254 255 static int fc_target_setup(struct device *dev) 256 { 257 struct scsi_target *starget = to_scsi_target(dev); 258 struct fc_rport *rport = starget_to_rport(starget); 259 260 /* 261 * if parent is remote port, use values from remote port. 262 * Otherwise, this host uses the fc_transport, but not the 263 * remote port interface. As such, initialize to known non-values. 264 */ 265 if (rport) { 266 fc_starget_node_name(starget) = rport->node_name; 267 fc_starget_port_name(starget) = rport->port_name; 268 fc_starget_port_id(starget) = rport->port_id; 269 } else { 270 fc_starget_node_name(starget) = -1; 271 fc_starget_port_name(starget) = -1; 272 fc_starget_port_id(starget) = -1; 273 } 274 275 return 0; 276 } 277 278 static DECLARE_TRANSPORT_CLASS(fc_transport_class, 279 "fc_transport", 280 fc_target_setup, 281 NULL, 282 NULL); 283 284 static int fc_host_setup(struct device *dev) 285 { 286 struct Scsi_Host *shost = dev_to_shost(dev); 287 288 /* 289 * Set default values easily detected by the midlayer as 290 * failure cases. The scsi lldd is responsible for initializing 291 * all transport attributes to valid values per host. 292 */ 293 fc_host_node_name(shost) = -1; 294 fc_host_port_name(shost) = -1; 295 fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED; 296 memset(fc_host_supported_fc4s(shost), 0, 297 sizeof(fc_host_supported_fc4s(shost))); 298 memset(fc_host_symbolic_name(shost), 0, 299 sizeof(fc_host_symbolic_name(shost))); 300 fc_host_supported_speeds(shost) = FC_PORTSPEED_UNKNOWN; 301 fc_host_maxframe_size(shost) = -1; 302 memset(fc_host_serial_number(shost), 0, 303 sizeof(fc_host_serial_number(shost))); 304 305 fc_host_port_id(shost) = -1; 306 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; 307 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; 308 memset(fc_host_active_fc4s(shost), 0, 309 sizeof(fc_host_active_fc4s(shost))); 310 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; 311 fc_host_fabric_name(shost) = -1; 312 313 fc_host_tgtid_bind_type(shost) = FC_TGTID_BIND_BY_WWPN; 314 315 INIT_LIST_HEAD(&fc_host_rports(shost)); 316 INIT_LIST_HEAD(&fc_host_rport_bindings(shost)); 317 fc_host_next_rport_number(shost) = 0; 318 fc_host_next_target_id(shost) = 0; 319 320 return 0; 321 } 322 323 static DECLARE_TRANSPORT_CLASS(fc_host_class, 324 "fc_host", 325 fc_host_setup, 326 NULL, 327 NULL); 328 329 /* 330 * Setup and Remove actions for remote ports are handled 331 * in the service functions below. 332 */ 333 static DECLARE_TRANSPORT_CLASS(fc_rport_class, 334 "fc_remote_ports", 335 NULL, 336 NULL, 337 NULL); 338 339 /* 340 * Module Parameters 341 */ 342 343 /* 344 * dev_loss_tmo: the default number of seconds that the FC transport 345 * should insulate the loss of a remote port. 346 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. 347 */ 348 static unsigned int fc_dev_loss_tmo = SCSI_DEVICE_BLOCK_MAX_TIMEOUT; 349 350 module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); 351 MODULE_PARM_DESC(dev_loss_tmo, 352 "Maximum number of seconds that the FC transport should" 353 " insulate the loss of a remote port. Once this value is" 354 " exceeded, the scsi target is removed. Value should be" 355 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); 356 357 358 static __init int fc_transport_init(void) 359 { 360 int error = transport_class_register(&fc_host_class); 361 if (error) 362 return error; 363 error = transport_class_register(&fc_rport_class); 364 if (error) 365 return error; 366 return transport_class_register(&fc_transport_class); 367 } 368 369 static void __exit fc_transport_exit(void) 370 { 371 transport_class_unregister(&fc_transport_class); 372 transport_class_unregister(&fc_rport_class); 373 transport_class_unregister(&fc_host_class); 374 } 375 376 /* 377 * FC Remote Port Attribute Management 378 */ 379 380 #define fc_rport_show_function(field, format_string, sz, cast) \ 381 static ssize_t \ 382 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 383 { \ 384 struct fc_rport *rport = transport_class_to_rport(cdev); \ 385 struct Scsi_Host *shost = rport_to_shost(rport); \ 386 struct fc_internal *i = to_fc_internal(shost->transportt); \ 387 if (i->f->get_rport_##field) \ 388 i->f->get_rport_##field(rport); \ 389 return snprintf(buf, sz, format_string, cast rport->field); \ 390 } 391 392 #define fc_rport_store_function(field) \ 393 static ssize_t \ 394 store_fc_rport_##field(struct class_device *cdev, const char *buf, \ 395 size_t count) \ 396 { \ 397 int val; \ 398 struct fc_rport *rport = transport_class_to_rport(cdev); \ 399 struct Scsi_Host *shost = rport_to_shost(rport); \ 400 struct fc_internal *i = to_fc_internal(shost->transportt); \ 401 val = simple_strtoul(buf, NULL, 0); \ 402 i->f->set_rport_##field(rport, val); \ 403 return count; \ 404 } 405 406 #define fc_rport_rd_attr(field, format_string, sz) \ 407 fc_rport_show_function(field, format_string, sz, ) \ 408 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 409 show_fc_rport_##field, NULL) 410 411 #define fc_rport_rd_attr_cast(field, format_string, sz, cast) \ 412 fc_rport_show_function(field, format_string, sz, (cast)) \ 413 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 414 show_fc_rport_##field, NULL) 415 416 #define fc_rport_rw_attr(field, format_string, sz) \ 417 fc_rport_show_function(field, format_string, sz, ) \ 418 fc_rport_store_function(field) \ 419 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO | S_IWUSR, \ 420 show_fc_rport_##field, \ 421 store_fc_rport_##field) 422 423 424 #define fc_private_rport_show_function(field, format_string, sz, cast) \ 425 static ssize_t \ 426 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 427 { \ 428 struct fc_rport *rport = transport_class_to_rport(cdev); \ 429 return snprintf(buf, sz, format_string, cast rport->field); \ 430 } 431 432 #define fc_private_rport_rd_attr(field, format_string, sz) \ 433 fc_private_rport_show_function(field, format_string, sz, ) \ 434 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 435 show_fc_rport_##field, NULL) 436 437 #define fc_private_rport_rd_attr_cast(field, format_string, sz, cast) \ 438 fc_private_rport_show_function(field, format_string, sz, (cast)) \ 439 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 440 show_fc_rport_##field, NULL) 441 442 443 #define fc_private_rport_rd_enum_attr(title, maxlen) \ 444 static ssize_t \ 445 show_fc_rport_##title (struct class_device *cdev, char *buf) \ 446 { \ 447 struct fc_rport *rport = transport_class_to_rport(cdev); \ 448 const char *name; \ 449 name = get_fc_##title##_name(rport->title); \ 450 if (!name) \ 451 return -EINVAL; \ 452 return snprintf(buf, maxlen, "%s\n", name); \ 453 } \ 454 static FC_CLASS_DEVICE_ATTR(rport, title, S_IRUGO, \ 455 show_fc_rport_##title, NULL) 456 457 458 #define SETUP_RPORT_ATTRIBUTE_RD(field) \ 459 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 460 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 461 i->private_rport_attrs[count].store = NULL; \ 462 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 463 if (i->f->show_rport_##field) \ 464 count++ 465 466 #define SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(field) \ 467 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 468 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 469 i->private_rport_attrs[count].store = NULL; \ 470 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 471 count++ 472 473 #define SETUP_RPORT_ATTRIBUTE_RW(field) \ 474 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 475 if (!i->f->set_rport_##field) { \ 476 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 477 i->private_rport_attrs[count].store = NULL; \ 478 } \ 479 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 480 if (i->f->show_rport_##field) \ 481 count++ 482 483 484 /* The FC Transport Remote Port Attributes: */ 485 486 /* Fixed Remote Port Attributes */ 487 488 fc_private_rport_rd_attr(maxframe_size, "%u bytes\n", 20); 489 490 static ssize_t 491 show_fc_rport_supported_classes (struct class_device *cdev, char *buf) 492 { 493 struct fc_rport *rport = transport_class_to_rport(cdev); 494 if (rport->supported_classes == FC_COS_UNSPECIFIED) 495 return snprintf(buf, 20, "unspecified\n"); 496 return get_fc_cos_names(rport->supported_classes, buf); 497 } 498 static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO, 499 show_fc_rport_supported_classes, NULL); 500 501 /* Dynamic Remote Port Attributes */ 502 503 fc_rport_rw_attr(dev_loss_tmo, "%d\n", 20); 504 505 506 /* Private Remote Port Attributes */ 507 508 fc_private_rport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 509 fc_private_rport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 510 fc_private_rport_rd_attr(port_id, "0x%06x\n", 20); 511 512 static ssize_t 513 show_fc_rport_roles (struct class_device *cdev, char *buf) 514 { 515 struct fc_rport *rport = transport_class_to_rport(cdev); 516 517 /* identify any roles that are port_id specific */ 518 if ((rport->port_id != -1) && 519 (rport->port_id & FC_WELLKNOWN_PORTID_MASK) == 520 FC_WELLKNOWN_PORTID_MASK) { 521 switch (rport->port_id & FC_WELLKNOWN_ROLE_MASK) { 522 case FC_FPORT_PORTID: 523 return snprintf(buf, 30, "Fabric Port\n"); 524 case FC_FABCTLR_PORTID: 525 return snprintf(buf, 30, "Fabric Controller\n"); 526 case FC_DIRSRVR_PORTID: 527 return snprintf(buf, 30, "Directory Server\n"); 528 case FC_TIMESRVR_PORTID: 529 return snprintf(buf, 30, "Time Server\n"); 530 case FC_MGMTSRVR_PORTID: 531 return snprintf(buf, 30, "Management Server\n"); 532 default: 533 return snprintf(buf, 30, "Unknown Fabric Entity\n"); 534 } 535 } else { 536 if (rport->roles == FC_RPORT_ROLE_UNKNOWN) 537 return snprintf(buf, 20, "unknown\n"); 538 return get_fc_remote_port_roles_names(rport->roles, buf); 539 } 540 } 541 static FC_CLASS_DEVICE_ATTR(rport, roles, S_IRUGO, 542 show_fc_rport_roles, NULL); 543 544 fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 545 fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20); 546 547 548 549 /* 550 * FC SCSI Target Attribute Management 551 */ 552 553 /* 554 * Note: in the target show function we recognize when the remote 555 * port is in the heirarchy and do not allow the driver to get 556 * involved in sysfs functions. The driver only gets involved if 557 * it's the "old" style that doesn't use rports. 558 */ 559 #define fc_starget_show_function(field, format_string, sz, cast) \ 560 static ssize_t \ 561 show_fc_starget_##field (struct class_device *cdev, char *buf) \ 562 { \ 563 struct scsi_target *starget = transport_class_to_starget(cdev); \ 564 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ 565 struct fc_internal *i = to_fc_internal(shost->transportt); \ 566 struct fc_rport *rport = starget_to_rport(starget); \ 567 if (rport) \ 568 fc_starget_##field(starget) = rport->field; \ 569 else if (i->f->get_starget_##field) \ 570 i->f->get_starget_##field(starget); \ 571 return snprintf(buf, sz, format_string, \ 572 cast fc_starget_##field(starget)); \ 573 } 574 575 #define fc_starget_rd_attr(field, format_string, sz) \ 576 fc_starget_show_function(field, format_string, sz, ) \ 577 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 578 show_fc_starget_##field, NULL) 579 580 #define fc_starget_rd_attr_cast(field, format_string, sz, cast) \ 581 fc_starget_show_function(field, format_string, sz, (cast)) \ 582 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 583 show_fc_starget_##field, NULL) 584 585 #define SETUP_STARGET_ATTRIBUTE_RD(field) \ 586 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 587 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 588 i->private_starget_attrs[count].store = NULL; \ 589 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 590 if (i->f->show_starget_##field) \ 591 count++ 592 593 #define SETUP_STARGET_ATTRIBUTE_RW(field) \ 594 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 595 if (!i->f->set_starget_##field) { \ 596 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 597 i->private_starget_attrs[count].store = NULL; \ 598 } \ 599 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 600 if (i->f->show_starget_##field) \ 601 count++ 602 603 /* The FC Transport SCSI Target Attributes: */ 604 fc_starget_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 605 fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 606 fc_starget_rd_attr(port_id, "0x%06x\n", 20); 607 608 609 /* 610 * Host Attribute Management 611 */ 612 613 #define fc_host_show_function(field, format_string, sz, cast) \ 614 static ssize_t \ 615 show_fc_host_##field (struct class_device *cdev, char *buf) \ 616 { \ 617 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 618 struct fc_internal *i = to_fc_internal(shost->transportt); \ 619 if (i->f->get_host_##field) \ 620 i->f->get_host_##field(shost); \ 621 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 622 } 623 624 #define fc_host_store_function(field) \ 625 static ssize_t \ 626 store_fc_host_##field(struct class_device *cdev, const char *buf, \ 627 size_t count) \ 628 { \ 629 int val; \ 630 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 631 struct fc_internal *i = to_fc_internal(shost->transportt); \ 632 \ 633 val = simple_strtoul(buf, NULL, 0); \ 634 i->f->set_host_##field(shost, val); \ 635 return count; \ 636 } 637 638 #define fc_host_rd_attr(field, format_string, sz) \ 639 fc_host_show_function(field, format_string, sz, ) \ 640 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 641 show_fc_host_##field, NULL) 642 643 #define fc_host_rd_attr_cast(field, format_string, sz, cast) \ 644 fc_host_show_function(field, format_string, sz, (cast)) \ 645 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 646 show_fc_host_##field, NULL) 647 648 #define fc_host_rw_attr(field, format_string, sz) \ 649 fc_host_show_function(field, format_string, sz, ) \ 650 fc_host_store_function(field) \ 651 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR, \ 652 show_fc_host_##field, \ 653 store_fc_host_##field) 654 655 #define fc_host_rd_enum_attr(title, maxlen) \ 656 static ssize_t \ 657 show_fc_host_##title (struct class_device *cdev, char *buf) \ 658 { \ 659 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 660 struct fc_internal *i = to_fc_internal(shost->transportt); \ 661 const char *name; \ 662 if (i->f->get_host_##title) \ 663 i->f->get_host_##title(shost); \ 664 name = get_fc_##title##_name(fc_host_##title(shost)); \ 665 if (!name) \ 666 return -EINVAL; \ 667 return snprintf(buf, maxlen, "%s\n", name); \ 668 } \ 669 static FC_CLASS_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL) 670 671 #define SETUP_HOST_ATTRIBUTE_RD(field) \ 672 i->private_host_attrs[count] = class_device_attr_host_##field; \ 673 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 674 i->private_host_attrs[count].store = NULL; \ 675 i->host_attrs[count] = &i->private_host_attrs[count]; \ 676 if (i->f->show_host_##field) \ 677 count++ 678 679 #define SETUP_HOST_ATTRIBUTE_RW(field) \ 680 i->private_host_attrs[count] = class_device_attr_host_##field; \ 681 if (!i->f->set_host_##field) { \ 682 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 683 i->private_host_attrs[count].store = NULL; \ 684 } \ 685 i->host_attrs[count] = &i->private_host_attrs[count]; \ 686 if (i->f->show_host_##field) \ 687 count++ 688 689 690 #define fc_private_host_show_function(field, format_string, sz, cast) \ 691 static ssize_t \ 692 show_fc_host_##field (struct class_device *cdev, char *buf) \ 693 { \ 694 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 695 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 696 } 697 698 #define fc_private_host_rd_attr(field, format_string, sz) \ 699 fc_private_host_show_function(field, format_string, sz, ) \ 700 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 701 show_fc_host_##field, NULL) 702 703 #define fc_private_host_rd_attr_cast(field, format_string, sz, cast) \ 704 fc_private_host_show_function(field, format_string, sz, (cast)) \ 705 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 706 show_fc_host_##field, NULL) 707 708 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field) \ 709 i->private_host_attrs[count] = class_device_attr_host_##field; \ 710 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 711 i->private_host_attrs[count].store = NULL; \ 712 i->host_attrs[count] = &i->private_host_attrs[count]; \ 713 count++ 714 715 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \ 716 i->private_host_attrs[count] = class_device_attr_host_##field; \ 717 i->host_attrs[count] = &i->private_host_attrs[count]; \ 718 count++ 719 720 721 /* Fixed Host Attributes */ 722 723 static ssize_t 724 show_fc_host_supported_classes (struct class_device *cdev, char *buf) 725 { 726 struct Scsi_Host *shost = transport_class_to_shost(cdev); 727 728 if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED) 729 return snprintf(buf, 20, "unspecified\n"); 730 731 return get_fc_cos_names(fc_host_supported_classes(shost), buf); 732 } 733 static FC_CLASS_DEVICE_ATTR(host, supported_classes, S_IRUGO, 734 show_fc_host_supported_classes, NULL); 735 736 static ssize_t 737 show_fc_host_supported_fc4s (struct class_device *cdev, char *buf) 738 { 739 struct Scsi_Host *shost = transport_class_to_shost(cdev); 740 return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost)); 741 } 742 static FC_CLASS_DEVICE_ATTR(host, supported_fc4s, S_IRUGO, 743 show_fc_host_supported_fc4s, NULL); 744 745 static ssize_t 746 show_fc_host_supported_speeds (struct class_device *cdev, char *buf) 747 { 748 struct Scsi_Host *shost = transport_class_to_shost(cdev); 749 750 if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN) 751 return snprintf(buf, 20, "unknown\n"); 752 753 return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf); 754 } 755 static FC_CLASS_DEVICE_ATTR(host, supported_speeds, S_IRUGO, 756 show_fc_host_supported_speeds, NULL); 757 758 759 fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 760 fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 761 fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1)); 762 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20); 763 fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1)); 764 765 766 /* Dynamic Host Attributes */ 767 768 static ssize_t 769 show_fc_host_active_fc4s (struct class_device *cdev, char *buf) 770 { 771 struct Scsi_Host *shost = transport_class_to_shost(cdev); 772 struct fc_internal *i = to_fc_internal(shost->transportt); 773 774 if (i->f->get_host_active_fc4s) 775 i->f->get_host_active_fc4s(shost); 776 777 return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost)); 778 } 779 static FC_CLASS_DEVICE_ATTR(host, active_fc4s, S_IRUGO, 780 show_fc_host_active_fc4s, NULL); 781 782 static ssize_t 783 show_fc_host_speed (struct class_device *cdev, char *buf) 784 { 785 struct Scsi_Host *shost = transport_class_to_shost(cdev); 786 struct fc_internal *i = to_fc_internal(shost->transportt); 787 788 if (i->f->get_host_speed) 789 i->f->get_host_speed(shost); 790 791 if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN) 792 return snprintf(buf, 20, "unknown\n"); 793 794 return get_fc_port_speed_names(fc_host_speed(shost), buf); 795 } 796 static FC_CLASS_DEVICE_ATTR(host, speed, S_IRUGO, 797 show_fc_host_speed, NULL); 798 799 800 fc_host_rd_attr(port_id, "0x%06x\n", 20); 801 fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN); 802 fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 803 fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 804 805 806 /* Private Host Attributes */ 807 808 static ssize_t 809 show_fc_private_host_tgtid_bind_type(struct class_device *cdev, char *buf) 810 { 811 struct Scsi_Host *shost = transport_class_to_shost(cdev); 812 const char *name; 813 814 name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost)); 815 if (!name) 816 return -EINVAL; 817 return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name); 818 } 819 820 static ssize_t 821 store_fc_private_host_tgtid_bind_type(struct class_device *cdev, 822 const char *buf, size_t count) 823 { 824 struct Scsi_Host *shost = transport_class_to_shost(cdev); 825 struct fc_rport *rport, *next_rport; 826 enum fc_tgtid_binding_type val; 827 unsigned long flags; 828 829 if (get_fc_tgtid_bind_type_match(buf, &val)) 830 return -EINVAL; 831 832 /* if changing bind type, purge all unused consistent bindings */ 833 if (val != fc_host_tgtid_bind_type(shost)) { 834 spin_lock_irqsave(shost->host_lock, flags); 835 list_for_each_entry_safe(rport, next_rport, 836 &fc_host_rport_bindings(shost), peers) 837 fc_rport_terminate(rport); 838 spin_unlock_irqrestore(shost->host_lock, flags); 839 } 840 841 fc_host_tgtid_bind_type(shost) = val; 842 return count; 843 } 844 845 static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR, 846 show_fc_private_host_tgtid_bind_type, 847 store_fc_private_host_tgtid_bind_type); 848 849 /* 850 * Host Statistics Management 851 */ 852 853 /* Show a given an attribute in the statistics group */ 854 static ssize_t 855 fc_stat_show(const struct class_device *cdev, char *buf, unsigned long offset) 856 { 857 struct Scsi_Host *shost = transport_class_to_shost(cdev); 858 struct fc_internal *i = to_fc_internal(shost->transportt); 859 struct fc_host_statistics *stats; 860 ssize_t ret = -ENOENT; 861 862 if (offset > sizeof(struct fc_host_statistics) || 863 offset % sizeof(u64) != 0) 864 WARN_ON(1); 865 866 if (i->f->get_fc_host_stats) { 867 stats = (i->f->get_fc_host_stats)(shost); 868 if (stats) 869 ret = snprintf(buf, 20, "0x%llx\n", 870 (unsigned long long)*(u64 *)(((u8 *) stats) + offset)); 871 } 872 return ret; 873 } 874 875 876 /* generate a read-only statistics attribute */ 877 #define fc_host_statistic(name) \ 878 static ssize_t show_fcstat_##name(struct class_device *cd, char *buf) \ 879 { \ 880 return fc_stat_show(cd, buf, \ 881 offsetof(struct fc_host_statistics, name)); \ 882 } \ 883 static FC_CLASS_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL) 884 885 fc_host_statistic(seconds_since_last_reset); 886 fc_host_statistic(tx_frames); 887 fc_host_statistic(tx_words); 888 fc_host_statistic(rx_frames); 889 fc_host_statistic(rx_words); 890 fc_host_statistic(lip_count); 891 fc_host_statistic(nos_count); 892 fc_host_statistic(error_frames); 893 fc_host_statistic(dumped_frames); 894 fc_host_statistic(link_failure_count); 895 fc_host_statistic(loss_of_sync_count); 896 fc_host_statistic(loss_of_signal_count); 897 fc_host_statistic(prim_seq_protocol_err_count); 898 fc_host_statistic(invalid_tx_word_count); 899 fc_host_statistic(invalid_crc_count); 900 fc_host_statistic(fcp_input_requests); 901 fc_host_statistic(fcp_output_requests); 902 fc_host_statistic(fcp_control_requests); 903 fc_host_statistic(fcp_input_megabytes); 904 fc_host_statistic(fcp_output_megabytes); 905 906 static ssize_t 907 fc_reset_statistics(struct class_device *cdev, const char *buf, 908 size_t count) 909 { 910 struct Scsi_Host *shost = transport_class_to_shost(cdev); 911 struct fc_internal *i = to_fc_internal(shost->transportt); 912 913 /* ignore any data value written to the attribute */ 914 if (i->f->reset_fc_host_stats) { 915 i->f->reset_fc_host_stats(shost); 916 return count; 917 } 918 919 return -ENOENT; 920 } 921 static FC_CLASS_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL, 922 fc_reset_statistics); 923 924 925 static struct attribute *fc_statistics_attrs[] = { 926 &class_device_attr_host_seconds_since_last_reset.attr, 927 &class_device_attr_host_tx_frames.attr, 928 &class_device_attr_host_tx_words.attr, 929 &class_device_attr_host_rx_frames.attr, 930 &class_device_attr_host_rx_words.attr, 931 &class_device_attr_host_lip_count.attr, 932 &class_device_attr_host_nos_count.attr, 933 &class_device_attr_host_error_frames.attr, 934 &class_device_attr_host_dumped_frames.attr, 935 &class_device_attr_host_link_failure_count.attr, 936 &class_device_attr_host_loss_of_sync_count.attr, 937 &class_device_attr_host_loss_of_signal_count.attr, 938 &class_device_attr_host_prim_seq_protocol_err_count.attr, 939 &class_device_attr_host_invalid_tx_word_count.attr, 940 &class_device_attr_host_invalid_crc_count.attr, 941 &class_device_attr_host_fcp_input_requests.attr, 942 &class_device_attr_host_fcp_output_requests.attr, 943 &class_device_attr_host_fcp_control_requests.attr, 944 &class_device_attr_host_fcp_input_megabytes.attr, 945 &class_device_attr_host_fcp_output_megabytes.attr, 946 &class_device_attr_host_reset_statistics.attr, 947 NULL 948 }; 949 950 static struct attribute_group fc_statistics_group = { 951 .name = "statistics", 952 .attrs = fc_statistics_attrs, 953 }; 954 955 static int fc_host_match(struct attribute_container *cont, 956 struct device *dev) 957 { 958 struct Scsi_Host *shost; 959 struct fc_internal *i; 960 961 if (!scsi_is_host_device(dev)) 962 return 0; 963 964 shost = dev_to_shost(dev); 965 if (!shost->transportt || shost->transportt->host_attrs.ac.class 966 != &fc_host_class.class) 967 return 0; 968 969 i = to_fc_internal(shost->transportt); 970 971 return &i->t.host_attrs.ac == cont; 972 } 973 974 static int fc_target_match(struct attribute_container *cont, 975 struct device *dev) 976 { 977 struct Scsi_Host *shost; 978 struct fc_internal *i; 979 980 if (!scsi_is_target_device(dev)) 981 return 0; 982 983 shost = dev_to_shost(dev->parent); 984 if (!shost->transportt || shost->transportt->host_attrs.ac.class 985 != &fc_host_class.class) 986 return 0; 987 988 i = to_fc_internal(shost->transportt); 989 990 return &i->t.target_attrs.ac == cont; 991 } 992 993 static void fc_rport_dev_release(struct device *dev) 994 { 995 struct fc_rport *rport = dev_to_rport(dev); 996 put_device(dev->parent); 997 kfree(rport); 998 } 999 1000 int scsi_is_fc_rport(const struct device *dev) 1001 { 1002 return dev->release == fc_rport_dev_release; 1003 } 1004 EXPORT_SYMBOL(scsi_is_fc_rport); 1005 1006 static int fc_rport_match(struct attribute_container *cont, 1007 struct device *dev) 1008 { 1009 struct Scsi_Host *shost; 1010 struct fc_internal *i; 1011 1012 if (!scsi_is_fc_rport(dev)) 1013 return 0; 1014 1015 shost = dev_to_shost(dev->parent); 1016 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1017 != &fc_host_class.class) 1018 return 0; 1019 1020 i = to_fc_internal(shost->transportt); 1021 1022 return &i->rport_attr_cont.ac == cont; 1023 } 1024 1025 struct scsi_transport_template * 1026 fc_attach_transport(struct fc_function_template *ft) 1027 { 1028 struct fc_internal *i = kmalloc(sizeof(struct fc_internal), 1029 GFP_KERNEL); 1030 int count; 1031 1032 if (unlikely(!i)) 1033 return NULL; 1034 1035 memset(i, 0, sizeof(struct fc_internal)); 1036 1037 i->t.target_attrs.ac.attrs = &i->starget_attrs[0]; 1038 i->t.target_attrs.ac.class = &fc_transport_class.class; 1039 i->t.target_attrs.ac.match = fc_target_match; 1040 i->t.target_size = sizeof(struct fc_starget_attrs); 1041 transport_container_register(&i->t.target_attrs); 1042 1043 i->t.host_attrs.ac.attrs = &i->host_attrs[0]; 1044 i->t.host_attrs.ac.class = &fc_host_class.class; 1045 i->t.host_attrs.ac.match = fc_host_match; 1046 i->t.host_size = sizeof(struct fc_host_attrs); 1047 if (ft->get_fc_host_stats) 1048 i->t.host_attrs.statistics = &fc_statistics_group; 1049 transport_container_register(&i->t.host_attrs); 1050 1051 i->rport_attr_cont.ac.attrs = &i->rport_attrs[0]; 1052 i->rport_attr_cont.ac.class = &fc_rport_class.class; 1053 i->rport_attr_cont.ac.match = fc_rport_match; 1054 transport_container_register(&i->rport_attr_cont); 1055 1056 i->f = ft; 1057 1058 /* Transport uses the shost workq for scsi scanning */ 1059 i->t.create_work_queue = 1; 1060 1061 /* 1062 * Setup SCSI Target Attributes. 1063 */ 1064 count = 0; 1065 SETUP_STARGET_ATTRIBUTE_RD(node_name); 1066 SETUP_STARGET_ATTRIBUTE_RD(port_name); 1067 SETUP_STARGET_ATTRIBUTE_RD(port_id); 1068 1069 BUG_ON(count > FC_STARGET_NUM_ATTRS); 1070 1071 i->starget_attrs[count] = NULL; 1072 1073 1074 /* 1075 * Setup SCSI Host Attributes. 1076 */ 1077 count=0; 1078 SETUP_HOST_ATTRIBUTE_RD(node_name); 1079 SETUP_HOST_ATTRIBUTE_RD(port_name); 1080 SETUP_HOST_ATTRIBUTE_RD(supported_classes); 1081 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s); 1082 SETUP_HOST_ATTRIBUTE_RD(symbolic_name); 1083 SETUP_HOST_ATTRIBUTE_RD(supported_speeds); 1084 SETUP_HOST_ATTRIBUTE_RD(maxframe_size); 1085 SETUP_HOST_ATTRIBUTE_RD(serial_number); 1086 1087 SETUP_HOST_ATTRIBUTE_RD(port_id); 1088 SETUP_HOST_ATTRIBUTE_RD(port_type); 1089 SETUP_HOST_ATTRIBUTE_RD(port_state); 1090 SETUP_HOST_ATTRIBUTE_RD(active_fc4s); 1091 SETUP_HOST_ATTRIBUTE_RD(speed); 1092 SETUP_HOST_ATTRIBUTE_RD(fabric_name); 1093 1094 /* Transport-managed attributes */ 1095 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 1096 1097 BUG_ON(count > FC_HOST_NUM_ATTRS); 1098 1099 i->host_attrs[count] = NULL; 1100 1101 /* 1102 * Setup Remote Port Attributes. 1103 */ 1104 count=0; 1105 SETUP_RPORT_ATTRIBUTE_RD(maxframe_size); 1106 SETUP_RPORT_ATTRIBUTE_RD(supported_classes); 1107 SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo); 1108 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name); 1109 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name); 1110 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id); 1111 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles); 1112 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state); 1113 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id); 1114 1115 BUG_ON(count > FC_RPORT_NUM_ATTRS); 1116 1117 i->rport_attrs[count] = NULL; 1118 1119 return &i->t; 1120 } 1121 EXPORT_SYMBOL(fc_attach_transport); 1122 1123 void fc_release_transport(struct scsi_transport_template *t) 1124 { 1125 struct fc_internal *i = to_fc_internal(t); 1126 1127 transport_container_unregister(&i->t.target_attrs); 1128 transport_container_unregister(&i->t.host_attrs); 1129 transport_container_unregister(&i->rport_attr_cont); 1130 1131 kfree(i); 1132 } 1133 EXPORT_SYMBOL(fc_release_transport); 1134 1135 1136 /** 1137 * fc_remove_host - called to terminate any fc_transport-related elements 1138 * for a scsi host. 1139 * @rport: remote port to be unblocked. 1140 * 1141 * This routine is expected to be called immediately preceeding the 1142 * a driver's call to scsi_remove_host(). 1143 * 1144 * WARNING: A driver utilizing the fc_transport, which fails to call 1145 * this routine prior to scsi_remote_host(), will leave dangling 1146 * objects in /sys/class/fc_remote_ports. Access to any of these 1147 * objects can result in a system crash !!! 1148 * 1149 * Notes: 1150 * This routine assumes no locks are held on entry. 1151 **/ 1152 void 1153 fc_remove_host(struct Scsi_Host *shost) 1154 { 1155 struct fc_rport *rport, *next_rport; 1156 1157 /* Remove any remote ports */ 1158 list_for_each_entry_safe(rport, next_rport, 1159 &fc_host_rports(shost), peers) 1160 fc_rport_terminate(rport); 1161 list_for_each_entry_safe(rport, next_rport, 1162 &fc_host_rport_bindings(shost), peers) 1163 fc_rport_terminate(rport); 1164 } 1165 EXPORT_SYMBOL(fc_remove_host); 1166 1167 /** 1168 * fc_rport_create - allocates and creates a remote FC port. 1169 * @shost: scsi host the remote port is connected to. 1170 * @channel: Channel on shost port connected to. 1171 * @ids: The world wide names, fc address, and FC4 port 1172 * roles for the remote port. 1173 * 1174 * Allocates and creates the remoter port structure, including the 1175 * class and sysfs creation. 1176 * 1177 * Notes: 1178 * This routine assumes no locks are held on entry. 1179 **/ 1180 struct fc_rport * 1181 fc_rport_create(struct Scsi_Host *shost, int channel, 1182 struct fc_rport_identifiers *ids) 1183 { 1184 struct fc_host_attrs *fc_host = 1185 (struct fc_host_attrs *)shost->shost_data; 1186 struct fc_internal *fci = to_fc_internal(shost->transportt); 1187 struct fc_rport *rport; 1188 struct device *dev; 1189 unsigned long flags; 1190 int error; 1191 size_t size; 1192 1193 size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); 1194 rport = kmalloc(size, GFP_KERNEL); 1195 if (unlikely(!rport)) { 1196 printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); 1197 return NULL; 1198 } 1199 memset(rport, 0, size); 1200 1201 rport->maxframe_size = -1; 1202 rport->supported_classes = FC_COS_UNSPECIFIED; 1203 rport->dev_loss_tmo = fc_dev_loss_tmo; 1204 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); 1205 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name)); 1206 rport->port_id = ids->port_id; 1207 rport->roles = ids->roles; 1208 rport->port_state = FC_PORTSTATE_ONLINE; 1209 if (fci->f->dd_fcrport_size) 1210 rport->dd_data = &rport[1]; 1211 rport->channel = channel; 1212 1213 INIT_WORK(&rport->dev_loss_work, fc_timeout_blocked_rport, rport); 1214 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); 1215 1216 spin_lock_irqsave(shost->host_lock, flags); 1217 1218 rport->number = fc_host->next_rport_number++; 1219 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1220 rport->scsi_target_id = fc_host->next_target_id++; 1221 else 1222 rport->scsi_target_id = -1; 1223 list_add_tail(&rport->peers, &fc_host_rports(shost)); 1224 get_device(&shost->shost_gendev); 1225 1226 spin_unlock_irqrestore(shost->host_lock, flags); 1227 1228 dev = &rport->dev; 1229 device_initialize(dev); 1230 dev->parent = get_device(&shost->shost_gendev); 1231 dev->release = fc_rport_dev_release; 1232 sprintf(dev->bus_id, "rport-%d:%d-%d", 1233 shost->host_no, channel, rport->number); 1234 transport_setup_device(dev); 1235 1236 error = device_add(dev); 1237 if (error) { 1238 printk(KERN_ERR "FC Remote Port device_add failed\n"); 1239 goto delete_rport; 1240 } 1241 transport_add_device(dev); 1242 transport_configure_device(dev); 1243 1244 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1245 /* initiate a scan of the target */ 1246 scsi_queue_work(shost, &rport->scan_work); 1247 1248 return rport; 1249 1250 delete_rport: 1251 transport_destroy_device(dev); 1252 put_device(dev->parent); 1253 spin_lock_irqsave(shost->host_lock, flags); 1254 list_del(&rport->peers); 1255 put_device(&shost->shost_gendev); 1256 spin_unlock_irqrestore(shost->host_lock, flags); 1257 put_device(dev->parent); 1258 kfree(rport); 1259 return NULL; 1260 } 1261 1262 /** 1263 * fc_remote_port_add - notifies the fc transport of the existence 1264 * of a remote FC port. 1265 * @shost: scsi host the remote port is connected to. 1266 * @channel: Channel on shost port connected to. 1267 * @ids: The world wide names, fc address, and FC4 port 1268 * roles for the remote port. 1269 * 1270 * The LLDD calls this routine to notify the transport of the existence 1271 * of a remote port. The LLDD provides the unique identifiers (wwpn,wwn) 1272 * of the port, it's FC address (port_id), and the FC4 roles that are 1273 * active for the port. 1274 * 1275 * For ports that are FCP targets (aka scsi targets), the FC transport 1276 * maintains consistent target id bindings on behalf of the LLDD. 1277 * A consistent target id binding is an assignment of a target id to 1278 * a remote port identifier, which persists while the scsi host is 1279 * attached. The remote port can disappear, then later reappear, and 1280 * it's target id assignment remains the same. This allows for shifts 1281 * in FC addressing (if binding by wwpn or wwnn) with no apparent 1282 * changes to the scsi subsystem which is based on scsi host number and 1283 * target id values. Bindings are only valid during the attachment of 1284 * the scsi host. If the host detaches, then later re-attaches, target 1285 * id bindings may change. 1286 * 1287 * This routine is responsible for returning a remote port structure. 1288 * The routine will search the list of remote ports it maintains 1289 * internally on behalf of consistent target id mappings. If found, the 1290 * remote port structure will be reused. Otherwise, a new remote port 1291 * structure will be allocated. 1292 * 1293 * Whenever a remote port is allocated, a new fc_remote_port class 1294 * device is created. 1295 * 1296 * Should not be called from interrupt context. 1297 * 1298 * Notes: 1299 * This routine assumes no locks are held on entry. 1300 **/ 1301 struct fc_rport * 1302 fc_remote_port_add(struct Scsi_Host *shost, int channel, 1303 struct fc_rport_identifiers *ids) 1304 { 1305 struct fc_rport *rport; 1306 unsigned long flags; 1307 int match = 0; 1308 1309 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) && 1310 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) { 1311 1312 /* search for a matching consistent binding */ 1313 1314 spin_lock_irqsave(shost->host_lock, flags); 1315 1316 list_for_each_entry(rport, &fc_host_rport_bindings(shost), 1317 peers) { 1318 if (rport->channel != channel) 1319 continue; 1320 1321 switch (fc_host_tgtid_bind_type(shost)) { 1322 case FC_TGTID_BIND_BY_WWPN: 1323 if (rport->port_name == ids->port_name) 1324 match = 1; 1325 break; 1326 case FC_TGTID_BIND_BY_WWNN: 1327 if (rport->node_name == ids->node_name) 1328 match = 1; 1329 break; 1330 case FC_TGTID_BIND_BY_ID: 1331 if (rport->port_id == ids->port_id) 1332 match = 1; 1333 break; 1334 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 1335 break; 1336 } 1337 1338 if (match) { 1339 list_move_tail(&rport->peers, 1340 &fc_host_rports(shost)); 1341 break; 1342 } 1343 } 1344 1345 spin_unlock_irqrestore(shost->host_lock, flags); 1346 1347 if (match) { 1348 memcpy(&rport->node_name, &ids->node_name, 1349 sizeof(rport->node_name)); 1350 memcpy(&rport->port_name, &ids->port_name, 1351 sizeof(rport->port_name)); 1352 rport->port_id = ids->port_id; 1353 rport->roles = ids->roles; 1354 rport->port_state = FC_PORTSTATE_ONLINE; 1355 1356 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1357 /* initiate a scan of the target */ 1358 scsi_queue_work(shost, &rport->scan_work); 1359 1360 return rport; 1361 } 1362 } 1363 1364 /* No consistent binding found - create new remote port entry */ 1365 rport = fc_rport_create(shost, channel, ids); 1366 1367 return rport; 1368 } 1369 EXPORT_SYMBOL(fc_remote_port_add); 1370 1371 /* 1372 * fc_rport_tgt_remove - Removes the scsi target on the remote port 1373 * @rport: The remote port to be operated on 1374 */ 1375 static void 1376 fc_rport_tgt_remove(struct fc_rport *rport) 1377 { 1378 struct Scsi_Host *shost = rport_to_shost(rport); 1379 1380 scsi_target_unblock(&rport->dev); 1381 1382 /* Stop anything on the workq */ 1383 if (!cancel_delayed_work(&rport->dev_loss_work)) 1384 flush_scheduled_work(); 1385 scsi_flush_work(shost); 1386 1387 scsi_remove_target(&rport->dev); 1388 } 1389 1390 /* 1391 * fc_rport_terminate - this routine tears down and deallocates a remote port. 1392 * @rport: The remote port to be terminated 1393 * 1394 * Notes: 1395 * This routine assumes no locks are held on entry. 1396 */ 1397 static void 1398 fc_rport_terminate(struct fc_rport *rport) 1399 { 1400 struct Scsi_Host *shost = rport_to_shost(rport); 1401 struct device *dev = &rport->dev; 1402 unsigned long flags; 1403 1404 fc_rport_tgt_remove(rport); 1405 1406 transport_remove_device(dev); 1407 device_del(dev); 1408 transport_destroy_device(dev); 1409 spin_lock_irqsave(shost->host_lock, flags); 1410 list_del(&rport->peers); 1411 spin_unlock_irqrestore(shost->host_lock, flags); 1412 put_device(&shost->shost_gendev); 1413 } 1414 1415 /** 1416 * fc_remote_port_delete - notifies the fc transport that a remote 1417 * port is no longer in existence. 1418 * @rport: The remote port that no longer exists 1419 * 1420 * The LLDD calls this routine to notify the transport that a remote 1421 * port is no longer part of the topology. Note: Although a port 1422 * may no longer be part of the topology, it may persist in the remote 1423 * ports displayed by the fc_host. This is done so that target id 1424 * mappings (managed via the remote port structures), are always visible 1425 * as long as the mapping is valid, regardless of port state, 1426 * 1427 * If the remote port is not an FCP Target, it will be fully torn down 1428 * and deallocated, including the fc_remote_port class device. 1429 * 1430 * If the remote port is an FCP Target, the port structure will be 1431 * marked as Not Present, but will remain as long as there is a valid 1432 * SCSI target id mapping associated with the port structure. Validity 1433 * is determined by the binding type. If binding by wwpn, then the port 1434 * structure is always valid and will not be deallocated until the host 1435 * is removed. If binding by wwnn, then the port structure is valid 1436 * until another port with the same node name is found in the topology. 1437 * If binding by port id (fc address), then the port structure is valid 1438 * valid until another port with the same address is identified. 1439 * 1440 * Called from interrupt or normal process context. 1441 * 1442 * Notes: 1443 * This routine assumes no locks are held on entry. 1444 **/ 1445 void 1446 fc_remote_port_delete(struct fc_rport *rport) 1447 { 1448 struct Scsi_Host *shost = rport_to_shost(rport); 1449 unsigned long flags; 1450 1451 /* If no scsi target id mapping or consistent binding type, delete it */ 1452 if ((rport->scsi_target_id == -1) || 1453 (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE)) { 1454 fc_rport_terminate(rport); 1455 return; 1456 } 1457 1458 fc_rport_tgt_remove(rport); 1459 1460 spin_lock_irqsave(shost->host_lock, flags); 1461 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost)); 1462 spin_unlock_irqrestore(shost->host_lock, flags); 1463 1464 /* 1465 * Note: We do not remove or clear the hostdata area. This allows 1466 * host-specific target data to persist along with the 1467 * scsi_target_id. It's up to the host to manage it's hostdata area. 1468 */ 1469 1470 /* 1471 * Reinitialize port attributes that may change if the port comes back. 1472 */ 1473 rport->maxframe_size = -1; 1474 rport->supported_classes = FC_COS_UNSPECIFIED; 1475 rport->roles = FC_RPORT_ROLE_UNKNOWN; 1476 rport->port_state = FC_PORTSTATE_NOTPRESENT; 1477 1478 /* remove the identifiers that aren't used in the consisting binding */ 1479 switch (fc_host_tgtid_bind_type(shost)) { 1480 case FC_TGTID_BIND_BY_WWPN: 1481 rport->node_name = -1; 1482 rport->port_id = -1; 1483 break; 1484 case FC_TGTID_BIND_BY_WWNN: 1485 rport->port_name = -1; 1486 rport->port_id = -1; 1487 break; 1488 case FC_TGTID_BIND_BY_ID: 1489 rport->node_name = -1; 1490 rport->port_name = -1; 1491 break; 1492 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 1493 break; 1494 } 1495 } 1496 EXPORT_SYMBOL(fc_remote_port_delete); 1497 1498 /** 1499 * fc_remote_port_rolechg - notifies the fc transport that the roles 1500 * on a remote may have changed. 1501 * @rport: The remote port that changed. 1502 * 1503 * The LLDD calls this routine to notify the transport that the roles 1504 * on a remote port may have changed. The largest effect of this is 1505 * if a port now becomes a FCP Target, it must be allocated a 1506 * scsi target id. If the port is no longer a FCP target, any 1507 * scsi target id value assigned to it will persist in case the 1508 * role changes back to include FCP Target. No changes in the scsi 1509 * midlayer will be invoked if the role changes (in the expectation 1510 * that the role will be resumed. If it doesn't normal error processing 1511 * will take place). 1512 * 1513 * Should not be called from interrupt context. 1514 * 1515 * Notes: 1516 * This routine assumes no locks are held on entry. 1517 **/ 1518 void 1519 fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) 1520 { 1521 struct Scsi_Host *shost = rport_to_shost(rport); 1522 struct fc_host_attrs *fc_host = 1523 (struct fc_host_attrs *)shost->shost_data; 1524 unsigned long flags; 1525 int create = 0; 1526 1527 rport->roles = roles; 1528 1529 spin_lock_irqsave(shost->host_lock, flags); 1530 if ((rport->scsi_target_id == -1) && 1531 (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { 1532 rport->scsi_target_id = fc_host->next_target_id++; 1533 create = 1; 1534 } 1535 spin_unlock_irqrestore(shost->host_lock, flags); 1536 1537 if (create) 1538 /* initiate a scan of the target */ 1539 scsi_queue_work(shost, &rport->scan_work); 1540 } 1541 EXPORT_SYMBOL(fc_remote_port_rolechg); 1542 1543 /** 1544 * fc_timeout_blocked_rport - Timeout handler for blocked remote port 1545 * that fails to return in the alloted time. 1546 * @data: scsi target that failed to reappear in the alloted time. 1547 **/ 1548 static void 1549 fc_timeout_blocked_rport(void *data) 1550 { 1551 struct fc_rport *rport = (struct fc_rport *)data; 1552 1553 rport->port_state = FC_PORTSTATE_OFFLINE; 1554 1555 dev_printk(KERN_ERR, &rport->dev, 1556 "blocked FC remote port time out: removing target\n"); 1557 1558 /* 1559 * As this only occurs if the remote port (scsi target) 1560 * went away and didn't come back - we'll remove 1561 * all attached scsi devices. 1562 */ 1563 scsi_target_unblock(&rport->dev); 1564 scsi_remove_target(&rport->dev); 1565 } 1566 1567 /** 1568 * fc_remote_port_block - temporarily block any scsi traffic to a remote port. 1569 * @rport: remote port to be blocked. 1570 * 1571 * scsi lldd's with a FC transport call this routine to temporarily stop 1572 * all scsi traffic to a remote port. If the port is not a SCSI target, 1573 * no action is taken. If the port is a SCSI target, all attached devices 1574 * are placed into a SDEV_BLOCK state and a timer is started. The timer is 1575 * represents the maximum amount of time the port may be blocked. If the 1576 * timer expires, the port is considered non-existent and the attached 1577 * scsi devices will be removed. 1578 * 1579 * Called from interrupt or normal process context. 1580 * 1581 * Returns zero if successful or error if not 1582 * 1583 * Notes: 1584 * This routine assumes no locks are held on entry. 1585 * 1586 * The timeout and timer types are extracted from the fc transport 1587 * attributes from the caller's rport pointer. 1588 **/ 1589 int 1590 fc_remote_port_block(struct fc_rport *rport) 1591 { 1592 int timeout = rport->dev_loss_tmo; 1593 struct work_struct *work = &rport->dev_loss_work; 1594 1595 if (timeout < 0 || timeout > SCSI_DEVICE_BLOCK_MAX_TIMEOUT) 1596 return -EINVAL; 1597 1598 scsi_target_block(&rport->dev); 1599 1600 /* cap the length the devices can be blocked */ 1601 schedule_delayed_work(work, timeout * HZ); 1602 1603 rport->port_state = FC_PORTSTATE_BLOCKED; 1604 return 0; 1605 } 1606 EXPORT_SYMBOL(fc_remote_port_block); 1607 1608 /** 1609 * fc_remote_port_unblock - restart any blocked scsi traffic to a remote port. 1610 * @rport: remote port to be unblocked. 1611 * 1612 * scsi lld's with a FC transport call this routine to restart IO to all 1613 * devices associated with the caller's scsi target following a fc_target_block 1614 * request. Called from interrupt or normal process context. 1615 * 1616 * Notes: 1617 * This routine assumes no locks are held on entry. 1618 **/ 1619 void 1620 fc_remote_port_unblock(struct fc_rport *rport) 1621 { 1622 struct work_struct *work = &rport->dev_loss_work; 1623 struct Scsi_Host *shost = rport_to_shost(rport); 1624 1625 /* 1626 * Stop the target timer first. Take no action on the del_timer 1627 * failure as the state machine state change will validate the 1628 * transaction. 1629 */ 1630 if (!cancel_delayed_work(work)) 1631 flush_scheduled_work(); 1632 1633 if (rport->port_state == FC_PORTSTATE_OFFLINE) 1634 /* 1635 * initiate a scan of the target as the target has 1636 * been torn down. 1637 */ 1638 scsi_queue_work(shost, &rport->scan_work); 1639 else 1640 scsi_target_unblock(&rport->dev); 1641 1642 rport->port_state = FC_PORTSTATE_ONLINE; 1643 } 1644 EXPORT_SYMBOL(fc_remote_port_unblock); 1645 1646 /** 1647 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 1648 * @data: remote port to be scanned. 1649 **/ 1650 static void 1651 fc_scsi_scan_rport(void *data) 1652 { 1653 struct fc_rport *rport = (struct fc_rport *)data; 1654 1655 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, 1656 SCAN_WILD_CARD, 1); 1657 } 1658 1659 1660 MODULE_AUTHOR("Martin Hicks"); 1661 MODULE_DESCRIPTION("FC Transport Attributes"); 1662 MODULE_LICENSE("GPL"); 1663 1664 module_init(fc_transport_init); 1665 module_exit(fc_transport_exit); 1666