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 <linux/sched.h> /* workqueue stuff, HZ */ 30 #include <scsi/scsi_device.h> 31 #include <scsi/scsi_host.h> 32 #include <scsi/scsi_transport.h> 33 #include <scsi/scsi_transport_fc.h> 34 #include "scsi_priv.h" 35 36 /* 37 * Redefine so that we can have same named attributes in the 38 * sdev/starget/host objects. 39 */ 40 #define FC_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \ 41 struct class_device_attribute class_device_attr_##_prefix##_##_name = \ 42 __ATTR(_name,_mode,_show,_store) 43 44 #define fc_enum_name_search(title, table_type, table) \ 45 static const char *get_fc_##title##_name(enum table_type table_key) \ 46 { \ 47 int i; \ 48 char *name = NULL; \ 49 \ 50 for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ 51 if (table[i].value == table_key) { \ 52 name = table[i].name; \ 53 break; \ 54 } \ 55 } \ 56 return name; \ 57 } 58 59 #define fc_enum_name_match(title, table_type, table) \ 60 static int get_fc_##title##_match(const char *table_key, \ 61 enum table_type *value) \ 62 { \ 63 int i; \ 64 \ 65 for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) { \ 66 if (strncmp(table_key, table[i].name, \ 67 table[i].matchlen) == 0) { \ 68 *value = table[i].value; \ 69 return 0; /* success */ \ 70 } \ 71 } \ 72 return 1; /* failure */ \ 73 } 74 75 76 /* Convert fc_port_type values to ascii string name */ 77 static struct { 78 enum fc_port_type value; 79 char *name; 80 } fc_port_type_names[] = { 81 { FC_PORTTYPE_UNKNOWN, "Unknown" }, 82 { FC_PORTTYPE_OTHER, "Other" }, 83 { FC_PORTTYPE_NOTPRESENT, "Not Present" }, 84 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" }, 85 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" }, 86 { FC_PORTTYPE_LPORT, "LPort (private loop)" }, 87 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection" }, 88 }; 89 fc_enum_name_search(port_type, fc_port_type, fc_port_type_names) 90 #define FC_PORTTYPE_MAX_NAMELEN 50 91 92 93 /* Convert fc_port_state values to ascii string name */ 94 static struct { 95 enum fc_port_state value; 96 char *name; 97 } fc_port_state_names[] = { 98 { FC_PORTSTATE_UNKNOWN, "Unknown" }, 99 { FC_PORTSTATE_NOTPRESENT, "Not Present" }, 100 { FC_PORTSTATE_ONLINE, "Online" }, 101 { FC_PORTSTATE_OFFLINE, "Offline" }, 102 { FC_PORTSTATE_BLOCKED, "Blocked" }, 103 { FC_PORTSTATE_BYPASSED, "Bypassed" }, 104 { FC_PORTSTATE_DIAGNOSTICS, "Diagnostics" }, 105 { FC_PORTSTATE_LINKDOWN, "Linkdown" }, 106 { FC_PORTSTATE_ERROR, "Error" }, 107 { FC_PORTSTATE_LOOPBACK, "Loopback" }, 108 { FC_PORTSTATE_DELETED, "Deleted" }, 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 const 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 const 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 const 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 const 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_shost_remove_rports(void *data); 216 static void fc_timeout_deleted_rport(void *data); 217 static void fc_scsi_scan_rport(void *data); 218 static void fc_rport_terminate(struct fc_rport *rport); 219 220 /* 221 * Attribute counts pre object type... 222 * Increase these values if you add attributes 223 */ 224 #define FC_STARGET_NUM_ATTRS 3 225 #define FC_RPORT_NUM_ATTRS 9 226 #define FC_HOST_NUM_ATTRS 16 227 228 struct fc_internal { 229 struct scsi_transport_template t; 230 struct fc_function_template *f; 231 232 /* 233 * For attributes : each object has : 234 * An array of the actual attributes structures 235 * An array of null-terminated pointers to the attribute 236 * structures - used for mid-layer interaction. 237 * 238 * The attribute containers for the starget and host are are 239 * part of the midlayer. As the remote port is specific to the 240 * fc transport, we must provide the attribute container. 241 */ 242 struct class_device_attribute private_starget_attrs[ 243 FC_STARGET_NUM_ATTRS]; 244 struct class_device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1]; 245 246 struct class_device_attribute private_host_attrs[FC_HOST_NUM_ATTRS]; 247 struct class_device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1]; 248 249 struct transport_container rport_attr_cont; 250 struct class_device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS]; 251 struct class_device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1]; 252 }; 253 254 #define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t) 255 256 static int fc_target_setup(struct transport_container *tc, struct device *dev, 257 struct class_device *cdev) 258 { 259 struct scsi_target *starget = to_scsi_target(dev); 260 struct fc_rport *rport = starget_to_rport(starget); 261 262 /* 263 * if parent is remote port, use values from remote port. 264 * Otherwise, this host uses the fc_transport, but not the 265 * remote port interface. As such, initialize to known non-values. 266 */ 267 if (rport) { 268 fc_starget_node_name(starget) = rport->node_name; 269 fc_starget_port_name(starget) = rport->port_name; 270 fc_starget_port_id(starget) = rport->port_id; 271 } else { 272 fc_starget_node_name(starget) = -1; 273 fc_starget_port_name(starget) = -1; 274 fc_starget_port_id(starget) = -1; 275 } 276 277 return 0; 278 } 279 280 static DECLARE_TRANSPORT_CLASS(fc_transport_class, 281 "fc_transport", 282 fc_target_setup, 283 NULL, 284 NULL); 285 286 static int fc_host_setup(struct transport_container *tc, struct device *dev, 287 struct class_device *cdev) 288 { 289 struct Scsi_Host *shost = dev_to_shost(dev); 290 291 /* 292 * Set default values easily detected by the midlayer as 293 * failure cases. The scsi lldd is responsible for initializing 294 * all transport attributes to valid values per host. 295 */ 296 fc_host_node_name(shost) = -1; 297 fc_host_port_name(shost) = -1; 298 fc_host_supported_classes(shost) = FC_COS_UNSPECIFIED; 299 memset(fc_host_supported_fc4s(shost), 0, 300 sizeof(fc_host_supported_fc4s(shost))); 301 memset(fc_host_symbolic_name(shost), 0, 302 sizeof(fc_host_symbolic_name(shost))); 303 fc_host_supported_speeds(shost) = FC_PORTSPEED_UNKNOWN; 304 fc_host_maxframe_size(shost) = -1; 305 memset(fc_host_serial_number(shost), 0, 306 sizeof(fc_host_serial_number(shost))); 307 308 fc_host_port_id(shost) = -1; 309 fc_host_port_type(shost) = FC_PORTTYPE_UNKNOWN; 310 fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; 311 memset(fc_host_active_fc4s(shost), 0, 312 sizeof(fc_host_active_fc4s(shost))); 313 fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; 314 fc_host_fabric_name(shost) = -1; 315 316 fc_host_tgtid_bind_type(shost) = FC_TGTID_BIND_BY_WWPN; 317 318 INIT_LIST_HEAD(&fc_host_rports(shost)); 319 INIT_LIST_HEAD(&fc_host_rport_bindings(shost)); 320 fc_host_next_rport_number(shost) = 0; 321 fc_host_next_target_id(shost) = 0; 322 323 fc_host_flags(shost) = 0; 324 INIT_WORK(&fc_host_rport_del_work(shost), fc_shost_remove_rports, shost); 325 return 0; 326 } 327 328 static DECLARE_TRANSPORT_CLASS(fc_host_class, 329 "fc_host", 330 fc_host_setup, 331 NULL, 332 NULL); 333 334 /* 335 * Setup and Remove actions for remote ports are handled 336 * in the service functions below. 337 */ 338 static DECLARE_TRANSPORT_CLASS(fc_rport_class, 339 "fc_remote_ports", 340 NULL, 341 NULL, 342 NULL); 343 344 /* 345 * Module Parameters 346 */ 347 348 /* 349 * dev_loss_tmo: the default number of seconds that the FC transport 350 * should insulate the loss of a remote port. 351 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. 352 */ 353 static unsigned int fc_dev_loss_tmo = SCSI_DEVICE_BLOCK_MAX_TIMEOUT; 354 355 module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); 356 MODULE_PARM_DESC(dev_loss_tmo, 357 "Maximum number of seconds that the FC transport should" 358 " insulate the loss of a remote port. Once this value is" 359 " exceeded, the scsi target is removed. Value should be" 360 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); 361 362 363 static __init int fc_transport_init(void) 364 { 365 int error = transport_class_register(&fc_host_class); 366 if (error) 367 return error; 368 error = transport_class_register(&fc_rport_class); 369 if (error) 370 return error; 371 return transport_class_register(&fc_transport_class); 372 } 373 374 static void __exit fc_transport_exit(void) 375 { 376 transport_class_unregister(&fc_transport_class); 377 transport_class_unregister(&fc_rport_class); 378 transport_class_unregister(&fc_host_class); 379 } 380 381 /* 382 * FC Remote Port Attribute Management 383 */ 384 385 #define fc_rport_show_function(field, format_string, sz, cast) \ 386 static ssize_t \ 387 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 388 { \ 389 struct fc_rport *rport = transport_class_to_rport(cdev); \ 390 struct Scsi_Host *shost = rport_to_shost(rport); \ 391 struct fc_internal *i = to_fc_internal(shost->transportt); \ 392 if ((i->f->get_rport_##field) && \ 393 !((rport->port_state == FC_PORTSTATE_BLOCKED) || \ 394 (rport->port_state == FC_PORTSTATE_DELETED) || \ 395 (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \ 396 i->f->get_rport_##field(rport); \ 397 return snprintf(buf, sz, format_string, cast rport->field); \ 398 } 399 400 #define fc_rport_store_function(field) \ 401 static ssize_t \ 402 store_fc_rport_##field(struct class_device *cdev, const char *buf, \ 403 size_t count) \ 404 { \ 405 int val; \ 406 struct fc_rport *rport = transport_class_to_rport(cdev); \ 407 struct Scsi_Host *shost = rport_to_shost(rport); \ 408 struct fc_internal *i = to_fc_internal(shost->transportt); \ 409 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ 410 (rport->port_state == FC_PORTSTATE_DELETED) || \ 411 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ 412 return -EBUSY; \ 413 val = simple_strtoul(buf, NULL, 0); \ 414 i->f->set_rport_##field(rport, val); \ 415 return count; \ 416 } 417 418 #define fc_rport_rd_attr(field, format_string, sz) \ 419 fc_rport_show_function(field, format_string, sz, ) \ 420 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 421 show_fc_rport_##field, NULL) 422 423 #define fc_rport_rd_attr_cast(field, format_string, sz, cast) \ 424 fc_rport_show_function(field, format_string, sz, (cast)) \ 425 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 426 show_fc_rport_##field, NULL) 427 428 #define fc_rport_rw_attr(field, format_string, sz) \ 429 fc_rport_show_function(field, format_string, sz, ) \ 430 fc_rport_store_function(field) \ 431 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO | S_IWUSR, \ 432 show_fc_rport_##field, \ 433 store_fc_rport_##field) 434 435 436 #define fc_private_rport_show_function(field, format_string, sz, cast) \ 437 static ssize_t \ 438 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 439 { \ 440 struct fc_rport *rport = transport_class_to_rport(cdev); \ 441 return snprintf(buf, sz, format_string, cast rport->field); \ 442 } 443 444 #define fc_private_rport_rd_attr(field, format_string, sz) \ 445 fc_private_rport_show_function(field, format_string, sz, ) \ 446 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 447 show_fc_rport_##field, NULL) 448 449 #define fc_private_rport_rd_attr_cast(field, format_string, sz, cast) \ 450 fc_private_rport_show_function(field, format_string, sz, (cast)) \ 451 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 452 show_fc_rport_##field, NULL) 453 454 455 #define fc_private_rport_rd_enum_attr(title, maxlen) \ 456 static ssize_t \ 457 show_fc_rport_##title (struct class_device *cdev, char *buf) \ 458 { \ 459 struct fc_rport *rport = transport_class_to_rport(cdev); \ 460 const char *name; \ 461 name = get_fc_##title##_name(rport->title); \ 462 if (!name) \ 463 return -EINVAL; \ 464 return snprintf(buf, maxlen, "%s\n", name); \ 465 } \ 466 static FC_CLASS_DEVICE_ATTR(rport, title, S_IRUGO, \ 467 show_fc_rport_##title, NULL) 468 469 470 #define SETUP_RPORT_ATTRIBUTE_RD(field) \ 471 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 472 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 473 i->private_rport_attrs[count].store = NULL; \ 474 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 475 if (i->f->show_rport_##field) \ 476 count++ 477 478 #define SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(field) \ 479 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 480 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 481 i->private_rport_attrs[count].store = NULL; \ 482 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 483 count++ 484 485 #define SETUP_RPORT_ATTRIBUTE_RW(field) \ 486 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 487 if (!i->f->set_rport_##field) { \ 488 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 489 i->private_rport_attrs[count].store = NULL; \ 490 } \ 491 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 492 if (i->f->show_rport_##field) \ 493 count++ 494 495 496 /* The FC Transport Remote Port Attributes: */ 497 498 /* Fixed Remote Port Attributes */ 499 500 fc_private_rport_rd_attr(maxframe_size, "%u bytes\n", 20); 501 502 static ssize_t 503 show_fc_rport_supported_classes (struct class_device *cdev, char *buf) 504 { 505 struct fc_rport *rport = transport_class_to_rport(cdev); 506 if (rport->supported_classes == FC_COS_UNSPECIFIED) 507 return snprintf(buf, 20, "unspecified\n"); 508 return get_fc_cos_names(rport->supported_classes, buf); 509 } 510 static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO, 511 show_fc_rport_supported_classes, NULL); 512 513 /* Dynamic Remote Port Attributes */ 514 515 /* 516 * dev_loss_tmo attribute 517 */ 518 fc_rport_show_function(dev_loss_tmo, "%d\n", 20, ) 519 static ssize_t 520 store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf, 521 size_t count) 522 { 523 int val; 524 struct fc_rport *rport = transport_class_to_rport(cdev); 525 struct Scsi_Host *shost = rport_to_shost(rport); 526 struct fc_internal *i = to_fc_internal(shost->transportt); 527 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 528 (rport->port_state == FC_PORTSTATE_DELETED) || 529 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 530 return -EBUSY; 531 val = simple_strtoul(buf, NULL, 0); 532 if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)) 533 return -EINVAL; 534 i->f->set_rport_dev_loss_tmo(rport, val); 535 return count; 536 } 537 static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR, 538 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo); 539 540 541 /* Private Remote Port Attributes */ 542 543 fc_private_rport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 544 fc_private_rport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 545 fc_private_rport_rd_attr(port_id, "0x%06x\n", 20); 546 547 static ssize_t 548 show_fc_rport_roles (struct class_device *cdev, char *buf) 549 { 550 struct fc_rport *rport = transport_class_to_rport(cdev); 551 552 /* identify any roles that are port_id specific */ 553 if ((rport->port_id != -1) && 554 (rport->port_id & FC_WELLKNOWN_PORTID_MASK) == 555 FC_WELLKNOWN_PORTID_MASK) { 556 switch (rport->port_id & FC_WELLKNOWN_ROLE_MASK) { 557 case FC_FPORT_PORTID: 558 return snprintf(buf, 30, "Fabric Port\n"); 559 case FC_FABCTLR_PORTID: 560 return snprintf(buf, 30, "Fabric Controller\n"); 561 case FC_DIRSRVR_PORTID: 562 return snprintf(buf, 30, "Directory Server\n"); 563 case FC_TIMESRVR_PORTID: 564 return snprintf(buf, 30, "Time Server\n"); 565 case FC_MGMTSRVR_PORTID: 566 return snprintf(buf, 30, "Management Server\n"); 567 default: 568 return snprintf(buf, 30, "Unknown Fabric Entity\n"); 569 } 570 } else { 571 if (rport->roles == FC_RPORT_ROLE_UNKNOWN) 572 return snprintf(buf, 20, "unknown\n"); 573 return get_fc_remote_port_roles_names(rport->roles, buf); 574 } 575 } 576 static FC_CLASS_DEVICE_ATTR(rport, roles, S_IRUGO, 577 show_fc_rport_roles, NULL); 578 579 fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 580 fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20); 581 582 583 584 /* 585 * FC SCSI Target Attribute Management 586 */ 587 588 /* 589 * Note: in the target show function we recognize when the remote 590 * port is in the heirarchy and do not allow the driver to get 591 * involved in sysfs functions. The driver only gets involved if 592 * it's the "old" style that doesn't use rports. 593 */ 594 #define fc_starget_show_function(field, format_string, sz, cast) \ 595 static ssize_t \ 596 show_fc_starget_##field (struct class_device *cdev, char *buf) \ 597 { \ 598 struct scsi_target *starget = transport_class_to_starget(cdev); \ 599 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ 600 struct fc_internal *i = to_fc_internal(shost->transportt); \ 601 struct fc_rport *rport = starget_to_rport(starget); \ 602 if (rport) \ 603 fc_starget_##field(starget) = rport->field; \ 604 else if (i->f->get_starget_##field) \ 605 i->f->get_starget_##field(starget); \ 606 return snprintf(buf, sz, format_string, \ 607 cast fc_starget_##field(starget)); \ 608 } 609 610 #define fc_starget_rd_attr(field, format_string, sz) \ 611 fc_starget_show_function(field, format_string, sz, ) \ 612 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 613 show_fc_starget_##field, NULL) 614 615 #define fc_starget_rd_attr_cast(field, format_string, sz, cast) \ 616 fc_starget_show_function(field, format_string, sz, (cast)) \ 617 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 618 show_fc_starget_##field, NULL) 619 620 #define SETUP_STARGET_ATTRIBUTE_RD(field) \ 621 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 622 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 623 i->private_starget_attrs[count].store = NULL; \ 624 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 625 if (i->f->show_starget_##field) \ 626 count++ 627 628 #define SETUP_STARGET_ATTRIBUTE_RW(field) \ 629 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 630 if (!i->f->set_starget_##field) { \ 631 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 632 i->private_starget_attrs[count].store = NULL; \ 633 } \ 634 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 635 if (i->f->show_starget_##field) \ 636 count++ 637 638 /* The FC Transport SCSI Target Attributes: */ 639 fc_starget_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 640 fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 641 fc_starget_rd_attr(port_id, "0x%06x\n", 20); 642 643 644 /* 645 * Host Attribute Management 646 */ 647 648 #define fc_host_show_function(field, format_string, sz, cast) \ 649 static ssize_t \ 650 show_fc_host_##field (struct class_device *cdev, char *buf) \ 651 { \ 652 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 653 struct fc_internal *i = to_fc_internal(shost->transportt); \ 654 if (i->f->get_host_##field) \ 655 i->f->get_host_##field(shost); \ 656 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 657 } 658 659 #define fc_host_store_function(field) \ 660 static ssize_t \ 661 store_fc_host_##field(struct class_device *cdev, const char *buf, \ 662 size_t count) \ 663 { \ 664 int val; \ 665 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 666 struct fc_internal *i = to_fc_internal(shost->transportt); \ 667 \ 668 val = simple_strtoul(buf, NULL, 0); \ 669 i->f->set_host_##field(shost, val); \ 670 return count; \ 671 } 672 673 #define fc_host_rd_attr(field, format_string, sz) \ 674 fc_host_show_function(field, format_string, sz, ) \ 675 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 676 show_fc_host_##field, NULL) 677 678 #define fc_host_rd_attr_cast(field, format_string, sz, cast) \ 679 fc_host_show_function(field, format_string, sz, (cast)) \ 680 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 681 show_fc_host_##field, NULL) 682 683 #define fc_host_rw_attr(field, format_string, sz) \ 684 fc_host_show_function(field, format_string, sz, ) \ 685 fc_host_store_function(field) \ 686 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR, \ 687 show_fc_host_##field, \ 688 store_fc_host_##field) 689 690 #define fc_host_rd_enum_attr(title, maxlen) \ 691 static ssize_t \ 692 show_fc_host_##title (struct class_device *cdev, char *buf) \ 693 { \ 694 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 695 struct fc_internal *i = to_fc_internal(shost->transportt); \ 696 const char *name; \ 697 if (i->f->get_host_##title) \ 698 i->f->get_host_##title(shost); \ 699 name = get_fc_##title##_name(fc_host_##title(shost)); \ 700 if (!name) \ 701 return -EINVAL; \ 702 return snprintf(buf, maxlen, "%s\n", name); \ 703 } \ 704 static FC_CLASS_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL) 705 706 #define SETUP_HOST_ATTRIBUTE_RD(field) \ 707 i->private_host_attrs[count] = class_device_attr_host_##field; \ 708 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 709 i->private_host_attrs[count].store = NULL; \ 710 i->host_attrs[count] = &i->private_host_attrs[count]; \ 711 if (i->f->show_host_##field) \ 712 count++ 713 714 #define SETUP_HOST_ATTRIBUTE_RW(field) \ 715 i->private_host_attrs[count] = class_device_attr_host_##field; \ 716 if (!i->f->set_host_##field) { \ 717 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 718 i->private_host_attrs[count].store = NULL; \ 719 } \ 720 i->host_attrs[count] = &i->private_host_attrs[count]; \ 721 if (i->f->show_host_##field) \ 722 count++ 723 724 725 #define fc_private_host_show_function(field, format_string, sz, cast) \ 726 static ssize_t \ 727 show_fc_host_##field (struct class_device *cdev, char *buf) \ 728 { \ 729 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 730 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 731 } 732 733 #define fc_private_host_rd_attr(field, format_string, sz) \ 734 fc_private_host_show_function(field, format_string, sz, ) \ 735 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 736 show_fc_host_##field, NULL) 737 738 #define fc_private_host_rd_attr_cast(field, format_string, sz, cast) \ 739 fc_private_host_show_function(field, format_string, sz, (cast)) \ 740 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 741 show_fc_host_##field, NULL) 742 743 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field) \ 744 i->private_host_attrs[count] = class_device_attr_host_##field; \ 745 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 746 i->private_host_attrs[count].store = NULL; \ 747 i->host_attrs[count] = &i->private_host_attrs[count]; \ 748 count++ 749 750 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \ 751 { \ 752 i->private_host_attrs[count] = class_device_attr_host_##field; \ 753 i->host_attrs[count] = &i->private_host_attrs[count]; \ 754 count++; \ 755 } 756 757 758 /* Fixed Host Attributes */ 759 760 static ssize_t 761 show_fc_host_supported_classes (struct class_device *cdev, char *buf) 762 { 763 struct Scsi_Host *shost = transport_class_to_shost(cdev); 764 765 if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED) 766 return snprintf(buf, 20, "unspecified\n"); 767 768 return get_fc_cos_names(fc_host_supported_classes(shost), buf); 769 } 770 static FC_CLASS_DEVICE_ATTR(host, supported_classes, S_IRUGO, 771 show_fc_host_supported_classes, NULL); 772 773 static ssize_t 774 show_fc_host_supported_fc4s (struct class_device *cdev, char *buf) 775 { 776 struct Scsi_Host *shost = transport_class_to_shost(cdev); 777 return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost)); 778 } 779 static FC_CLASS_DEVICE_ATTR(host, supported_fc4s, S_IRUGO, 780 show_fc_host_supported_fc4s, NULL); 781 782 static ssize_t 783 show_fc_host_supported_speeds (struct class_device *cdev, char *buf) 784 { 785 struct Scsi_Host *shost = transport_class_to_shost(cdev); 786 787 if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN) 788 return snprintf(buf, 20, "unknown\n"); 789 790 return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf); 791 } 792 static FC_CLASS_DEVICE_ATTR(host, supported_speeds, S_IRUGO, 793 show_fc_host_supported_speeds, NULL); 794 795 796 fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 797 fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 798 fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1)); 799 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20); 800 fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1)); 801 802 803 /* Dynamic Host Attributes */ 804 805 static ssize_t 806 show_fc_host_active_fc4s (struct class_device *cdev, char *buf) 807 { 808 struct Scsi_Host *shost = transport_class_to_shost(cdev); 809 struct fc_internal *i = to_fc_internal(shost->transportt); 810 811 if (i->f->get_host_active_fc4s) 812 i->f->get_host_active_fc4s(shost); 813 814 return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost)); 815 } 816 static FC_CLASS_DEVICE_ATTR(host, active_fc4s, S_IRUGO, 817 show_fc_host_active_fc4s, NULL); 818 819 static ssize_t 820 show_fc_host_speed (struct class_device *cdev, char *buf) 821 { 822 struct Scsi_Host *shost = transport_class_to_shost(cdev); 823 struct fc_internal *i = to_fc_internal(shost->transportt); 824 825 if (i->f->get_host_speed) 826 i->f->get_host_speed(shost); 827 828 if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN) 829 return snprintf(buf, 20, "unknown\n"); 830 831 return get_fc_port_speed_names(fc_host_speed(shost), buf); 832 } 833 static FC_CLASS_DEVICE_ATTR(host, speed, S_IRUGO, 834 show_fc_host_speed, NULL); 835 836 837 fc_host_rd_attr(port_id, "0x%06x\n", 20); 838 fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN); 839 fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 840 fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 841 842 843 /* Private Host Attributes */ 844 845 static ssize_t 846 show_fc_private_host_tgtid_bind_type(struct class_device *cdev, char *buf) 847 { 848 struct Scsi_Host *shost = transport_class_to_shost(cdev); 849 const char *name; 850 851 name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost)); 852 if (!name) 853 return -EINVAL; 854 return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name); 855 } 856 857 #define get_list_head_entry(pos, head, member) \ 858 pos = list_entry((head)->next, typeof(*pos), member) 859 860 static ssize_t 861 store_fc_private_host_tgtid_bind_type(struct class_device *cdev, 862 const char *buf, size_t count) 863 { 864 struct Scsi_Host *shost = transport_class_to_shost(cdev); 865 struct fc_rport *rport; 866 enum fc_tgtid_binding_type val; 867 unsigned long flags; 868 869 if (get_fc_tgtid_bind_type_match(buf, &val)) 870 return -EINVAL; 871 872 /* if changing bind type, purge all unused consistent bindings */ 873 if (val != fc_host_tgtid_bind_type(shost)) { 874 spin_lock_irqsave(shost->host_lock, flags); 875 while (!list_empty(&fc_host_rport_bindings(shost))) { 876 get_list_head_entry(rport, 877 &fc_host_rport_bindings(shost), peers); 878 spin_unlock_irqrestore(shost->host_lock, flags); 879 fc_rport_terminate(rport); 880 spin_lock_irqsave(shost->host_lock, flags); 881 } 882 spin_unlock_irqrestore(shost->host_lock, flags); 883 } 884 885 fc_host_tgtid_bind_type(shost) = val; 886 return count; 887 } 888 889 static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR, 890 show_fc_private_host_tgtid_bind_type, 891 store_fc_private_host_tgtid_bind_type); 892 893 static ssize_t 894 store_fc_private_host_issue_lip(struct class_device *cdev, 895 const char *buf, size_t count) 896 { 897 struct Scsi_Host *shost = transport_class_to_shost(cdev); 898 struct fc_internal *i = to_fc_internal(shost->transportt); 899 int ret; 900 901 /* ignore any data value written to the attribute */ 902 if (i->f->issue_fc_host_lip) { 903 ret = i->f->issue_fc_host_lip(shost); 904 return ret ? ret: count; 905 } 906 907 return -ENOENT; 908 } 909 910 static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL, 911 store_fc_private_host_issue_lip); 912 913 /* 914 * Host Statistics Management 915 */ 916 917 /* Show a given an attribute in the statistics group */ 918 static ssize_t 919 fc_stat_show(const struct class_device *cdev, char *buf, unsigned long offset) 920 { 921 struct Scsi_Host *shost = transport_class_to_shost(cdev); 922 struct fc_internal *i = to_fc_internal(shost->transportt); 923 struct fc_host_statistics *stats; 924 ssize_t ret = -ENOENT; 925 926 if (offset > sizeof(struct fc_host_statistics) || 927 offset % sizeof(u64) != 0) 928 WARN_ON(1); 929 930 if (i->f->get_fc_host_stats) { 931 stats = (i->f->get_fc_host_stats)(shost); 932 if (stats) 933 ret = snprintf(buf, 20, "0x%llx\n", 934 (unsigned long long)*(u64 *)(((u8 *) stats) + offset)); 935 } 936 return ret; 937 } 938 939 940 /* generate a read-only statistics attribute */ 941 #define fc_host_statistic(name) \ 942 static ssize_t show_fcstat_##name(struct class_device *cd, char *buf) \ 943 { \ 944 return fc_stat_show(cd, buf, \ 945 offsetof(struct fc_host_statistics, name)); \ 946 } \ 947 static FC_CLASS_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL) 948 949 fc_host_statistic(seconds_since_last_reset); 950 fc_host_statistic(tx_frames); 951 fc_host_statistic(tx_words); 952 fc_host_statistic(rx_frames); 953 fc_host_statistic(rx_words); 954 fc_host_statistic(lip_count); 955 fc_host_statistic(nos_count); 956 fc_host_statistic(error_frames); 957 fc_host_statistic(dumped_frames); 958 fc_host_statistic(link_failure_count); 959 fc_host_statistic(loss_of_sync_count); 960 fc_host_statistic(loss_of_signal_count); 961 fc_host_statistic(prim_seq_protocol_err_count); 962 fc_host_statistic(invalid_tx_word_count); 963 fc_host_statistic(invalid_crc_count); 964 fc_host_statistic(fcp_input_requests); 965 fc_host_statistic(fcp_output_requests); 966 fc_host_statistic(fcp_control_requests); 967 fc_host_statistic(fcp_input_megabytes); 968 fc_host_statistic(fcp_output_megabytes); 969 970 static ssize_t 971 fc_reset_statistics(struct class_device *cdev, const char *buf, 972 size_t count) 973 { 974 struct Scsi_Host *shost = transport_class_to_shost(cdev); 975 struct fc_internal *i = to_fc_internal(shost->transportt); 976 977 /* ignore any data value written to the attribute */ 978 if (i->f->reset_fc_host_stats) { 979 i->f->reset_fc_host_stats(shost); 980 return count; 981 } 982 983 return -ENOENT; 984 } 985 static FC_CLASS_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL, 986 fc_reset_statistics); 987 988 989 static struct attribute *fc_statistics_attrs[] = { 990 &class_device_attr_host_seconds_since_last_reset.attr, 991 &class_device_attr_host_tx_frames.attr, 992 &class_device_attr_host_tx_words.attr, 993 &class_device_attr_host_rx_frames.attr, 994 &class_device_attr_host_rx_words.attr, 995 &class_device_attr_host_lip_count.attr, 996 &class_device_attr_host_nos_count.attr, 997 &class_device_attr_host_error_frames.attr, 998 &class_device_attr_host_dumped_frames.attr, 999 &class_device_attr_host_link_failure_count.attr, 1000 &class_device_attr_host_loss_of_sync_count.attr, 1001 &class_device_attr_host_loss_of_signal_count.attr, 1002 &class_device_attr_host_prim_seq_protocol_err_count.attr, 1003 &class_device_attr_host_invalid_tx_word_count.attr, 1004 &class_device_attr_host_invalid_crc_count.attr, 1005 &class_device_attr_host_fcp_input_requests.attr, 1006 &class_device_attr_host_fcp_output_requests.attr, 1007 &class_device_attr_host_fcp_control_requests.attr, 1008 &class_device_attr_host_fcp_input_megabytes.attr, 1009 &class_device_attr_host_fcp_output_megabytes.attr, 1010 &class_device_attr_host_reset_statistics.attr, 1011 NULL 1012 }; 1013 1014 static struct attribute_group fc_statistics_group = { 1015 .name = "statistics", 1016 .attrs = fc_statistics_attrs, 1017 }; 1018 1019 static int fc_host_match(struct attribute_container *cont, 1020 struct device *dev) 1021 { 1022 struct Scsi_Host *shost; 1023 struct fc_internal *i; 1024 1025 if (!scsi_is_host_device(dev)) 1026 return 0; 1027 1028 shost = dev_to_shost(dev); 1029 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1030 != &fc_host_class.class) 1031 return 0; 1032 1033 i = to_fc_internal(shost->transportt); 1034 1035 return &i->t.host_attrs.ac == cont; 1036 } 1037 1038 static int fc_target_match(struct attribute_container *cont, 1039 struct device *dev) 1040 { 1041 struct Scsi_Host *shost; 1042 struct fc_internal *i; 1043 1044 if (!scsi_is_target_device(dev)) 1045 return 0; 1046 1047 shost = dev_to_shost(dev->parent); 1048 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1049 != &fc_host_class.class) 1050 return 0; 1051 1052 i = to_fc_internal(shost->transportt); 1053 1054 return &i->t.target_attrs.ac == cont; 1055 } 1056 1057 static void fc_rport_dev_release(struct device *dev) 1058 { 1059 struct fc_rport *rport = dev_to_rport(dev); 1060 put_device(dev->parent); 1061 kfree(rport); 1062 } 1063 1064 int scsi_is_fc_rport(const struct device *dev) 1065 { 1066 return dev->release == fc_rport_dev_release; 1067 } 1068 EXPORT_SYMBOL(scsi_is_fc_rport); 1069 1070 static int fc_rport_match(struct attribute_container *cont, 1071 struct device *dev) 1072 { 1073 struct Scsi_Host *shost; 1074 struct fc_internal *i; 1075 1076 if (!scsi_is_fc_rport(dev)) 1077 return 0; 1078 1079 shost = dev_to_shost(dev->parent); 1080 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1081 != &fc_host_class.class) 1082 return 0; 1083 1084 i = to_fc_internal(shost->transportt); 1085 1086 return &i->rport_attr_cont.ac == cont; 1087 } 1088 1089 1090 /* 1091 * Must be called with shost->host_lock held 1092 */ 1093 static struct device *fc_target_parent(struct Scsi_Host *shost, 1094 int channel, uint id) 1095 { 1096 struct fc_rport *rport; 1097 1098 list_for_each_entry(rport, &fc_host_rports(shost), peers) 1099 if ((rport->channel == channel) && 1100 (rport->scsi_target_id == id)) 1101 return &rport->dev; 1102 1103 return NULL; 1104 } 1105 1106 struct scsi_transport_template * 1107 fc_attach_transport(struct fc_function_template *ft) 1108 { 1109 struct fc_internal *i = kmalloc(sizeof(struct fc_internal), 1110 GFP_KERNEL); 1111 int count; 1112 1113 if (unlikely(!i)) 1114 return NULL; 1115 1116 memset(i, 0, sizeof(struct fc_internal)); 1117 1118 i->t.target_attrs.ac.attrs = &i->starget_attrs[0]; 1119 i->t.target_attrs.ac.class = &fc_transport_class.class; 1120 i->t.target_attrs.ac.match = fc_target_match; 1121 i->t.target_size = sizeof(struct fc_starget_attrs); 1122 transport_container_register(&i->t.target_attrs); 1123 1124 i->t.host_attrs.ac.attrs = &i->host_attrs[0]; 1125 i->t.host_attrs.ac.class = &fc_host_class.class; 1126 i->t.host_attrs.ac.match = fc_host_match; 1127 i->t.host_size = sizeof(struct fc_host_attrs); 1128 if (ft->get_fc_host_stats) 1129 i->t.host_attrs.statistics = &fc_statistics_group; 1130 transport_container_register(&i->t.host_attrs); 1131 1132 i->rport_attr_cont.ac.attrs = &i->rport_attrs[0]; 1133 i->rport_attr_cont.ac.class = &fc_rport_class.class; 1134 i->rport_attr_cont.ac.match = fc_rport_match; 1135 transport_container_register(&i->rport_attr_cont); 1136 1137 i->f = ft; 1138 1139 /* Transport uses the shost workq for scsi scanning */ 1140 i->t.create_work_queue = 1; 1141 1142 i->t.target_parent = fc_target_parent; 1143 1144 /* 1145 * Setup SCSI Target Attributes. 1146 */ 1147 count = 0; 1148 SETUP_STARGET_ATTRIBUTE_RD(node_name); 1149 SETUP_STARGET_ATTRIBUTE_RD(port_name); 1150 SETUP_STARGET_ATTRIBUTE_RD(port_id); 1151 1152 BUG_ON(count > FC_STARGET_NUM_ATTRS); 1153 1154 i->starget_attrs[count] = NULL; 1155 1156 1157 /* 1158 * Setup SCSI Host Attributes. 1159 */ 1160 count=0; 1161 SETUP_HOST_ATTRIBUTE_RD(node_name); 1162 SETUP_HOST_ATTRIBUTE_RD(port_name); 1163 SETUP_HOST_ATTRIBUTE_RD(supported_classes); 1164 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s); 1165 SETUP_HOST_ATTRIBUTE_RD(symbolic_name); 1166 SETUP_HOST_ATTRIBUTE_RD(supported_speeds); 1167 SETUP_HOST_ATTRIBUTE_RD(maxframe_size); 1168 SETUP_HOST_ATTRIBUTE_RD(serial_number); 1169 1170 SETUP_HOST_ATTRIBUTE_RD(port_id); 1171 SETUP_HOST_ATTRIBUTE_RD(port_type); 1172 SETUP_HOST_ATTRIBUTE_RD(port_state); 1173 SETUP_HOST_ATTRIBUTE_RD(active_fc4s); 1174 SETUP_HOST_ATTRIBUTE_RD(speed); 1175 SETUP_HOST_ATTRIBUTE_RD(fabric_name); 1176 1177 /* Transport-managed attributes */ 1178 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 1179 if (ft->issue_fc_host_lip) 1180 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip); 1181 1182 BUG_ON(count > FC_HOST_NUM_ATTRS); 1183 1184 i->host_attrs[count] = NULL; 1185 1186 /* 1187 * Setup Remote Port Attributes. 1188 */ 1189 count=0; 1190 SETUP_RPORT_ATTRIBUTE_RD(maxframe_size); 1191 SETUP_RPORT_ATTRIBUTE_RD(supported_classes); 1192 SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo); 1193 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name); 1194 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name); 1195 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id); 1196 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles); 1197 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state); 1198 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id); 1199 1200 BUG_ON(count > FC_RPORT_NUM_ATTRS); 1201 1202 i->rport_attrs[count] = NULL; 1203 1204 return &i->t; 1205 } 1206 EXPORT_SYMBOL(fc_attach_transport); 1207 1208 void fc_release_transport(struct scsi_transport_template *t) 1209 { 1210 struct fc_internal *i = to_fc_internal(t); 1211 1212 transport_container_unregister(&i->t.target_attrs); 1213 transport_container_unregister(&i->t.host_attrs); 1214 transport_container_unregister(&i->rport_attr_cont); 1215 1216 kfree(i); 1217 } 1218 EXPORT_SYMBOL(fc_release_transport); 1219 1220 1221 /** 1222 * fc_remove_host - called to terminate any fc_transport-related elements 1223 * for a scsi host. 1224 * @rport: remote port to be unblocked. 1225 * 1226 * This routine is expected to be called immediately preceeding the 1227 * a driver's call to scsi_remove_host(). 1228 * 1229 * WARNING: A driver utilizing the fc_transport, which fails to call 1230 * this routine prior to scsi_remote_host(), will leave dangling 1231 * objects in /sys/class/fc_remote_ports. Access to any of these 1232 * objects can result in a system crash !!! 1233 * 1234 * Notes: 1235 * This routine assumes no locks are held on entry. 1236 **/ 1237 void 1238 fc_remove_host(struct Scsi_Host *shost) 1239 { 1240 struct fc_rport *rport, *next_rport; 1241 1242 /* Remove any remote ports */ 1243 list_for_each_entry_safe(rport, next_rport, 1244 &fc_host_rports(shost), peers) 1245 fc_rport_terminate(rport); 1246 list_for_each_entry_safe(rport, next_rport, 1247 &fc_host_rport_bindings(shost), peers) 1248 fc_rport_terminate(rport); 1249 } 1250 EXPORT_SYMBOL(fc_remove_host); 1251 1252 /* 1253 * fc_rport_tgt_remove - Removes the scsi target on the remote port 1254 * @rport: The remote port to be operated on 1255 */ 1256 static void 1257 fc_rport_tgt_remove(struct fc_rport *rport) 1258 { 1259 struct Scsi_Host *shost = rport_to_shost(rport); 1260 1261 scsi_target_unblock(&rport->dev); 1262 1263 /* Stop anything on the workq */ 1264 if (!cancel_delayed_work(&rport->dev_loss_work)) 1265 flush_scheduled_work(); 1266 scsi_flush_work(shost); 1267 1268 scsi_remove_target(&rport->dev); 1269 } 1270 1271 /** 1272 * fc_rport_create - allocates and creates a remote FC port. 1273 * @shost: scsi host the remote port is connected to. 1274 * @channel: Channel on shost port connected to. 1275 * @ids: The world wide names, fc address, and FC4 port 1276 * roles for the remote port. 1277 * 1278 * Allocates and creates the remoter port structure, including the 1279 * class and sysfs creation. 1280 * 1281 * Notes: 1282 * This routine assumes no locks are held on entry. 1283 **/ 1284 struct fc_rport * 1285 fc_rport_create(struct Scsi_Host *shost, int channel, 1286 struct fc_rport_identifiers *ids) 1287 { 1288 struct fc_host_attrs *fc_host = 1289 (struct fc_host_attrs *)shost->shost_data; 1290 struct fc_internal *fci = to_fc_internal(shost->transportt); 1291 struct fc_rport *rport; 1292 struct device *dev; 1293 unsigned long flags; 1294 int error; 1295 size_t size; 1296 1297 size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); 1298 rport = kmalloc(size, GFP_KERNEL); 1299 if (unlikely(!rport)) { 1300 printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); 1301 return NULL; 1302 } 1303 memset(rport, 0, size); 1304 1305 rport->maxframe_size = -1; 1306 rport->supported_classes = FC_COS_UNSPECIFIED; 1307 rport->dev_loss_tmo = fc_dev_loss_tmo; 1308 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); 1309 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name)); 1310 rport->port_id = ids->port_id; 1311 rport->roles = ids->roles; 1312 rport->port_state = FC_PORTSTATE_ONLINE; 1313 if (fci->f->dd_fcrport_size) 1314 rport->dd_data = &rport[1]; 1315 rport->channel = channel; 1316 1317 INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport); 1318 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); 1319 1320 spin_lock_irqsave(shost->host_lock, flags); 1321 1322 rport->number = fc_host->next_rport_number++; 1323 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1324 rport->scsi_target_id = fc_host->next_target_id++; 1325 else 1326 rport->scsi_target_id = -1; 1327 list_add_tail(&rport->peers, &fc_host_rports(shost)); 1328 get_device(&shost->shost_gendev); 1329 1330 spin_unlock_irqrestore(shost->host_lock, flags); 1331 1332 dev = &rport->dev; 1333 device_initialize(dev); 1334 dev->parent = get_device(&shost->shost_gendev); 1335 dev->release = fc_rport_dev_release; 1336 sprintf(dev->bus_id, "rport-%d:%d-%d", 1337 shost->host_no, channel, rport->number); 1338 transport_setup_device(dev); 1339 1340 error = device_add(dev); 1341 if (error) { 1342 printk(KERN_ERR "FC Remote Port device_add failed\n"); 1343 goto delete_rport; 1344 } 1345 transport_add_device(dev); 1346 transport_configure_device(dev); 1347 1348 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1349 /* initiate a scan of the target */ 1350 scsi_queue_work(shost, &rport->scan_work); 1351 1352 return rport; 1353 1354 delete_rport: 1355 transport_destroy_device(dev); 1356 put_device(dev->parent); 1357 spin_lock_irqsave(shost->host_lock, flags); 1358 list_del(&rport->peers); 1359 put_device(&shost->shost_gendev); 1360 spin_unlock_irqrestore(shost->host_lock, flags); 1361 put_device(dev->parent); 1362 kfree(rport); 1363 return NULL; 1364 } 1365 1366 /** 1367 * fc_remote_port_add - notifies the fc transport of the existence 1368 * of a remote FC port. 1369 * @shost: scsi host the remote port is connected to. 1370 * @channel: Channel on shost port connected to. 1371 * @ids: The world wide names, fc address, and FC4 port 1372 * roles for the remote port. 1373 * 1374 * The LLDD calls this routine to notify the transport of the existence 1375 * of a remote port. The LLDD provides the unique identifiers (wwpn,wwn) 1376 * of the port, it's FC address (port_id), and the FC4 roles that are 1377 * active for the port. 1378 * 1379 * For ports that are FCP targets (aka scsi targets), the FC transport 1380 * maintains consistent target id bindings on behalf of the LLDD. 1381 * A consistent target id binding is an assignment of a target id to 1382 * a remote port identifier, which persists while the scsi host is 1383 * attached. The remote port can disappear, then later reappear, and 1384 * it's target id assignment remains the same. This allows for shifts 1385 * in FC addressing (if binding by wwpn or wwnn) with no apparent 1386 * changes to the scsi subsystem which is based on scsi host number and 1387 * target id values. Bindings are only valid during the attachment of 1388 * the scsi host. If the host detaches, then later re-attaches, target 1389 * id bindings may change. 1390 * 1391 * This routine is responsible for returning a remote port structure. 1392 * The routine will search the list of remote ports it maintains 1393 * internally on behalf of consistent target id mappings. If found, the 1394 * remote port structure will be reused. Otherwise, a new remote port 1395 * structure will be allocated. 1396 * 1397 * Whenever a remote port is allocated, a new fc_remote_port class 1398 * device is created. 1399 * 1400 * Should not be called from interrupt context. 1401 * 1402 * Notes: 1403 * This routine assumes no locks are held on entry. 1404 **/ 1405 struct fc_rport * 1406 fc_remote_port_add(struct Scsi_Host *shost, int channel, 1407 struct fc_rport_identifiers *ids) 1408 { 1409 struct fc_internal *fci = to_fc_internal(shost->transportt); 1410 struct fc_rport *rport; 1411 unsigned long flags; 1412 int match = 0; 1413 1414 /* 1415 * Search the list of "active" rports, for an rport that has been 1416 * deleted, but we've held off the real delete while the target 1417 * is in a "blocked" state. 1418 */ 1419 spin_lock_irqsave(shost->host_lock, flags); 1420 1421 list_for_each_entry(rport, &fc_host_rports(shost), peers) { 1422 1423 if ((rport->port_state == FC_PORTSTATE_BLOCKED) && 1424 (rport->channel == channel)) { 1425 1426 switch (fc_host_tgtid_bind_type(shost)) { 1427 case FC_TGTID_BIND_BY_WWPN: 1428 case FC_TGTID_BIND_NONE: 1429 if (rport->port_name == ids->port_name) 1430 match = 1; 1431 break; 1432 case FC_TGTID_BIND_BY_WWNN: 1433 if (rport->node_name == ids->node_name) 1434 match = 1; 1435 break; 1436 case FC_TGTID_BIND_BY_ID: 1437 if (rport->port_id == ids->port_id) 1438 match = 1; 1439 break; 1440 } 1441 1442 if (match) { 1443 struct work_struct *work = 1444 &rport->dev_loss_work; 1445 1446 memcpy(&rport->node_name, &ids->node_name, 1447 sizeof(rport->node_name)); 1448 memcpy(&rport->port_name, &ids->port_name, 1449 sizeof(rport->port_name)); 1450 rport->port_id = ids->port_id; 1451 1452 rport->port_state = FC_PORTSTATE_ONLINE; 1453 rport->roles = ids->roles; 1454 1455 spin_unlock_irqrestore(shost->host_lock, flags); 1456 1457 if (fci->f->dd_fcrport_size) 1458 memset(rport->dd_data, 0, 1459 fci->f->dd_fcrport_size); 1460 1461 /* 1462 * If we were blocked, we were a target. 1463 * If no longer a target, we leave the timer 1464 * running in case the port changes roles 1465 * prior to the timer expiring. If the timer 1466 * fires, the target will be torn down. 1467 */ 1468 if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET)) 1469 return rport; 1470 1471 /* restart the target */ 1472 1473 /* 1474 * Stop the target timer first. Take no action 1475 * on the del_timer failure as the state 1476 * machine state change will validate the 1477 * transaction. 1478 */ 1479 if (!cancel_delayed_work(work)) 1480 flush_scheduled_work(); 1481 1482 /* initiate a scan of the target */ 1483 scsi_queue_work(shost, &rport->scan_work); 1484 1485 return rport; 1486 } 1487 } 1488 } 1489 1490 /* Search the bindings array */ 1491 if (likely((ids->roles & FC_RPORT_ROLE_FCP_TARGET) && 1492 (fc_host_tgtid_bind_type(shost) != FC_TGTID_BIND_NONE))) { 1493 1494 /* search for a matching consistent binding */ 1495 1496 list_for_each_entry(rport, &fc_host_rport_bindings(shost), 1497 peers) { 1498 if (rport->channel != channel) 1499 continue; 1500 1501 switch (fc_host_tgtid_bind_type(shost)) { 1502 case FC_TGTID_BIND_BY_WWPN: 1503 if (rport->port_name == ids->port_name) 1504 match = 1; 1505 break; 1506 case FC_TGTID_BIND_BY_WWNN: 1507 if (rport->node_name == ids->node_name) 1508 match = 1; 1509 break; 1510 case FC_TGTID_BIND_BY_ID: 1511 if (rport->port_id == ids->port_id) 1512 match = 1; 1513 break; 1514 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 1515 break; 1516 } 1517 1518 if (match) { 1519 list_move_tail(&rport->peers, 1520 &fc_host_rports(shost)); 1521 break; 1522 } 1523 } 1524 1525 if (match) { 1526 memcpy(&rport->node_name, &ids->node_name, 1527 sizeof(rport->node_name)); 1528 memcpy(&rport->port_name, &ids->port_name, 1529 sizeof(rport->port_name)); 1530 rport->port_id = ids->port_id; 1531 rport->roles = ids->roles; 1532 rport->port_state = FC_PORTSTATE_ONLINE; 1533 1534 spin_unlock_irqrestore(shost->host_lock, flags); 1535 1536 if (fci->f->dd_fcrport_size) 1537 memset(rport->dd_data, 0, 1538 fci->f->dd_fcrport_size); 1539 1540 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1541 /* initiate a scan of the target */ 1542 scsi_queue_work(shost, &rport->scan_work); 1543 1544 return rport; 1545 } 1546 } 1547 1548 spin_unlock_irqrestore(shost->host_lock, flags); 1549 1550 /* No consistent binding found - create new remote port entry */ 1551 rport = fc_rport_create(shost, channel, ids); 1552 1553 return rport; 1554 } 1555 EXPORT_SYMBOL(fc_remote_port_add); 1556 1557 /* 1558 * fc_rport_terminate - this routine tears down and deallocates a remote port. 1559 * @rport: The remote port to be terminated 1560 * 1561 * Notes: 1562 * This routine assumes no locks are held on entry. 1563 */ 1564 static void 1565 fc_rport_terminate(struct fc_rport *rport) 1566 { 1567 struct Scsi_Host *shost = rport_to_shost(rport); 1568 struct device *dev = &rport->dev; 1569 unsigned long flags; 1570 1571 fc_rport_tgt_remove(rport); 1572 1573 transport_remove_device(dev); 1574 device_del(dev); 1575 transport_destroy_device(dev); 1576 spin_lock_irqsave(shost->host_lock, flags); 1577 list_del(&rport->peers); 1578 spin_unlock_irqrestore(shost->host_lock, flags); 1579 put_device(&shost->shost_gendev); 1580 } 1581 1582 /** 1583 * fc_remote_port_delete - notifies the fc transport that a remote 1584 * port is no longer in existence. 1585 * @rport: The remote port that no longer exists 1586 * 1587 * The LLDD calls this routine to notify the transport that a remote 1588 * port is no longer part of the topology. Note: Although a port 1589 * may no longer be part of the topology, it may persist in the remote 1590 * ports displayed by the fc_host. We do this under 2 conditions: 1591 * - If the port was a scsi target, we delay its deletion by "blocking" it. 1592 * This allows the port to temporarily disappear, then reappear without 1593 * disrupting the SCSI device tree attached to it. During the "blocked" 1594 * period the port will still exist. 1595 * - If the port was a scsi target and disappears for longer than we 1596 * expect, we'll delete the port and the tear down the SCSI device tree 1597 * attached to it. However, we want to semi-persist the target id assigned 1598 * to that port if it eventually does exist. The port structure will 1599 * remain (although with minimal information) so that the target id 1600 * bindings remails. 1601 * 1602 * If the remote port is not an FCP Target, it will be fully torn down 1603 * and deallocated, including the fc_remote_port class device. 1604 * 1605 * If the remote port is an FCP Target, the port will be placed in a 1606 * temporary blocked state. From the LLDD's perspective, the rport no 1607 * longer exists. From the SCSI midlayer's perspective, the SCSI target 1608 * exists, but all sdevs on it are blocked from further I/O. The following 1609 * is then expected: 1610 * If the remote port does not return (signaled by a LLDD call to 1611 * fc_remote_port_add()) within the dev_loss_tmo timeout, then the 1612 * scsi target is removed - killing all outstanding i/o and removing the 1613 * scsi devices attached ot it. The port structure will be marked Not 1614 * Present and be partially cleared, leaving only enough information to 1615 * recognize the remote port relative to the scsi target id binding if 1616 * it later appears. The port will remain as long as there is a valid 1617 * binding (e.g. until the user changes the binding type or unloads the 1618 * scsi host with the binding). 1619 * 1620 * If the remote port returns within the dev_loss_tmo value (and matches 1621 * according to the target id binding type), the port structure will be 1622 * reused. If it is no longer a SCSI target, the target will be torn 1623 * down. If it continues to be a SCSI target, then the target will be 1624 * unblocked (allowing i/o to be resumed), and a scan will be activated 1625 * to ensure that all luns are detected. 1626 * 1627 * Called from normal process context only - cannot be called from interrupt. 1628 * 1629 * Notes: 1630 * This routine assumes no locks are held on entry. 1631 **/ 1632 void 1633 fc_remote_port_delete(struct fc_rport *rport) 1634 { 1635 int timeout = rport->dev_loss_tmo; 1636 1637 /* If no scsi target id mapping, delete it */ 1638 if (rport->scsi_target_id == -1) { 1639 fc_rport_terminate(rport); 1640 return; 1641 } 1642 1643 scsi_target_block(&rport->dev); 1644 1645 /* cap the length the devices can be blocked until they are deleted */ 1646 schedule_delayed_work(&rport->dev_loss_work, timeout * HZ); 1647 1648 rport->port_state = FC_PORTSTATE_BLOCKED; 1649 } 1650 EXPORT_SYMBOL(fc_remote_port_delete); 1651 1652 /** 1653 * fc_remote_port_rolechg - notifies the fc transport that the roles 1654 * on a remote may have changed. 1655 * @rport: The remote port that changed. 1656 * 1657 * The LLDD calls this routine to notify the transport that the roles 1658 * on a remote port may have changed. The largest effect of this is 1659 * if a port now becomes a FCP Target, it must be allocated a 1660 * scsi target id. If the port is no longer a FCP target, any 1661 * scsi target id value assigned to it will persist in case the 1662 * role changes back to include FCP Target. No changes in the scsi 1663 * midlayer will be invoked if the role changes (in the expectation 1664 * that the role will be resumed. If it doesn't normal error processing 1665 * will take place). 1666 * 1667 * Should not be called from interrupt context. 1668 * 1669 * Notes: 1670 * This routine assumes no locks are held on entry. 1671 **/ 1672 void 1673 fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) 1674 { 1675 struct Scsi_Host *shost = rport_to_shost(rport); 1676 struct fc_host_attrs *fc_host = 1677 (struct fc_host_attrs *)shost->shost_data; 1678 unsigned long flags; 1679 int create = 0; 1680 1681 spin_lock_irqsave(shost->host_lock, flags); 1682 if (roles & FC_RPORT_ROLE_FCP_TARGET) { 1683 if (rport->scsi_target_id == -1) { 1684 rport->scsi_target_id = fc_host->next_target_id++; 1685 create = 1; 1686 } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) 1687 create = 1; 1688 } 1689 spin_unlock_irqrestore(shost->host_lock, flags); 1690 1691 rport->roles = roles; 1692 1693 if (create) { 1694 /* 1695 * There may have been a delete timer running on the 1696 * port. Ensure that it is cancelled as we now know 1697 * the port is an FCP Target. 1698 * Note: we know the rport is exists and in an online 1699 * state as the LLDD would not have had an rport 1700 * reference to pass us. 1701 * 1702 * Take no action on the del_timer failure as the state 1703 * machine state change will validate the 1704 * transaction. 1705 */ 1706 if (!cancel_delayed_work(&rport->dev_loss_work)) 1707 flush_scheduled_work(); 1708 1709 /* initiate a scan of the target */ 1710 scsi_queue_work(shost, &rport->scan_work); 1711 } 1712 } 1713 EXPORT_SYMBOL(fc_remote_port_rolechg); 1714 1715 /** 1716 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that 1717 * was a SCSI target (thus was blocked), and failed 1718 * to return in the alloted time. 1719 * 1720 * @data: rport target that failed to reappear in the alloted time. 1721 **/ 1722 static void 1723 fc_timeout_deleted_rport(void *data) 1724 { 1725 struct fc_rport *rport = (struct fc_rport *)data; 1726 struct Scsi_Host *shost = rport_to_shost(rport); 1727 unsigned long flags; 1728 1729 spin_lock_irqsave(shost->host_lock, flags); 1730 1731 /* 1732 * If the port is ONLINE, then it came back, but was no longer an 1733 * FCP target. Thus we need to tear down the scsi_target on it. 1734 */ 1735 if (rport->port_state == FC_PORTSTATE_ONLINE) { 1736 spin_unlock_irqrestore(shost->host_lock, flags); 1737 1738 dev_printk(KERN_ERR, &rport->dev, 1739 "blocked FC remote port time out: removing target\n"); 1740 1741 fc_rport_tgt_remove(rport); 1742 1743 return; 1744 } 1745 1746 if (rport->port_state != FC_PORTSTATE_BLOCKED) { 1747 spin_unlock_irqrestore(shost->host_lock, flags); 1748 dev_printk(KERN_ERR, &rport->dev, 1749 "blocked FC remote port time out: leaving target alone\n"); 1750 return; 1751 } 1752 1753 if (fc_host_tgtid_bind_type(shost) == FC_TGTID_BIND_NONE) { 1754 spin_unlock_irqrestore(shost->host_lock, flags); 1755 dev_printk(KERN_ERR, &rport->dev, 1756 "blocked FC remote port time out: removing target\n"); 1757 fc_rport_terminate(rport); 1758 return; 1759 } 1760 1761 dev_printk(KERN_ERR, &rport->dev, 1762 "blocked FC remote port time out: removing target and " 1763 "saving binding\n"); 1764 1765 list_move_tail(&rport->peers, &fc_host_rport_bindings(shost)); 1766 1767 /* 1768 * Note: We do not remove or clear the hostdata area. This allows 1769 * host-specific target data to persist along with the 1770 * scsi_target_id. It's up to the host to manage it's hostdata area. 1771 */ 1772 1773 /* 1774 * Reinitialize port attributes that may change if the port comes back. 1775 */ 1776 rport->maxframe_size = -1; 1777 rport->supported_classes = FC_COS_UNSPECIFIED; 1778 rport->roles = FC_RPORT_ROLE_UNKNOWN; 1779 rport->port_state = FC_PORTSTATE_DELETED; 1780 1781 /* remove the identifiers that aren't used in the consisting binding */ 1782 switch (fc_host_tgtid_bind_type(shost)) { 1783 case FC_TGTID_BIND_BY_WWPN: 1784 rport->node_name = -1; 1785 rport->port_id = -1; 1786 break; 1787 case FC_TGTID_BIND_BY_WWNN: 1788 rport->port_name = -1; 1789 rport->port_id = -1; 1790 break; 1791 case FC_TGTID_BIND_BY_ID: 1792 rport->node_name = -1; 1793 rport->port_name = -1; 1794 break; 1795 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 1796 break; 1797 } 1798 1799 /* 1800 * As this only occurs if the remote port (scsi target) 1801 * went away and didn't come back - we'll remove 1802 * all attached scsi devices. 1803 * 1804 * We'll schedule the shost work item to perform the actual removal 1805 * to avoid recursion in the different flush calls if we perform 1806 * the removal in each target - and there are lots of targets 1807 * whose timeouts fire at the same time. 1808 */ 1809 1810 if ( !(fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED)) { 1811 fc_host_flags(shost) |= FC_SHOST_RPORT_DEL_SCHEDULED; 1812 scsi_queue_work(shost, &fc_host_rport_del_work(shost)); 1813 } 1814 1815 spin_unlock_irqrestore(shost->host_lock, flags); 1816 } 1817 1818 /** 1819 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 1820 * 1821 * Will unblock the target (in case it went away and has now come back), 1822 * then invoke a scan. 1823 * 1824 * @data: remote port to be scanned. 1825 **/ 1826 static void 1827 fc_scsi_scan_rport(void *data) 1828 { 1829 struct fc_rport *rport = (struct fc_rport *)data; 1830 1831 scsi_target_unblock(&rport->dev); 1832 scsi_scan_target(&rport->dev, rport->channel, rport->scsi_target_id, 1833 SCAN_WILD_CARD, 1); 1834 } 1835 1836 1837 /** 1838 * fc_shost_remove_rports - called to remove all rports that are marked 1839 * as in a deleted (not connected) state. 1840 * 1841 * @data: shost whose rports are to be looked at 1842 **/ 1843 static void 1844 fc_shost_remove_rports(void *data) 1845 { 1846 struct Scsi_Host *shost = (struct Scsi_Host *)data; 1847 struct fc_rport *rport, *next_rport; 1848 unsigned long flags; 1849 1850 spin_lock_irqsave(shost->host_lock, flags); 1851 while (fc_host_flags(shost) & FC_SHOST_RPORT_DEL_SCHEDULED) { 1852 1853 fc_host_flags(shost) &= ~FC_SHOST_RPORT_DEL_SCHEDULED; 1854 1855 restart_search: 1856 list_for_each_entry_safe(rport, next_rport, 1857 &fc_host_rport_bindings(shost), peers) { 1858 if (rport->port_state == FC_PORTSTATE_DELETED) { 1859 rport->port_state = FC_PORTSTATE_NOTPRESENT; 1860 spin_unlock_irqrestore(shost->host_lock, flags); 1861 fc_rport_tgt_remove(rport); 1862 spin_lock_irqsave(shost->host_lock, flags); 1863 goto restart_search; 1864 } 1865 } 1866 1867 } 1868 spin_unlock_irqrestore(shost->host_lock, flags); 1869 } 1870 1871 1872 MODULE_AUTHOR("Martin Hicks"); 1873 MODULE_DESCRIPTION("FC Transport Attributes"); 1874 MODULE_LICENSE("GPL"); 1875 1876 module_init(fc_transport_init); 1877 module_exit(fc_transport_exit); 1878