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