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