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