1 /* 2 * FiberChannel transport specific attributes exported to sysfs. 3 * 4 * Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 * ======== 21 * 22 * Copyright (C) 2004-2005 James Smart, Emulex Corporation 23 * Rewrite for host, target, device, and remote port attributes, 24 * statistics, and service functions... 25 * 26 */ 27 #include <linux/module.h> 28 #include <linux/init.h> 29 #include <scsi/scsi_device.h> 30 #include <scsi/scsi_host.h> 31 #include <scsi/scsi_transport.h> 32 #include <scsi/scsi_transport_fc.h> 33 #include <scsi/scsi_cmnd.h> 34 #include <linux/netlink.h> 35 #include <net/netlink.h> 36 #include <scsi/scsi_netlink_fc.h> 37 #include "scsi_priv.h" 38 39 static int fc_queue_work(struct Scsi_Host *, struct work_struct *); 40 41 /* 42 * Redefine so that we can have same named attributes in the 43 * sdev/starget/host objects. 44 */ 45 #define FC_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \ 46 struct class_device_attribute class_device_attr_##_prefix##_##_name = \ 47 __ATTR(_name,_mode,_show,_store) 48 49 #define fc_enum_name_search(title, table_type, table) \ 50 static const char *get_fc_##title##_name(enum table_type table_key) \ 51 { \ 52 int i; \ 53 char *name = NULL; \ 54 \ 55 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 56 if (table[i].value == table_key) { \ 57 name = table[i].name; \ 58 break; \ 59 } \ 60 } \ 61 return name; \ 62 } 63 64 #define fc_enum_name_match(title, table_type, table) \ 65 static int get_fc_##title##_match(const char *table_key, \ 66 enum table_type *value) \ 67 { \ 68 int i; \ 69 \ 70 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 71 if (strncmp(table_key, table[i].name, \ 72 table[i].matchlen) == 0) { \ 73 *value = table[i].value; \ 74 return 0; /* success */ \ 75 } \ 76 } \ 77 return 1; /* failure */ \ 78 } 79 80 81 /* Convert fc_port_type values to ascii string name */ 82 static struct { 83 enum fc_port_type value; 84 char *name; 85 } fc_port_type_names[] = { 86 { FC_PORTTYPE_UNKNOWN, "Unknown" }, 87 { FC_PORTTYPE_OTHER, "Other" }, 88 { FC_PORTTYPE_NOTPRESENT, "Not Present" }, 89 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" }, 90 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" }, 91 { FC_PORTTYPE_LPORT, "LPort (private loop)" }, 92 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection" }, 93 }; 94 fc_enum_name_search(port_type, fc_port_type, fc_port_type_names) 95 #define FC_PORTTYPE_MAX_NAMELEN 50 96 97 98 /* Convert fc_host_event_code values to ascii string name */ 99 static const struct { 100 enum fc_host_event_code value; 101 char *name; 102 } fc_host_event_code_names[] = { 103 { FCH_EVT_LIP, "lip" }, 104 { FCH_EVT_LINKUP, "link_up" }, 105 { FCH_EVT_LINKDOWN, "link_down" }, 106 { FCH_EVT_LIPRESET, "lip_reset" }, 107 { FCH_EVT_RSCN, "rscn" }, 108 { FCH_EVT_ADAPTER_CHANGE, "adapter_chg" }, 109 { FCH_EVT_PORT_UNKNOWN, "port_unknown" }, 110 { FCH_EVT_PORT_ONLINE, "port_online" }, 111 { FCH_EVT_PORT_OFFLINE, "port_offline" }, 112 { FCH_EVT_PORT_FABRIC, "port_fabric" }, 113 { FCH_EVT_LINK_UNKNOWN, "link_unknown" }, 114 { FCH_EVT_VENDOR_UNIQUE, "vendor_unique" }, 115 }; 116 fc_enum_name_search(host_event_code, fc_host_event_code, 117 fc_host_event_code_names) 118 #define FC_HOST_EVENT_CODE_MAX_NAMELEN 30 119 120 121 /* Convert fc_port_state values to ascii string name */ 122 static struct { 123 enum fc_port_state value; 124 char *name; 125 } fc_port_state_names[] = { 126 { FC_PORTSTATE_UNKNOWN, "Unknown" }, 127 { FC_PORTSTATE_NOTPRESENT, "Not Present" }, 128 { FC_PORTSTATE_ONLINE, "Online" }, 129 { FC_PORTSTATE_OFFLINE, "Offline" }, 130 { FC_PORTSTATE_BLOCKED, "Blocked" }, 131 { FC_PORTSTATE_BYPASSED, "Bypassed" }, 132 { FC_PORTSTATE_DIAGNOSTICS, "Diagnostics" }, 133 { FC_PORTSTATE_LINKDOWN, "Linkdown" }, 134 { FC_PORTSTATE_ERROR, "Error" }, 135 { FC_PORTSTATE_LOOPBACK, "Loopback" }, 136 { FC_PORTSTATE_DELETED, "Deleted" }, 137 }; 138 fc_enum_name_search(port_state, fc_port_state, fc_port_state_names) 139 #define FC_PORTSTATE_MAX_NAMELEN 20 140 141 142 /* Convert fc_tgtid_binding_type values to ascii string name */ 143 static const struct { 144 enum fc_tgtid_binding_type value; 145 char *name; 146 int matchlen; 147 } fc_tgtid_binding_type_names[] = { 148 { FC_TGTID_BIND_NONE, "none", 4 }, 149 { FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 }, 150 { FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 }, 151 { FC_TGTID_BIND_BY_ID, "port_id (FC Address)", 7 }, 152 }; 153 fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type, 154 fc_tgtid_binding_type_names) 155 fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type, 156 fc_tgtid_binding_type_names) 157 #define FC_BINDTYPE_MAX_NAMELEN 30 158 159 160 #define fc_bitfield_name_search(title, table) \ 161 static ssize_t \ 162 get_fc_##title##_names(u32 table_key, char *buf) \ 163 { \ 164 char *prefix = ""; \ 165 ssize_t len = 0; \ 166 int i; \ 167 \ 168 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 169 if (table[i].value & table_key) { \ 170 len += sprintf(buf + len, "%s%s", \ 171 prefix, table[i].name); \ 172 prefix = ", "; \ 173 } \ 174 } \ 175 len += sprintf(buf + len, "\n"); \ 176 return len; \ 177 } 178 179 180 /* Convert FC_COS bit values to ascii string name */ 181 static const struct { 182 u32 value; 183 char *name; 184 } fc_cos_names[] = { 185 { FC_COS_CLASS1, "Class 1" }, 186 { FC_COS_CLASS2, "Class 2" }, 187 { FC_COS_CLASS3, "Class 3" }, 188 { FC_COS_CLASS4, "Class 4" }, 189 { FC_COS_CLASS6, "Class 6" }, 190 }; 191 fc_bitfield_name_search(cos, fc_cos_names) 192 193 194 /* Convert FC_PORTSPEED bit values to ascii string name */ 195 static const struct { 196 u32 value; 197 char *name; 198 } fc_port_speed_names[] = { 199 { FC_PORTSPEED_1GBIT, "1 Gbit" }, 200 { FC_PORTSPEED_2GBIT, "2 Gbit" }, 201 { FC_PORTSPEED_4GBIT, "4 Gbit" }, 202 { FC_PORTSPEED_10GBIT, "10 Gbit" }, 203 { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" }, 204 }; 205 fc_bitfield_name_search(port_speed, fc_port_speed_names) 206 207 208 static int 209 show_fc_fc4s (char *buf, u8 *fc4_list) 210 { 211 int i, len=0; 212 213 for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++) 214 len += sprintf(buf + len , "0x%02x ", *fc4_list); 215 len += sprintf(buf + len, "\n"); 216 return len; 217 } 218 219 220 /* Convert FC_RPORT_ROLE bit values to ascii string name */ 221 static const struct { 222 u32 value; 223 char *name; 224 } fc_remote_port_role_names[] = { 225 { FC_RPORT_ROLE_FCP_TARGET, "FCP Target" }, 226 { FC_RPORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, 227 { FC_RPORT_ROLE_IP_PORT, "IP Port" }, 228 }; 229 fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names) 230 231 /* 232 * Define roles that are specific to port_id. Values are relative to ROLE_MASK. 233 */ 234 #define FC_WELLKNOWN_PORTID_MASK 0xfffff0 235 #define FC_WELLKNOWN_ROLE_MASK 0x00000f 236 #define FC_FPORT_PORTID 0x00000e 237 #define FC_FABCTLR_PORTID 0x00000d 238 #define FC_DIRSRVR_PORTID 0x00000c 239 #define FC_TIMESRVR_PORTID 0x00000b 240 #define FC_MGMTSRVR_PORTID 0x00000a 241 242 243 static void fc_timeout_deleted_rport(struct work_struct *work); 244 static void fc_timeout_fail_rport_io(struct work_struct *work); 245 static void fc_scsi_scan_rport(struct work_struct *work); 246 247 /* 248 * Attribute counts pre object type... 249 * Increase these values if you add attributes 250 */ 251 #define FC_STARGET_NUM_ATTRS 3 252 #define FC_RPORT_NUM_ATTRS 10 253 #define FC_HOST_NUM_ATTRS 17 254 255 struct fc_internal { 256 struct scsi_transport_template t; 257 struct fc_function_template *f; 258 259 /* 260 * For attributes : each object has : 261 * An array of the actual attributes structures 262 * An array of null-terminated pointers to the attribute 263 * structures - used for mid-layer interaction. 264 * 265 * The attribute containers for the starget and host are are 266 * part of the midlayer. As the remote port is specific to the 267 * fc transport, we must provide the attribute container. 268 */ 269 struct class_device_attribute private_starget_attrs[ 270 FC_STARGET_NUM_ATTRS]; 271 struct class_device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1]; 272 273 struct class_device_attribute private_host_attrs[FC_HOST_NUM_ATTRS]; 274 struct class_device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1]; 275 276 struct transport_container rport_attr_cont; 277 struct class_device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS]; 278 struct class_device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1]; 279 }; 280 281 #define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t) 282 283 static int fc_target_setup(struct transport_container *tc, struct device *dev, 284 struct class_device *cdev) 285 { 286 struct scsi_target *starget = to_scsi_target(dev); 287 struct fc_rport *rport = starget_to_rport(starget); 288 289 /* 290 * if parent is remote port, use values from remote port. 291 * Otherwise, this host uses the fc_transport, but not the 292 * remote port interface. As such, initialize to known non-values. 293 */ 294 if (rport) { 295 fc_starget_node_name(starget) = rport->node_name; 296 fc_starget_port_name(starget) = rport->port_name; 297 fc_starget_port_id(starget) = rport->port_id; 298 } else { 299 fc_starget_node_name(starget) = -1; 300 fc_starget_port_name(starget) = -1; 301 fc_starget_port_id(starget) = -1; 302 } 303 304 return 0; 305 } 306 307 static DECLARE_TRANSPORT_CLASS(fc_transport_class, 308 "fc_transport", 309 fc_target_setup, 310 NULL, 311 NULL); 312 313 static int fc_host_setup(struct transport_container *tc, struct device *dev, 314 struct class_device *cdev) 315 { 316 struct Scsi_Host *shost = dev_to_shost(dev); 317 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 318 319 /* 320 * Set default values easily detected by the midlayer as 321 * failure cases. The scsi lldd is responsible for initializing 322 * all transport attributes to valid values per host. 323 */ 324 fc_host->node_name = -1; 325 fc_host->port_name = -1; 326 fc_host->permanent_port_name = -1; 327 fc_host->supported_classes = FC_COS_UNSPECIFIED; 328 memset(fc_host->supported_fc4s, 0, 329 sizeof(fc_host->supported_fc4s)); 330 fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN; 331 fc_host->maxframe_size = -1; 332 memset(fc_host->serial_number, 0, 333 sizeof(fc_host->serial_number)); 334 335 fc_host->port_id = -1; 336 fc_host->port_type = FC_PORTTYPE_UNKNOWN; 337 fc_host->port_state = FC_PORTSTATE_UNKNOWN; 338 memset(fc_host->active_fc4s, 0, 339 sizeof(fc_host->active_fc4s)); 340 fc_host->speed = FC_PORTSPEED_UNKNOWN; 341 fc_host->fabric_name = -1; 342 memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name)); 343 memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname)); 344 345 fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN; 346 347 INIT_LIST_HEAD(&fc_host->rports); 348 INIT_LIST_HEAD(&fc_host->rport_bindings); 349 fc_host->next_rport_number = 0; 350 fc_host->next_target_id = 0; 351 352 snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d", 353 shost->host_no); 354 fc_host->work_q = create_singlethread_workqueue( 355 fc_host->work_q_name); 356 if (!fc_host->work_q) 357 return -ENOMEM; 358 359 snprintf(fc_host->devloss_work_q_name, KOBJ_NAME_LEN, "fc_dl_%d", 360 shost->host_no); 361 fc_host->devloss_work_q = create_singlethread_workqueue( 362 fc_host->devloss_work_q_name); 363 if (!fc_host->devloss_work_q) { 364 destroy_workqueue(fc_host->work_q); 365 fc_host->work_q = NULL; 366 return -ENOMEM; 367 } 368 369 return 0; 370 } 371 372 static DECLARE_TRANSPORT_CLASS(fc_host_class, 373 "fc_host", 374 fc_host_setup, 375 NULL, 376 NULL); 377 378 /* 379 * Setup and Remove actions for remote ports are handled 380 * in the service functions below. 381 */ 382 static DECLARE_TRANSPORT_CLASS(fc_rport_class, 383 "fc_remote_ports", 384 NULL, 385 NULL, 386 NULL); 387 388 /* 389 * Module Parameters 390 */ 391 392 /* 393 * dev_loss_tmo: the default number of seconds that the FC transport 394 * should insulate the loss of a remote port. 395 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. 396 */ 397 static unsigned int fc_dev_loss_tmo = 60; /* seconds */ 398 399 module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); 400 MODULE_PARM_DESC(dev_loss_tmo, 401 "Maximum number of seconds that the FC transport should" 402 " insulate the loss of a remote port. Once this value is" 403 " exceeded, the scsi target is removed. Value should be" 404 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); 405 406 /** 407 * Netlink Infrastructure 408 **/ 409 410 static atomic_t fc_event_seq; 411 412 /** 413 * fc_get_event_number - Obtain the next sequential FC event number 414 * 415 * Notes: 416 * We could have inline'd this, but it would have required fc_event_seq to 417 * be exposed. For now, live with the subroutine call. 418 * Atomic used to avoid lock/unlock... 419 **/ 420 u32 421 fc_get_event_number(void) 422 { 423 return atomic_add_return(1, &fc_event_seq); 424 } 425 EXPORT_SYMBOL(fc_get_event_number); 426 427 428 /** 429 * fc_host_post_event - called to post an even on an fc_host. 430 * 431 * @shost: host the event occurred on 432 * @event_number: fc event number obtained from get_fc_event_number() 433 * @event_code: fc_host event being posted 434 * @event_data: 32bits of data for the event being posted 435 * 436 * Notes: 437 * This routine assumes no locks are held on entry. 438 **/ 439 void 440 fc_host_post_event(struct Scsi_Host *shost, u32 event_number, 441 enum fc_host_event_code event_code, u32 event_data) 442 { 443 struct sk_buff *skb; 444 struct nlmsghdr *nlh; 445 struct fc_nl_event *event; 446 const char *name; 447 u32 len, skblen; 448 int err; 449 450 if (!scsi_nl_sock) { 451 err = -ENOENT; 452 goto send_fail; 453 } 454 455 len = FC_NL_MSGALIGN(sizeof(*event)); 456 skblen = NLMSG_SPACE(len); 457 458 skb = alloc_skb(skblen, GFP_KERNEL); 459 if (!skb) { 460 err = -ENOBUFS; 461 goto send_fail; 462 } 463 464 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG, 465 skblen - sizeof(*nlh), 0); 466 if (!nlh) { 467 err = -ENOBUFS; 468 goto send_fail_skb; 469 } 470 event = NLMSG_DATA(nlh); 471 472 INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC, 473 FC_NL_ASYNC_EVENT, len); 474 event->seconds = get_seconds(); 475 event->vendor_id = 0; 476 event->host_no = shost->host_no; 477 event->event_datalen = sizeof(u32); /* bytes */ 478 event->event_num = event_number; 479 event->event_code = event_code; 480 event->event_data = event_data; 481 482 err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, 483 GFP_KERNEL); 484 if (err && (err != -ESRCH)) /* filter no recipient errors */ 485 /* nlmsg_multicast already kfree_skb'd */ 486 goto send_fail; 487 488 return; 489 490 send_fail_skb: 491 kfree_skb(skb); 492 send_fail: 493 name = get_fc_host_event_code_name(event_code); 494 printk(KERN_WARNING 495 "%s: Dropped Event : host %d %s data 0x%08x - err %d\n", 496 __FUNCTION__, shost->host_no, 497 (name) ? name : "<unknown>", event_data, err); 498 return; 499 } 500 EXPORT_SYMBOL(fc_host_post_event); 501 502 503 /** 504 * fc_host_post_vendor_event - called to post a vendor unique event on 505 * a fc_host 506 * 507 * @shost: host the event occurred on 508 * @event_number: fc event number obtained from get_fc_event_number() 509 * @data_len: amount, in bytes, of vendor unique data 510 * @data_buf: pointer to vendor unique data 511 * 512 * Notes: 513 * This routine assumes no locks are held on entry. 514 **/ 515 void 516 fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, 517 u32 data_len, char * data_buf, u64 vendor_id) 518 { 519 struct sk_buff *skb; 520 struct nlmsghdr *nlh; 521 struct fc_nl_event *event; 522 u32 len, skblen; 523 int err; 524 525 if (!scsi_nl_sock) { 526 err = -ENOENT; 527 goto send_vendor_fail; 528 } 529 530 len = FC_NL_MSGALIGN(sizeof(*event) + data_len); 531 skblen = NLMSG_SPACE(len); 532 533 skb = alloc_skb(skblen, GFP_KERNEL); 534 if (!skb) { 535 err = -ENOBUFS; 536 goto send_vendor_fail; 537 } 538 539 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG, 540 skblen - sizeof(*nlh), 0); 541 if (!nlh) { 542 err = -ENOBUFS; 543 goto send_vendor_fail_skb; 544 } 545 event = NLMSG_DATA(nlh); 546 547 INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC, 548 FC_NL_ASYNC_EVENT, len); 549 event->seconds = get_seconds(); 550 event->vendor_id = vendor_id; 551 event->host_no = shost->host_no; 552 event->event_datalen = data_len; /* bytes */ 553 event->event_num = event_number; 554 event->event_code = FCH_EVT_VENDOR_UNIQUE; 555 memcpy(&event->event_data, data_buf, data_len); 556 557 err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, 558 GFP_KERNEL); 559 if (err && (err != -ESRCH)) /* filter no recipient errors */ 560 /* nlmsg_multicast already kfree_skb'd */ 561 goto send_vendor_fail; 562 563 return; 564 565 send_vendor_fail_skb: 566 kfree_skb(skb); 567 send_vendor_fail: 568 printk(KERN_WARNING 569 "%s: Dropped Event : host %d vendor_unique - err %d\n", 570 __FUNCTION__, shost->host_no, err); 571 return; 572 } 573 EXPORT_SYMBOL(fc_host_post_vendor_event); 574 575 576 577 static __init int fc_transport_init(void) 578 { 579 int error; 580 581 atomic_set(&fc_event_seq, 0); 582 583 error = transport_class_register(&fc_host_class); 584 if (error) 585 return error; 586 error = transport_class_register(&fc_rport_class); 587 if (error) 588 return error; 589 return transport_class_register(&fc_transport_class); 590 } 591 592 static void __exit fc_transport_exit(void) 593 { 594 transport_class_unregister(&fc_transport_class); 595 transport_class_unregister(&fc_rport_class); 596 transport_class_unregister(&fc_host_class); 597 } 598 599 /* 600 * FC Remote Port Attribute Management 601 */ 602 603 #define fc_rport_show_function(field, format_string, sz, cast) \ 604 static ssize_t \ 605 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 606 { \ 607 struct fc_rport *rport = transport_class_to_rport(cdev); \ 608 struct Scsi_Host *shost = rport_to_shost(rport); \ 609 struct fc_internal *i = to_fc_internal(shost->transportt); \ 610 if ((i->f->get_rport_##field) && \ 611 !((rport->port_state == FC_PORTSTATE_BLOCKED) || \ 612 (rport->port_state == FC_PORTSTATE_DELETED) || \ 613 (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \ 614 i->f->get_rport_##field(rport); \ 615 return snprintf(buf, sz, format_string, cast rport->field); \ 616 } 617 618 #define fc_rport_store_function(field) \ 619 static ssize_t \ 620 store_fc_rport_##field(struct class_device *cdev, const char *buf, \ 621 size_t count) \ 622 { \ 623 int val; \ 624 struct fc_rport *rport = transport_class_to_rport(cdev); \ 625 struct Scsi_Host *shost = rport_to_shost(rport); \ 626 struct fc_internal *i = to_fc_internal(shost->transportt); \ 627 char *cp; \ 628 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ 629 (rport->port_state == FC_PORTSTATE_DELETED) || \ 630 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ 631 return -EBUSY; \ 632 val = simple_strtoul(buf, &cp, 0); \ 633 if (*cp && (*cp != '\n')) \ 634 return -EINVAL; \ 635 i->f->set_rport_##field(rport, val); \ 636 return count; \ 637 } 638 639 #define fc_rport_rd_attr(field, format_string, sz) \ 640 fc_rport_show_function(field, format_string, sz, ) \ 641 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 642 show_fc_rport_##field, NULL) 643 644 #define fc_rport_rd_attr_cast(field, format_string, sz, cast) \ 645 fc_rport_show_function(field, format_string, sz, (cast)) \ 646 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 647 show_fc_rport_##field, NULL) 648 649 #define fc_rport_rw_attr(field, format_string, sz) \ 650 fc_rport_show_function(field, format_string, sz, ) \ 651 fc_rport_store_function(field) \ 652 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO | S_IWUSR, \ 653 show_fc_rport_##field, \ 654 store_fc_rport_##field) 655 656 657 #define fc_private_rport_show_function(field, format_string, sz, cast) \ 658 static ssize_t \ 659 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 660 { \ 661 struct fc_rport *rport = transport_class_to_rport(cdev); \ 662 return snprintf(buf, sz, format_string, cast rport->field); \ 663 } 664 665 #define fc_private_rport_rd_attr(field, format_string, sz) \ 666 fc_private_rport_show_function(field, format_string, sz, ) \ 667 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 668 show_fc_rport_##field, NULL) 669 670 #define fc_private_rport_rd_attr_cast(field, format_string, sz, cast) \ 671 fc_private_rport_show_function(field, format_string, sz, (cast)) \ 672 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 673 show_fc_rport_##field, NULL) 674 675 676 #define fc_private_rport_rd_enum_attr(title, maxlen) \ 677 static ssize_t \ 678 show_fc_rport_##title (struct class_device *cdev, char *buf) \ 679 { \ 680 struct fc_rport *rport = transport_class_to_rport(cdev); \ 681 const char *name; \ 682 name = get_fc_##title##_name(rport->title); \ 683 if (!name) \ 684 return -EINVAL; \ 685 return snprintf(buf, maxlen, "%s\n", name); \ 686 } \ 687 static FC_CLASS_DEVICE_ATTR(rport, title, S_IRUGO, \ 688 show_fc_rport_##title, NULL) 689 690 691 #define SETUP_RPORT_ATTRIBUTE_RD(field) \ 692 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 693 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 694 i->private_rport_attrs[count].store = NULL; \ 695 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 696 if (i->f->show_rport_##field) \ 697 count++ 698 699 #define SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(field) \ 700 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 701 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 702 i->private_rport_attrs[count].store = NULL; \ 703 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 704 count++ 705 706 #define SETUP_RPORT_ATTRIBUTE_RW(field) \ 707 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 708 if (!i->f->set_rport_##field) { \ 709 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 710 i->private_rport_attrs[count].store = NULL; \ 711 } \ 712 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 713 if (i->f->show_rport_##field) \ 714 count++ 715 716 #define SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(field) \ 717 { \ 718 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 719 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 720 count++; \ 721 } 722 723 724 /* The FC Transport Remote Port Attributes: */ 725 726 /* Fixed Remote Port Attributes */ 727 728 fc_private_rport_rd_attr(maxframe_size, "%u bytes\n", 20); 729 730 static ssize_t 731 show_fc_rport_supported_classes (struct class_device *cdev, char *buf) 732 { 733 struct fc_rport *rport = transport_class_to_rport(cdev); 734 if (rport->supported_classes == FC_COS_UNSPECIFIED) 735 return snprintf(buf, 20, "unspecified\n"); 736 return get_fc_cos_names(rport->supported_classes, buf); 737 } 738 static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO, 739 show_fc_rport_supported_classes, NULL); 740 741 /* Dynamic Remote Port Attributes */ 742 743 /* 744 * dev_loss_tmo attribute 745 */ 746 fc_rport_show_function(dev_loss_tmo, "%d\n", 20, ) 747 static ssize_t 748 store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf, 749 size_t count) 750 { 751 int val; 752 struct fc_rport *rport = transport_class_to_rport(cdev); 753 struct Scsi_Host *shost = rport_to_shost(rport); 754 struct fc_internal *i = to_fc_internal(shost->transportt); 755 char *cp; 756 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 757 (rport->port_state == FC_PORTSTATE_DELETED) || 758 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 759 return -EBUSY; 760 val = simple_strtoul(buf, &cp, 0); 761 if ((*cp && (*cp != '\n')) || 762 (val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)) 763 return -EINVAL; 764 i->f->set_rport_dev_loss_tmo(rport, val); 765 return count; 766 } 767 static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR, 768 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo); 769 770 771 /* Private Remote Port Attributes */ 772 773 fc_private_rport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 774 fc_private_rport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 775 fc_private_rport_rd_attr(port_id, "0x%06x\n", 20); 776 777 static ssize_t 778 show_fc_rport_roles (struct class_device *cdev, char *buf) 779 { 780 struct fc_rport *rport = transport_class_to_rport(cdev); 781 782 /* identify any roles that are port_id specific */ 783 if ((rport->port_id != -1) && 784 (rport->port_id & FC_WELLKNOWN_PORTID_MASK) == 785 FC_WELLKNOWN_PORTID_MASK) { 786 switch (rport->port_id & FC_WELLKNOWN_ROLE_MASK) { 787 case FC_FPORT_PORTID: 788 return snprintf(buf, 30, "Fabric Port\n"); 789 case FC_FABCTLR_PORTID: 790 return snprintf(buf, 30, "Fabric Controller\n"); 791 case FC_DIRSRVR_PORTID: 792 return snprintf(buf, 30, "Directory Server\n"); 793 case FC_TIMESRVR_PORTID: 794 return snprintf(buf, 30, "Time Server\n"); 795 case FC_MGMTSRVR_PORTID: 796 return snprintf(buf, 30, "Management Server\n"); 797 default: 798 return snprintf(buf, 30, "Unknown Fabric Entity\n"); 799 } 800 } else { 801 if (rport->roles == FC_RPORT_ROLE_UNKNOWN) 802 return snprintf(buf, 20, "unknown\n"); 803 return get_fc_remote_port_roles_names(rport->roles, buf); 804 } 805 } 806 static FC_CLASS_DEVICE_ATTR(rport, roles, S_IRUGO, 807 show_fc_rport_roles, NULL); 808 809 fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 810 fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20); 811 812 /* 813 * fast_io_fail_tmo attribute 814 */ 815 static ssize_t 816 show_fc_rport_fast_io_fail_tmo (struct class_device *cdev, char *buf) 817 { 818 struct fc_rport *rport = transport_class_to_rport(cdev); 819 820 if (rport->fast_io_fail_tmo == -1) 821 return snprintf(buf, 5, "off\n"); 822 return snprintf(buf, 20, "%d\n", rport->fast_io_fail_tmo); 823 } 824 825 static ssize_t 826 store_fc_rport_fast_io_fail_tmo(struct class_device *cdev, const char *buf, 827 size_t count) 828 { 829 int val; 830 char *cp; 831 struct fc_rport *rport = transport_class_to_rport(cdev); 832 833 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 834 (rport->port_state == FC_PORTSTATE_DELETED) || 835 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 836 return -EBUSY; 837 if (strncmp(buf, "off", 3) == 0) 838 rport->fast_io_fail_tmo = -1; 839 else { 840 val = simple_strtoul(buf, &cp, 0); 841 if ((*cp && (*cp != '\n')) || 842 (val < 0) || (val >= rport->dev_loss_tmo)) 843 return -EINVAL; 844 rport->fast_io_fail_tmo = val; 845 } 846 return count; 847 } 848 static FC_CLASS_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR, 849 show_fc_rport_fast_io_fail_tmo, store_fc_rport_fast_io_fail_tmo); 850 851 852 /* 853 * FC SCSI Target Attribute Management 854 */ 855 856 /* 857 * Note: in the target show function we recognize when the remote 858 * port is in the hierarchy and do not allow the driver to get 859 * involved in sysfs functions. The driver only gets involved if 860 * it's the "old" style that doesn't use rports. 861 */ 862 #define fc_starget_show_function(field, format_string, sz, cast) \ 863 static ssize_t \ 864 show_fc_starget_##field (struct class_device *cdev, char *buf) \ 865 { \ 866 struct scsi_target *starget = transport_class_to_starget(cdev); \ 867 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ 868 struct fc_internal *i = to_fc_internal(shost->transportt); \ 869 struct fc_rport *rport = starget_to_rport(starget); \ 870 if (rport) \ 871 fc_starget_##field(starget) = rport->field; \ 872 else if (i->f->get_starget_##field) \ 873 i->f->get_starget_##field(starget); \ 874 return snprintf(buf, sz, format_string, \ 875 cast fc_starget_##field(starget)); \ 876 } 877 878 #define fc_starget_rd_attr(field, format_string, sz) \ 879 fc_starget_show_function(field, format_string, sz, ) \ 880 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 881 show_fc_starget_##field, NULL) 882 883 #define fc_starget_rd_attr_cast(field, format_string, sz, cast) \ 884 fc_starget_show_function(field, format_string, sz, (cast)) \ 885 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 886 show_fc_starget_##field, NULL) 887 888 #define SETUP_STARGET_ATTRIBUTE_RD(field) \ 889 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 890 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 891 i->private_starget_attrs[count].store = NULL; \ 892 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 893 if (i->f->show_starget_##field) \ 894 count++ 895 896 #define SETUP_STARGET_ATTRIBUTE_RW(field) \ 897 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 898 if (!i->f->set_starget_##field) { \ 899 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 900 i->private_starget_attrs[count].store = NULL; \ 901 } \ 902 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 903 if (i->f->show_starget_##field) \ 904 count++ 905 906 /* The FC Transport SCSI Target Attributes: */ 907 fc_starget_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 908 fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 909 fc_starget_rd_attr(port_id, "0x%06x\n", 20); 910 911 912 /* 913 * Host Attribute Management 914 */ 915 916 #define fc_host_show_function(field, format_string, sz, cast) \ 917 static ssize_t \ 918 show_fc_host_##field (struct class_device *cdev, char *buf) \ 919 { \ 920 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 921 struct fc_internal *i = to_fc_internal(shost->transportt); \ 922 if (i->f->get_host_##field) \ 923 i->f->get_host_##field(shost); \ 924 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 925 } 926 927 #define fc_host_store_function(field) \ 928 static ssize_t \ 929 store_fc_host_##field(struct class_device *cdev, const char *buf, \ 930 size_t count) \ 931 { \ 932 int val; \ 933 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 934 struct fc_internal *i = to_fc_internal(shost->transportt); \ 935 char *cp; \ 936 \ 937 val = simple_strtoul(buf, &cp, 0); \ 938 if (*cp && (*cp != '\n')) \ 939 return -EINVAL; \ 940 i->f->set_host_##field(shost, val); \ 941 return count; \ 942 } 943 944 #define fc_host_store_str_function(field, slen) \ 945 static ssize_t \ 946 store_fc_host_##field(struct class_device *cdev, const char *buf, \ 947 size_t count) \ 948 { \ 949 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 950 struct fc_internal *i = to_fc_internal(shost->transportt); \ 951 unsigned int cnt=count; \ 952 \ 953 /* count may include a LF at end of string */ \ 954 if (buf[cnt-1] == '\n') \ 955 cnt--; \ 956 if (cnt > ((slen) - 1)) \ 957 return -EINVAL; \ 958 memcpy(fc_host_##field(shost), buf, cnt); \ 959 i->f->set_host_##field(shost); \ 960 return count; \ 961 } 962 963 #define fc_host_rd_attr(field, format_string, sz) \ 964 fc_host_show_function(field, format_string, sz, ) \ 965 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 966 show_fc_host_##field, NULL) 967 968 #define fc_host_rd_attr_cast(field, format_string, sz, cast) \ 969 fc_host_show_function(field, format_string, sz, (cast)) \ 970 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 971 show_fc_host_##field, NULL) 972 973 #define fc_host_rw_attr(field, format_string, sz) \ 974 fc_host_show_function(field, format_string, sz, ) \ 975 fc_host_store_function(field) \ 976 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR, \ 977 show_fc_host_##field, \ 978 store_fc_host_##field) 979 980 #define fc_host_rd_enum_attr(title, maxlen) \ 981 static ssize_t \ 982 show_fc_host_##title (struct class_device *cdev, char *buf) \ 983 { \ 984 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 985 struct fc_internal *i = to_fc_internal(shost->transportt); \ 986 const char *name; \ 987 if (i->f->get_host_##title) \ 988 i->f->get_host_##title(shost); \ 989 name = get_fc_##title##_name(fc_host_##title(shost)); \ 990 if (!name) \ 991 return -EINVAL; \ 992 return snprintf(buf, maxlen, "%s\n", name); \ 993 } \ 994 static FC_CLASS_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL) 995 996 #define SETUP_HOST_ATTRIBUTE_RD(field) \ 997 i->private_host_attrs[count] = class_device_attr_host_##field; \ 998 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 999 i->private_host_attrs[count].store = NULL; \ 1000 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1001 if (i->f->show_host_##field) \ 1002 count++ 1003 1004 #define SETUP_HOST_ATTRIBUTE_RW(field) \ 1005 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1006 if (!i->f->set_host_##field) { \ 1007 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 1008 i->private_host_attrs[count].store = NULL; \ 1009 } \ 1010 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1011 if (i->f->show_host_##field) \ 1012 count++ 1013 1014 1015 #define fc_private_host_show_function(field, format_string, sz, cast) \ 1016 static ssize_t \ 1017 show_fc_host_##field (struct class_device *cdev, char *buf) \ 1018 { \ 1019 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 1020 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 1021 } 1022 1023 #define fc_private_host_rd_attr(field, format_string, sz) \ 1024 fc_private_host_show_function(field, format_string, sz, ) \ 1025 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 1026 show_fc_host_##field, NULL) 1027 1028 #define fc_private_host_rd_attr_cast(field, format_string, sz, cast) \ 1029 fc_private_host_show_function(field, format_string, sz, (cast)) \ 1030 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 1031 show_fc_host_##field, NULL) 1032 1033 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field) \ 1034 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1035 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 1036 i->private_host_attrs[count].store = NULL; \ 1037 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1038 count++ 1039 1040 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \ 1041 { \ 1042 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1043 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1044 count++; \ 1045 } 1046 1047 1048 /* Fixed Host Attributes */ 1049 1050 static ssize_t 1051 show_fc_host_supported_classes (struct class_device *cdev, char *buf) 1052 { 1053 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1054 1055 if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED) 1056 return snprintf(buf, 20, "unspecified\n"); 1057 1058 return get_fc_cos_names(fc_host_supported_classes(shost), buf); 1059 } 1060 static FC_CLASS_DEVICE_ATTR(host, supported_classes, S_IRUGO, 1061 show_fc_host_supported_classes, NULL); 1062 1063 static ssize_t 1064 show_fc_host_supported_fc4s (struct class_device *cdev, char *buf) 1065 { 1066 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1067 return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost)); 1068 } 1069 static FC_CLASS_DEVICE_ATTR(host, supported_fc4s, S_IRUGO, 1070 show_fc_host_supported_fc4s, NULL); 1071 1072 static ssize_t 1073 show_fc_host_supported_speeds (struct class_device *cdev, char *buf) 1074 { 1075 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1076 1077 if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN) 1078 return snprintf(buf, 20, "unknown\n"); 1079 1080 return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf); 1081 } 1082 static FC_CLASS_DEVICE_ATTR(host, supported_speeds, S_IRUGO, 1083 show_fc_host_supported_speeds, NULL); 1084 1085 1086 fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 1087 fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 1088 fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20, 1089 unsigned long long); 1090 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20); 1091 fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1)); 1092 1093 1094 /* Dynamic Host Attributes */ 1095 1096 static ssize_t 1097 show_fc_host_active_fc4s (struct class_device *cdev, char *buf) 1098 { 1099 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1100 struct fc_internal *i = to_fc_internal(shost->transportt); 1101 1102 if (i->f->get_host_active_fc4s) 1103 i->f->get_host_active_fc4s(shost); 1104 1105 return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost)); 1106 } 1107 static FC_CLASS_DEVICE_ATTR(host, active_fc4s, S_IRUGO, 1108 show_fc_host_active_fc4s, NULL); 1109 1110 static ssize_t 1111 show_fc_host_speed (struct class_device *cdev, char *buf) 1112 { 1113 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1114 struct fc_internal *i = to_fc_internal(shost->transportt); 1115 1116 if (i->f->get_host_speed) 1117 i->f->get_host_speed(shost); 1118 1119 if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN) 1120 return snprintf(buf, 20, "unknown\n"); 1121 1122 return get_fc_port_speed_names(fc_host_speed(shost), buf); 1123 } 1124 static FC_CLASS_DEVICE_ATTR(host, speed, S_IRUGO, 1125 show_fc_host_speed, NULL); 1126 1127 1128 fc_host_rd_attr(port_id, "0x%06x\n", 20); 1129 fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN); 1130 fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 1131 fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 1132 fc_host_rd_attr(symbolic_name, "%s\n", FC_SYMBOLIC_NAME_SIZE + 1); 1133 1134 fc_private_host_show_function(system_hostname, "%s\n", 1135 FC_SYMBOLIC_NAME_SIZE + 1, ) 1136 fc_host_store_str_function(system_hostname, FC_SYMBOLIC_NAME_SIZE) 1137 static FC_CLASS_DEVICE_ATTR(host, system_hostname, S_IRUGO | S_IWUSR, 1138 show_fc_host_system_hostname, store_fc_host_system_hostname); 1139 1140 1141 /* Private Host Attributes */ 1142 1143 static ssize_t 1144 show_fc_private_host_tgtid_bind_type(struct class_device *cdev, char *buf) 1145 { 1146 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1147 const char *name; 1148 1149 name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost)); 1150 if (!name) 1151 return -EINVAL; 1152 return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name); 1153 } 1154 1155 #define get_list_head_entry(pos, head, member) \ 1156 pos = list_entry((head)->next, typeof(*pos), member) 1157 1158 static ssize_t 1159 store_fc_private_host_tgtid_bind_type(struct class_device *cdev, 1160 const char *buf, size_t count) 1161 { 1162 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1163 struct fc_rport *rport; 1164 enum fc_tgtid_binding_type val; 1165 unsigned long flags; 1166 1167 if (get_fc_tgtid_bind_type_match(buf, &val)) 1168 return -EINVAL; 1169 1170 /* if changing bind type, purge all unused consistent bindings */ 1171 if (val != fc_host_tgtid_bind_type(shost)) { 1172 spin_lock_irqsave(shost->host_lock, flags); 1173 while (!list_empty(&fc_host_rport_bindings(shost))) { 1174 get_list_head_entry(rport, 1175 &fc_host_rport_bindings(shost), peers); 1176 list_del(&rport->peers); 1177 rport->port_state = FC_PORTSTATE_DELETED; 1178 fc_queue_work(shost, &rport->rport_delete_work); 1179 } 1180 spin_unlock_irqrestore(shost->host_lock, flags); 1181 } 1182 1183 fc_host_tgtid_bind_type(shost) = val; 1184 return count; 1185 } 1186 1187 static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR, 1188 show_fc_private_host_tgtid_bind_type, 1189 store_fc_private_host_tgtid_bind_type); 1190 1191 static ssize_t 1192 store_fc_private_host_issue_lip(struct class_device *cdev, 1193 const char *buf, size_t count) 1194 { 1195 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1196 struct fc_internal *i = to_fc_internal(shost->transportt); 1197 int ret; 1198 1199 /* ignore any data value written to the attribute */ 1200 if (i->f->issue_fc_host_lip) { 1201 ret = i->f->issue_fc_host_lip(shost); 1202 return ret ? ret: count; 1203 } 1204 1205 return -ENOENT; 1206 } 1207 1208 static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL, 1209 store_fc_private_host_issue_lip); 1210 1211 /* 1212 * Host Statistics Management 1213 */ 1214 1215 /* Show a given an attribute in the statistics group */ 1216 static ssize_t 1217 fc_stat_show(const struct class_device *cdev, char *buf, unsigned long offset) 1218 { 1219 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1220 struct fc_internal *i = to_fc_internal(shost->transportt); 1221 struct fc_host_statistics *stats; 1222 ssize_t ret = -ENOENT; 1223 1224 if (offset > sizeof(struct fc_host_statistics) || 1225 offset % sizeof(u64) != 0) 1226 WARN_ON(1); 1227 1228 if (i->f->get_fc_host_stats) { 1229 stats = (i->f->get_fc_host_stats)(shost); 1230 if (stats) 1231 ret = snprintf(buf, 20, "0x%llx\n", 1232 (unsigned long long)*(u64 *)(((u8 *) stats) + offset)); 1233 } 1234 return ret; 1235 } 1236 1237 1238 /* generate a read-only statistics attribute */ 1239 #define fc_host_statistic(name) \ 1240 static ssize_t show_fcstat_##name(struct class_device *cd, char *buf) \ 1241 { \ 1242 return fc_stat_show(cd, buf, \ 1243 offsetof(struct fc_host_statistics, name)); \ 1244 } \ 1245 static FC_CLASS_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL) 1246 1247 fc_host_statistic(seconds_since_last_reset); 1248 fc_host_statistic(tx_frames); 1249 fc_host_statistic(tx_words); 1250 fc_host_statistic(rx_frames); 1251 fc_host_statistic(rx_words); 1252 fc_host_statistic(lip_count); 1253 fc_host_statistic(nos_count); 1254 fc_host_statistic(error_frames); 1255 fc_host_statistic(dumped_frames); 1256 fc_host_statistic(link_failure_count); 1257 fc_host_statistic(loss_of_sync_count); 1258 fc_host_statistic(loss_of_signal_count); 1259 fc_host_statistic(prim_seq_protocol_err_count); 1260 fc_host_statistic(invalid_tx_word_count); 1261 fc_host_statistic(invalid_crc_count); 1262 fc_host_statistic(fcp_input_requests); 1263 fc_host_statistic(fcp_output_requests); 1264 fc_host_statistic(fcp_control_requests); 1265 fc_host_statistic(fcp_input_megabytes); 1266 fc_host_statistic(fcp_output_megabytes); 1267 1268 static ssize_t 1269 fc_reset_statistics(struct class_device *cdev, const char *buf, 1270 size_t count) 1271 { 1272 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1273 struct fc_internal *i = to_fc_internal(shost->transportt); 1274 1275 /* ignore any data value written to the attribute */ 1276 if (i->f->reset_fc_host_stats) { 1277 i->f->reset_fc_host_stats(shost); 1278 return count; 1279 } 1280 1281 return -ENOENT; 1282 } 1283 static FC_CLASS_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL, 1284 fc_reset_statistics); 1285 1286 1287 static struct attribute *fc_statistics_attrs[] = { 1288 &class_device_attr_host_seconds_since_last_reset.attr, 1289 &class_device_attr_host_tx_frames.attr, 1290 &class_device_attr_host_tx_words.attr, 1291 &class_device_attr_host_rx_frames.attr, 1292 &class_device_attr_host_rx_words.attr, 1293 &class_device_attr_host_lip_count.attr, 1294 &class_device_attr_host_nos_count.attr, 1295 &class_device_attr_host_error_frames.attr, 1296 &class_device_attr_host_dumped_frames.attr, 1297 &class_device_attr_host_link_failure_count.attr, 1298 &class_device_attr_host_loss_of_sync_count.attr, 1299 &class_device_attr_host_loss_of_signal_count.attr, 1300 &class_device_attr_host_prim_seq_protocol_err_count.attr, 1301 &class_device_attr_host_invalid_tx_word_count.attr, 1302 &class_device_attr_host_invalid_crc_count.attr, 1303 &class_device_attr_host_fcp_input_requests.attr, 1304 &class_device_attr_host_fcp_output_requests.attr, 1305 &class_device_attr_host_fcp_control_requests.attr, 1306 &class_device_attr_host_fcp_input_megabytes.attr, 1307 &class_device_attr_host_fcp_output_megabytes.attr, 1308 &class_device_attr_host_reset_statistics.attr, 1309 NULL 1310 }; 1311 1312 static struct attribute_group fc_statistics_group = { 1313 .name = "statistics", 1314 .attrs = fc_statistics_attrs, 1315 }; 1316 1317 static int fc_host_match(struct attribute_container *cont, 1318 struct device *dev) 1319 { 1320 struct Scsi_Host *shost; 1321 struct fc_internal *i; 1322 1323 if (!scsi_is_host_device(dev)) 1324 return 0; 1325 1326 shost = dev_to_shost(dev); 1327 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1328 != &fc_host_class.class) 1329 return 0; 1330 1331 i = to_fc_internal(shost->transportt); 1332 1333 return &i->t.host_attrs.ac == cont; 1334 } 1335 1336 static int fc_target_match(struct attribute_container *cont, 1337 struct device *dev) 1338 { 1339 struct Scsi_Host *shost; 1340 struct fc_internal *i; 1341 1342 if (!scsi_is_target_device(dev)) 1343 return 0; 1344 1345 shost = dev_to_shost(dev->parent); 1346 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1347 != &fc_host_class.class) 1348 return 0; 1349 1350 i = to_fc_internal(shost->transportt); 1351 1352 return &i->t.target_attrs.ac == cont; 1353 } 1354 1355 static void fc_rport_dev_release(struct device *dev) 1356 { 1357 struct fc_rport *rport = dev_to_rport(dev); 1358 put_device(dev->parent); 1359 kfree(rport); 1360 } 1361 1362 int scsi_is_fc_rport(const struct device *dev) 1363 { 1364 return dev->release == fc_rport_dev_release; 1365 } 1366 EXPORT_SYMBOL(scsi_is_fc_rport); 1367 1368 static int fc_rport_match(struct attribute_container *cont, 1369 struct device *dev) 1370 { 1371 struct Scsi_Host *shost; 1372 struct fc_internal *i; 1373 1374 if (!scsi_is_fc_rport(dev)) 1375 return 0; 1376 1377 shost = dev_to_shost(dev->parent); 1378 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1379 != &fc_host_class.class) 1380 return 0; 1381 1382 i = to_fc_internal(shost->transportt); 1383 1384 return &i->rport_attr_cont.ac == cont; 1385 } 1386 1387 1388 /** 1389 * fc_timed_out - FC Transport I/O timeout intercept handler 1390 * 1391 * @scmd: The SCSI command which timed out 1392 * 1393 * This routine protects against error handlers getting invoked while a 1394 * rport is in a blocked state, typically due to a temporarily loss of 1395 * connectivity. If the error handlers are allowed to proceed, requests 1396 * to abort i/o, reset the target, etc will likely fail as there is no way 1397 * to communicate with the device to perform the requested function. These 1398 * failures may result in the midlayer taking the device offline, requiring 1399 * manual intervention to restore operation. 1400 * 1401 * This routine, called whenever an i/o times out, validates the state of 1402 * the underlying rport. If the rport is blocked, it returns 1403 * EH_RESET_TIMER, which will continue to reschedule the timeout. 1404 * Eventually, either the device will return, or devloss_tmo will fire, 1405 * and when the timeout then fires, it will be handled normally. 1406 * If the rport is not blocked, normal error handling continues. 1407 * 1408 * Notes: 1409 * This routine assumes no locks are held on entry. 1410 **/ 1411 static enum scsi_eh_timer_return 1412 fc_timed_out(struct scsi_cmnd *scmd) 1413 { 1414 struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device)); 1415 1416 if (rport->port_state == FC_PORTSTATE_BLOCKED) 1417 return EH_RESET_TIMER; 1418 1419 return EH_NOT_HANDLED; 1420 } 1421 1422 /* 1423 * Must be called with shost->host_lock held 1424 */ 1425 static int fc_user_scan(struct Scsi_Host *shost, uint channel, 1426 uint id, uint lun) 1427 { 1428 struct fc_rport *rport; 1429 1430 list_for_each_entry(rport, &fc_host_rports(shost), peers) { 1431 if (rport->scsi_target_id == -1) 1432 continue; 1433 1434 if ((channel == SCAN_WILD_CARD || channel == rport->channel) && 1435 (id == SCAN_WILD_CARD || id == rport->scsi_target_id)) { 1436 scsi_scan_target(&rport->dev, rport->channel, 1437 rport->scsi_target_id, lun, 1); 1438 } 1439 } 1440 1441 return 0; 1442 } 1443 1444 struct scsi_transport_template * 1445 fc_attach_transport(struct fc_function_template *ft) 1446 { 1447 int count; 1448 struct fc_internal *i = kzalloc(sizeof(struct fc_internal), 1449 GFP_KERNEL); 1450 1451 if (unlikely(!i)) 1452 return NULL; 1453 1454 i->t.target_attrs.ac.attrs = &i->starget_attrs[0]; 1455 i->t.target_attrs.ac.class = &fc_transport_class.class; 1456 i->t.target_attrs.ac.match = fc_target_match; 1457 i->t.target_size = sizeof(struct fc_starget_attrs); 1458 transport_container_register(&i->t.target_attrs); 1459 1460 i->t.host_attrs.ac.attrs = &i->host_attrs[0]; 1461 i->t.host_attrs.ac.class = &fc_host_class.class; 1462 i->t.host_attrs.ac.match = fc_host_match; 1463 i->t.host_size = sizeof(struct fc_host_attrs); 1464 if (ft->get_fc_host_stats) 1465 i->t.host_attrs.statistics = &fc_statistics_group; 1466 transport_container_register(&i->t.host_attrs); 1467 1468 i->rport_attr_cont.ac.attrs = &i->rport_attrs[0]; 1469 i->rport_attr_cont.ac.class = &fc_rport_class.class; 1470 i->rport_attr_cont.ac.match = fc_rport_match; 1471 transport_container_register(&i->rport_attr_cont); 1472 1473 i->f = ft; 1474 1475 /* Transport uses the shost workq for scsi scanning */ 1476 i->t.create_work_queue = 1; 1477 1478 i->t.eh_timed_out = fc_timed_out; 1479 1480 i->t.user_scan = fc_user_scan; 1481 1482 /* 1483 * Setup SCSI Target Attributes. 1484 */ 1485 count = 0; 1486 SETUP_STARGET_ATTRIBUTE_RD(node_name); 1487 SETUP_STARGET_ATTRIBUTE_RD(port_name); 1488 SETUP_STARGET_ATTRIBUTE_RD(port_id); 1489 1490 BUG_ON(count > FC_STARGET_NUM_ATTRS); 1491 1492 i->starget_attrs[count] = NULL; 1493 1494 1495 /* 1496 * Setup SCSI Host Attributes. 1497 */ 1498 count=0; 1499 SETUP_HOST_ATTRIBUTE_RD(node_name); 1500 SETUP_HOST_ATTRIBUTE_RD(port_name); 1501 SETUP_HOST_ATTRIBUTE_RD(permanent_port_name); 1502 SETUP_HOST_ATTRIBUTE_RD(supported_classes); 1503 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s); 1504 SETUP_HOST_ATTRIBUTE_RD(supported_speeds); 1505 SETUP_HOST_ATTRIBUTE_RD(maxframe_size); 1506 SETUP_HOST_ATTRIBUTE_RD(serial_number); 1507 1508 SETUP_HOST_ATTRIBUTE_RD(port_id); 1509 SETUP_HOST_ATTRIBUTE_RD(port_type); 1510 SETUP_HOST_ATTRIBUTE_RD(port_state); 1511 SETUP_HOST_ATTRIBUTE_RD(active_fc4s); 1512 SETUP_HOST_ATTRIBUTE_RD(speed); 1513 SETUP_HOST_ATTRIBUTE_RD(fabric_name); 1514 SETUP_HOST_ATTRIBUTE_RD(symbolic_name); 1515 SETUP_HOST_ATTRIBUTE_RW(system_hostname); 1516 1517 /* Transport-managed attributes */ 1518 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 1519 if (ft->issue_fc_host_lip) 1520 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip); 1521 1522 BUG_ON(count > FC_HOST_NUM_ATTRS); 1523 1524 i->host_attrs[count] = NULL; 1525 1526 /* 1527 * Setup Remote Port Attributes. 1528 */ 1529 count=0; 1530 SETUP_RPORT_ATTRIBUTE_RD(maxframe_size); 1531 SETUP_RPORT_ATTRIBUTE_RD(supported_classes); 1532 SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo); 1533 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name); 1534 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name); 1535 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id); 1536 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles); 1537 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state); 1538 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id); 1539 if (ft->terminate_rport_io) 1540 SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo); 1541 1542 BUG_ON(count > FC_RPORT_NUM_ATTRS); 1543 1544 i->rport_attrs[count] = NULL; 1545 1546 return &i->t; 1547 } 1548 EXPORT_SYMBOL(fc_attach_transport); 1549 1550 void fc_release_transport(struct scsi_transport_template *t) 1551 { 1552 struct fc_internal *i = to_fc_internal(t); 1553 1554 transport_container_unregister(&i->t.target_attrs); 1555 transport_container_unregister(&i->t.host_attrs); 1556 transport_container_unregister(&i->rport_attr_cont); 1557 1558 kfree(i); 1559 } 1560 EXPORT_SYMBOL(fc_release_transport); 1561 1562 /** 1563 * fc_queue_work - Queue work to the fc_host workqueue. 1564 * @shost: Pointer to Scsi_Host bound to fc_host. 1565 * @work: Work to queue for execution. 1566 * 1567 * Return value: 1568 * 1 - work queued for execution 1569 * 0 - work is already queued 1570 * -EINVAL - work queue doesn't exist 1571 **/ 1572 static int 1573 fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) 1574 { 1575 if (unlikely(!fc_host_work_q(shost))) { 1576 printk(KERN_ERR 1577 "ERROR: FC host '%s' attempted to queue work, " 1578 "when no workqueue created.\n", shost->hostt->name); 1579 dump_stack(); 1580 1581 return -EINVAL; 1582 } 1583 1584 return queue_work(fc_host_work_q(shost), work); 1585 } 1586 1587 /** 1588 * fc_flush_work - Flush a fc_host's workqueue. 1589 * @shost: Pointer to Scsi_Host bound to fc_host. 1590 **/ 1591 static void 1592 fc_flush_work(struct Scsi_Host *shost) 1593 { 1594 if (!fc_host_work_q(shost)) { 1595 printk(KERN_ERR 1596 "ERROR: FC host '%s' attempted to flush work, " 1597 "when no workqueue created.\n", shost->hostt->name); 1598 dump_stack(); 1599 return; 1600 } 1601 1602 flush_workqueue(fc_host_work_q(shost)); 1603 } 1604 1605 /** 1606 * fc_queue_devloss_work - Schedule work for the fc_host devloss workqueue. 1607 * @shost: Pointer to Scsi_Host bound to fc_host. 1608 * @work: Work to queue for execution. 1609 * @delay: jiffies to delay the work queuing 1610 * 1611 * Return value: 1612 * 1 on success / 0 already queued / < 0 for error 1613 **/ 1614 static int 1615 fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work, 1616 unsigned long delay) 1617 { 1618 if (unlikely(!fc_host_devloss_work_q(shost))) { 1619 printk(KERN_ERR 1620 "ERROR: FC host '%s' attempted to queue work, " 1621 "when no workqueue created.\n", shost->hostt->name); 1622 dump_stack(); 1623 1624 return -EINVAL; 1625 } 1626 1627 return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay); 1628 } 1629 1630 /** 1631 * fc_flush_devloss - Flush a fc_host's devloss workqueue. 1632 * @shost: Pointer to Scsi_Host bound to fc_host. 1633 **/ 1634 static void 1635 fc_flush_devloss(struct Scsi_Host *shost) 1636 { 1637 if (!fc_host_devloss_work_q(shost)) { 1638 printk(KERN_ERR 1639 "ERROR: FC host '%s' attempted to flush work, " 1640 "when no workqueue created.\n", shost->hostt->name); 1641 dump_stack(); 1642 return; 1643 } 1644 1645 flush_workqueue(fc_host_devloss_work_q(shost)); 1646 } 1647 1648 1649 /** 1650 * fc_remove_host - called to terminate any fc_transport-related elements 1651 * for a scsi host. 1652 * @rport: remote port to be unblocked. 1653 * 1654 * This routine is expected to be called immediately preceeding the 1655 * a driver's call to scsi_remove_host(). 1656 * 1657 * WARNING: A driver utilizing the fc_transport, which fails to call 1658 * this routine prior to scsi_remote_host(), will leave dangling 1659 * objects in /sys/class/fc_remote_ports. Access to any of these 1660 * objects can result in a system crash !!! 1661 * 1662 * Notes: 1663 * This routine assumes no locks are held on entry. 1664 **/ 1665 void 1666 fc_remove_host(struct Scsi_Host *shost) 1667 { 1668 struct fc_rport *rport, *next_rport; 1669 struct workqueue_struct *work_q; 1670 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 1671 1672 /* Remove any remote ports */ 1673 list_for_each_entry_safe(rport, next_rport, 1674 &fc_host->rports, peers) { 1675 list_del(&rport->peers); 1676 rport->port_state = FC_PORTSTATE_DELETED; 1677 fc_queue_work(shost, &rport->rport_delete_work); 1678 } 1679 1680 list_for_each_entry_safe(rport, next_rport, 1681 &fc_host->rport_bindings, peers) { 1682 list_del(&rport->peers); 1683 rport->port_state = FC_PORTSTATE_DELETED; 1684 fc_queue_work(shost, &rport->rport_delete_work); 1685 } 1686 1687 /* flush all scan work items */ 1688 scsi_flush_work(shost); 1689 1690 /* flush all stgt delete, and rport delete work items, then kill it */ 1691 if (fc_host->work_q) { 1692 work_q = fc_host->work_q; 1693 fc_host->work_q = NULL; 1694 destroy_workqueue(work_q); 1695 } 1696 1697 /* flush all devloss work items, then kill it */ 1698 if (fc_host->devloss_work_q) { 1699 work_q = fc_host->devloss_work_q; 1700 fc_host->devloss_work_q = NULL; 1701 destroy_workqueue(work_q); 1702 } 1703 } 1704 EXPORT_SYMBOL(fc_remove_host); 1705 1706 1707 /** 1708 * fc_starget_delete - called to delete the scsi decendents of an rport 1709 * (target and all sdevs) 1710 * 1711 * @work: remote port to be operated on. 1712 **/ 1713 static void 1714 fc_starget_delete(struct work_struct *work) 1715 { 1716 struct fc_rport *rport = 1717 container_of(work, struct fc_rport, stgt_delete_work); 1718 struct Scsi_Host *shost = rport_to_shost(rport); 1719 unsigned long flags; 1720 struct fc_internal *i = to_fc_internal(shost->transportt); 1721 1722 /* 1723 * Involve the LLDD if possible. All io on the rport is to 1724 * be terminated, either as part of the dev_loss_tmo callback 1725 * processing, or via the terminate_rport_io function. 1726 */ 1727 if (i->f->dev_loss_tmo_callbk) 1728 i->f->dev_loss_tmo_callbk(rport); 1729 else if (i->f->terminate_rport_io) 1730 i->f->terminate_rport_io(rport); 1731 1732 spin_lock_irqsave(shost->host_lock, flags); 1733 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { 1734 spin_unlock_irqrestore(shost->host_lock, flags); 1735 if (!cancel_delayed_work(&rport->fail_io_work)) 1736 fc_flush_devloss(shost); 1737 if (!cancel_delayed_work(&rport->dev_loss_work)) 1738 fc_flush_devloss(shost); 1739 spin_lock_irqsave(shost->host_lock, flags); 1740 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 1741 } 1742 spin_unlock_irqrestore(shost->host_lock, flags); 1743 1744 scsi_remove_target(&rport->dev); 1745 } 1746 1747 1748 /** 1749 * fc_rport_final_delete - finish rport termination and delete it. 1750 * 1751 * @work: remote port to be deleted. 1752 **/ 1753 static void 1754 fc_rport_final_delete(struct work_struct *work) 1755 { 1756 struct fc_rport *rport = 1757 container_of(work, struct fc_rport, rport_delete_work); 1758 struct device *dev = &rport->dev; 1759 struct Scsi_Host *shost = rport_to_shost(rport); 1760 struct fc_internal *i = to_fc_internal(shost->transportt); 1761 1762 /* 1763 * if a scan is pending, flush the SCSI Host work_q so that 1764 * that we can reclaim the rport scan work element. 1765 */ 1766 if (rport->flags & FC_RPORT_SCAN_PENDING) 1767 scsi_flush_work(shost); 1768 1769 /* Delete SCSI target and sdevs */ 1770 if (rport->scsi_target_id != -1) 1771 fc_starget_delete(&rport->stgt_delete_work); 1772 else if (i->f->dev_loss_tmo_callbk) 1773 i->f->dev_loss_tmo_callbk(rport); 1774 else if (i->f->terminate_rport_io) 1775 i->f->terminate_rport_io(rport); 1776 1777 transport_remove_device(dev); 1778 device_del(dev); 1779 transport_destroy_device(dev); 1780 put_device(&shost->shost_gendev); /* for fc_host->rport list */ 1781 put_device(dev); /* for self-reference */ 1782 } 1783 1784 1785 /** 1786 * fc_rport_create - allocates and creates a remote FC port. 1787 * @shost: scsi host the remote port is connected to. 1788 * @channel: Channel on shost port connected to. 1789 * @ids: The world wide names, fc address, and FC4 port 1790 * roles for the remote port. 1791 * 1792 * Allocates and creates the remoter port structure, including the 1793 * class and sysfs creation. 1794 * 1795 * Notes: 1796 * This routine assumes no locks are held on entry. 1797 **/ 1798 struct fc_rport * 1799 fc_rport_create(struct Scsi_Host *shost, int channel, 1800 struct fc_rport_identifiers *ids) 1801 { 1802 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 1803 struct fc_internal *fci = to_fc_internal(shost->transportt); 1804 struct fc_rport *rport; 1805 struct device *dev; 1806 unsigned long flags; 1807 int error; 1808 size_t size; 1809 1810 size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); 1811 rport = kzalloc(size, GFP_KERNEL); 1812 if (unlikely(!rport)) { 1813 printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); 1814 return NULL; 1815 } 1816 1817 rport->maxframe_size = -1; 1818 rport->supported_classes = FC_COS_UNSPECIFIED; 1819 rport->dev_loss_tmo = fc_dev_loss_tmo; 1820 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); 1821 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name)); 1822 rport->port_id = ids->port_id; 1823 rport->roles = ids->roles; 1824 rport->port_state = FC_PORTSTATE_ONLINE; 1825 if (fci->f->dd_fcrport_size) 1826 rport->dd_data = &rport[1]; 1827 rport->channel = channel; 1828 rport->fast_io_fail_tmo = -1; 1829 1830 INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport); 1831 INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io); 1832 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport); 1833 INIT_WORK(&rport->stgt_delete_work, fc_starget_delete); 1834 INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete); 1835 1836 spin_lock_irqsave(shost->host_lock, flags); 1837 1838 rport->number = fc_host->next_rport_number++; 1839 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) 1840 rport->scsi_target_id = fc_host->next_target_id++; 1841 else 1842 rport->scsi_target_id = -1; 1843 list_add_tail(&rport->peers, &fc_host->rports); 1844 get_device(&shost->shost_gendev); /* for fc_host->rport list */ 1845 1846 spin_unlock_irqrestore(shost->host_lock, flags); 1847 1848 dev = &rport->dev; 1849 device_initialize(dev); /* takes self reference */ 1850 dev->parent = get_device(&shost->shost_gendev); /* parent reference */ 1851 dev->release = fc_rport_dev_release; 1852 sprintf(dev->bus_id, "rport-%d:%d-%d", 1853 shost->host_no, channel, rport->number); 1854 transport_setup_device(dev); 1855 1856 error = device_add(dev); 1857 if (error) { 1858 printk(KERN_ERR "FC Remote Port device_add failed\n"); 1859 goto delete_rport; 1860 } 1861 transport_add_device(dev); 1862 transport_configure_device(dev); 1863 1864 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) { 1865 /* initiate a scan of the target */ 1866 rport->flags |= FC_RPORT_SCAN_PENDING; 1867 scsi_queue_work(shost, &rport->scan_work); 1868 } 1869 1870 return rport; 1871 1872 delete_rport: 1873 transport_destroy_device(dev); 1874 spin_lock_irqsave(shost->host_lock, flags); 1875 list_del(&rport->peers); 1876 put_device(&shost->shost_gendev); /* for fc_host->rport list */ 1877 spin_unlock_irqrestore(shost->host_lock, flags); 1878 put_device(dev->parent); 1879 kfree(rport); 1880 return NULL; 1881 } 1882 1883 /** 1884 * fc_remote_port_add - notifies the fc transport of the existence 1885 * of a remote FC port. 1886 * @shost: scsi host the remote port is connected to. 1887 * @channel: Channel on shost port connected to. 1888 * @ids: The world wide names, fc address, and FC4 port 1889 * roles for the remote port. 1890 * 1891 * The LLDD calls this routine to notify the transport of the existence 1892 * of a remote port. The LLDD provides the unique identifiers (wwpn,wwn) 1893 * of the port, it's FC address (port_id), and the FC4 roles that are 1894 * active for the port. 1895 * 1896 * For ports that are FCP targets (aka scsi targets), the FC transport 1897 * maintains consistent target id bindings on behalf of the LLDD. 1898 * A consistent target id binding is an assignment of a target id to 1899 * a remote port identifier, which persists while the scsi host is 1900 * attached. The remote port can disappear, then later reappear, and 1901 * it's target id assignment remains the same. This allows for shifts 1902 * in FC addressing (if binding by wwpn or wwnn) with no apparent 1903 * changes to the scsi subsystem which is based on scsi host number and 1904 * target id values. Bindings are only valid during the attachment of 1905 * the scsi host. If the host detaches, then later re-attaches, target 1906 * id bindings may change. 1907 * 1908 * This routine is responsible for returning a remote port structure. 1909 * The routine will search the list of remote ports it maintains 1910 * internally on behalf of consistent target id mappings. If found, the 1911 * remote port structure will be reused. Otherwise, a new remote port 1912 * structure will be allocated. 1913 * 1914 * Whenever a remote port is allocated, a new fc_remote_port class 1915 * device is created. 1916 * 1917 * Should not be called from interrupt context. 1918 * 1919 * Notes: 1920 * This routine assumes no locks are held on entry. 1921 **/ 1922 struct fc_rport * 1923 fc_remote_port_add(struct Scsi_Host *shost, int channel, 1924 struct fc_rport_identifiers *ids) 1925 { 1926 struct fc_internal *fci = to_fc_internal(shost->transportt); 1927 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 1928 struct fc_rport *rport; 1929 unsigned long flags; 1930 int match = 0; 1931 1932 /* ensure any stgt delete functions are done */ 1933 fc_flush_work(shost); 1934 1935 /* 1936 * Search the list of "active" rports, for an rport that has been 1937 * deleted, but we've held off the real delete while the target 1938 * is in a "blocked" state. 1939 */ 1940 spin_lock_irqsave(shost->host_lock, flags); 1941 1942 list_for_each_entry(rport, &fc_host->rports, peers) { 1943 1944 if ((rport->port_state == FC_PORTSTATE_BLOCKED) && 1945 (rport->channel == channel)) { 1946 1947 switch (fc_host->tgtid_bind_type) { 1948 case FC_TGTID_BIND_BY_WWPN: 1949 case FC_TGTID_BIND_NONE: 1950 if (rport->port_name == ids->port_name) 1951 match = 1; 1952 break; 1953 case FC_TGTID_BIND_BY_WWNN: 1954 if (rport->node_name == ids->node_name) 1955 match = 1; 1956 break; 1957 case FC_TGTID_BIND_BY_ID: 1958 if (rport->port_id == ids->port_id) 1959 match = 1; 1960 break; 1961 } 1962 1963 if (match) { 1964 struct delayed_work *work = 1965 &rport->dev_loss_work; 1966 1967 memcpy(&rport->node_name, &ids->node_name, 1968 sizeof(rport->node_name)); 1969 memcpy(&rport->port_name, &ids->port_name, 1970 sizeof(rport->port_name)); 1971 rport->port_id = ids->port_id; 1972 1973 rport->port_state = FC_PORTSTATE_ONLINE; 1974 rport->roles = ids->roles; 1975 1976 spin_unlock_irqrestore(shost->host_lock, flags); 1977 1978 if (fci->f->dd_fcrport_size) 1979 memset(rport->dd_data, 0, 1980 fci->f->dd_fcrport_size); 1981 1982 /* 1983 * If we were blocked, we were a target. 1984 * If no longer a target, we leave the timer 1985 * running in case the port changes roles 1986 * prior to the timer expiring. If the timer 1987 * fires, the target will be torn down. 1988 */ 1989 if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET)) 1990 return rport; 1991 1992 /* restart the target */ 1993 1994 /* 1995 * Stop the target timers first. Take no action 1996 * on the del_timer failure as the state 1997 * machine state change will validate the 1998 * transaction. 1999 */ 2000 if (!cancel_delayed_work(&rport->fail_io_work)) 2001 fc_flush_devloss(shost); 2002 if (!cancel_delayed_work(work)) 2003 fc_flush_devloss(shost); 2004 2005 spin_lock_irqsave(shost->host_lock, flags); 2006 2007 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2008 2009 /* initiate a scan of the target */ 2010 rport->flags |= FC_RPORT_SCAN_PENDING; 2011 scsi_queue_work(shost, &rport->scan_work); 2012 2013 spin_unlock_irqrestore(shost->host_lock, flags); 2014 2015 scsi_target_unblock(&rport->dev); 2016 2017 return rport; 2018 } 2019 } 2020 } 2021 2022 /* Search the bindings array */ 2023 if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) { 2024 2025 /* search for a matching consistent binding */ 2026 2027 list_for_each_entry(rport, &fc_host->rport_bindings, 2028 peers) { 2029 if (rport->channel != channel) 2030 continue; 2031 2032 switch (fc_host->tgtid_bind_type) { 2033 case FC_TGTID_BIND_BY_WWPN: 2034 if (rport->port_name == ids->port_name) 2035 match = 1; 2036 break; 2037 case FC_TGTID_BIND_BY_WWNN: 2038 if (rport->node_name == ids->node_name) 2039 match = 1; 2040 break; 2041 case FC_TGTID_BIND_BY_ID: 2042 if (rport->port_id == ids->port_id) 2043 match = 1; 2044 break; 2045 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 2046 break; 2047 } 2048 2049 if (match) { 2050 list_move_tail(&rport->peers, &fc_host->rports); 2051 break; 2052 } 2053 } 2054 2055 if (match) { 2056 memcpy(&rport->node_name, &ids->node_name, 2057 sizeof(rport->node_name)); 2058 memcpy(&rport->port_name, &ids->port_name, 2059 sizeof(rport->port_name)); 2060 rport->port_id = ids->port_id; 2061 rport->roles = ids->roles; 2062 rport->port_state = FC_PORTSTATE_ONLINE; 2063 2064 if (fci->f->dd_fcrport_size) 2065 memset(rport->dd_data, 0, 2066 fci->f->dd_fcrport_size); 2067 2068 if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) { 2069 /* initiate a scan of the target */ 2070 rport->flags |= FC_RPORT_SCAN_PENDING; 2071 scsi_queue_work(shost, &rport->scan_work); 2072 spin_unlock_irqrestore(shost->host_lock, flags); 2073 scsi_target_unblock(&rport->dev); 2074 } else 2075 spin_unlock_irqrestore(shost->host_lock, flags); 2076 2077 return rport; 2078 } 2079 } 2080 2081 spin_unlock_irqrestore(shost->host_lock, flags); 2082 2083 /* No consistent binding found - create new remote port entry */ 2084 rport = fc_rport_create(shost, channel, ids); 2085 2086 return rport; 2087 } 2088 EXPORT_SYMBOL(fc_remote_port_add); 2089 2090 2091 /** 2092 * fc_remote_port_delete - notifies the fc transport that a remote 2093 * port is no longer in existence. 2094 * @rport: The remote port that no longer exists 2095 * 2096 * The LLDD calls this routine to notify the transport that a remote 2097 * port is no longer part of the topology. Note: Although a port 2098 * may no longer be part of the topology, it may persist in the remote 2099 * ports displayed by the fc_host. We do this under 2 conditions: 2100 * - If the port was a scsi target, we delay its deletion by "blocking" it. 2101 * This allows the port to temporarily disappear, then reappear without 2102 * disrupting the SCSI device tree attached to it. During the "blocked" 2103 * period the port will still exist. 2104 * - If the port was a scsi target and disappears for longer than we 2105 * expect, we'll delete the port and the tear down the SCSI device tree 2106 * attached to it. However, we want to semi-persist the target id assigned 2107 * to that port if it eventually does exist. The port structure will 2108 * remain (although with minimal information) so that the target id 2109 * bindings remails. 2110 * 2111 * If the remote port is not an FCP Target, it will be fully torn down 2112 * and deallocated, including the fc_remote_port class device. 2113 * 2114 * If the remote port is an FCP Target, the port will be placed in a 2115 * temporary blocked state. From the LLDD's perspective, the rport no 2116 * longer exists. From the SCSI midlayer's perspective, the SCSI target 2117 * exists, but all sdevs on it are blocked from further I/O. The following 2118 * is then expected: 2119 * If the remote port does not return (signaled by a LLDD call to 2120 * fc_remote_port_add()) within the dev_loss_tmo timeout, then the 2121 * scsi target is removed - killing all outstanding i/o and removing the 2122 * scsi devices attached ot it. The port structure will be marked Not 2123 * Present and be partially cleared, leaving only enough information to 2124 * recognize the remote port relative to the scsi target id binding if 2125 * it later appears. The port will remain as long as there is a valid 2126 * binding (e.g. until the user changes the binding type or unloads the 2127 * scsi host with the binding). 2128 * 2129 * If the remote port returns within the dev_loss_tmo value (and matches 2130 * according to the target id binding type), the port structure will be 2131 * reused. If it is no longer a SCSI target, the target will be torn 2132 * down. If it continues to be a SCSI target, then the target will be 2133 * unblocked (allowing i/o to be resumed), and a scan will be activated 2134 * to ensure that all luns are detected. 2135 * 2136 * Called from normal process context only - cannot be called from interrupt. 2137 * 2138 * Notes: 2139 * This routine assumes no locks are held on entry. 2140 **/ 2141 void 2142 fc_remote_port_delete(struct fc_rport *rport) 2143 { 2144 struct Scsi_Host *shost = rport_to_shost(rport); 2145 struct fc_internal *i = to_fc_internal(shost->transportt); 2146 int timeout = rport->dev_loss_tmo; 2147 unsigned long flags; 2148 2149 /* 2150 * No need to flush the fc_host work_q's, as all adds are synchronous. 2151 * 2152 * We do need to reclaim the rport scan work element, so eventually 2153 * (in fc_rport_final_delete()) we'll flush the scsi host work_q if 2154 * there's still a scan pending. 2155 */ 2156 2157 spin_lock_irqsave(shost->host_lock, flags); 2158 2159 /* If no scsi target id mapping, delete it */ 2160 if (rport->scsi_target_id == -1) { 2161 list_del(&rport->peers); 2162 rport->port_state = FC_PORTSTATE_DELETED; 2163 fc_queue_work(shost, &rport->rport_delete_work); 2164 spin_unlock_irqrestore(shost->host_lock, flags); 2165 return; 2166 } 2167 2168 rport->port_state = FC_PORTSTATE_BLOCKED; 2169 2170 rport->flags |= FC_RPORT_DEVLOSS_PENDING; 2171 2172 spin_unlock_irqrestore(shost->host_lock, flags); 2173 2174 scsi_target_block(&rport->dev); 2175 2176 /* see if we need to kill io faster than waiting for device loss */ 2177 if ((rport->fast_io_fail_tmo != -1) && 2178 (rport->fast_io_fail_tmo < timeout) && (i->f->terminate_rport_io)) 2179 fc_queue_devloss_work(shost, &rport->fail_io_work, 2180 rport->fast_io_fail_tmo * HZ); 2181 2182 /* cap the length the devices can be blocked until they are deleted */ 2183 fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ); 2184 } 2185 EXPORT_SYMBOL(fc_remote_port_delete); 2186 2187 /** 2188 * fc_remote_port_rolechg - notifies the fc transport that the roles 2189 * on a remote may have changed. 2190 * @rport: The remote port that changed. 2191 * 2192 * The LLDD calls this routine to notify the transport that the roles 2193 * on a remote port may have changed. The largest effect of this is 2194 * if a port now becomes a FCP Target, it must be allocated a 2195 * scsi target id. If the port is no longer a FCP target, any 2196 * scsi target id value assigned to it will persist in case the 2197 * role changes back to include FCP Target. No changes in the scsi 2198 * midlayer will be invoked if the role changes (in the expectation 2199 * that the role will be resumed. If it doesn't normal error processing 2200 * will take place). 2201 * 2202 * Should not be called from interrupt context. 2203 * 2204 * Notes: 2205 * This routine assumes no locks are held on entry. 2206 **/ 2207 void 2208 fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) 2209 { 2210 struct Scsi_Host *shost = rport_to_shost(rport); 2211 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2212 unsigned long flags; 2213 int create = 0; 2214 2215 spin_lock_irqsave(shost->host_lock, flags); 2216 if (roles & FC_RPORT_ROLE_FCP_TARGET) { 2217 if (rport->scsi_target_id == -1) { 2218 rport->scsi_target_id = fc_host->next_target_id++; 2219 create = 1; 2220 } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) 2221 create = 1; 2222 } 2223 2224 rport->roles = roles; 2225 2226 spin_unlock_irqrestore(shost->host_lock, flags); 2227 2228 if (create) { 2229 /* 2230 * There may have been a delete timer running on the 2231 * port. Ensure that it is cancelled as we now know 2232 * the port is an FCP Target. 2233 * Note: we know the rport is exists and in an online 2234 * state as the LLDD would not have had an rport 2235 * reference to pass us. 2236 * 2237 * Take no action on the del_timer failure as the state 2238 * machine state change will validate the 2239 * transaction. 2240 */ 2241 if (!cancel_delayed_work(&rport->fail_io_work)) 2242 fc_flush_devloss(shost); 2243 if (!cancel_delayed_work(&rport->dev_loss_work)) 2244 fc_flush_devloss(shost); 2245 2246 spin_lock_irqsave(shost->host_lock, flags); 2247 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2248 spin_unlock_irqrestore(shost->host_lock, flags); 2249 2250 /* ensure any stgt delete functions are done */ 2251 fc_flush_work(shost); 2252 2253 /* initiate a scan of the target */ 2254 spin_lock_irqsave(shost->host_lock, flags); 2255 rport->flags |= FC_RPORT_SCAN_PENDING; 2256 scsi_queue_work(shost, &rport->scan_work); 2257 spin_unlock_irqrestore(shost->host_lock, flags); 2258 scsi_target_unblock(&rport->dev); 2259 } 2260 } 2261 EXPORT_SYMBOL(fc_remote_port_rolechg); 2262 2263 /** 2264 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that 2265 * was a SCSI target (thus was blocked), and failed 2266 * to return in the alloted time. 2267 * 2268 * @work: rport target that failed to reappear in the alloted time. 2269 **/ 2270 static void 2271 fc_timeout_deleted_rport(struct work_struct *work) 2272 { 2273 struct fc_rport *rport = 2274 container_of(work, struct fc_rport, dev_loss_work.work); 2275 struct Scsi_Host *shost = rport_to_shost(rport); 2276 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2277 unsigned long flags; 2278 2279 spin_lock_irqsave(shost->host_lock, flags); 2280 2281 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2282 2283 /* 2284 * If the port is ONLINE, then it came back. Validate it's still an 2285 * FCP target. If not, tear down the scsi_target on it. 2286 */ 2287 if ((rport->port_state == FC_PORTSTATE_ONLINE) && 2288 !(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { 2289 dev_printk(KERN_ERR, &rport->dev, 2290 "blocked FC remote port time out: no longer" 2291 " a FCP target, removing starget\n"); 2292 spin_unlock_irqrestore(shost->host_lock, flags); 2293 scsi_target_unblock(&rport->dev); 2294 fc_queue_work(shost, &rport->stgt_delete_work); 2295 return; 2296 } 2297 2298 if (rport->port_state != FC_PORTSTATE_BLOCKED) { 2299 spin_unlock_irqrestore(shost->host_lock, flags); 2300 dev_printk(KERN_ERR, &rport->dev, 2301 "blocked FC remote port time out: leaving target alone\n"); 2302 return; 2303 } 2304 2305 if (fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) { 2306 list_del(&rport->peers); 2307 rport->port_state = FC_PORTSTATE_DELETED; 2308 dev_printk(KERN_ERR, &rport->dev, 2309 "blocked FC remote port time out: removing target\n"); 2310 fc_queue_work(shost, &rport->rport_delete_work); 2311 spin_unlock_irqrestore(shost->host_lock, flags); 2312 return; 2313 } 2314 2315 dev_printk(KERN_ERR, &rport->dev, 2316 "blocked FC remote port time out: removing target and " 2317 "saving binding\n"); 2318 2319 list_move_tail(&rport->peers, &fc_host->rport_bindings); 2320 2321 /* 2322 * Note: We do not remove or clear the hostdata area. This allows 2323 * host-specific target data to persist along with the 2324 * scsi_target_id. It's up to the host to manage it's hostdata area. 2325 */ 2326 2327 /* 2328 * Reinitialize port attributes that may change if the port comes back. 2329 */ 2330 rport->maxframe_size = -1; 2331 rport->supported_classes = FC_COS_UNSPECIFIED; 2332 rport->roles = FC_RPORT_ROLE_UNKNOWN; 2333 rport->port_state = FC_PORTSTATE_NOTPRESENT; 2334 2335 /* remove the identifiers that aren't used in the consisting binding */ 2336 switch (fc_host->tgtid_bind_type) { 2337 case FC_TGTID_BIND_BY_WWPN: 2338 rport->node_name = -1; 2339 rport->port_id = -1; 2340 break; 2341 case FC_TGTID_BIND_BY_WWNN: 2342 rport->port_name = -1; 2343 rport->port_id = -1; 2344 break; 2345 case FC_TGTID_BIND_BY_ID: 2346 rport->node_name = -1; 2347 rport->port_name = -1; 2348 break; 2349 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 2350 break; 2351 } 2352 2353 /* 2354 * As this only occurs if the remote port (scsi target) 2355 * went away and didn't come back - we'll remove 2356 * all attached scsi devices. 2357 */ 2358 spin_unlock_irqrestore(shost->host_lock, flags); 2359 2360 scsi_target_unblock(&rport->dev); 2361 fc_queue_work(shost, &rport->stgt_delete_work); 2362 } 2363 2364 /** 2365 * fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a 2366 * disconnected SCSI target. 2367 * 2368 * @work: rport to terminate io on. 2369 * 2370 * Notes: Only requests the failure of the io, not that all are flushed 2371 * prior to returning. 2372 **/ 2373 static void 2374 fc_timeout_fail_rport_io(struct work_struct *work) 2375 { 2376 struct fc_rport *rport = 2377 container_of(work, struct fc_rport, fail_io_work.work); 2378 struct Scsi_Host *shost = rport_to_shost(rport); 2379 struct fc_internal *i = to_fc_internal(shost->transportt); 2380 2381 if (rport->port_state != FC_PORTSTATE_BLOCKED) 2382 return; 2383 2384 i->f->terminate_rport_io(rport); 2385 } 2386 2387 /** 2388 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 2389 * 2390 * @work: remote port to be scanned. 2391 **/ 2392 static void 2393 fc_scsi_scan_rport(struct work_struct *work) 2394 { 2395 struct fc_rport *rport = 2396 container_of(work, struct fc_rport, scan_work); 2397 struct Scsi_Host *shost = rport_to_shost(rport); 2398 unsigned long flags; 2399 2400 if ((rport->port_state == FC_PORTSTATE_ONLINE) && 2401 (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) { 2402 scsi_scan_target(&rport->dev, rport->channel, 2403 rport->scsi_target_id, SCAN_WILD_CARD, 1); 2404 } 2405 2406 spin_lock_irqsave(shost->host_lock, flags); 2407 rport->flags &= ~FC_RPORT_SCAN_PENDING; 2408 spin_unlock_irqrestore(shost->host_lock, flags); 2409 } 2410 2411 2412 MODULE_AUTHOR("Martin Hicks"); 2413 MODULE_DESCRIPTION("FC Transport Attributes"); 2414 MODULE_LICENSE("GPL"); 2415 2416 module_init(fc_transport_init); 2417 module_exit(fc_transport_exit); 2418