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-2007 James Smart, Emulex Corporation 23 * Rewrite for host, target, device, and remote port attributes, 24 * statistics, and service functions... 25 * Add vports, etc 26 * 27 */ 28 #include <linux/module.h> 29 #include <linux/init.h> 30 #include <scsi/scsi_device.h> 31 #include <scsi/scsi_host.h> 32 #include <scsi/scsi_transport.h> 33 #include <scsi/scsi_transport_fc.h> 34 #include <scsi/scsi_cmnd.h> 35 #include <linux/netlink.h> 36 #include <net/netlink.h> 37 #include <scsi/scsi_netlink_fc.h> 38 #include "scsi_priv.h" 39 40 static int fc_queue_work(struct Scsi_Host *, struct work_struct *); 41 static void fc_vport_sched_delete(struct work_struct *work); 42 43 /* 44 * This is a temporary carrier for creating a vport. It will eventually 45 * be replaced by a real message definition for sgio or netlink. 46 * 47 * fc_vport_identifiers: This set of data contains all elements 48 * to uniquely identify and instantiate a FC virtual port. 49 * 50 * Notes: 51 * symbolic_name: The driver is to append the symbolic_name string data 52 * to the symbolic_node_name data that it generates by default. 53 * the resulting combination should then be registered with the switch. 54 * It is expected that things like Xen may stuff a VM title into 55 * this field. 56 */ 57 struct fc_vport_identifiers { 58 u64 node_name; 59 u64 port_name; 60 u32 roles; 61 bool disable; 62 enum fc_port_type vport_type; /* only FC_PORTTYPE_NPIV allowed */ 63 char symbolic_name[FC_VPORT_SYMBOLIC_NAMELEN]; 64 }; 65 66 static int fc_vport_create(struct Scsi_Host *shost, int channel, 67 struct device *pdev, struct fc_vport_identifiers *ids, 68 struct fc_vport **vport); 69 70 /* 71 * Redefine so that we can have same named attributes in the 72 * sdev/starget/host objects. 73 */ 74 #define FC_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \ 75 struct class_device_attribute class_device_attr_##_prefix##_##_name = \ 76 __ATTR(_name,_mode,_show,_store) 77 78 #define fc_enum_name_search(title, table_type, table) \ 79 static const char *get_fc_##title##_name(enum table_type table_key) \ 80 { \ 81 int i; \ 82 char *name = NULL; \ 83 \ 84 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 85 if (table[i].value == table_key) { \ 86 name = table[i].name; \ 87 break; \ 88 } \ 89 } \ 90 return name; \ 91 } 92 93 #define fc_enum_name_match(title, table_type, table) \ 94 static int get_fc_##title##_match(const char *table_key, \ 95 enum table_type *value) \ 96 { \ 97 int i; \ 98 \ 99 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 100 if (strncmp(table_key, table[i].name, \ 101 table[i].matchlen) == 0) { \ 102 *value = table[i].value; \ 103 return 0; /* success */ \ 104 } \ 105 } \ 106 return 1; /* failure */ \ 107 } 108 109 110 /* Convert fc_port_type values to ascii string name */ 111 static struct { 112 enum fc_port_type value; 113 char *name; 114 } fc_port_type_names[] = { 115 { FC_PORTTYPE_UNKNOWN, "Unknown" }, 116 { FC_PORTTYPE_OTHER, "Other" }, 117 { FC_PORTTYPE_NOTPRESENT, "Not Present" }, 118 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" }, 119 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" }, 120 { FC_PORTTYPE_LPORT, "LPort (private loop)" }, 121 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection" }, 122 { FC_PORTTYPE_NPIV, "NPIV VPORT" }, 123 }; 124 fc_enum_name_search(port_type, fc_port_type, fc_port_type_names) 125 #define FC_PORTTYPE_MAX_NAMELEN 50 126 127 /* Reuse fc_port_type enum function for vport_type */ 128 #define get_fc_vport_type_name get_fc_port_type_name 129 130 131 /* Convert fc_host_event_code values to ascii string name */ 132 static const struct { 133 enum fc_host_event_code value; 134 char *name; 135 } fc_host_event_code_names[] = { 136 { FCH_EVT_LIP, "lip" }, 137 { FCH_EVT_LINKUP, "link_up" }, 138 { FCH_EVT_LINKDOWN, "link_down" }, 139 { FCH_EVT_LIPRESET, "lip_reset" }, 140 { FCH_EVT_RSCN, "rscn" }, 141 { FCH_EVT_ADAPTER_CHANGE, "adapter_chg" }, 142 { FCH_EVT_PORT_UNKNOWN, "port_unknown" }, 143 { FCH_EVT_PORT_ONLINE, "port_online" }, 144 { FCH_EVT_PORT_OFFLINE, "port_offline" }, 145 { FCH_EVT_PORT_FABRIC, "port_fabric" }, 146 { FCH_EVT_LINK_UNKNOWN, "link_unknown" }, 147 { FCH_EVT_VENDOR_UNIQUE, "vendor_unique" }, 148 }; 149 fc_enum_name_search(host_event_code, fc_host_event_code, 150 fc_host_event_code_names) 151 #define FC_HOST_EVENT_CODE_MAX_NAMELEN 30 152 153 154 /* Convert fc_port_state values to ascii string name */ 155 static struct { 156 enum fc_port_state value; 157 char *name; 158 } fc_port_state_names[] = { 159 { FC_PORTSTATE_UNKNOWN, "Unknown" }, 160 { FC_PORTSTATE_NOTPRESENT, "Not Present" }, 161 { FC_PORTSTATE_ONLINE, "Online" }, 162 { FC_PORTSTATE_OFFLINE, "Offline" }, 163 { FC_PORTSTATE_BLOCKED, "Blocked" }, 164 { FC_PORTSTATE_BYPASSED, "Bypassed" }, 165 { FC_PORTSTATE_DIAGNOSTICS, "Diagnostics" }, 166 { FC_PORTSTATE_LINKDOWN, "Linkdown" }, 167 { FC_PORTSTATE_ERROR, "Error" }, 168 { FC_PORTSTATE_LOOPBACK, "Loopback" }, 169 { FC_PORTSTATE_DELETED, "Deleted" }, 170 }; 171 fc_enum_name_search(port_state, fc_port_state, fc_port_state_names) 172 #define FC_PORTSTATE_MAX_NAMELEN 20 173 174 175 /* Convert fc_vport_state values to ascii string name */ 176 static struct { 177 enum fc_vport_state value; 178 char *name; 179 } fc_vport_state_names[] = { 180 { FC_VPORT_UNKNOWN, "Unknown" }, 181 { FC_VPORT_ACTIVE, "Active" }, 182 { FC_VPORT_DISABLED, "Disabled" }, 183 { FC_VPORT_LINKDOWN, "Linkdown" }, 184 { FC_VPORT_INITIALIZING, "Initializing" }, 185 { FC_VPORT_NO_FABRIC_SUPP, "No Fabric Support" }, 186 { FC_VPORT_NO_FABRIC_RSCS, "No Fabric Resources" }, 187 { FC_VPORT_FABRIC_LOGOUT, "Fabric Logout" }, 188 { FC_VPORT_FABRIC_REJ_WWN, "Fabric Rejected WWN" }, 189 { FC_VPORT_FAILED, "VPort Failed" }, 190 }; 191 fc_enum_name_search(vport_state, fc_vport_state, fc_vport_state_names) 192 #define FC_VPORTSTATE_MAX_NAMELEN 24 193 194 /* Reuse fc_vport_state enum function for vport_last_state */ 195 #define get_fc_vport_last_state_name get_fc_vport_state_name 196 197 198 /* Convert fc_tgtid_binding_type values to ascii string name */ 199 static const struct { 200 enum fc_tgtid_binding_type value; 201 char *name; 202 int matchlen; 203 } fc_tgtid_binding_type_names[] = { 204 { FC_TGTID_BIND_NONE, "none", 4 }, 205 { FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 }, 206 { FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 }, 207 { FC_TGTID_BIND_BY_ID, "port_id (FC Address)", 7 }, 208 }; 209 fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type, 210 fc_tgtid_binding_type_names) 211 fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type, 212 fc_tgtid_binding_type_names) 213 #define FC_BINDTYPE_MAX_NAMELEN 30 214 215 216 #define fc_bitfield_name_search(title, table) \ 217 static ssize_t \ 218 get_fc_##title##_names(u32 table_key, char *buf) \ 219 { \ 220 char *prefix = ""; \ 221 ssize_t len = 0; \ 222 int i; \ 223 \ 224 for (i = 0; i < ARRAY_SIZE(table); i++) { \ 225 if (table[i].value & table_key) { \ 226 len += sprintf(buf + len, "%s%s", \ 227 prefix, table[i].name); \ 228 prefix = ", "; \ 229 } \ 230 } \ 231 len += sprintf(buf + len, "\n"); \ 232 return len; \ 233 } 234 235 236 /* Convert FC_COS bit values to ascii string name */ 237 static const struct { 238 u32 value; 239 char *name; 240 } fc_cos_names[] = { 241 { FC_COS_CLASS1, "Class 1" }, 242 { FC_COS_CLASS2, "Class 2" }, 243 { FC_COS_CLASS3, "Class 3" }, 244 { FC_COS_CLASS4, "Class 4" }, 245 { FC_COS_CLASS6, "Class 6" }, 246 }; 247 fc_bitfield_name_search(cos, fc_cos_names) 248 249 250 /* Convert FC_PORTSPEED bit values to ascii string name */ 251 static const struct { 252 u32 value; 253 char *name; 254 } fc_port_speed_names[] = { 255 { FC_PORTSPEED_1GBIT, "1 Gbit" }, 256 { FC_PORTSPEED_2GBIT, "2 Gbit" }, 257 { FC_PORTSPEED_4GBIT, "4 Gbit" }, 258 { FC_PORTSPEED_10GBIT, "10 Gbit" }, 259 { FC_PORTSPEED_8GBIT, "8 Gbit" }, 260 { FC_PORTSPEED_16GBIT, "16 Gbit" }, 261 { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" }, 262 }; 263 fc_bitfield_name_search(port_speed, fc_port_speed_names) 264 265 266 static int 267 show_fc_fc4s (char *buf, u8 *fc4_list) 268 { 269 int i, len=0; 270 271 for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++) 272 len += sprintf(buf + len , "0x%02x ", *fc4_list); 273 len += sprintf(buf + len, "\n"); 274 return len; 275 } 276 277 278 /* Convert FC_PORT_ROLE bit values to ascii string name */ 279 static const struct { 280 u32 value; 281 char *name; 282 } fc_port_role_names[] = { 283 { FC_PORT_ROLE_FCP_TARGET, "FCP Target" }, 284 { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" }, 285 { FC_PORT_ROLE_IP_PORT, "IP Port" }, 286 }; 287 fc_bitfield_name_search(port_roles, fc_port_role_names) 288 289 /* 290 * Define roles that are specific to port_id. Values are relative to ROLE_MASK. 291 */ 292 #define FC_WELLKNOWN_PORTID_MASK 0xfffff0 293 #define FC_WELLKNOWN_ROLE_MASK 0x00000f 294 #define FC_FPORT_PORTID 0x00000e 295 #define FC_FABCTLR_PORTID 0x00000d 296 #define FC_DIRSRVR_PORTID 0x00000c 297 #define FC_TIMESRVR_PORTID 0x00000b 298 #define FC_MGMTSRVR_PORTID 0x00000a 299 300 301 static void fc_timeout_deleted_rport(struct work_struct *work); 302 static void fc_timeout_fail_rport_io(struct work_struct *work); 303 static void fc_scsi_scan_rport(struct work_struct *work); 304 305 /* 306 * Attribute counts pre object type... 307 * Increase these values if you add attributes 308 */ 309 #define FC_STARGET_NUM_ATTRS 3 310 #define FC_RPORT_NUM_ATTRS 10 311 #define FC_VPORT_NUM_ATTRS 9 312 #define FC_HOST_NUM_ATTRS 21 313 314 struct fc_internal { 315 struct scsi_transport_template t; 316 struct fc_function_template *f; 317 318 /* 319 * For attributes : each object has : 320 * An array of the actual attributes structures 321 * An array of null-terminated pointers to the attribute 322 * structures - used for mid-layer interaction. 323 * 324 * The attribute containers for the starget and host are are 325 * part of the midlayer. As the remote port is specific to the 326 * fc transport, we must provide the attribute container. 327 */ 328 struct class_device_attribute private_starget_attrs[ 329 FC_STARGET_NUM_ATTRS]; 330 struct class_device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1]; 331 332 struct class_device_attribute private_host_attrs[FC_HOST_NUM_ATTRS]; 333 struct class_device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1]; 334 335 struct transport_container rport_attr_cont; 336 struct class_device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS]; 337 struct class_device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1]; 338 339 struct transport_container vport_attr_cont; 340 struct class_device_attribute private_vport_attrs[FC_VPORT_NUM_ATTRS]; 341 struct class_device_attribute *vport_attrs[FC_VPORT_NUM_ATTRS + 1]; 342 }; 343 344 #define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t) 345 346 static int fc_target_setup(struct transport_container *tc, struct device *dev, 347 struct class_device *cdev) 348 { 349 struct scsi_target *starget = to_scsi_target(dev); 350 struct fc_rport *rport = starget_to_rport(starget); 351 352 /* 353 * if parent is remote port, use values from remote port. 354 * Otherwise, this host uses the fc_transport, but not the 355 * remote port interface. As such, initialize to known non-values. 356 */ 357 if (rport) { 358 fc_starget_node_name(starget) = rport->node_name; 359 fc_starget_port_name(starget) = rport->port_name; 360 fc_starget_port_id(starget) = rport->port_id; 361 } else { 362 fc_starget_node_name(starget) = -1; 363 fc_starget_port_name(starget) = -1; 364 fc_starget_port_id(starget) = -1; 365 } 366 367 return 0; 368 } 369 370 static DECLARE_TRANSPORT_CLASS(fc_transport_class, 371 "fc_transport", 372 fc_target_setup, 373 NULL, 374 NULL); 375 376 static int fc_host_setup(struct transport_container *tc, struct device *dev, 377 struct class_device *cdev) 378 { 379 struct Scsi_Host *shost = dev_to_shost(dev); 380 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 381 382 /* 383 * Set default values easily detected by the midlayer as 384 * failure cases. The scsi lldd is responsible for initializing 385 * all transport attributes to valid values per host. 386 */ 387 fc_host->node_name = -1; 388 fc_host->port_name = -1; 389 fc_host->permanent_port_name = -1; 390 fc_host->supported_classes = FC_COS_UNSPECIFIED; 391 memset(fc_host->supported_fc4s, 0, 392 sizeof(fc_host->supported_fc4s)); 393 fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN; 394 fc_host->maxframe_size = -1; 395 fc_host->max_npiv_vports = 0; 396 memset(fc_host->serial_number, 0, 397 sizeof(fc_host->serial_number)); 398 399 fc_host->port_id = -1; 400 fc_host->port_type = FC_PORTTYPE_UNKNOWN; 401 fc_host->port_state = FC_PORTSTATE_UNKNOWN; 402 memset(fc_host->active_fc4s, 0, 403 sizeof(fc_host->active_fc4s)); 404 fc_host->speed = FC_PORTSPEED_UNKNOWN; 405 fc_host->fabric_name = -1; 406 memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name)); 407 memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname)); 408 409 fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN; 410 411 INIT_LIST_HEAD(&fc_host->rports); 412 INIT_LIST_HEAD(&fc_host->rport_bindings); 413 INIT_LIST_HEAD(&fc_host->vports); 414 fc_host->next_rport_number = 0; 415 fc_host->next_target_id = 0; 416 fc_host->next_vport_number = 0; 417 fc_host->npiv_vports_inuse = 0; 418 419 snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d", 420 shost->host_no); 421 fc_host->work_q = create_singlethread_workqueue( 422 fc_host->work_q_name); 423 if (!fc_host->work_q) 424 return -ENOMEM; 425 426 snprintf(fc_host->devloss_work_q_name, KOBJ_NAME_LEN, "fc_dl_%d", 427 shost->host_no); 428 fc_host->devloss_work_q = create_singlethread_workqueue( 429 fc_host->devloss_work_q_name); 430 if (!fc_host->devloss_work_q) { 431 destroy_workqueue(fc_host->work_q); 432 fc_host->work_q = NULL; 433 return -ENOMEM; 434 } 435 436 return 0; 437 } 438 439 static DECLARE_TRANSPORT_CLASS(fc_host_class, 440 "fc_host", 441 fc_host_setup, 442 NULL, 443 NULL); 444 445 /* 446 * Setup and Remove actions for remote ports are handled 447 * in the service functions below. 448 */ 449 static DECLARE_TRANSPORT_CLASS(fc_rport_class, 450 "fc_remote_ports", 451 NULL, 452 NULL, 453 NULL); 454 455 /* 456 * Setup and Remove actions for virtual ports are handled 457 * in the service functions below. 458 */ 459 static DECLARE_TRANSPORT_CLASS(fc_vport_class, 460 "fc_vports", 461 NULL, 462 NULL, 463 NULL); 464 465 /* 466 * Module Parameters 467 */ 468 469 /* 470 * dev_loss_tmo: the default number of seconds that the FC transport 471 * should insulate the loss of a remote port. 472 * The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT. 473 */ 474 static unsigned int fc_dev_loss_tmo = 60; /* seconds */ 475 476 module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); 477 MODULE_PARM_DESC(dev_loss_tmo, 478 "Maximum number of seconds that the FC transport should" 479 " insulate the loss of a remote port. Once this value is" 480 " exceeded, the scsi target is removed. Value should be" 481 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); 482 483 /** 484 * Netlink Infrastructure 485 **/ 486 487 static atomic_t fc_event_seq; 488 489 /** 490 * fc_get_event_number - Obtain the next sequential FC event number 491 * 492 * Notes: 493 * We could have inline'd this, but it would have required fc_event_seq to 494 * be exposed. For now, live with the subroutine call. 495 * Atomic used to avoid lock/unlock... 496 **/ 497 u32 498 fc_get_event_number(void) 499 { 500 return atomic_add_return(1, &fc_event_seq); 501 } 502 EXPORT_SYMBOL(fc_get_event_number); 503 504 505 /** 506 * fc_host_post_event - called to post an even on an fc_host. 507 * 508 * @shost: host the event occurred on 509 * @event_number: fc event number obtained from get_fc_event_number() 510 * @event_code: fc_host event being posted 511 * @event_data: 32bits of data for the event being posted 512 * 513 * Notes: 514 * This routine assumes no locks are held on entry. 515 **/ 516 void 517 fc_host_post_event(struct Scsi_Host *shost, u32 event_number, 518 enum fc_host_event_code event_code, u32 event_data) 519 { 520 struct sk_buff *skb; 521 struct nlmsghdr *nlh; 522 struct fc_nl_event *event; 523 const char *name; 524 u32 len, skblen; 525 int err; 526 527 if (!scsi_nl_sock) { 528 err = -ENOENT; 529 goto send_fail; 530 } 531 532 len = FC_NL_MSGALIGN(sizeof(*event)); 533 skblen = NLMSG_SPACE(len); 534 535 skb = alloc_skb(skblen, GFP_KERNEL); 536 if (!skb) { 537 err = -ENOBUFS; 538 goto send_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_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 = 0; 553 event->host_no = shost->host_no; 554 event->event_datalen = sizeof(u32); /* bytes */ 555 event->event_num = event_number; 556 event->event_code = event_code; 557 event->event_data = event_data; 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_fail; 564 565 return; 566 567 send_fail_skb: 568 kfree_skb(skb); 569 send_fail: 570 name = get_fc_host_event_code_name(event_code); 571 printk(KERN_WARNING 572 "%s: Dropped Event : host %d %s data 0x%08x - err %d\n", 573 __FUNCTION__, shost->host_no, 574 (name) ? name : "<unknown>", event_data, err); 575 return; 576 } 577 EXPORT_SYMBOL(fc_host_post_event); 578 579 580 /** 581 * fc_host_post_vendor_event - called to post a vendor unique event on 582 * a fc_host 583 * 584 * @shost: host the event occurred on 585 * @event_number: fc event number obtained from get_fc_event_number() 586 * @data_len: amount, in bytes, of vendor unique data 587 * @data_buf: pointer to vendor unique data 588 * 589 * Notes: 590 * This routine assumes no locks are held on entry. 591 **/ 592 void 593 fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number, 594 u32 data_len, char * data_buf, u64 vendor_id) 595 { 596 struct sk_buff *skb; 597 struct nlmsghdr *nlh; 598 struct fc_nl_event *event; 599 u32 len, skblen; 600 int err; 601 602 if (!scsi_nl_sock) { 603 err = -ENOENT; 604 goto send_vendor_fail; 605 } 606 607 len = FC_NL_MSGALIGN(sizeof(*event) + data_len); 608 skblen = NLMSG_SPACE(len); 609 610 skb = alloc_skb(skblen, GFP_KERNEL); 611 if (!skb) { 612 err = -ENOBUFS; 613 goto send_vendor_fail; 614 } 615 616 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG, 617 skblen - sizeof(*nlh), 0); 618 if (!nlh) { 619 err = -ENOBUFS; 620 goto send_vendor_fail_skb; 621 } 622 event = NLMSG_DATA(nlh); 623 624 INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC, 625 FC_NL_ASYNC_EVENT, len); 626 event->seconds = get_seconds(); 627 event->vendor_id = vendor_id; 628 event->host_no = shost->host_no; 629 event->event_datalen = data_len; /* bytes */ 630 event->event_num = event_number; 631 event->event_code = FCH_EVT_VENDOR_UNIQUE; 632 memcpy(&event->event_data, data_buf, data_len); 633 634 err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS, 635 GFP_KERNEL); 636 if (err && (err != -ESRCH)) /* filter no recipient errors */ 637 /* nlmsg_multicast already kfree_skb'd */ 638 goto send_vendor_fail; 639 640 return; 641 642 send_vendor_fail_skb: 643 kfree_skb(skb); 644 send_vendor_fail: 645 printk(KERN_WARNING 646 "%s: Dropped Event : host %d vendor_unique - err %d\n", 647 __FUNCTION__, shost->host_no, err); 648 return; 649 } 650 EXPORT_SYMBOL(fc_host_post_vendor_event); 651 652 653 654 static __init int fc_transport_init(void) 655 { 656 int error; 657 658 atomic_set(&fc_event_seq, 0); 659 660 error = transport_class_register(&fc_host_class); 661 if (error) 662 return error; 663 error = transport_class_register(&fc_vport_class); 664 if (error) 665 return error; 666 error = transport_class_register(&fc_rport_class); 667 if (error) 668 return error; 669 return transport_class_register(&fc_transport_class); 670 } 671 672 static void __exit fc_transport_exit(void) 673 { 674 transport_class_unregister(&fc_transport_class); 675 transport_class_unregister(&fc_rport_class); 676 transport_class_unregister(&fc_host_class); 677 transport_class_unregister(&fc_vport_class); 678 } 679 680 /* 681 * FC Remote Port Attribute Management 682 */ 683 684 #define fc_rport_show_function(field, format_string, sz, cast) \ 685 static ssize_t \ 686 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 687 { \ 688 struct fc_rport *rport = transport_class_to_rport(cdev); \ 689 struct Scsi_Host *shost = rport_to_shost(rport); \ 690 struct fc_internal *i = to_fc_internal(shost->transportt); \ 691 if ((i->f->get_rport_##field) && \ 692 !((rport->port_state == FC_PORTSTATE_BLOCKED) || \ 693 (rport->port_state == FC_PORTSTATE_DELETED) || \ 694 (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \ 695 i->f->get_rport_##field(rport); \ 696 return snprintf(buf, sz, format_string, cast rport->field); \ 697 } 698 699 #define fc_rport_store_function(field) \ 700 static ssize_t \ 701 store_fc_rport_##field(struct class_device *cdev, const char *buf, \ 702 size_t count) \ 703 { \ 704 int val; \ 705 struct fc_rport *rport = transport_class_to_rport(cdev); \ 706 struct Scsi_Host *shost = rport_to_shost(rport); \ 707 struct fc_internal *i = to_fc_internal(shost->transportt); \ 708 char *cp; \ 709 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ 710 (rport->port_state == FC_PORTSTATE_DELETED) || \ 711 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ 712 return -EBUSY; \ 713 val = simple_strtoul(buf, &cp, 0); \ 714 if (*cp && (*cp != '\n')) \ 715 return -EINVAL; \ 716 i->f->set_rport_##field(rport, val); \ 717 return count; \ 718 } 719 720 #define fc_rport_rd_attr(field, format_string, sz) \ 721 fc_rport_show_function(field, format_string, sz, ) \ 722 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 723 show_fc_rport_##field, NULL) 724 725 #define fc_rport_rd_attr_cast(field, format_string, sz, cast) \ 726 fc_rport_show_function(field, format_string, sz, (cast)) \ 727 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 728 show_fc_rport_##field, NULL) 729 730 #define fc_rport_rw_attr(field, format_string, sz) \ 731 fc_rport_show_function(field, format_string, sz, ) \ 732 fc_rport_store_function(field) \ 733 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO | S_IWUSR, \ 734 show_fc_rport_##field, \ 735 store_fc_rport_##field) 736 737 738 #define fc_private_rport_show_function(field, format_string, sz, cast) \ 739 static ssize_t \ 740 show_fc_rport_##field (struct class_device *cdev, char *buf) \ 741 { \ 742 struct fc_rport *rport = transport_class_to_rport(cdev); \ 743 return snprintf(buf, sz, format_string, cast rport->field); \ 744 } 745 746 #define fc_private_rport_rd_attr(field, format_string, sz) \ 747 fc_private_rport_show_function(field, format_string, sz, ) \ 748 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 749 show_fc_rport_##field, NULL) 750 751 #define fc_private_rport_rd_attr_cast(field, format_string, sz, cast) \ 752 fc_private_rport_show_function(field, format_string, sz, (cast)) \ 753 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO, \ 754 show_fc_rport_##field, NULL) 755 756 757 #define fc_private_rport_rd_enum_attr(title, maxlen) \ 758 static ssize_t \ 759 show_fc_rport_##title (struct class_device *cdev, char *buf) \ 760 { \ 761 struct fc_rport *rport = transport_class_to_rport(cdev); \ 762 const char *name; \ 763 name = get_fc_##title##_name(rport->title); \ 764 if (!name) \ 765 return -EINVAL; \ 766 return snprintf(buf, maxlen, "%s\n", name); \ 767 } \ 768 static FC_CLASS_DEVICE_ATTR(rport, title, S_IRUGO, \ 769 show_fc_rport_##title, NULL) 770 771 772 #define SETUP_RPORT_ATTRIBUTE_RD(field) \ 773 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 774 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 775 i->private_rport_attrs[count].store = NULL; \ 776 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 777 if (i->f->show_rport_##field) \ 778 count++ 779 780 #define SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(field) \ 781 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 782 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 783 i->private_rport_attrs[count].store = NULL; \ 784 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 785 count++ 786 787 #define SETUP_RPORT_ATTRIBUTE_RW(field) \ 788 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 789 if (!i->f->set_rport_##field) { \ 790 i->private_rport_attrs[count].attr.mode = S_IRUGO; \ 791 i->private_rport_attrs[count].store = NULL; \ 792 } \ 793 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 794 if (i->f->show_rport_##field) \ 795 count++ 796 797 #define SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(field) \ 798 { \ 799 i->private_rport_attrs[count] = class_device_attr_rport_##field; \ 800 i->rport_attrs[count] = &i->private_rport_attrs[count]; \ 801 count++; \ 802 } 803 804 805 /* The FC Transport Remote Port Attributes: */ 806 807 /* Fixed Remote Port Attributes */ 808 809 fc_private_rport_rd_attr(maxframe_size, "%u bytes\n", 20); 810 811 static ssize_t 812 show_fc_rport_supported_classes (struct class_device *cdev, char *buf) 813 { 814 struct fc_rport *rport = transport_class_to_rport(cdev); 815 if (rport->supported_classes == FC_COS_UNSPECIFIED) 816 return snprintf(buf, 20, "unspecified\n"); 817 return get_fc_cos_names(rport->supported_classes, buf); 818 } 819 static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO, 820 show_fc_rport_supported_classes, NULL); 821 822 /* Dynamic Remote Port Attributes */ 823 824 /* 825 * dev_loss_tmo attribute 826 */ 827 fc_rport_show_function(dev_loss_tmo, "%d\n", 20, ) 828 static ssize_t 829 store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf, 830 size_t count) 831 { 832 int val; 833 struct fc_rport *rport = transport_class_to_rport(cdev); 834 struct Scsi_Host *shost = rport_to_shost(rport); 835 struct fc_internal *i = to_fc_internal(shost->transportt); 836 char *cp; 837 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 838 (rport->port_state == FC_PORTSTATE_DELETED) || 839 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 840 return -EBUSY; 841 val = simple_strtoul(buf, &cp, 0); 842 if ((*cp && (*cp != '\n')) || 843 (val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)) 844 return -EINVAL; 845 i->f->set_rport_dev_loss_tmo(rport, val); 846 return count; 847 } 848 static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR, 849 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo); 850 851 852 /* Private Remote Port Attributes */ 853 854 fc_private_rport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 855 fc_private_rport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 856 fc_private_rport_rd_attr(port_id, "0x%06x\n", 20); 857 858 static ssize_t 859 show_fc_rport_roles (struct class_device *cdev, char *buf) 860 { 861 struct fc_rport *rport = transport_class_to_rport(cdev); 862 863 /* identify any roles that are port_id specific */ 864 if ((rport->port_id != -1) && 865 (rport->port_id & FC_WELLKNOWN_PORTID_MASK) == 866 FC_WELLKNOWN_PORTID_MASK) { 867 switch (rport->port_id & FC_WELLKNOWN_ROLE_MASK) { 868 case FC_FPORT_PORTID: 869 return snprintf(buf, 30, "Fabric Port\n"); 870 case FC_FABCTLR_PORTID: 871 return snprintf(buf, 30, "Fabric Controller\n"); 872 case FC_DIRSRVR_PORTID: 873 return snprintf(buf, 30, "Directory Server\n"); 874 case FC_TIMESRVR_PORTID: 875 return snprintf(buf, 30, "Time Server\n"); 876 case FC_MGMTSRVR_PORTID: 877 return snprintf(buf, 30, "Management Server\n"); 878 default: 879 return snprintf(buf, 30, "Unknown Fabric Entity\n"); 880 } 881 } else { 882 if (rport->roles == FC_PORT_ROLE_UNKNOWN) 883 return snprintf(buf, 20, "unknown\n"); 884 return get_fc_port_roles_names(rport->roles, buf); 885 } 886 } 887 static FC_CLASS_DEVICE_ATTR(rport, roles, S_IRUGO, 888 show_fc_rport_roles, NULL); 889 890 fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 891 fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20); 892 893 /* 894 * fast_io_fail_tmo attribute 895 */ 896 static ssize_t 897 show_fc_rport_fast_io_fail_tmo (struct class_device *cdev, char *buf) 898 { 899 struct fc_rport *rport = transport_class_to_rport(cdev); 900 901 if (rport->fast_io_fail_tmo == -1) 902 return snprintf(buf, 5, "off\n"); 903 return snprintf(buf, 20, "%d\n", rport->fast_io_fail_tmo); 904 } 905 906 static ssize_t 907 store_fc_rport_fast_io_fail_tmo(struct class_device *cdev, const char *buf, 908 size_t count) 909 { 910 int val; 911 char *cp; 912 struct fc_rport *rport = transport_class_to_rport(cdev); 913 914 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 915 (rport->port_state == FC_PORTSTATE_DELETED) || 916 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 917 return -EBUSY; 918 if (strncmp(buf, "off", 3) == 0) 919 rport->fast_io_fail_tmo = -1; 920 else { 921 val = simple_strtoul(buf, &cp, 0); 922 if ((*cp && (*cp != '\n')) || 923 (val < 0) || (val >= rport->dev_loss_tmo)) 924 return -EINVAL; 925 rport->fast_io_fail_tmo = val; 926 } 927 return count; 928 } 929 static FC_CLASS_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR, 930 show_fc_rport_fast_io_fail_tmo, store_fc_rport_fast_io_fail_tmo); 931 932 933 /* 934 * FC SCSI Target Attribute Management 935 */ 936 937 /* 938 * Note: in the target show function we recognize when the remote 939 * port is in the heirarchy and do not allow the driver to get 940 * involved in sysfs functions. The driver only gets involved if 941 * it's the "old" style that doesn't use rports. 942 */ 943 #define fc_starget_show_function(field, format_string, sz, cast) \ 944 static ssize_t \ 945 show_fc_starget_##field (struct class_device *cdev, char *buf) \ 946 { \ 947 struct scsi_target *starget = transport_class_to_starget(cdev); \ 948 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ 949 struct fc_internal *i = to_fc_internal(shost->transportt); \ 950 struct fc_rport *rport = starget_to_rport(starget); \ 951 if (rport) \ 952 fc_starget_##field(starget) = rport->field; \ 953 else if (i->f->get_starget_##field) \ 954 i->f->get_starget_##field(starget); \ 955 return snprintf(buf, sz, format_string, \ 956 cast fc_starget_##field(starget)); \ 957 } 958 959 #define fc_starget_rd_attr(field, format_string, sz) \ 960 fc_starget_show_function(field, format_string, sz, ) \ 961 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 962 show_fc_starget_##field, NULL) 963 964 #define fc_starget_rd_attr_cast(field, format_string, sz, cast) \ 965 fc_starget_show_function(field, format_string, sz, (cast)) \ 966 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO, \ 967 show_fc_starget_##field, NULL) 968 969 #define SETUP_STARGET_ATTRIBUTE_RD(field) \ 970 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 971 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 972 i->private_starget_attrs[count].store = NULL; \ 973 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 974 if (i->f->show_starget_##field) \ 975 count++ 976 977 #define SETUP_STARGET_ATTRIBUTE_RW(field) \ 978 i->private_starget_attrs[count] = class_device_attr_starget_##field; \ 979 if (!i->f->set_starget_##field) { \ 980 i->private_starget_attrs[count].attr.mode = S_IRUGO; \ 981 i->private_starget_attrs[count].store = NULL; \ 982 } \ 983 i->starget_attrs[count] = &i->private_starget_attrs[count]; \ 984 if (i->f->show_starget_##field) \ 985 count++ 986 987 /* The FC Transport SCSI Target Attributes: */ 988 fc_starget_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 989 fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 990 fc_starget_rd_attr(port_id, "0x%06x\n", 20); 991 992 993 /* 994 * FC Virtual Port Attribute Management 995 */ 996 997 #define fc_vport_show_function(field, format_string, sz, cast) \ 998 static ssize_t \ 999 show_fc_vport_##field (struct class_device *cdev, char *buf) \ 1000 { \ 1001 struct fc_vport *vport = transport_class_to_vport(cdev); \ 1002 struct Scsi_Host *shost = vport_to_shost(vport); \ 1003 struct fc_internal *i = to_fc_internal(shost->transportt); \ 1004 if ((i->f->get_vport_##field) && \ 1005 !(vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))) \ 1006 i->f->get_vport_##field(vport); \ 1007 return snprintf(buf, sz, format_string, cast vport->field); \ 1008 } 1009 1010 #define fc_vport_store_function(field) \ 1011 static ssize_t \ 1012 store_fc_vport_##field(struct class_device *cdev, const char *buf, \ 1013 size_t count) \ 1014 { \ 1015 int val; \ 1016 struct fc_vport *vport = transport_class_to_vport(cdev); \ 1017 struct Scsi_Host *shost = vport_to_shost(vport); \ 1018 struct fc_internal *i = to_fc_internal(shost->transportt); \ 1019 char *cp; \ 1020 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) \ 1021 return -EBUSY; \ 1022 val = simple_strtoul(buf, &cp, 0); \ 1023 if (*cp && (*cp != '\n')) \ 1024 return -EINVAL; \ 1025 i->f->set_vport_##field(vport, val); \ 1026 return count; \ 1027 } 1028 1029 #define fc_vport_store_str_function(field, slen) \ 1030 static ssize_t \ 1031 store_fc_vport_##field(struct class_device *cdev, const char *buf, \ 1032 size_t count) \ 1033 { \ 1034 struct fc_vport *vport = transport_class_to_vport(cdev); \ 1035 struct Scsi_Host *shost = vport_to_shost(vport); \ 1036 struct fc_internal *i = to_fc_internal(shost->transportt); \ 1037 unsigned int cnt=count; \ 1038 \ 1039 /* count may include a LF at end of string */ \ 1040 if (buf[cnt-1] == '\n') \ 1041 cnt--; \ 1042 if (cnt > ((slen) - 1)) \ 1043 return -EINVAL; \ 1044 memcpy(vport->field, buf, cnt); \ 1045 i->f->set_vport_##field(vport); \ 1046 return count; \ 1047 } 1048 1049 #define fc_vport_rd_attr(field, format_string, sz) \ 1050 fc_vport_show_function(field, format_string, sz, ) \ 1051 static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO, \ 1052 show_fc_vport_##field, NULL) 1053 1054 #define fc_vport_rd_attr_cast(field, format_string, sz, cast) \ 1055 fc_vport_show_function(field, format_string, sz, (cast)) \ 1056 static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO, \ 1057 show_fc_vport_##field, NULL) 1058 1059 #define fc_vport_rw_attr(field, format_string, sz) \ 1060 fc_vport_show_function(field, format_string, sz, ) \ 1061 fc_vport_store_function(field) \ 1062 static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR, \ 1063 show_fc_vport_##field, \ 1064 store_fc_vport_##field) 1065 1066 #define fc_private_vport_show_function(field, format_string, sz, cast) \ 1067 static ssize_t \ 1068 show_fc_vport_##field (struct class_device *cdev, char *buf) \ 1069 { \ 1070 struct fc_vport *vport = transport_class_to_vport(cdev); \ 1071 return snprintf(buf, sz, format_string, cast vport->field); \ 1072 } 1073 1074 #define fc_private_vport_store_u32_function(field) \ 1075 static ssize_t \ 1076 store_fc_vport_##field(struct class_device *cdev, const char *buf, \ 1077 size_t count) \ 1078 { \ 1079 u32 val; \ 1080 struct fc_vport *vport = transport_class_to_vport(cdev); \ 1081 char *cp; \ 1082 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) \ 1083 return -EBUSY; \ 1084 val = simple_strtoul(buf, &cp, 0); \ 1085 if (*cp && (*cp != '\n')) \ 1086 return -EINVAL; \ 1087 vport->field = val; \ 1088 return count; \ 1089 } 1090 1091 1092 #define fc_private_vport_rd_attr(field, format_string, sz) \ 1093 fc_private_vport_show_function(field, format_string, sz, ) \ 1094 static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO, \ 1095 show_fc_vport_##field, NULL) 1096 1097 #define fc_private_vport_rd_attr_cast(field, format_string, sz, cast) \ 1098 fc_private_vport_show_function(field, format_string, sz, (cast)) \ 1099 static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO, \ 1100 show_fc_vport_##field, NULL) 1101 1102 #define fc_private_vport_rw_u32_attr(field, format_string, sz) \ 1103 fc_private_vport_show_function(field, format_string, sz, ) \ 1104 fc_private_vport_store_u32_function(field) \ 1105 static FC_CLASS_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR, \ 1106 show_fc_vport_##field, \ 1107 store_fc_vport_##field) 1108 1109 1110 #define fc_private_vport_rd_enum_attr(title, maxlen) \ 1111 static ssize_t \ 1112 show_fc_vport_##title (struct class_device *cdev, char *buf) \ 1113 { \ 1114 struct fc_vport *vport = transport_class_to_vport(cdev); \ 1115 const char *name; \ 1116 name = get_fc_##title##_name(vport->title); \ 1117 if (!name) \ 1118 return -EINVAL; \ 1119 return snprintf(buf, maxlen, "%s\n", name); \ 1120 } \ 1121 static FC_CLASS_DEVICE_ATTR(vport, title, S_IRUGO, \ 1122 show_fc_vport_##title, NULL) 1123 1124 1125 #define SETUP_VPORT_ATTRIBUTE_RD(field) \ 1126 i->private_vport_attrs[count] = class_device_attr_vport_##field; \ 1127 i->private_vport_attrs[count].attr.mode = S_IRUGO; \ 1128 i->private_vport_attrs[count].store = NULL; \ 1129 i->vport_attrs[count] = &i->private_vport_attrs[count]; \ 1130 if (i->f->get_##field) \ 1131 count++ 1132 /* NOTE: Above MACRO differs: checks function not show bit */ 1133 1134 #define SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(field) \ 1135 i->private_vport_attrs[count] = class_device_attr_vport_##field; \ 1136 i->private_vport_attrs[count].attr.mode = S_IRUGO; \ 1137 i->private_vport_attrs[count].store = NULL; \ 1138 i->vport_attrs[count] = &i->private_vport_attrs[count]; \ 1139 count++ 1140 1141 #define SETUP_VPORT_ATTRIBUTE_WR(field) \ 1142 i->private_vport_attrs[count] = class_device_attr_vport_##field; \ 1143 i->vport_attrs[count] = &i->private_vport_attrs[count]; \ 1144 if (i->f->field) \ 1145 count++ 1146 /* NOTE: Above MACRO differs: checks function */ 1147 1148 #define SETUP_VPORT_ATTRIBUTE_RW(field) \ 1149 i->private_vport_attrs[count] = class_device_attr_vport_##field; \ 1150 if (!i->f->set_vport_##field) { \ 1151 i->private_vport_attrs[count].attr.mode = S_IRUGO; \ 1152 i->private_vport_attrs[count].store = NULL; \ 1153 } \ 1154 i->vport_attrs[count] = &i->private_vport_attrs[count]; \ 1155 count++ 1156 /* NOTE: Above MACRO differs: does not check show bit */ 1157 1158 #define SETUP_PRIVATE_VPORT_ATTRIBUTE_RW(field) \ 1159 { \ 1160 i->private_vport_attrs[count] = class_device_attr_vport_##field; \ 1161 i->vport_attrs[count] = &i->private_vport_attrs[count]; \ 1162 count++; \ 1163 } 1164 1165 1166 /* The FC Transport Virtual Port Attributes: */ 1167 1168 /* Fixed Virtual Port Attributes */ 1169 1170 /* Dynamic Virtual Port Attributes */ 1171 1172 /* Private Virtual Port Attributes */ 1173 1174 fc_private_vport_rd_enum_attr(vport_state, FC_VPORTSTATE_MAX_NAMELEN); 1175 fc_private_vport_rd_enum_attr(vport_last_state, FC_VPORTSTATE_MAX_NAMELEN); 1176 fc_private_vport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 1177 fc_private_vport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 1178 1179 static ssize_t 1180 show_fc_vport_roles (struct class_device *cdev, char *buf) 1181 { 1182 struct fc_vport *vport = transport_class_to_vport(cdev); 1183 1184 if (vport->roles == FC_PORT_ROLE_UNKNOWN) 1185 return snprintf(buf, 20, "unknown\n"); 1186 return get_fc_port_roles_names(vport->roles, buf); 1187 } 1188 static FC_CLASS_DEVICE_ATTR(vport, roles, S_IRUGO, show_fc_vport_roles, NULL); 1189 1190 fc_private_vport_rd_enum_attr(vport_type, FC_PORTTYPE_MAX_NAMELEN); 1191 1192 fc_private_vport_show_function(symbolic_name, "%s\n", 1193 FC_VPORT_SYMBOLIC_NAMELEN + 1, ) 1194 fc_vport_store_str_function(symbolic_name, FC_VPORT_SYMBOLIC_NAMELEN) 1195 static FC_CLASS_DEVICE_ATTR(vport, symbolic_name, S_IRUGO | S_IWUSR, 1196 show_fc_vport_symbolic_name, store_fc_vport_symbolic_name); 1197 1198 static ssize_t 1199 store_fc_vport_delete(struct class_device *cdev, const char *buf, 1200 size_t count) 1201 { 1202 struct fc_vport *vport = transport_class_to_vport(cdev); 1203 struct Scsi_Host *shost = vport_to_shost(vport); 1204 1205 fc_queue_work(shost, &vport->vport_delete_work); 1206 return count; 1207 } 1208 static FC_CLASS_DEVICE_ATTR(vport, vport_delete, S_IWUSR, 1209 NULL, store_fc_vport_delete); 1210 1211 1212 /* 1213 * Enable/Disable vport 1214 * Write "1" to disable, write "0" to enable 1215 */ 1216 static ssize_t 1217 store_fc_vport_disable(struct class_device *cdev, const char *buf, 1218 size_t count) 1219 { 1220 struct fc_vport *vport = transport_class_to_vport(cdev); 1221 struct Scsi_Host *shost = vport_to_shost(vport); 1222 struct fc_internal *i = to_fc_internal(shost->transportt); 1223 int stat; 1224 1225 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) 1226 return -EBUSY; 1227 1228 if (*buf == '0') { 1229 if (vport->vport_state != FC_VPORT_DISABLED) 1230 return -EALREADY; 1231 } else if (*buf == '1') { 1232 if (vport->vport_state == FC_VPORT_DISABLED) 1233 return -EALREADY; 1234 } else 1235 return -EINVAL; 1236 1237 stat = i->f->vport_disable(vport, ((*buf == '0') ? false : true)); 1238 return stat ? stat : count; 1239 } 1240 static FC_CLASS_DEVICE_ATTR(vport, vport_disable, S_IWUSR, 1241 NULL, store_fc_vport_disable); 1242 1243 1244 /* 1245 * Host Attribute Management 1246 */ 1247 1248 #define fc_host_show_function(field, format_string, sz, cast) \ 1249 static ssize_t \ 1250 show_fc_host_##field (struct class_device *cdev, char *buf) \ 1251 { \ 1252 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 1253 struct fc_internal *i = to_fc_internal(shost->transportt); \ 1254 if (i->f->get_host_##field) \ 1255 i->f->get_host_##field(shost); \ 1256 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 1257 } 1258 1259 #define fc_host_store_function(field) \ 1260 static ssize_t \ 1261 store_fc_host_##field(struct class_device *cdev, const char *buf, \ 1262 size_t count) \ 1263 { \ 1264 int val; \ 1265 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 1266 struct fc_internal *i = to_fc_internal(shost->transportt); \ 1267 char *cp; \ 1268 \ 1269 val = simple_strtoul(buf, &cp, 0); \ 1270 if (*cp && (*cp != '\n')) \ 1271 return -EINVAL; \ 1272 i->f->set_host_##field(shost, val); \ 1273 return count; \ 1274 } 1275 1276 #define fc_host_store_str_function(field, slen) \ 1277 static ssize_t \ 1278 store_fc_host_##field(struct class_device *cdev, const char *buf, \ 1279 size_t count) \ 1280 { \ 1281 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 1282 struct fc_internal *i = to_fc_internal(shost->transportt); \ 1283 unsigned int cnt=count; \ 1284 \ 1285 /* count may include a LF at end of string */ \ 1286 if (buf[cnt-1] == '\n') \ 1287 cnt--; \ 1288 if (cnt > ((slen) - 1)) \ 1289 return -EINVAL; \ 1290 memcpy(fc_host_##field(shost), buf, cnt); \ 1291 i->f->set_host_##field(shost); \ 1292 return count; \ 1293 } 1294 1295 #define fc_host_rd_attr(field, format_string, sz) \ 1296 fc_host_show_function(field, format_string, sz, ) \ 1297 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 1298 show_fc_host_##field, NULL) 1299 1300 #define fc_host_rd_attr_cast(field, format_string, sz, cast) \ 1301 fc_host_show_function(field, format_string, sz, (cast)) \ 1302 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 1303 show_fc_host_##field, NULL) 1304 1305 #define fc_host_rw_attr(field, format_string, sz) \ 1306 fc_host_show_function(field, format_string, sz, ) \ 1307 fc_host_store_function(field) \ 1308 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR, \ 1309 show_fc_host_##field, \ 1310 store_fc_host_##field) 1311 1312 #define fc_host_rd_enum_attr(title, maxlen) \ 1313 static ssize_t \ 1314 show_fc_host_##title (struct class_device *cdev, char *buf) \ 1315 { \ 1316 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 1317 struct fc_internal *i = to_fc_internal(shost->transportt); \ 1318 const char *name; \ 1319 if (i->f->get_host_##title) \ 1320 i->f->get_host_##title(shost); \ 1321 name = get_fc_##title##_name(fc_host_##title(shost)); \ 1322 if (!name) \ 1323 return -EINVAL; \ 1324 return snprintf(buf, maxlen, "%s\n", name); \ 1325 } \ 1326 static FC_CLASS_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL) 1327 1328 #define SETUP_HOST_ATTRIBUTE_RD(field) \ 1329 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1330 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 1331 i->private_host_attrs[count].store = NULL; \ 1332 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1333 if (i->f->show_host_##field) \ 1334 count++ 1335 1336 #define SETUP_HOST_ATTRIBUTE_RD_NS(field) \ 1337 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1338 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 1339 i->private_host_attrs[count].store = NULL; \ 1340 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1341 count++ 1342 1343 #define SETUP_HOST_ATTRIBUTE_RW(field) \ 1344 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1345 if (!i->f->set_host_##field) { \ 1346 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 1347 i->private_host_attrs[count].store = NULL; \ 1348 } \ 1349 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1350 if (i->f->show_host_##field) \ 1351 count++ 1352 1353 1354 #define fc_private_host_show_function(field, format_string, sz, cast) \ 1355 static ssize_t \ 1356 show_fc_host_##field (struct class_device *cdev, char *buf) \ 1357 { \ 1358 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 1359 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \ 1360 } 1361 1362 #define fc_private_host_rd_attr(field, format_string, sz) \ 1363 fc_private_host_show_function(field, format_string, sz, ) \ 1364 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 1365 show_fc_host_##field, NULL) 1366 1367 #define fc_private_host_rd_attr_cast(field, format_string, sz, cast) \ 1368 fc_private_host_show_function(field, format_string, sz, (cast)) \ 1369 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 1370 show_fc_host_##field, NULL) 1371 1372 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field) \ 1373 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1374 i->private_host_attrs[count].attr.mode = S_IRUGO; \ 1375 i->private_host_attrs[count].store = NULL; \ 1376 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1377 count++ 1378 1379 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \ 1380 { \ 1381 i->private_host_attrs[count] = class_device_attr_host_##field; \ 1382 i->host_attrs[count] = &i->private_host_attrs[count]; \ 1383 count++; \ 1384 } 1385 1386 1387 /* Fixed Host Attributes */ 1388 1389 static ssize_t 1390 show_fc_host_supported_classes (struct class_device *cdev, char *buf) 1391 { 1392 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1393 1394 if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED) 1395 return snprintf(buf, 20, "unspecified\n"); 1396 1397 return get_fc_cos_names(fc_host_supported_classes(shost), buf); 1398 } 1399 static FC_CLASS_DEVICE_ATTR(host, supported_classes, S_IRUGO, 1400 show_fc_host_supported_classes, NULL); 1401 1402 static ssize_t 1403 show_fc_host_supported_fc4s (struct class_device *cdev, char *buf) 1404 { 1405 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1406 return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost)); 1407 } 1408 static FC_CLASS_DEVICE_ATTR(host, supported_fc4s, S_IRUGO, 1409 show_fc_host_supported_fc4s, NULL); 1410 1411 static ssize_t 1412 show_fc_host_supported_speeds (struct class_device *cdev, char *buf) 1413 { 1414 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1415 1416 if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN) 1417 return snprintf(buf, 20, "unknown\n"); 1418 1419 return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf); 1420 } 1421 static FC_CLASS_DEVICE_ATTR(host, supported_speeds, S_IRUGO, 1422 show_fc_host_supported_speeds, NULL); 1423 1424 1425 fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long); 1426 fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 1427 fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20, 1428 unsigned long long); 1429 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20); 1430 fc_private_host_rd_attr(max_npiv_vports, "%u\n", 20); 1431 fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1)); 1432 1433 1434 /* Dynamic Host Attributes */ 1435 1436 static ssize_t 1437 show_fc_host_active_fc4s (struct class_device *cdev, char *buf) 1438 { 1439 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1440 struct fc_internal *i = to_fc_internal(shost->transportt); 1441 1442 if (i->f->get_host_active_fc4s) 1443 i->f->get_host_active_fc4s(shost); 1444 1445 return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost)); 1446 } 1447 static FC_CLASS_DEVICE_ATTR(host, active_fc4s, S_IRUGO, 1448 show_fc_host_active_fc4s, NULL); 1449 1450 static ssize_t 1451 show_fc_host_speed (struct class_device *cdev, char *buf) 1452 { 1453 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1454 struct fc_internal *i = to_fc_internal(shost->transportt); 1455 1456 if (i->f->get_host_speed) 1457 i->f->get_host_speed(shost); 1458 1459 if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN) 1460 return snprintf(buf, 20, "unknown\n"); 1461 1462 return get_fc_port_speed_names(fc_host_speed(shost), buf); 1463 } 1464 static FC_CLASS_DEVICE_ATTR(host, speed, S_IRUGO, 1465 show_fc_host_speed, NULL); 1466 1467 1468 fc_host_rd_attr(port_id, "0x%06x\n", 20); 1469 fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN); 1470 fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 1471 fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 1472 fc_host_rd_attr(symbolic_name, "%s\n", FC_SYMBOLIC_NAME_SIZE + 1); 1473 1474 fc_private_host_show_function(system_hostname, "%s\n", 1475 FC_SYMBOLIC_NAME_SIZE + 1, ) 1476 fc_host_store_str_function(system_hostname, FC_SYMBOLIC_NAME_SIZE) 1477 static FC_CLASS_DEVICE_ATTR(host, system_hostname, S_IRUGO | S_IWUSR, 1478 show_fc_host_system_hostname, store_fc_host_system_hostname); 1479 1480 1481 /* Private Host Attributes */ 1482 1483 static ssize_t 1484 show_fc_private_host_tgtid_bind_type(struct class_device *cdev, char *buf) 1485 { 1486 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1487 const char *name; 1488 1489 name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost)); 1490 if (!name) 1491 return -EINVAL; 1492 return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name); 1493 } 1494 1495 #define get_list_head_entry(pos, head, member) \ 1496 pos = list_entry((head)->next, typeof(*pos), member) 1497 1498 static ssize_t 1499 store_fc_private_host_tgtid_bind_type(struct class_device *cdev, 1500 const char *buf, size_t count) 1501 { 1502 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1503 struct fc_rport *rport; 1504 enum fc_tgtid_binding_type val; 1505 unsigned long flags; 1506 1507 if (get_fc_tgtid_bind_type_match(buf, &val)) 1508 return -EINVAL; 1509 1510 /* if changing bind type, purge all unused consistent bindings */ 1511 if (val != fc_host_tgtid_bind_type(shost)) { 1512 spin_lock_irqsave(shost->host_lock, flags); 1513 while (!list_empty(&fc_host_rport_bindings(shost))) { 1514 get_list_head_entry(rport, 1515 &fc_host_rport_bindings(shost), peers); 1516 list_del(&rport->peers); 1517 rport->port_state = FC_PORTSTATE_DELETED; 1518 fc_queue_work(shost, &rport->rport_delete_work); 1519 } 1520 spin_unlock_irqrestore(shost->host_lock, flags); 1521 } 1522 1523 fc_host_tgtid_bind_type(shost) = val; 1524 return count; 1525 } 1526 1527 static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR, 1528 show_fc_private_host_tgtid_bind_type, 1529 store_fc_private_host_tgtid_bind_type); 1530 1531 static ssize_t 1532 store_fc_private_host_issue_lip(struct class_device *cdev, 1533 const char *buf, size_t count) 1534 { 1535 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1536 struct fc_internal *i = to_fc_internal(shost->transportt); 1537 int ret; 1538 1539 /* ignore any data value written to the attribute */ 1540 if (i->f->issue_fc_host_lip) { 1541 ret = i->f->issue_fc_host_lip(shost); 1542 return ret ? ret: count; 1543 } 1544 1545 return -ENOENT; 1546 } 1547 1548 static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL, 1549 store_fc_private_host_issue_lip); 1550 1551 fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20); 1552 1553 1554 /* 1555 * Host Statistics Management 1556 */ 1557 1558 /* Show a given an attribute in the statistics group */ 1559 static ssize_t 1560 fc_stat_show(const struct class_device *cdev, char *buf, unsigned long offset) 1561 { 1562 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1563 struct fc_internal *i = to_fc_internal(shost->transportt); 1564 struct fc_host_statistics *stats; 1565 ssize_t ret = -ENOENT; 1566 1567 if (offset > sizeof(struct fc_host_statistics) || 1568 offset % sizeof(u64) != 0) 1569 WARN_ON(1); 1570 1571 if (i->f->get_fc_host_stats) { 1572 stats = (i->f->get_fc_host_stats)(shost); 1573 if (stats) 1574 ret = snprintf(buf, 20, "0x%llx\n", 1575 (unsigned long long)*(u64 *)(((u8 *) stats) + offset)); 1576 } 1577 return ret; 1578 } 1579 1580 1581 /* generate a read-only statistics attribute */ 1582 #define fc_host_statistic(name) \ 1583 static ssize_t show_fcstat_##name(struct class_device *cd, char *buf) \ 1584 { \ 1585 return fc_stat_show(cd, buf, \ 1586 offsetof(struct fc_host_statistics, name)); \ 1587 } \ 1588 static FC_CLASS_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL) 1589 1590 fc_host_statistic(seconds_since_last_reset); 1591 fc_host_statistic(tx_frames); 1592 fc_host_statistic(tx_words); 1593 fc_host_statistic(rx_frames); 1594 fc_host_statistic(rx_words); 1595 fc_host_statistic(lip_count); 1596 fc_host_statistic(nos_count); 1597 fc_host_statistic(error_frames); 1598 fc_host_statistic(dumped_frames); 1599 fc_host_statistic(link_failure_count); 1600 fc_host_statistic(loss_of_sync_count); 1601 fc_host_statistic(loss_of_signal_count); 1602 fc_host_statistic(prim_seq_protocol_err_count); 1603 fc_host_statistic(invalid_tx_word_count); 1604 fc_host_statistic(invalid_crc_count); 1605 fc_host_statistic(fcp_input_requests); 1606 fc_host_statistic(fcp_output_requests); 1607 fc_host_statistic(fcp_control_requests); 1608 fc_host_statistic(fcp_input_megabytes); 1609 fc_host_statistic(fcp_output_megabytes); 1610 1611 static ssize_t 1612 fc_reset_statistics(struct class_device *cdev, const char *buf, 1613 size_t count) 1614 { 1615 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1616 struct fc_internal *i = to_fc_internal(shost->transportt); 1617 1618 /* ignore any data value written to the attribute */ 1619 if (i->f->reset_fc_host_stats) { 1620 i->f->reset_fc_host_stats(shost); 1621 return count; 1622 } 1623 1624 return -ENOENT; 1625 } 1626 static FC_CLASS_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL, 1627 fc_reset_statistics); 1628 1629 static struct attribute *fc_statistics_attrs[] = { 1630 &class_device_attr_host_seconds_since_last_reset.attr, 1631 &class_device_attr_host_tx_frames.attr, 1632 &class_device_attr_host_tx_words.attr, 1633 &class_device_attr_host_rx_frames.attr, 1634 &class_device_attr_host_rx_words.attr, 1635 &class_device_attr_host_lip_count.attr, 1636 &class_device_attr_host_nos_count.attr, 1637 &class_device_attr_host_error_frames.attr, 1638 &class_device_attr_host_dumped_frames.attr, 1639 &class_device_attr_host_link_failure_count.attr, 1640 &class_device_attr_host_loss_of_sync_count.attr, 1641 &class_device_attr_host_loss_of_signal_count.attr, 1642 &class_device_attr_host_prim_seq_protocol_err_count.attr, 1643 &class_device_attr_host_invalid_tx_word_count.attr, 1644 &class_device_attr_host_invalid_crc_count.attr, 1645 &class_device_attr_host_fcp_input_requests.attr, 1646 &class_device_attr_host_fcp_output_requests.attr, 1647 &class_device_attr_host_fcp_control_requests.attr, 1648 &class_device_attr_host_fcp_input_megabytes.attr, 1649 &class_device_attr_host_fcp_output_megabytes.attr, 1650 &class_device_attr_host_reset_statistics.attr, 1651 NULL 1652 }; 1653 1654 static struct attribute_group fc_statistics_group = { 1655 .name = "statistics", 1656 .attrs = fc_statistics_attrs, 1657 }; 1658 1659 1660 /* Host Vport Attributes */ 1661 1662 static int 1663 fc_parse_wwn(const char *ns, u64 *nm) 1664 { 1665 unsigned int i, j; 1666 u8 wwn[8]; 1667 1668 memset(wwn, 0, sizeof(wwn)); 1669 1670 /* Validate and store the new name */ 1671 for (i=0, j=0; i < 16; i++) { 1672 if ((*ns >= 'a') && (*ns <= 'f')) 1673 j = ((j << 4) | ((*ns++ -'a') + 10)); 1674 else if ((*ns >= 'A') && (*ns <= 'F')) 1675 j = ((j << 4) | ((*ns++ -'A') + 10)); 1676 else if ((*ns >= '0') && (*ns <= '9')) 1677 j = ((j << 4) | (*ns++ -'0')); 1678 else 1679 return -EINVAL; 1680 if (i % 2) { 1681 wwn[i/2] = j & 0xff; 1682 j = 0; 1683 } 1684 } 1685 1686 *nm = wwn_to_u64(wwn); 1687 1688 return 0; 1689 } 1690 1691 1692 /* 1693 * "Short-cut" sysfs variable to create a new vport on a FC Host. 1694 * Input is a string of the form "<WWPN>:<WWNN>". Other attributes 1695 * will default to a NPIV-based FCP_Initiator; The WWNs are specified 1696 * as hex characters, and may *not* contain any prefixes (e.g. 0x, x, etc) 1697 */ 1698 static ssize_t 1699 store_fc_host_vport_create(struct class_device *cdev, const char *buf, 1700 size_t count) 1701 { 1702 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1703 struct fc_vport_identifiers vid; 1704 struct fc_vport *vport; 1705 unsigned int cnt=count; 1706 int stat; 1707 1708 memset(&vid, 0, sizeof(vid)); 1709 1710 /* count may include a LF at end of string */ 1711 if (buf[cnt-1] == '\n') 1712 cnt--; 1713 1714 /* validate we have enough characters for WWPN */ 1715 if ((cnt != (16+1+16)) || (buf[16] != ':')) 1716 return -EINVAL; 1717 1718 stat = fc_parse_wwn(&buf[0], &vid.port_name); 1719 if (stat) 1720 return stat; 1721 1722 stat = fc_parse_wwn(&buf[17], &vid.node_name); 1723 if (stat) 1724 return stat; 1725 1726 vid.roles = FC_PORT_ROLE_FCP_INITIATOR; 1727 vid.vport_type = FC_PORTTYPE_NPIV; 1728 /* vid.symbolic_name is already zero/NULL's */ 1729 vid.disable = false; /* always enabled */ 1730 1731 /* we only allow support on Channel 0 !!! */ 1732 stat = fc_vport_create(shost, 0, &shost->shost_gendev, &vid, &vport); 1733 return stat ? stat : count; 1734 } 1735 static FC_CLASS_DEVICE_ATTR(host, vport_create, S_IWUSR, NULL, 1736 store_fc_host_vport_create); 1737 1738 1739 /* 1740 * "Short-cut" sysfs variable to delete a vport on a FC Host. 1741 * Vport is identified by a string containing "<WWPN>:<WWNN>". 1742 * The WWNs are specified as hex characters, and may *not* contain 1743 * any prefixes (e.g. 0x, x, etc) 1744 */ 1745 static ssize_t 1746 store_fc_host_vport_delete(struct class_device *cdev, const char *buf, 1747 size_t count) 1748 { 1749 struct Scsi_Host *shost = transport_class_to_shost(cdev); 1750 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 1751 struct fc_vport *vport; 1752 u64 wwpn, wwnn; 1753 unsigned long flags; 1754 unsigned int cnt=count; 1755 int stat, match; 1756 1757 /* count may include a LF at end of string */ 1758 if (buf[cnt-1] == '\n') 1759 cnt--; 1760 1761 /* validate we have enough characters for WWPN */ 1762 if ((cnt != (16+1+16)) || (buf[16] != ':')) 1763 return -EINVAL; 1764 1765 stat = fc_parse_wwn(&buf[0], &wwpn); 1766 if (stat) 1767 return stat; 1768 1769 stat = fc_parse_wwn(&buf[17], &wwnn); 1770 if (stat) 1771 return stat; 1772 1773 spin_lock_irqsave(shost->host_lock, flags); 1774 match = 0; 1775 /* we only allow support on Channel 0 !!! */ 1776 list_for_each_entry(vport, &fc_host->vports, peers) { 1777 if ((vport->channel == 0) && 1778 (vport->port_name == wwpn) && (vport->node_name == wwnn)) { 1779 match = 1; 1780 break; 1781 } 1782 } 1783 spin_unlock_irqrestore(shost->host_lock, flags); 1784 1785 if (!match) 1786 return -ENODEV; 1787 1788 stat = fc_vport_terminate(vport); 1789 return stat ? stat : count; 1790 } 1791 static FC_CLASS_DEVICE_ATTR(host, vport_delete, S_IWUSR, NULL, 1792 store_fc_host_vport_delete); 1793 1794 1795 static int fc_host_match(struct attribute_container *cont, 1796 struct device *dev) 1797 { 1798 struct Scsi_Host *shost; 1799 struct fc_internal *i; 1800 1801 if (!scsi_is_host_device(dev)) 1802 return 0; 1803 1804 shost = dev_to_shost(dev); 1805 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1806 != &fc_host_class.class) 1807 return 0; 1808 1809 i = to_fc_internal(shost->transportt); 1810 1811 return &i->t.host_attrs.ac == cont; 1812 } 1813 1814 static int fc_target_match(struct attribute_container *cont, 1815 struct device *dev) 1816 { 1817 struct Scsi_Host *shost; 1818 struct fc_internal *i; 1819 1820 if (!scsi_is_target_device(dev)) 1821 return 0; 1822 1823 shost = dev_to_shost(dev->parent); 1824 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1825 != &fc_host_class.class) 1826 return 0; 1827 1828 i = to_fc_internal(shost->transportt); 1829 1830 return &i->t.target_attrs.ac == cont; 1831 } 1832 1833 static void fc_rport_dev_release(struct device *dev) 1834 { 1835 struct fc_rport *rport = dev_to_rport(dev); 1836 put_device(dev->parent); 1837 kfree(rport); 1838 } 1839 1840 int scsi_is_fc_rport(const struct device *dev) 1841 { 1842 return dev->release == fc_rport_dev_release; 1843 } 1844 EXPORT_SYMBOL(scsi_is_fc_rport); 1845 1846 static int fc_rport_match(struct attribute_container *cont, 1847 struct device *dev) 1848 { 1849 struct Scsi_Host *shost; 1850 struct fc_internal *i; 1851 1852 if (!scsi_is_fc_rport(dev)) 1853 return 0; 1854 1855 shost = dev_to_shost(dev->parent); 1856 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1857 != &fc_host_class.class) 1858 return 0; 1859 1860 i = to_fc_internal(shost->transportt); 1861 1862 return &i->rport_attr_cont.ac == cont; 1863 } 1864 1865 1866 static void fc_vport_dev_release(struct device *dev) 1867 { 1868 struct fc_vport *vport = dev_to_vport(dev); 1869 put_device(dev->parent); /* release kobj parent */ 1870 kfree(vport); 1871 } 1872 1873 int scsi_is_fc_vport(const struct device *dev) 1874 { 1875 return dev->release == fc_vport_dev_release; 1876 } 1877 EXPORT_SYMBOL(scsi_is_fc_vport); 1878 1879 static int fc_vport_match(struct attribute_container *cont, 1880 struct device *dev) 1881 { 1882 struct fc_vport *vport; 1883 struct Scsi_Host *shost; 1884 struct fc_internal *i; 1885 1886 if (!scsi_is_fc_vport(dev)) 1887 return 0; 1888 vport = dev_to_vport(dev); 1889 1890 shost = vport_to_shost(vport); 1891 if (!shost->transportt || shost->transportt->host_attrs.ac.class 1892 != &fc_host_class.class) 1893 return 0; 1894 1895 i = to_fc_internal(shost->transportt); 1896 return &i->vport_attr_cont.ac == cont; 1897 } 1898 1899 1900 /** 1901 * fc_timed_out - FC Transport I/O timeout intercept handler 1902 * 1903 * @scmd: The SCSI command which timed out 1904 * 1905 * This routine protects against error handlers getting invoked while a 1906 * rport is in a blocked state, typically due to a temporarily loss of 1907 * connectivity. If the error handlers are allowed to proceed, requests 1908 * to abort i/o, reset the target, etc will likely fail as there is no way 1909 * to communicate with the device to perform the requested function. These 1910 * failures may result in the midlayer taking the device offline, requiring 1911 * manual intervention to restore operation. 1912 * 1913 * This routine, called whenever an i/o times out, validates the state of 1914 * the underlying rport. If the rport is blocked, it returns 1915 * EH_RESET_TIMER, which will continue to reschedule the timeout. 1916 * Eventually, either the device will return, or devloss_tmo will fire, 1917 * and when the timeout then fires, it will be handled normally. 1918 * If the rport is not blocked, normal error handling continues. 1919 * 1920 * Notes: 1921 * This routine assumes no locks are held on entry. 1922 **/ 1923 static enum scsi_eh_timer_return 1924 fc_timed_out(struct scsi_cmnd *scmd) 1925 { 1926 struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device)); 1927 1928 if (rport->port_state == FC_PORTSTATE_BLOCKED) 1929 return EH_RESET_TIMER; 1930 1931 return EH_NOT_HANDLED; 1932 } 1933 1934 /* 1935 * Must be called with shost->host_lock held 1936 */ 1937 static int fc_user_scan(struct Scsi_Host *shost, uint channel, 1938 uint id, uint lun) 1939 { 1940 struct fc_rport *rport; 1941 1942 list_for_each_entry(rport, &fc_host_rports(shost), peers) { 1943 if (rport->scsi_target_id == -1) 1944 continue; 1945 1946 if (rport->port_state != FC_PORTSTATE_ONLINE) 1947 continue; 1948 1949 if ((channel == SCAN_WILD_CARD || channel == rport->channel) && 1950 (id == SCAN_WILD_CARD || id == rport->scsi_target_id)) { 1951 scsi_scan_target(&rport->dev, rport->channel, 1952 rport->scsi_target_id, lun, 1); 1953 } 1954 } 1955 1956 return 0; 1957 } 1958 1959 struct scsi_transport_template * 1960 fc_attach_transport(struct fc_function_template *ft) 1961 { 1962 int count; 1963 struct fc_internal *i = kzalloc(sizeof(struct fc_internal), 1964 GFP_KERNEL); 1965 1966 if (unlikely(!i)) 1967 return NULL; 1968 1969 i->t.target_attrs.ac.attrs = &i->starget_attrs[0]; 1970 i->t.target_attrs.ac.class = &fc_transport_class.class; 1971 i->t.target_attrs.ac.match = fc_target_match; 1972 i->t.target_size = sizeof(struct fc_starget_attrs); 1973 transport_container_register(&i->t.target_attrs); 1974 1975 i->t.host_attrs.ac.attrs = &i->host_attrs[0]; 1976 i->t.host_attrs.ac.class = &fc_host_class.class; 1977 i->t.host_attrs.ac.match = fc_host_match; 1978 i->t.host_size = sizeof(struct fc_host_attrs); 1979 if (ft->get_fc_host_stats) 1980 i->t.host_attrs.statistics = &fc_statistics_group; 1981 transport_container_register(&i->t.host_attrs); 1982 1983 i->rport_attr_cont.ac.attrs = &i->rport_attrs[0]; 1984 i->rport_attr_cont.ac.class = &fc_rport_class.class; 1985 i->rport_attr_cont.ac.match = fc_rport_match; 1986 transport_container_register(&i->rport_attr_cont); 1987 1988 i->vport_attr_cont.ac.attrs = &i->vport_attrs[0]; 1989 i->vport_attr_cont.ac.class = &fc_vport_class.class; 1990 i->vport_attr_cont.ac.match = fc_vport_match; 1991 transport_container_register(&i->vport_attr_cont); 1992 1993 i->f = ft; 1994 1995 /* Transport uses the shost workq for scsi scanning */ 1996 i->t.create_work_queue = 1; 1997 1998 i->t.eh_timed_out = fc_timed_out; 1999 2000 i->t.user_scan = fc_user_scan; 2001 2002 /* 2003 * Setup SCSI Target Attributes. 2004 */ 2005 count = 0; 2006 SETUP_STARGET_ATTRIBUTE_RD(node_name); 2007 SETUP_STARGET_ATTRIBUTE_RD(port_name); 2008 SETUP_STARGET_ATTRIBUTE_RD(port_id); 2009 2010 BUG_ON(count > FC_STARGET_NUM_ATTRS); 2011 2012 i->starget_attrs[count] = NULL; 2013 2014 2015 /* 2016 * Setup SCSI Host Attributes. 2017 */ 2018 count=0; 2019 SETUP_HOST_ATTRIBUTE_RD(node_name); 2020 SETUP_HOST_ATTRIBUTE_RD(port_name); 2021 SETUP_HOST_ATTRIBUTE_RD(permanent_port_name); 2022 SETUP_HOST_ATTRIBUTE_RD(supported_classes); 2023 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s); 2024 SETUP_HOST_ATTRIBUTE_RD(supported_speeds); 2025 SETUP_HOST_ATTRIBUTE_RD(maxframe_size); 2026 if (ft->vport_create) { 2027 SETUP_HOST_ATTRIBUTE_RD_NS(max_npiv_vports); 2028 SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse); 2029 } 2030 SETUP_HOST_ATTRIBUTE_RD(serial_number); 2031 2032 SETUP_HOST_ATTRIBUTE_RD(port_id); 2033 SETUP_HOST_ATTRIBUTE_RD(port_type); 2034 SETUP_HOST_ATTRIBUTE_RD(port_state); 2035 SETUP_HOST_ATTRIBUTE_RD(active_fc4s); 2036 SETUP_HOST_ATTRIBUTE_RD(speed); 2037 SETUP_HOST_ATTRIBUTE_RD(fabric_name); 2038 SETUP_HOST_ATTRIBUTE_RD(symbolic_name); 2039 SETUP_HOST_ATTRIBUTE_RW(system_hostname); 2040 2041 /* Transport-managed attributes */ 2042 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 2043 if (ft->issue_fc_host_lip) 2044 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip); 2045 if (ft->vport_create) 2046 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_create); 2047 if (ft->vport_delete) 2048 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_delete); 2049 2050 BUG_ON(count > FC_HOST_NUM_ATTRS); 2051 2052 i->host_attrs[count] = NULL; 2053 2054 /* 2055 * Setup Remote Port Attributes. 2056 */ 2057 count=0; 2058 SETUP_RPORT_ATTRIBUTE_RD(maxframe_size); 2059 SETUP_RPORT_ATTRIBUTE_RD(supported_classes); 2060 SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo); 2061 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name); 2062 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name); 2063 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id); 2064 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles); 2065 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state); 2066 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id); 2067 if (ft->terminate_rport_io) 2068 SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo); 2069 2070 BUG_ON(count > FC_RPORT_NUM_ATTRS); 2071 2072 i->rport_attrs[count] = NULL; 2073 2074 /* 2075 * Setup Virtual Port Attributes. 2076 */ 2077 count=0; 2078 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_state); 2079 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_last_state); 2080 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(node_name); 2081 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(port_name); 2082 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(roles); 2083 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_type); 2084 SETUP_VPORT_ATTRIBUTE_RW(symbolic_name); 2085 SETUP_VPORT_ATTRIBUTE_WR(vport_delete); 2086 SETUP_VPORT_ATTRIBUTE_WR(vport_disable); 2087 2088 BUG_ON(count > FC_VPORT_NUM_ATTRS); 2089 2090 i->vport_attrs[count] = NULL; 2091 2092 return &i->t; 2093 } 2094 EXPORT_SYMBOL(fc_attach_transport); 2095 2096 void fc_release_transport(struct scsi_transport_template *t) 2097 { 2098 struct fc_internal *i = to_fc_internal(t); 2099 2100 transport_container_unregister(&i->t.target_attrs); 2101 transport_container_unregister(&i->t.host_attrs); 2102 transport_container_unregister(&i->rport_attr_cont); 2103 transport_container_unregister(&i->vport_attr_cont); 2104 2105 kfree(i); 2106 } 2107 EXPORT_SYMBOL(fc_release_transport); 2108 2109 /** 2110 * fc_queue_work - Queue work to the fc_host workqueue. 2111 * @shost: Pointer to Scsi_Host bound to fc_host. 2112 * @work: Work to queue for execution. 2113 * 2114 * Return value: 2115 * 1 - work queued for execution 2116 * 0 - work is already queued 2117 * -EINVAL - work queue doesn't exist 2118 **/ 2119 static int 2120 fc_queue_work(struct Scsi_Host *shost, struct work_struct *work) 2121 { 2122 if (unlikely(!fc_host_work_q(shost))) { 2123 printk(KERN_ERR 2124 "ERROR: FC host '%s' attempted to queue work, " 2125 "when no workqueue created.\n", shost->hostt->name); 2126 dump_stack(); 2127 2128 return -EINVAL; 2129 } 2130 2131 return queue_work(fc_host_work_q(shost), work); 2132 } 2133 2134 /** 2135 * fc_flush_work - Flush a fc_host's workqueue. 2136 * @shost: Pointer to Scsi_Host bound to fc_host. 2137 **/ 2138 static void 2139 fc_flush_work(struct Scsi_Host *shost) 2140 { 2141 if (!fc_host_work_q(shost)) { 2142 printk(KERN_ERR 2143 "ERROR: FC host '%s' attempted to flush work, " 2144 "when no workqueue created.\n", shost->hostt->name); 2145 dump_stack(); 2146 return; 2147 } 2148 2149 flush_workqueue(fc_host_work_q(shost)); 2150 } 2151 2152 /** 2153 * fc_queue_devloss_work - Schedule work for the fc_host devloss workqueue. 2154 * @shost: Pointer to Scsi_Host bound to fc_host. 2155 * @work: Work to queue for execution. 2156 * @delay: jiffies to delay the work queuing 2157 * 2158 * Return value: 2159 * 1 on success / 0 already queued / < 0 for error 2160 **/ 2161 static int 2162 fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work, 2163 unsigned long delay) 2164 { 2165 if (unlikely(!fc_host_devloss_work_q(shost))) { 2166 printk(KERN_ERR 2167 "ERROR: FC host '%s' attempted to queue work, " 2168 "when no workqueue created.\n", shost->hostt->name); 2169 dump_stack(); 2170 2171 return -EINVAL; 2172 } 2173 2174 return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay); 2175 } 2176 2177 /** 2178 * fc_flush_devloss - Flush a fc_host's devloss workqueue. 2179 * @shost: Pointer to Scsi_Host bound to fc_host. 2180 **/ 2181 static void 2182 fc_flush_devloss(struct Scsi_Host *shost) 2183 { 2184 if (!fc_host_devloss_work_q(shost)) { 2185 printk(KERN_ERR 2186 "ERROR: FC host '%s' attempted to flush work, " 2187 "when no workqueue created.\n", shost->hostt->name); 2188 dump_stack(); 2189 return; 2190 } 2191 2192 flush_workqueue(fc_host_devloss_work_q(shost)); 2193 } 2194 2195 2196 /** 2197 * fc_remove_host - called to terminate any fc_transport-related elements 2198 * for a scsi host. 2199 * @rport: remote port to be unblocked. 2200 * 2201 * This routine is expected to be called immediately preceeding the 2202 * a driver's call to scsi_remove_host(). 2203 * 2204 * WARNING: A driver utilizing the fc_transport, which fails to call 2205 * this routine prior to scsi_remote_host(), will leave dangling 2206 * objects in /sys/class/fc_remote_ports. Access to any of these 2207 * objects can result in a system crash !!! 2208 * 2209 * Notes: 2210 * This routine assumes no locks are held on entry. 2211 **/ 2212 void 2213 fc_remove_host(struct Scsi_Host *shost) 2214 { 2215 struct fc_vport *vport = NULL, *next_vport = NULL; 2216 struct fc_rport *rport = NULL, *next_rport = NULL; 2217 struct workqueue_struct *work_q; 2218 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2219 unsigned long flags; 2220 2221 spin_lock_irqsave(shost->host_lock, flags); 2222 2223 /* Remove any vports */ 2224 list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) 2225 fc_queue_work(shost, &vport->vport_delete_work); 2226 2227 /* Remove any remote ports */ 2228 list_for_each_entry_safe(rport, next_rport, 2229 &fc_host->rports, peers) { 2230 list_del(&rport->peers); 2231 rport->port_state = FC_PORTSTATE_DELETED; 2232 fc_queue_work(shost, &rport->rport_delete_work); 2233 } 2234 2235 list_for_each_entry_safe(rport, next_rport, 2236 &fc_host->rport_bindings, peers) { 2237 list_del(&rport->peers); 2238 rport->port_state = FC_PORTSTATE_DELETED; 2239 fc_queue_work(shost, &rport->rport_delete_work); 2240 } 2241 2242 spin_unlock_irqrestore(shost->host_lock, flags); 2243 2244 /* flush all scan work items */ 2245 scsi_flush_work(shost); 2246 2247 /* flush all stgt delete, and rport delete work items, then kill it */ 2248 if (fc_host->work_q) { 2249 work_q = fc_host->work_q; 2250 fc_host->work_q = NULL; 2251 destroy_workqueue(work_q); 2252 } 2253 2254 /* flush all devloss work items, then kill it */ 2255 if (fc_host->devloss_work_q) { 2256 work_q = fc_host->devloss_work_q; 2257 fc_host->devloss_work_q = NULL; 2258 destroy_workqueue(work_q); 2259 } 2260 } 2261 EXPORT_SYMBOL(fc_remove_host); 2262 2263 2264 /** 2265 * fc_starget_delete - called to delete the scsi decendents of an rport 2266 * (target and all sdevs) 2267 * 2268 * @work: remote port to be operated on. 2269 **/ 2270 static void 2271 fc_starget_delete(struct work_struct *work) 2272 { 2273 struct fc_rport *rport = 2274 container_of(work, struct fc_rport, stgt_delete_work); 2275 struct Scsi_Host *shost = rport_to_shost(rport); 2276 struct fc_internal *i = to_fc_internal(shost->transportt); 2277 2278 /* Involve the LLDD if possible to terminate all io on the rport. */ 2279 if (i->f->terminate_rport_io) 2280 i->f->terminate_rport_io(rport); 2281 2282 scsi_remove_target(&rport->dev); 2283 } 2284 2285 2286 /** 2287 * fc_rport_final_delete - finish rport termination and delete it. 2288 * 2289 * @work: remote port to be deleted. 2290 **/ 2291 static void 2292 fc_rport_final_delete(struct work_struct *work) 2293 { 2294 struct fc_rport *rport = 2295 container_of(work, struct fc_rport, rport_delete_work); 2296 struct device *dev = &rport->dev; 2297 struct Scsi_Host *shost = rport_to_shost(rport); 2298 struct fc_internal *i = to_fc_internal(shost->transportt); 2299 unsigned long flags; 2300 2301 /* 2302 * if a scan is pending, flush the SCSI Host work_q so that 2303 * that we can reclaim the rport scan work element. 2304 */ 2305 if (rport->flags & FC_RPORT_SCAN_PENDING) 2306 scsi_flush_work(shost); 2307 2308 /* involve the LLDD to terminate all pending i/o */ 2309 if (i->f->terminate_rport_io) 2310 i->f->terminate_rport_io(rport); 2311 2312 /* 2313 * Cancel any outstanding timers. These should really exist 2314 * only when rmmod'ing the LLDD and we're asking for 2315 * immediate termination of the rports 2316 */ 2317 spin_lock_irqsave(shost->host_lock, flags); 2318 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { 2319 spin_unlock_irqrestore(shost->host_lock, flags); 2320 if (!cancel_delayed_work(&rport->fail_io_work)) 2321 fc_flush_devloss(shost); 2322 if (!cancel_delayed_work(&rport->dev_loss_work)) 2323 fc_flush_devloss(shost); 2324 spin_lock_irqsave(shost->host_lock, flags); 2325 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2326 } 2327 spin_unlock_irqrestore(shost->host_lock, flags); 2328 2329 /* Delete SCSI target and sdevs */ 2330 if (rport->scsi_target_id != -1) 2331 fc_starget_delete(&rport->stgt_delete_work); 2332 2333 /* 2334 * Notify the driver that the rport is now dead. The LLDD will 2335 * also guarantee that any communication to the rport is terminated 2336 */ 2337 if (i->f->dev_loss_tmo_callbk) 2338 i->f->dev_loss_tmo_callbk(rport); 2339 2340 transport_remove_device(dev); 2341 device_del(dev); 2342 transport_destroy_device(dev); 2343 put_device(&shost->shost_gendev); /* for fc_host->rport list */ 2344 put_device(dev); /* for self-reference */ 2345 } 2346 2347 2348 /** 2349 * fc_rport_create - allocates and creates a remote FC port. 2350 * @shost: scsi host the remote port is connected to. 2351 * @channel: Channel on shost port connected to. 2352 * @ids: The world wide names, fc address, and FC4 port 2353 * roles for the remote port. 2354 * 2355 * Allocates and creates the remoter port structure, including the 2356 * class and sysfs creation. 2357 * 2358 * Notes: 2359 * This routine assumes no locks are held on entry. 2360 **/ 2361 static struct fc_rport * 2362 fc_rport_create(struct Scsi_Host *shost, int channel, 2363 struct fc_rport_identifiers *ids) 2364 { 2365 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2366 struct fc_internal *fci = to_fc_internal(shost->transportt); 2367 struct fc_rport *rport; 2368 struct device *dev; 2369 unsigned long flags; 2370 int error; 2371 size_t size; 2372 2373 size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size); 2374 rport = kzalloc(size, GFP_KERNEL); 2375 if (unlikely(!rport)) { 2376 printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); 2377 return NULL; 2378 } 2379 2380 rport->maxframe_size = -1; 2381 rport->supported_classes = FC_COS_UNSPECIFIED; 2382 rport->dev_loss_tmo = fc_dev_loss_tmo; 2383 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name)); 2384 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name)); 2385 rport->port_id = ids->port_id; 2386 rport->roles = ids->roles; 2387 rport->port_state = FC_PORTSTATE_ONLINE; 2388 if (fci->f->dd_fcrport_size) 2389 rport->dd_data = &rport[1]; 2390 rport->channel = channel; 2391 rport->fast_io_fail_tmo = -1; 2392 2393 INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport); 2394 INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io); 2395 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport); 2396 INIT_WORK(&rport->stgt_delete_work, fc_starget_delete); 2397 INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete); 2398 2399 spin_lock_irqsave(shost->host_lock, flags); 2400 2401 rport->number = fc_host->next_rport_number++; 2402 if (rport->roles & FC_PORT_ROLE_FCP_TARGET) 2403 rport->scsi_target_id = fc_host->next_target_id++; 2404 else 2405 rport->scsi_target_id = -1; 2406 list_add_tail(&rport->peers, &fc_host->rports); 2407 get_device(&shost->shost_gendev); /* for fc_host->rport list */ 2408 2409 spin_unlock_irqrestore(shost->host_lock, flags); 2410 2411 dev = &rport->dev; 2412 device_initialize(dev); /* takes self reference */ 2413 dev->parent = get_device(&shost->shost_gendev); /* parent reference */ 2414 dev->release = fc_rport_dev_release; 2415 sprintf(dev->bus_id, "rport-%d:%d-%d", 2416 shost->host_no, channel, rport->number); 2417 transport_setup_device(dev); 2418 2419 error = device_add(dev); 2420 if (error) { 2421 printk(KERN_ERR "FC Remote Port device_add failed\n"); 2422 goto delete_rport; 2423 } 2424 transport_add_device(dev); 2425 transport_configure_device(dev); 2426 2427 if (rport->roles & FC_PORT_ROLE_FCP_TARGET) { 2428 /* initiate a scan of the target */ 2429 rport->flags |= FC_RPORT_SCAN_PENDING; 2430 scsi_queue_work(shost, &rport->scan_work); 2431 } 2432 2433 return rport; 2434 2435 delete_rport: 2436 transport_destroy_device(dev); 2437 spin_lock_irqsave(shost->host_lock, flags); 2438 list_del(&rport->peers); 2439 put_device(&shost->shost_gendev); /* for fc_host->rport list */ 2440 spin_unlock_irqrestore(shost->host_lock, flags); 2441 put_device(dev->parent); 2442 kfree(rport); 2443 return NULL; 2444 } 2445 2446 /** 2447 * fc_remote_port_add - notifies the fc transport of the existence 2448 * of a remote FC port. 2449 * @shost: scsi host the remote port is connected to. 2450 * @channel: Channel on shost port connected to. 2451 * @ids: The world wide names, fc address, and FC4 port 2452 * roles for the remote port. 2453 * 2454 * The LLDD calls this routine to notify the transport of the existence 2455 * of a remote port. The LLDD provides the unique identifiers (wwpn,wwn) 2456 * of the port, it's FC address (port_id), and the FC4 roles that are 2457 * active for the port. 2458 * 2459 * For ports that are FCP targets (aka scsi targets), the FC transport 2460 * maintains consistent target id bindings on behalf of the LLDD. 2461 * A consistent target id binding is an assignment of a target id to 2462 * a remote port identifier, which persists while the scsi host is 2463 * attached. The remote port can disappear, then later reappear, and 2464 * it's target id assignment remains the same. This allows for shifts 2465 * in FC addressing (if binding by wwpn or wwnn) with no apparent 2466 * changes to the scsi subsystem which is based on scsi host number and 2467 * target id values. Bindings are only valid during the attachment of 2468 * the scsi host. If the host detaches, then later re-attaches, target 2469 * id bindings may change. 2470 * 2471 * This routine is responsible for returning a remote port structure. 2472 * The routine will search the list of remote ports it maintains 2473 * internally on behalf of consistent target id mappings. If found, the 2474 * remote port structure will be reused. Otherwise, a new remote port 2475 * structure will be allocated. 2476 * 2477 * Whenever a remote port is allocated, a new fc_remote_port class 2478 * device is created. 2479 * 2480 * Should not be called from interrupt context. 2481 * 2482 * Notes: 2483 * This routine assumes no locks are held on entry. 2484 **/ 2485 struct fc_rport * 2486 fc_remote_port_add(struct Scsi_Host *shost, int channel, 2487 struct fc_rport_identifiers *ids) 2488 { 2489 struct fc_internal *fci = to_fc_internal(shost->transportt); 2490 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2491 struct fc_rport *rport; 2492 unsigned long flags; 2493 int match = 0; 2494 2495 /* ensure any stgt delete functions are done */ 2496 fc_flush_work(shost); 2497 2498 /* 2499 * Search the list of "active" rports, for an rport that has been 2500 * deleted, but we've held off the real delete while the target 2501 * is in a "blocked" state. 2502 */ 2503 spin_lock_irqsave(shost->host_lock, flags); 2504 2505 list_for_each_entry(rport, &fc_host->rports, peers) { 2506 2507 if ((rport->port_state == FC_PORTSTATE_BLOCKED) && 2508 (rport->channel == channel)) { 2509 2510 switch (fc_host->tgtid_bind_type) { 2511 case FC_TGTID_BIND_BY_WWPN: 2512 case FC_TGTID_BIND_NONE: 2513 if (rport->port_name == ids->port_name) 2514 match = 1; 2515 break; 2516 case FC_TGTID_BIND_BY_WWNN: 2517 if (rport->node_name == ids->node_name) 2518 match = 1; 2519 break; 2520 case FC_TGTID_BIND_BY_ID: 2521 if (rport->port_id == ids->port_id) 2522 match = 1; 2523 break; 2524 } 2525 2526 if (match) { 2527 2528 memcpy(&rport->node_name, &ids->node_name, 2529 sizeof(rport->node_name)); 2530 memcpy(&rport->port_name, &ids->port_name, 2531 sizeof(rport->port_name)); 2532 rport->port_id = ids->port_id; 2533 2534 rport->port_state = FC_PORTSTATE_ONLINE; 2535 rport->roles = ids->roles; 2536 2537 spin_unlock_irqrestore(shost->host_lock, flags); 2538 2539 if (fci->f->dd_fcrport_size) 2540 memset(rport->dd_data, 0, 2541 fci->f->dd_fcrport_size); 2542 2543 /* 2544 * If we were not a target, cancel the 2545 * io terminate and rport timers, and 2546 * we're done. 2547 * 2548 * If we were a target, but our new role 2549 * doesn't indicate a target, leave the 2550 * timers running expecting the role to 2551 * change as the target fully logs in. If 2552 * it doesn't, the target will be torn down. 2553 * 2554 * If we were a target, and our role shows 2555 * we're still a target, cancel the timers 2556 * and kick off a scan. 2557 */ 2558 2559 /* was a target, not in roles */ 2560 if ((rport->scsi_target_id != -1) && 2561 (!(ids->roles & FC_PORT_ROLE_FCP_TARGET))) 2562 return rport; 2563 2564 /* 2565 * Stop the fail io and dev_loss timers. 2566 * If they flush, the port_state will 2567 * be checked and will NOOP the function. 2568 */ 2569 if (!cancel_delayed_work(&rport->fail_io_work)) 2570 fc_flush_devloss(shost); 2571 if (!cancel_delayed_work(&rport->dev_loss_work)) 2572 fc_flush_devloss(shost); 2573 2574 spin_lock_irqsave(shost->host_lock, flags); 2575 2576 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2577 2578 /* if target, initiate a scan */ 2579 if (rport->scsi_target_id != -1) { 2580 rport->flags |= FC_RPORT_SCAN_PENDING; 2581 scsi_queue_work(shost, 2582 &rport->scan_work); 2583 spin_unlock_irqrestore(shost->host_lock, 2584 flags); 2585 scsi_target_unblock(&rport->dev); 2586 } else 2587 spin_unlock_irqrestore(shost->host_lock, 2588 flags); 2589 2590 return rport; 2591 } 2592 } 2593 } 2594 2595 /* 2596 * Search the bindings array 2597 * Note: if never a FCP target, you won't be on this list 2598 */ 2599 if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) { 2600 2601 /* search for a matching consistent binding */ 2602 2603 list_for_each_entry(rport, &fc_host->rport_bindings, 2604 peers) { 2605 if (rport->channel != channel) 2606 continue; 2607 2608 switch (fc_host->tgtid_bind_type) { 2609 case FC_TGTID_BIND_BY_WWPN: 2610 if (rport->port_name == ids->port_name) 2611 match = 1; 2612 break; 2613 case FC_TGTID_BIND_BY_WWNN: 2614 if (rport->node_name == ids->node_name) 2615 match = 1; 2616 break; 2617 case FC_TGTID_BIND_BY_ID: 2618 if (rport->port_id == ids->port_id) 2619 match = 1; 2620 break; 2621 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 2622 break; 2623 } 2624 2625 if (match) { 2626 list_move_tail(&rport->peers, &fc_host->rports); 2627 break; 2628 } 2629 } 2630 2631 if (match) { 2632 memcpy(&rport->node_name, &ids->node_name, 2633 sizeof(rport->node_name)); 2634 memcpy(&rport->port_name, &ids->port_name, 2635 sizeof(rport->port_name)); 2636 rport->port_id = ids->port_id; 2637 rport->roles = ids->roles; 2638 rport->port_state = FC_PORTSTATE_ONLINE; 2639 2640 if (fci->f->dd_fcrport_size) 2641 memset(rport->dd_data, 0, 2642 fci->f->dd_fcrport_size); 2643 2644 if (rport->roles & FC_PORT_ROLE_FCP_TARGET) { 2645 /* initiate a scan of the target */ 2646 rport->flags |= FC_RPORT_SCAN_PENDING; 2647 scsi_queue_work(shost, &rport->scan_work); 2648 spin_unlock_irqrestore(shost->host_lock, flags); 2649 scsi_target_unblock(&rport->dev); 2650 } else 2651 spin_unlock_irqrestore(shost->host_lock, flags); 2652 2653 return rport; 2654 } 2655 } 2656 2657 spin_unlock_irqrestore(shost->host_lock, flags); 2658 2659 /* No consistent binding found - create new remote port entry */ 2660 rport = fc_rport_create(shost, channel, ids); 2661 2662 return rport; 2663 } 2664 EXPORT_SYMBOL(fc_remote_port_add); 2665 2666 2667 /** 2668 * fc_remote_port_delete - notifies the fc transport that a remote 2669 * port is no longer in existence. 2670 * @rport: The remote port that no longer exists 2671 * 2672 * The LLDD calls this routine to notify the transport that a remote 2673 * port is no longer part of the topology. Note: Although a port 2674 * may no longer be part of the topology, it may persist in the remote 2675 * ports displayed by the fc_host. We do this under 2 conditions: 2676 * - If the port was a scsi target, we delay its deletion by "blocking" it. 2677 * This allows the port to temporarily disappear, then reappear without 2678 * disrupting the SCSI device tree attached to it. During the "blocked" 2679 * period the port will still exist. 2680 * - If the port was a scsi target and disappears for longer than we 2681 * expect, we'll delete the port and the tear down the SCSI device tree 2682 * attached to it. However, we want to semi-persist the target id assigned 2683 * to that port if it eventually does exist. The port structure will 2684 * remain (although with minimal information) so that the target id 2685 * bindings remails. 2686 * 2687 * If the remote port is not an FCP Target, it will be fully torn down 2688 * and deallocated, including the fc_remote_port class device. 2689 * 2690 * If the remote port is an FCP Target, the port will be placed in a 2691 * temporary blocked state. From the LLDD's perspective, the rport no 2692 * longer exists. From the SCSI midlayer's perspective, the SCSI target 2693 * exists, but all sdevs on it are blocked from further I/O. The following 2694 * is then expected: 2695 * If the remote port does not return (signaled by a LLDD call to 2696 * fc_remote_port_add()) within the dev_loss_tmo timeout, then the 2697 * scsi target is removed - killing all outstanding i/o and removing the 2698 * scsi devices attached ot it. The port structure will be marked Not 2699 * Present and be partially cleared, leaving only enough information to 2700 * recognize the remote port relative to the scsi target id binding if 2701 * it later appears. The port will remain as long as there is a valid 2702 * binding (e.g. until the user changes the binding type or unloads the 2703 * scsi host with the binding). 2704 * 2705 * If the remote port returns within the dev_loss_tmo value (and matches 2706 * according to the target id binding type), the port structure will be 2707 * reused. If it is no longer a SCSI target, the target will be torn 2708 * down. If it continues to be a SCSI target, then the target will be 2709 * unblocked (allowing i/o to be resumed), and a scan will be activated 2710 * to ensure that all luns are detected. 2711 * 2712 * Called from normal process context only - cannot be called from interrupt. 2713 * 2714 * Notes: 2715 * This routine assumes no locks are held on entry. 2716 **/ 2717 void 2718 fc_remote_port_delete(struct fc_rport *rport) 2719 { 2720 struct Scsi_Host *shost = rport_to_shost(rport); 2721 struct fc_internal *i = to_fc_internal(shost->transportt); 2722 int timeout = rport->dev_loss_tmo; 2723 unsigned long flags; 2724 2725 /* 2726 * No need to flush the fc_host work_q's, as all adds are synchronous. 2727 * 2728 * We do need to reclaim the rport scan work element, so eventually 2729 * (in fc_rport_final_delete()) we'll flush the scsi host work_q if 2730 * there's still a scan pending. 2731 */ 2732 2733 spin_lock_irqsave(shost->host_lock, flags); 2734 2735 if (rport->port_state != FC_PORTSTATE_ONLINE) { 2736 spin_unlock_irqrestore(shost->host_lock, flags); 2737 return; 2738 } 2739 2740 /* 2741 * In the past, we if this was not an FCP-Target, we would 2742 * unconditionally just jump to deleting the rport. 2743 * However, rports can be used as node containers by the LLDD, 2744 * and its not appropriate to just terminate the rport at the 2745 * first sign of a loss in connectivity. The LLDD may want to 2746 * send ELS traffic to re-validate the login. If the rport is 2747 * immediately deleted, it makes it inappropriate for a node 2748 * container. 2749 * So... we now unconditionally wait dev_loss_tmo before 2750 * destroying an rport. 2751 */ 2752 2753 rport->port_state = FC_PORTSTATE_BLOCKED; 2754 2755 rport->flags |= FC_RPORT_DEVLOSS_PENDING; 2756 2757 spin_unlock_irqrestore(shost->host_lock, flags); 2758 2759 scsi_target_block(&rport->dev); 2760 2761 /* see if we need to kill io faster than waiting for device loss */ 2762 if ((rport->fast_io_fail_tmo != -1) && 2763 (rport->fast_io_fail_tmo < timeout) && (i->f->terminate_rport_io)) 2764 fc_queue_devloss_work(shost, &rport->fail_io_work, 2765 rport->fast_io_fail_tmo * HZ); 2766 2767 /* cap the length the devices can be blocked until they are deleted */ 2768 fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ); 2769 } 2770 EXPORT_SYMBOL(fc_remote_port_delete); 2771 2772 /** 2773 * fc_remote_port_rolechg - notifies the fc transport that the roles 2774 * on a remote may have changed. 2775 * @rport: The remote port that changed. 2776 * 2777 * The LLDD calls this routine to notify the transport that the roles 2778 * on a remote port may have changed. The largest effect of this is 2779 * if a port now becomes a FCP Target, it must be allocated a 2780 * scsi target id. If the port is no longer a FCP target, any 2781 * scsi target id value assigned to it will persist in case the 2782 * role changes back to include FCP Target. No changes in the scsi 2783 * midlayer will be invoked if the role changes (in the expectation 2784 * that the role will be resumed. If it doesn't normal error processing 2785 * will take place). 2786 * 2787 * Should not be called from interrupt context. 2788 * 2789 * Notes: 2790 * This routine assumes no locks are held on entry. 2791 **/ 2792 void 2793 fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) 2794 { 2795 struct Scsi_Host *shost = rport_to_shost(rport); 2796 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2797 unsigned long flags; 2798 int create = 0; 2799 2800 spin_lock_irqsave(shost->host_lock, flags); 2801 if (roles & FC_PORT_ROLE_FCP_TARGET) { 2802 if (rport->scsi_target_id == -1) { 2803 rport->scsi_target_id = fc_host->next_target_id++; 2804 create = 1; 2805 } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET)) 2806 create = 1; 2807 } 2808 2809 rport->roles = roles; 2810 2811 spin_unlock_irqrestore(shost->host_lock, flags); 2812 2813 if (create) { 2814 /* 2815 * There may have been a delete timer running on the 2816 * port. Ensure that it is cancelled as we now know 2817 * the port is an FCP Target. 2818 * Note: we know the rport is exists and in an online 2819 * state as the LLDD would not have had an rport 2820 * reference to pass us. 2821 * 2822 * Take no action on the del_timer failure as the state 2823 * machine state change will validate the 2824 * transaction. 2825 */ 2826 if (!cancel_delayed_work(&rport->fail_io_work)) 2827 fc_flush_devloss(shost); 2828 if (!cancel_delayed_work(&rport->dev_loss_work)) 2829 fc_flush_devloss(shost); 2830 2831 spin_lock_irqsave(shost->host_lock, flags); 2832 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2833 spin_unlock_irqrestore(shost->host_lock, flags); 2834 2835 /* ensure any stgt delete functions are done */ 2836 fc_flush_work(shost); 2837 2838 /* initiate a scan of the target */ 2839 spin_lock_irqsave(shost->host_lock, flags); 2840 rport->flags |= FC_RPORT_SCAN_PENDING; 2841 scsi_queue_work(shost, &rport->scan_work); 2842 spin_unlock_irqrestore(shost->host_lock, flags); 2843 scsi_target_unblock(&rport->dev); 2844 } 2845 } 2846 EXPORT_SYMBOL(fc_remote_port_rolechg); 2847 2848 /** 2849 * fc_timeout_deleted_rport - Timeout handler for a deleted remote port, 2850 * which we blocked, and has now failed to return 2851 * in the allotted time. 2852 * 2853 * @work: rport target that failed to reappear in the allotted time. 2854 **/ 2855 static void 2856 fc_timeout_deleted_rport(struct work_struct *work) 2857 { 2858 struct fc_rport *rport = 2859 container_of(work, struct fc_rport, dev_loss_work.work); 2860 struct Scsi_Host *shost = rport_to_shost(rport); 2861 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2862 unsigned long flags; 2863 2864 spin_lock_irqsave(shost->host_lock, flags); 2865 2866 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; 2867 2868 /* 2869 * If the port is ONLINE, then it came back. If it was a SCSI 2870 * target, validate it still is. If not, tear down the 2871 * scsi_target on it. 2872 */ 2873 if ((rport->port_state == FC_PORTSTATE_ONLINE) && 2874 (rport->scsi_target_id != -1) && 2875 !(rport->roles & FC_PORT_ROLE_FCP_TARGET)) { 2876 dev_printk(KERN_ERR, &rport->dev, 2877 "blocked FC remote port time out: no longer" 2878 " a FCP target, removing starget\n"); 2879 spin_unlock_irqrestore(shost->host_lock, flags); 2880 scsi_target_unblock(&rport->dev); 2881 fc_queue_work(shost, &rport->stgt_delete_work); 2882 return; 2883 } 2884 2885 /* NOOP state - we're flushing workq's */ 2886 if (rport->port_state != FC_PORTSTATE_BLOCKED) { 2887 spin_unlock_irqrestore(shost->host_lock, flags); 2888 dev_printk(KERN_ERR, &rport->dev, 2889 "blocked FC remote port time out: leaving" 2890 " rport%s alone\n", 2891 (rport->scsi_target_id != -1) ? " and starget" : ""); 2892 return; 2893 } 2894 2895 if ((fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) || 2896 (rport->scsi_target_id == -1)) { 2897 list_del(&rport->peers); 2898 rport->port_state = FC_PORTSTATE_DELETED; 2899 dev_printk(KERN_ERR, &rport->dev, 2900 "blocked FC remote port time out: removing" 2901 " rport%s\n", 2902 (rport->scsi_target_id != -1) ? " and starget" : ""); 2903 fc_queue_work(shost, &rport->rport_delete_work); 2904 spin_unlock_irqrestore(shost->host_lock, flags); 2905 return; 2906 } 2907 2908 dev_printk(KERN_ERR, &rport->dev, 2909 "blocked FC remote port time out: removing target and " 2910 "saving binding\n"); 2911 2912 list_move_tail(&rport->peers, &fc_host->rport_bindings); 2913 2914 /* 2915 * Note: We do not remove or clear the hostdata area. This allows 2916 * host-specific target data to persist along with the 2917 * scsi_target_id. It's up to the host to manage it's hostdata area. 2918 */ 2919 2920 /* 2921 * Reinitialize port attributes that may change if the port comes back. 2922 */ 2923 rport->maxframe_size = -1; 2924 rport->supported_classes = FC_COS_UNSPECIFIED; 2925 rport->roles = FC_PORT_ROLE_UNKNOWN; 2926 rport->port_state = FC_PORTSTATE_NOTPRESENT; 2927 2928 /* remove the identifiers that aren't used in the consisting binding */ 2929 switch (fc_host->tgtid_bind_type) { 2930 case FC_TGTID_BIND_BY_WWPN: 2931 rport->node_name = -1; 2932 rport->port_id = -1; 2933 break; 2934 case FC_TGTID_BIND_BY_WWNN: 2935 rport->port_name = -1; 2936 rport->port_id = -1; 2937 break; 2938 case FC_TGTID_BIND_BY_ID: 2939 rport->node_name = -1; 2940 rport->port_name = -1; 2941 break; 2942 case FC_TGTID_BIND_NONE: /* to keep compiler happy */ 2943 break; 2944 } 2945 2946 /* 2947 * As this only occurs if the remote port (scsi target) 2948 * went away and didn't come back - we'll remove 2949 * all attached scsi devices. 2950 */ 2951 spin_unlock_irqrestore(shost->host_lock, flags); 2952 2953 scsi_target_unblock(&rport->dev); 2954 fc_queue_work(shost, &rport->stgt_delete_work); 2955 } 2956 2957 /** 2958 * fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a 2959 * disconnected SCSI target. 2960 * 2961 * @work: rport to terminate io on. 2962 * 2963 * Notes: Only requests the failure of the io, not that all are flushed 2964 * prior to returning. 2965 **/ 2966 static void 2967 fc_timeout_fail_rport_io(struct work_struct *work) 2968 { 2969 struct fc_rport *rport = 2970 container_of(work, struct fc_rport, fail_io_work.work); 2971 struct Scsi_Host *shost = rport_to_shost(rport); 2972 struct fc_internal *i = to_fc_internal(shost->transportt); 2973 2974 if (rport->port_state != FC_PORTSTATE_BLOCKED) 2975 return; 2976 2977 i->f->terminate_rport_io(rport); 2978 } 2979 2980 /** 2981 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 2982 * 2983 * @work: remote port to be scanned. 2984 **/ 2985 static void 2986 fc_scsi_scan_rport(struct work_struct *work) 2987 { 2988 struct fc_rport *rport = 2989 container_of(work, struct fc_rport, scan_work); 2990 struct Scsi_Host *shost = rport_to_shost(rport); 2991 unsigned long flags; 2992 2993 if ((rport->port_state == FC_PORTSTATE_ONLINE) && 2994 (rport->roles & FC_PORT_ROLE_FCP_TARGET)) { 2995 scsi_scan_target(&rport->dev, rport->channel, 2996 rport->scsi_target_id, SCAN_WILD_CARD, 1); 2997 } 2998 2999 spin_lock_irqsave(shost->host_lock, flags); 3000 rport->flags &= ~FC_RPORT_SCAN_PENDING; 3001 spin_unlock_irqrestore(shost->host_lock, flags); 3002 } 3003 3004 3005 /** 3006 * fc_vport_create - allocates and creates a FC virtual port. 3007 * @shost: scsi host the virtual port is connected to. 3008 * @channel: Channel on shost port connected to. 3009 * @pdev: parent device for vport 3010 * @ids: The world wide names, FC4 port roles, etc for 3011 * the virtual port. 3012 * @ret_vport: The pointer to the created vport. 3013 * 3014 * Allocates and creates the vport structure, calls the parent host 3015 * to instantiate the vport, the completes w/ class and sysfs creation. 3016 * 3017 * Notes: 3018 * This routine assumes no locks are held on entry. 3019 **/ 3020 static int 3021 fc_vport_create(struct Scsi_Host *shost, int channel, struct device *pdev, 3022 struct fc_vport_identifiers *ids, struct fc_vport **ret_vport) 3023 { 3024 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 3025 struct fc_internal *fci = to_fc_internal(shost->transportt); 3026 struct fc_vport *vport; 3027 struct device *dev; 3028 unsigned long flags; 3029 size_t size; 3030 int error; 3031 3032 *ret_vport = NULL; 3033 3034 if ( ! fci->f->vport_create) 3035 return -ENOENT; 3036 3037 size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size); 3038 vport = kzalloc(size, GFP_KERNEL); 3039 if (unlikely(!vport)) { 3040 printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__); 3041 return -ENOMEM; 3042 } 3043 3044 vport->vport_state = FC_VPORT_UNKNOWN; 3045 vport->vport_last_state = FC_VPORT_UNKNOWN; 3046 vport->node_name = ids->node_name; 3047 vport->port_name = ids->port_name; 3048 vport->roles = ids->roles; 3049 vport->vport_type = ids->vport_type; 3050 if (fci->f->dd_fcvport_size) 3051 vport->dd_data = &vport[1]; 3052 vport->shost = shost; 3053 vport->channel = channel; 3054 vport->flags = FC_VPORT_CREATING; 3055 INIT_WORK(&vport->vport_delete_work, fc_vport_sched_delete); 3056 3057 spin_lock_irqsave(shost->host_lock, flags); 3058 3059 if (fc_host->npiv_vports_inuse >= fc_host->max_npiv_vports) { 3060 spin_unlock_irqrestore(shost->host_lock, flags); 3061 kfree(vport); 3062 return -ENOSPC; 3063 } 3064 fc_host->npiv_vports_inuse++; 3065 vport->number = fc_host->next_vport_number++; 3066 list_add_tail(&vport->peers, &fc_host->vports); 3067 get_device(&shost->shost_gendev); /* for fc_host->vport list */ 3068 3069 spin_unlock_irqrestore(shost->host_lock, flags); 3070 3071 dev = &vport->dev; 3072 device_initialize(dev); /* takes self reference */ 3073 dev->parent = get_device(pdev); /* takes parent reference */ 3074 dev->release = fc_vport_dev_release; 3075 sprintf(dev->bus_id, "vport-%d:%d-%d", 3076 shost->host_no, channel, vport->number); 3077 transport_setup_device(dev); 3078 3079 error = device_add(dev); 3080 if (error) { 3081 printk(KERN_ERR "FC Virtual Port device_add failed\n"); 3082 goto delete_vport; 3083 } 3084 transport_add_device(dev); 3085 transport_configure_device(dev); 3086 3087 error = fci->f->vport_create(vport, ids->disable); 3088 if (error) { 3089 printk(KERN_ERR "FC Virtual Port LLDD Create failed\n"); 3090 goto delete_vport_all; 3091 } 3092 3093 /* 3094 * if the parent isn't the physical adapter's Scsi_Host, ensure 3095 * the Scsi_Host at least contains ia symlink to the vport. 3096 */ 3097 if (pdev != &shost->shost_gendev) { 3098 error = sysfs_create_link(&shost->shost_gendev.kobj, 3099 &dev->kobj, dev->bus_id); 3100 if (error) 3101 printk(KERN_ERR 3102 "%s: Cannot create vport symlinks for " 3103 "%s, err=%d\n", 3104 __FUNCTION__, dev->bus_id, error); 3105 } 3106 spin_lock_irqsave(shost->host_lock, flags); 3107 vport->flags &= ~FC_VPORT_CREATING; 3108 spin_unlock_irqrestore(shost->host_lock, flags); 3109 3110 dev_printk(KERN_NOTICE, pdev, 3111 "%s created via shost%d channel %d\n", dev->bus_id, 3112 shost->host_no, channel); 3113 3114 *ret_vport = vport; 3115 3116 return 0; 3117 3118 delete_vport_all: 3119 transport_remove_device(dev); 3120 device_del(dev); 3121 delete_vport: 3122 transport_destroy_device(dev); 3123 spin_lock_irqsave(shost->host_lock, flags); 3124 list_del(&vport->peers); 3125 put_device(&shost->shost_gendev); /* for fc_host->vport list */ 3126 fc_host->npiv_vports_inuse--; 3127 spin_unlock_irqrestore(shost->host_lock, flags); 3128 put_device(dev->parent); 3129 kfree(vport); 3130 3131 return error; 3132 } 3133 3134 3135 /** 3136 * fc_vport_terminate - Admin App or LLDD requests termination of a vport 3137 * @vport: fc_vport to be terminated 3138 * 3139 * Calls the LLDD vport_delete() function, then deallocates and removes 3140 * the vport from the shost and object tree. 3141 * 3142 * Notes: 3143 * This routine assumes no locks are held on entry. 3144 **/ 3145 int 3146 fc_vport_terminate(struct fc_vport *vport) 3147 { 3148 struct Scsi_Host *shost = vport_to_shost(vport); 3149 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 3150 struct fc_internal *i = to_fc_internal(shost->transportt); 3151 struct device *dev = &vport->dev; 3152 unsigned long flags; 3153 int stat; 3154 3155 spin_lock_irqsave(shost->host_lock, flags); 3156 if (vport->flags & FC_VPORT_CREATING) { 3157 spin_unlock_irqrestore(shost->host_lock, flags); 3158 return -EBUSY; 3159 } 3160 if (vport->flags & (FC_VPORT_DEL)) { 3161 spin_unlock_irqrestore(shost->host_lock, flags); 3162 return -EALREADY; 3163 } 3164 vport->flags |= FC_VPORT_DELETING; 3165 spin_unlock_irqrestore(shost->host_lock, flags); 3166 3167 if (i->f->vport_delete) 3168 stat = i->f->vport_delete(vport); 3169 else 3170 stat = -ENOENT; 3171 3172 spin_lock_irqsave(shost->host_lock, flags); 3173 vport->flags &= ~FC_VPORT_DELETING; 3174 if (!stat) { 3175 vport->flags |= FC_VPORT_DELETED; 3176 list_del(&vport->peers); 3177 fc_host->npiv_vports_inuse--; 3178 put_device(&shost->shost_gendev); /* for fc_host->vport list */ 3179 } 3180 spin_unlock_irqrestore(shost->host_lock, flags); 3181 3182 if (stat) 3183 return stat; 3184 3185 if (dev->parent != &shost->shost_gendev) 3186 sysfs_remove_link(&shost->shost_gendev.kobj, dev->bus_id); 3187 transport_remove_device(dev); 3188 device_del(dev); 3189 transport_destroy_device(dev); 3190 3191 /* 3192 * Removing our self-reference should mean our 3193 * release function gets called, which will drop the remaining 3194 * parent reference and free the data structure. 3195 */ 3196 put_device(dev); /* for self-reference */ 3197 3198 return 0; /* SUCCESS */ 3199 } 3200 EXPORT_SYMBOL(fc_vport_terminate); 3201 3202 /** 3203 * fc_vport_sched_delete - workq-based delete request for a vport 3204 * 3205 * @work: vport to be deleted. 3206 **/ 3207 static void 3208 fc_vport_sched_delete(struct work_struct *work) 3209 { 3210 struct fc_vport *vport = 3211 container_of(work, struct fc_vport, vport_delete_work); 3212 int stat; 3213 3214 stat = fc_vport_terminate(vport); 3215 if (stat) 3216 dev_printk(KERN_ERR, vport->dev.parent, 3217 "%s: %s could not be deleted created via " 3218 "shost%d channel %d - error %d\n", __FUNCTION__, 3219 vport->dev.bus_id, vport->shost->host_no, 3220 vport->channel, stat); 3221 } 3222 3223 3224 /* Original Author: Martin Hicks */ 3225 MODULE_AUTHOR("James Smart"); 3226 MODULE_DESCRIPTION("FC Transport Attributes"); 3227 MODULE_LICENSE("GPL"); 3228 3229 module_init(fc_transport_init); 3230 module_exit(fc_transport_exit); 3231