aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_transport_fc.c')
-rw-r--r--drivers/scsi/scsi_transport_fc.c370
1 files changed, 354 insertions, 16 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index b03aa85108e5..38c215a78f69 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -32,6 +32,9 @@
32#include <scsi/scsi_transport.h> 32#include <scsi/scsi_transport.h>
33#include <scsi/scsi_transport_fc.h> 33#include <scsi/scsi_transport_fc.h>
34#include <scsi/scsi_cmnd.h> 34#include <scsi/scsi_cmnd.h>
35#include <linux/netlink.h>
36#include <net/netlink.h>
37#include <scsi/scsi_netlink_fc.h>
35#include "scsi_priv.h" 38#include "scsi_priv.h"
36 39
37static int fc_queue_work(struct Scsi_Host *, struct work_struct *); 40static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
@@ -93,6 +96,29 @@ fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
93#define FC_PORTTYPE_MAX_NAMELEN 50 96#define FC_PORTTYPE_MAX_NAMELEN 50
94 97
95 98
99/* Convert fc_host_event_code values to ascii string name */
100static const struct {
101 enum fc_host_event_code value;
102 char *name;
103} fc_host_event_code_names[] = {
104 { FCH_EVT_LIP, "lip" },
105 { FCH_EVT_LINKUP, "link_up" },
106 { FCH_EVT_LINKDOWN, "link_down" },
107 { FCH_EVT_LIPRESET, "lip_reset" },
108 { FCH_EVT_RSCN, "rscn" },
109 { FCH_EVT_ADAPTER_CHANGE, "adapter_chg" },
110 { FCH_EVT_PORT_UNKNOWN, "port_unknown" },
111 { FCH_EVT_PORT_ONLINE, "port_online" },
112 { FCH_EVT_PORT_OFFLINE, "port_offline" },
113 { FCH_EVT_PORT_FABRIC, "port_fabric" },
114 { FCH_EVT_LINK_UNKNOWN, "link_unknown" },
115 { FCH_EVT_VENDOR_UNIQUE, "vendor_unique" },
116};
117fc_enum_name_search(host_event_code, fc_host_event_code,
118 fc_host_event_code_names)
119#define FC_HOST_EVENT_CODE_MAX_NAMELEN 30
120
121
96/* Convert fc_port_state values to ascii string name */ 122/* Convert fc_port_state values to ascii string name */
97static struct { 123static struct {
98 enum fc_port_state value; 124 enum fc_port_state value;
@@ -216,6 +242,7 @@ fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
216 242
217 243
218static void fc_timeout_deleted_rport(void *data); 244static void fc_timeout_deleted_rport(void *data);
245static void fc_timeout_fail_rport_io(void *data);
219static void fc_scsi_scan_rport(void *data); 246static void fc_scsi_scan_rport(void *data);
220 247
221/* 248/*
@@ -223,7 +250,7 @@ static void fc_scsi_scan_rport(void *data);
223 * Increase these values if you add attributes 250 * Increase these values if you add attributes
224 */ 251 */
225#define FC_STARGET_NUM_ATTRS 3 252#define FC_STARGET_NUM_ATTRS 3
226#define FC_RPORT_NUM_ATTRS 9 253#define FC_RPORT_NUM_ATTRS 10
227#define FC_HOST_NUM_ATTRS 17 254#define FC_HOST_NUM_ATTRS 17
228 255
229struct fc_internal { 256struct fc_internal {
@@ -301,8 +328,6 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
301 fc_host->supported_classes = FC_COS_UNSPECIFIED; 328 fc_host->supported_classes = FC_COS_UNSPECIFIED;
302 memset(fc_host->supported_fc4s, 0, 329 memset(fc_host->supported_fc4s, 0,
303 sizeof(fc_host->supported_fc4s)); 330 sizeof(fc_host->supported_fc4s));
304 memset(fc_host->symbolic_name, 0,
305 sizeof(fc_host->symbolic_name));
306 fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN; 331 fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN;
307 fc_host->maxframe_size = -1; 332 fc_host->maxframe_size = -1;
308 memset(fc_host->serial_number, 0, 333 memset(fc_host->serial_number, 0,
@@ -315,6 +340,8 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
315 sizeof(fc_host->active_fc4s)); 340 sizeof(fc_host->active_fc4s));
316 fc_host->speed = FC_PORTSPEED_UNKNOWN; 341 fc_host->speed = FC_PORTSPEED_UNKNOWN;
317 fc_host->fabric_name = -1; 342 fc_host->fabric_name = -1;
343 memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name));
344 memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname));
318 345
319 fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN; 346 fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN;
320 347
@@ -377,10 +404,184 @@ MODULE_PARM_DESC(dev_loss_tmo,
377 " exceeded, the scsi target is removed. Value should be" 404 " exceeded, the scsi target is removed. Value should be"
378 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); 405 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT.");
379 406
407/**
408 * Netlink Infrastructure
409 **/
410
411static atomic_t fc_event_seq;
412
413/**
414 * fc_get_event_number - Obtain the next sequential FC event number
415 *
416 * Notes:
417 * We could have inline'd this, but it would have required fc_event_seq to
418 * be exposed. For now, live with the subroutine call.
419 * Atomic used to avoid lock/unlock...
420 **/
421u32
422fc_get_event_number(void)
423{
424 return atomic_add_return(1, &fc_event_seq);
425}
426EXPORT_SYMBOL(fc_get_event_number);
427
428
429/**
430 * fc_host_post_event - called to post an even on an fc_host.
431 *
432 * @shost: host the event occurred on
433 * @event_number: fc event number obtained from get_fc_event_number()
434 * @event_code: fc_host event being posted
435 * @event_data: 32bits of data for the event being posted
436 *
437 * Notes:
438 * This routine assumes no locks are held on entry.
439 **/
440void
441fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
442 enum fc_host_event_code event_code, u32 event_data)
443{
444 struct sk_buff *skb;
445 struct nlmsghdr *nlh;
446 struct fc_nl_event *event;
447 const char *name;
448 u32 len, skblen;
449 int err;
450
451 if (!scsi_nl_sock) {
452 err = -ENOENT;
453 goto send_fail;
454 }
455
456 len = FC_NL_MSGALIGN(sizeof(*event));
457 skblen = NLMSG_SPACE(len);
458
459 skb = alloc_skb(skblen, GFP_KERNEL);
460 if (!skb) {
461 err = -ENOBUFS;
462 goto send_fail;
463 }
464
465 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
466 skblen - sizeof(*nlh), 0);
467 if (!nlh) {
468 err = -ENOBUFS;
469 goto send_fail_skb;
470 }
471 event = NLMSG_DATA(nlh);
472
473 INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
474 FC_NL_ASYNC_EVENT, len);
475 event->seconds = get_seconds();
476 event->vendor_id = 0;
477 event->host_no = shost->host_no;
478 event->event_datalen = sizeof(u32); /* bytes */
479 event->event_num = event_number;
480 event->event_code = event_code;
481 event->event_data = event_data;
482
483 err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
484 GFP_KERNEL);
485 if (err && (err != -ESRCH)) /* filter no recipient errors */
486 /* nlmsg_multicast already kfree_skb'd */
487 goto send_fail;
488
489 return;
490
491send_fail_skb:
492 kfree_skb(skb);
493send_fail:
494 name = get_fc_host_event_code_name(event_code);
495 printk(KERN_WARNING
496 "%s: Dropped Event : host %d %s data 0x%08x - err %d\n",
497 __FUNCTION__, shost->host_no,
498 (name) ? name : "<unknown>", event_data, err);
499 return;
500}
501EXPORT_SYMBOL(fc_host_post_event);
502
503
504/**
505 * fc_host_post_vendor_event - called to post a vendor unique event on
506 * a fc_host
507 *
508 * @shost: host the event occurred on
509 * @event_number: fc event number obtained from get_fc_event_number()
510 * @data_len: amount, in bytes, of vendor unique data
511 * @data_buf: pointer to vendor unique data
512 *
513 * Notes:
514 * This routine assumes no locks are held on entry.
515 **/
516void
517fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
518 u32 data_len, char * data_buf, u64 vendor_id)
519{
520 struct sk_buff *skb;
521 struct nlmsghdr *nlh;
522 struct fc_nl_event *event;
523 u32 len, skblen;
524 int err;
525
526 if (!scsi_nl_sock) {
527 err = -ENOENT;
528 goto send_vendor_fail;
529 }
530
531 len = FC_NL_MSGALIGN(sizeof(*event) + data_len);
532 skblen = NLMSG_SPACE(len);
533
534 skb = alloc_skb(skblen, GFP_KERNEL);
535 if (!skb) {
536 err = -ENOBUFS;
537 goto send_vendor_fail;
538 }
539
540 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
541 skblen - sizeof(*nlh), 0);
542 if (!nlh) {
543 err = -ENOBUFS;
544 goto send_vendor_fail_skb;
545 }
546 event = NLMSG_DATA(nlh);
547
548 INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
549 FC_NL_ASYNC_EVENT, len);
550 event->seconds = get_seconds();
551 event->vendor_id = vendor_id;
552 event->host_no = shost->host_no;
553 event->event_datalen = data_len; /* bytes */
554 event->event_num = event_number;
555 event->event_code = FCH_EVT_VENDOR_UNIQUE;
556 memcpy(&event->event_data, data_buf, data_len);
557
558 err = nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
559 GFP_KERNEL);
560 if (err && (err != -ESRCH)) /* filter no recipient errors */
561 /* nlmsg_multicast already kfree_skb'd */
562 goto send_vendor_fail;
563
564 return;
565
566send_vendor_fail_skb:
567 kfree_skb(skb);
568send_vendor_fail:
569 printk(KERN_WARNING
570 "%s: Dropped Event : host %d vendor_unique - err %d\n",
571 __FUNCTION__, shost->host_no, err);
572 return;
573}
574EXPORT_SYMBOL(fc_host_post_vendor_event);
575
576
380 577
381static __init int fc_transport_init(void) 578static __init int fc_transport_init(void)
382{ 579{
383 int error = transport_class_register(&fc_host_class); 580 int error;
581
582 atomic_set(&fc_event_seq, 0);
583
584 error = transport_class_register(&fc_host_class);
384 if (error) 585 if (error)
385 return error; 586 return error;
386 error = transport_class_register(&fc_rport_class); 587 error = transport_class_register(&fc_rport_class);
@@ -424,11 +625,14 @@ store_fc_rport_##field(struct class_device *cdev, const char *buf, \
424 struct fc_rport *rport = transport_class_to_rport(cdev); \ 625 struct fc_rport *rport = transport_class_to_rport(cdev); \
425 struct Scsi_Host *shost = rport_to_shost(rport); \ 626 struct Scsi_Host *shost = rport_to_shost(rport); \
426 struct fc_internal *i = to_fc_internal(shost->transportt); \ 627 struct fc_internal *i = to_fc_internal(shost->transportt); \
628 char *cp; \
427 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \ 629 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \
428 (rport->port_state == FC_PORTSTATE_DELETED) || \ 630 (rport->port_state == FC_PORTSTATE_DELETED) || \
429 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \ 631 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \
430 return -EBUSY; \ 632 return -EBUSY; \
431 val = simple_strtoul(buf, NULL, 0); \ 633 val = simple_strtoul(buf, &cp, 0); \
634 if (*cp && (*cp != '\n')) \
635 return -EINVAL; \
432 i->f->set_rport_##field(rport, val); \ 636 i->f->set_rport_##field(rport, val); \
433 return count; \ 637 return count; \
434} 638}
@@ -510,6 +714,13 @@ static FC_CLASS_DEVICE_ATTR(rport, title, S_IRUGO, \
510 if (i->f->show_rport_##field) \ 714 if (i->f->show_rport_##field) \
511 count++ 715 count++
512 716
717#define SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(field) \
718{ \
719 i->private_rport_attrs[count] = class_device_attr_rport_##field; \
720 i->rport_attrs[count] = &i->private_rport_attrs[count]; \
721 count++; \
722}
723
513 724
514/* The FC Transport Remote Port Attributes: */ 725/* The FC Transport Remote Port Attributes: */
515 726
@@ -542,12 +753,14 @@ store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf,
542 struct fc_rport *rport = transport_class_to_rport(cdev); 753 struct fc_rport *rport = transport_class_to_rport(cdev);
543 struct Scsi_Host *shost = rport_to_shost(rport); 754 struct Scsi_Host *shost = rport_to_shost(rport);
544 struct fc_internal *i = to_fc_internal(shost->transportt); 755 struct fc_internal *i = to_fc_internal(shost->transportt);
756 char *cp;
545 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || 757 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
546 (rport->port_state == FC_PORTSTATE_DELETED) || 758 (rport->port_state == FC_PORTSTATE_DELETED) ||
547 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) 759 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
548 return -EBUSY; 760 return -EBUSY;
549 val = simple_strtoul(buf, NULL, 0); 761 val = simple_strtoul(buf, &cp, 0);
550 if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)) 762 if ((*cp && (*cp != '\n')) ||
763 (val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
551 return -EINVAL; 764 return -EINVAL;
552 i->f->set_rport_dev_loss_tmo(rport, val); 765 i->f->set_rport_dev_loss_tmo(rport, val);
553 return count; 766 return count;
@@ -597,6 +810,44 @@ static FC_CLASS_DEVICE_ATTR(rport, roles, S_IRUGO,
597fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 810fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
598fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20); 811fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20);
599 812
813/*
814 * fast_io_fail_tmo attribute
815 */
816static ssize_t
817show_fc_rport_fast_io_fail_tmo (struct class_device *cdev, char *buf)
818{
819 struct fc_rport *rport = transport_class_to_rport(cdev);
820
821 if (rport->fast_io_fail_tmo == -1)
822 return snprintf(buf, 5, "off\n");
823 return snprintf(buf, 20, "%d\n", rport->fast_io_fail_tmo);
824}
825
826static ssize_t
827store_fc_rport_fast_io_fail_tmo(struct class_device *cdev, const char *buf,
828 size_t count)
829{
830 int val;
831 char *cp;
832 struct fc_rport *rport = transport_class_to_rport(cdev);
833
834 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
835 (rport->port_state == FC_PORTSTATE_DELETED) ||
836 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
837 return -EBUSY;
838 if (strncmp(buf, "off", 3) == 0)
839 rport->fast_io_fail_tmo = -1;
840 else {
841 val = simple_strtoul(buf, &cp, 0);
842 if ((*cp && (*cp != '\n')) ||
843 (val < 0) || (val >= rport->dev_loss_tmo))
844 return -EINVAL;
845 rport->fast_io_fail_tmo = val;
846 }
847 return count;
848}
849static FC_CLASS_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR,
850 show_fc_rport_fast_io_fail_tmo, store_fc_rport_fast_io_fail_tmo);
600 851
601 852
602/* 853/*
@@ -682,12 +933,34 @@ store_fc_host_##field(struct class_device *cdev, const char *buf, \
682 int val; \ 933 int val; \
683 struct Scsi_Host *shost = transport_class_to_shost(cdev); \ 934 struct Scsi_Host *shost = transport_class_to_shost(cdev); \
684 struct fc_internal *i = to_fc_internal(shost->transportt); \ 935 struct fc_internal *i = to_fc_internal(shost->transportt); \
936 char *cp; \
685 \ 937 \
686 val = simple_strtoul(buf, NULL, 0); \ 938 val = simple_strtoul(buf, &cp, 0); \
939 if (*cp && (*cp != '\n')) \
940 return -EINVAL; \
687 i->f->set_host_##field(shost, val); \ 941 i->f->set_host_##field(shost, val); \
688 return count; \ 942 return count; \
689} 943}
690 944
945#define fc_host_store_str_function(field, slen) \
946static ssize_t \
947store_fc_host_##field(struct class_device *cdev, const char *buf, \
948 size_t count) \
949{ \
950 struct Scsi_Host *shost = transport_class_to_shost(cdev); \
951 struct fc_internal *i = to_fc_internal(shost->transportt); \
952 unsigned int cnt=count; \
953 \
954 /* count may include a LF at end of string */ \
955 if (buf[cnt-1] == '\n') \
956 cnt--; \
957 if (cnt > ((slen) - 1)) \
958 return -EINVAL; \
959 memcpy(fc_host_##field(shost), buf, cnt); \
960 i->f->set_host_##field(shost); \
961 return count; \
962}
963
691#define fc_host_rd_attr(field, format_string, sz) \ 964#define fc_host_rd_attr(field, format_string, sz) \
692 fc_host_show_function(field, format_string, sz, ) \ 965 fc_host_show_function(field, format_string, sz, ) \
693static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \ 966static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO, \
@@ -815,7 +1088,6 @@ fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
815fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long); 1088fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
816fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20, 1089fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,
817 unsigned long long); 1090 unsigned long long);
818fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));
819fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20); 1091fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
820fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1)); 1092fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
821 1093
@@ -858,6 +1130,13 @@ fc_host_rd_attr(port_id, "0x%06x\n", 20);
858fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN); 1130fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN);
859fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN); 1131fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
860fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long); 1132fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long);
1133fc_host_rd_attr(symbolic_name, "%s\n", FC_SYMBOLIC_NAME_SIZE + 1);
1134
1135fc_private_host_show_function(system_hostname, "%s\n",
1136 FC_SYMBOLIC_NAME_SIZE + 1, )
1137fc_host_store_str_function(system_hostname, FC_SYMBOLIC_NAME_SIZE)
1138static FC_CLASS_DEVICE_ATTR(host, system_hostname, S_IRUGO | S_IWUSR,
1139 show_fc_host_system_hostname, store_fc_host_system_hostname);
861 1140
862 1141
863/* Private Host Attributes */ 1142/* Private Host Attributes */
@@ -1223,7 +1502,6 @@ fc_attach_transport(struct fc_function_template *ft)
1223 SETUP_HOST_ATTRIBUTE_RD(permanent_port_name); 1502 SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
1224 SETUP_HOST_ATTRIBUTE_RD(supported_classes); 1503 SETUP_HOST_ATTRIBUTE_RD(supported_classes);
1225 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s); 1504 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
1226 SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
1227 SETUP_HOST_ATTRIBUTE_RD(supported_speeds); 1505 SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
1228 SETUP_HOST_ATTRIBUTE_RD(maxframe_size); 1506 SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
1229 SETUP_HOST_ATTRIBUTE_RD(serial_number); 1507 SETUP_HOST_ATTRIBUTE_RD(serial_number);
@@ -1234,6 +1512,8 @@ fc_attach_transport(struct fc_function_template *ft)
1234 SETUP_HOST_ATTRIBUTE_RD(active_fc4s); 1512 SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
1235 SETUP_HOST_ATTRIBUTE_RD(speed); 1513 SETUP_HOST_ATTRIBUTE_RD(speed);
1236 SETUP_HOST_ATTRIBUTE_RD(fabric_name); 1514 SETUP_HOST_ATTRIBUTE_RD(fabric_name);
1515 SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
1516 SETUP_HOST_ATTRIBUTE_RW(system_hostname);
1237 1517
1238 /* Transport-managed attributes */ 1518 /* Transport-managed attributes */
1239 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type); 1519 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
@@ -1257,6 +1537,8 @@ fc_attach_transport(struct fc_function_template *ft)
1257 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles); 1537 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
1258 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state); 1538 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
1259 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id); 1539 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
1540 if (ft->terminate_rport_io)
1541 SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
1260 1542
1261 BUG_ON(count > FC_RPORT_NUM_ATTRS); 1543 BUG_ON(count > FC_RPORT_NUM_ATTRS);
1262 1544
@@ -1328,7 +1610,7 @@ fc_flush_work(struct Scsi_Host *shost)
1328 * @delay: jiffies to delay the work queuing 1610 * @delay: jiffies to delay the work queuing
1329 * 1611 *
1330 * Return value: 1612 * Return value:
1331 * 0 on success / != 0 for error 1613 * 1 on success / 0 already queued / < 0 for error
1332 **/ 1614 **/
1333static int 1615static int
1334fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work, 1616fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work,
@@ -1343,6 +1625,9 @@ fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work,
1343 return -EINVAL; 1625 return -EINVAL;
1344 } 1626 }
1345 1627
1628 if (delay == 0)
1629 return queue_work(fc_host_devloss_work_q(shost), work);
1630
1346 return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay); 1631 return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay);
1347} 1632}
1348 1633
@@ -1435,10 +1720,23 @@ fc_starget_delete(void *data)
1435 struct fc_rport *rport = (struct fc_rport *)data; 1720 struct fc_rport *rport = (struct fc_rport *)data;
1436 struct Scsi_Host *shost = rport_to_shost(rport); 1721 struct Scsi_Host *shost = rport_to_shost(rport);
1437 unsigned long flags; 1722 unsigned long flags;
1723 struct fc_internal *i = to_fc_internal(shost->transportt);
1724
1725 /*
1726 * Involve the LLDD if possible. All io on the rport is to
1727 * be terminated, either as part of the dev_loss_tmo callback
1728 * processing, or via the terminate_rport_io function.
1729 */
1730 if (i->f->dev_loss_tmo_callbk)
1731 i->f->dev_loss_tmo_callbk(rport);
1732 else if (i->f->terminate_rport_io)
1733 i->f->terminate_rport_io(rport);
1438 1734
1439 spin_lock_irqsave(shost->host_lock, flags); 1735 spin_lock_irqsave(shost->host_lock, flags);
1440 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { 1736 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
1441 spin_unlock_irqrestore(shost->host_lock, flags); 1737 spin_unlock_irqrestore(shost->host_lock, flags);
1738 if (!cancel_delayed_work(&rport->fail_io_work))
1739 fc_flush_devloss(shost);
1442 if (!cancel_delayed_work(&rport->dev_loss_work)) 1740 if (!cancel_delayed_work(&rport->dev_loss_work))
1443 fc_flush_devloss(shost); 1741 fc_flush_devloss(shost);
1444 spin_lock_irqsave(shost->host_lock, flags); 1742 spin_lock_irqsave(shost->host_lock, flags);
@@ -1461,10 +1759,7 @@ fc_rport_final_delete(void *data)
1461 struct fc_rport *rport = (struct fc_rport *)data; 1759 struct fc_rport *rport = (struct fc_rport *)data;
1462 struct device *dev = &rport->dev; 1760 struct device *dev = &rport->dev;
1463 struct Scsi_Host *shost = rport_to_shost(rport); 1761 struct Scsi_Host *shost = rport_to_shost(rport);
1464 1762 struct fc_internal *i = to_fc_internal(shost->transportt);
1465 /* Delete SCSI target and sdevs */
1466 if (rport->scsi_target_id != -1)
1467 fc_starget_delete(data);
1468 1763
1469 /* 1764 /*
1470 * if a scan is pending, flush the SCSI Host work_q so that 1765 * if a scan is pending, flush the SCSI Host work_q so that
@@ -1473,6 +1768,14 @@ fc_rport_final_delete(void *data)
1473 if (rport->flags & FC_RPORT_SCAN_PENDING) 1768 if (rport->flags & FC_RPORT_SCAN_PENDING)
1474 scsi_flush_work(shost); 1769 scsi_flush_work(shost);
1475 1770
1771 /* Delete SCSI target and sdevs */
1772 if (rport->scsi_target_id != -1)
1773 fc_starget_delete(data);
1774 else if (i->f->dev_loss_tmo_callbk)
1775 i->f->dev_loss_tmo_callbk(rport);
1776 else if (i->f->terminate_rport_io)
1777 i->f->terminate_rport_io(rport);
1778
1476 transport_remove_device(dev); 1779 transport_remove_device(dev);
1477 device_del(dev); 1780 device_del(dev);
1478 transport_destroy_device(dev); 1781 transport_destroy_device(dev);
@@ -1524,8 +1827,10 @@ fc_rport_create(struct Scsi_Host *shost, int channel,
1524 if (fci->f->dd_fcrport_size) 1827 if (fci->f->dd_fcrport_size)
1525 rport->dd_data = &rport[1]; 1828 rport->dd_data = &rport[1];
1526 rport->channel = channel; 1829 rport->channel = channel;
1830 rport->fast_io_fail_tmo = -1;
1527 1831
1528 INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport); 1832 INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport);
1833 INIT_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io, rport);
1529 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport); 1834 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport);
1530 INIT_WORK(&rport->stgt_delete_work, fc_starget_delete, rport); 1835 INIT_WORK(&rport->stgt_delete_work, fc_starget_delete, rport);
1531 INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete, rport); 1836 INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete, rport);
@@ -1689,11 +1994,13 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel,
1689 /* restart the target */ 1994 /* restart the target */
1690 1995
1691 /* 1996 /*
1692 * Stop the target timer first. Take no action 1997 * Stop the target timers first. Take no action
1693 * on the del_timer failure as the state 1998 * on the del_timer failure as the state
1694 * machine state change will validate the 1999 * machine state change will validate the
1695 * transaction. 2000 * transaction.
1696 */ 2001 */
2002 if (!cancel_delayed_work(&rport->fail_io_work))
2003 fc_flush_devloss(shost);
1697 if (!cancel_delayed_work(work)) 2004 if (!cancel_delayed_work(work))
1698 fc_flush_devloss(shost); 2005 fc_flush_devloss(shost);
1699 2006
@@ -1837,6 +2144,7 @@ void
1837fc_remote_port_delete(struct fc_rport *rport) 2144fc_remote_port_delete(struct fc_rport *rport)
1838{ 2145{
1839 struct Scsi_Host *shost = rport_to_shost(rport); 2146 struct Scsi_Host *shost = rport_to_shost(rport);
2147 struct fc_internal *i = to_fc_internal(shost->transportt);
1840 int timeout = rport->dev_loss_tmo; 2148 int timeout = rport->dev_loss_tmo;
1841 unsigned long flags; 2149 unsigned long flags;
1842 2150
@@ -1867,6 +2175,12 @@ fc_remote_port_delete(struct fc_rport *rport)
1867 2175
1868 scsi_target_block(&rport->dev); 2176 scsi_target_block(&rport->dev);
1869 2177
2178 /* see if we need to kill io faster than waiting for device loss */
2179 if ((rport->fast_io_fail_tmo != -1) &&
2180 (rport->fast_io_fail_tmo < timeout) && (i->f->terminate_rport_io))
2181 fc_queue_devloss_work(shost, &rport->fail_io_work,
2182 rport->fast_io_fail_tmo * HZ);
2183
1870 /* cap the length the devices can be blocked until they are deleted */ 2184 /* cap the length the devices can be blocked until they are deleted */
1871 fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ); 2185 fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ);
1872} 2186}
@@ -1926,6 +2240,8 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
1926 * machine state change will validate the 2240 * machine state change will validate the
1927 * transaction. 2241 * transaction.
1928 */ 2242 */
2243 if (!cancel_delayed_work(&rport->fail_io_work))
2244 fc_flush_devloss(shost);
1929 if (!cancel_delayed_work(&rport->dev_loss_work)) 2245 if (!cancel_delayed_work(&rport->dev_loss_work))
1930 fc_flush_devloss(shost); 2246 fc_flush_devloss(shost);
1931 2247
@@ -2047,6 +2363,28 @@ fc_timeout_deleted_rport(void *data)
2047} 2363}
2048 2364
2049/** 2365/**
2366 * fc_timeout_fail_rport_io - Timeout handler for a fast io failing on a
2367 * disconnected SCSI target.
2368 *
2369 * @data: rport to terminate io on.
2370 *
2371 * Notes: Only requests the failure of the io, not that all are flushed
2372 * prior to returning.
2373 **/
2374static void
2375fc_timeout_fail_rport_io(void *data)
2376{
2377 struct fc_rport *rport = (struct fc_rport *)data;
2378 struct Scsi_Host *shost = rport_to_shost(rport);
2379 struct fc_internal *i = to_fc_internal(shost->transportt);
2380
2381 if (rport->port_state != FC_PORTSTATE_BLOCKED)
2382 return;
2383
2384 i->f->terminate_rport_io(rport);
2385}
2386
2387/**
2050 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port. 2388 * fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
2051 * 2389 *
2052 * @data: remote port to be scanned. 2390 * @data: remote port to be scanned.