1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <linux/module.h>
29#include <linux/init.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32#include <linux/kernel.h>
33#include <scsi/scsi_device.h>
34#include <scsi/scsi_host.h>
35#include <scsi/scsi_transport.h>
36#include <scsi/scsi_transport_fc.h>
37#include <scsi/scsi_cmnd.h>
38#include <linux/netlink.h>
39#include <net/netlink.h>
40#include <scsi/scsi_netlink_fc.h>
41#include <scsi/scsi_bsg_fc.h>
42#include "scsi_priv.h"
43#include "scsi_transport_fc_internal.h"
44
45static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
46static void fc_vport_sched_delete(struct work_struct *work);
47static int fc_vport_setup(struct Scsi_Host *shost, int channel,
48 struct device *pdev, struct fc_vport_identifiers *ids,
49 struct fc_vport **vport);
50static int fc_bsg_hostadd(struct Scsi_Host *, struct fc_host_attrs *);
51static int fc_bsg_rportadd(struct Scsi_Host *, struct fc_rport *);
52static void fc_bsg_remove(struct request_queue *);
53static void fc_bsg_goose_queue(struct fc_rport *);
54
55
56
57
58
59
60
61
62
63
64static unsigned int fc_dev_loss_tmo = 60;
65
66module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR);
67MODULE_PARM_DESC(dev_loss_tmo,
68 "Maximum number of seconds that the FC transport should"
69 " insulate the loss of a remote port. Once this value is"
70 " exceeded, the scsi target is removed. Value should be"
71 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
72 " fast_io_fail_tmo is not set.");
73
74
75
76
77
78#define FC_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
79struct device_attribute device_attr_##_prefix##_##_name = \
80 __ATTR(_name,_mode,_show,_store)
81
82#define fc_enum_name_search(title, table_type, table) \
83static const char *get_fc_##title##_name(enum table_type table_key) \
84{ \
85 int i; \
86 char *name = NULL; \
87 \
88 for (i = 0; i < ARRAY_SIZE(table); i++) { \
89 if (table[i].value == table_key) { \
90 name = table[i].name; \
91 break; \
92 } \
93 } \
94 return name; \
95}
96
97#define fc_enum_name_match(title, table_type, table) \
98static int get_fc_##title##_match(const char *table_key, \
99 enum table_type *value) \
100{ \
101 int i; \
102 \
103 for (i = 0; i < ARRAY_SIZE(table); i++) { \
104 if (strncmp(table_key, table[i].name, \
105 table[i].matchlen) == 0) { \
106 *value = table[i].value; \
107 return 0; \
108 } \
109 } \
110 return 1; \
111}
112
113
114
115static struct {
116 enum fc_port_type value;
117 char *name;
118} fc_port_type_names[] = {
119 { FC_PORTTYPE_UNKNOWN, "Unknown" },
120 { FC_PORTTYPE_OTHER, "Other" },
121 { FC_PORTTYPE_NOTPRESENT, "Not Present" },
122 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" },
123 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" },
124 { FC_PORTTYPE_LPORT, "LPort (private loop)" },
125 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection)" },
126 { FC_PORTTYPE_NPIV, "NPIV VPORT" },
127};
128fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
129#define FC_PORTTYPE_MAX_NAMELEN 50
130
131
132#define get_fc_vport_type_name get_fc_port_type_name
133
134
135
136static const struct {
137 enum fc_host_event_code value;
138 char *name;
139} fc_host_event_code_names[] = {
140 { FCH_EVT_LIP, "lip" },
141 { FCH_EVT_LINKUP, "link_up" },
142 { FCH_EVT_LINKDOWN, "link_down" },
143 { FCH_EVT_LIPRESET, "lip_reset" },
144 { FCH_EVT_RSCN, "rscn" },
145 { FCH_EVT_ADAPTER_CHANGE, "adapter_chg" },
146 { FCH_EVT_PORT_UNKNOWN, "port_unknown" },
147 { FCH_EVT_PORT_ONLINE, "port_online" },
148 { FCH_EVT_PORT_OFFLINE, "port_offline" },
149 { FCH_EVT_PORT_FABRIC, "port_fabric" },
150 { FCH_EVT_LINK_UNKNOWN, "link_unknown" },
151 { FCH_EVT_VENDOR_UNIQUE, "vendor_unique" },
152};
153fc_enum_name_search(host_event_code, fc_host_event_code,
154 fc_host_event_code_names)
155#define FC_HOST_EVENT_CODE_MAX_NAMELEN 30
156
157
158
159static struct {
160 enum fc_port_state value;
161 char *name;
162} fc_port_state_names[] = {
163 { FC_PORTSTATE_UNKNOWN, "Unknown" },
164 { FC_PORTSTATE_NOTPRESENT, "Not Present" },
165 { FC_PORTSTATE_ONLINE, "Online" },
166 { FC_PORTSTATE_OFFLINE, "Offline" },
167 { FC_PORTSTATE_BLOCKED, "Blocked" },
168 { FC_PORTSTATE_BYPASSED, "Bypassed" },
169 { FC_PORTSTATE_DIAGNOSTICS, "Diagnostics" },
170 { FC_PORTSTATE_LINKDOWN, "Linkdown" },
171 { FC_PORTSTATE_ERROR, "Error" },
172 { FC_PORTSTATE_LOOPBACK, "Loopback" },
173 { FC_PORTSTATE_DELETED, "Deleted" },
174};
175fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
176#define FC_PORTSTATE_MAX_NAMELEN 20
177
178
179
180static struct {
181 enum fc_vport_state value;
182 char *name;
183} fc_vport_state_names[] = {
184 { FC_VPORT_UNKNOWN, "Unknown" },
185 { FC_VPORT_ACTIVE, "Active" },
186 { FC_VPORT_DISABLED, "Disabled" },
187 { FC_VPORT_LINKDOWN, "Linkdown" },
188 { FC_VPORT_INITIALIZING, "Initializing" },
189 { FC_VPORT_NO_FABRIC_SUPP, "No Fabric Support" },
190 { FC_VPORT_NO_FABRIC_RSCS, "No Fabric Resources" },
191 { FC_VPORT_FABRIC_LOGOUT, "Fabric Logout" },
192 { FC_VPORT_FABRIC_REJ_WWN, "Fabric Rejected WWN" },
193 { FC_VPORT_FAILED, "VPort Failed" },
194};
195fc_enum_name_search(vport_state, fc_vport_state, fc_vport_state_names)
196#define FC_VPORTSTATE_MAX_NAMELEN 24
197
198
199#define get_fc_vport_last_state_name get_fc_vport_state_name
200
201
202
203static const struct {
204 enum fc_tgtid_binding_type value;
205 char *name;
206 int matchlen;
207} fc_tgtid_binding_type_names[] = {
208 { FC_TGTID_BIND_NONE, "none", 4 },
209 { FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 },
210 { FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 },
211 { FC_TGTID_BIND_BY_ID, "port_id (FC Address)", 7 },
212};
213fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type,
214 fc_tgtid_binding_type_names)
215fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type,
216 fc_tgtid_binding_type_names)
217#define FC_BINDTYPE_MAX_NAMELEN 30
218
219
220#define fc_bitfield_name_search(title, table) \
221static ssize_t \
222get_fc_##title##_names(u32 table_key, char *buf) \
223{ \
224 char *prefix = ""; \
225 ssize_t len = 0; \
226 int i; \
227 \
228 for (i = 0; i < ARRAY_SIZE(table); i++) { \
229 if (table[i].value & table_key) { \
230 len += sprintf(buf + len, "%s%s", \
231 prefix, table[i].name); \
232 prefix = ", "; \
233 } \
234 } \
235 len += sprintf(buf + len, "\n"); \
236 return len; \
237}
238
239
240
241static const struct {
242 u32 value;
243 char *name;
244} fc_cos_names[] = {
245 { FC_COS_CLASS1, "Class 1" },
246 { FC_COS_CLASS2, "Class 2" },
247 { FC_COS_CLASS3, "Class 3" },
248 { FC_COS_CLASS4, "Class 4" },
249 { FC_COS_CLASS6, "Class 6" },
250};
251fc_bitfield_name_search(cos, fc_cos_names)
252
253
254
255static const struct {
256 u32 value;
257 char *name;
258} fc_port_speed_names[] = {
259 { FC_PORTSPEED_1GBIT, "1 Gbit" },
260 { FC_PORTSPEED_2GBIT, "2 Gbit" },
261 { FC_PORTSPEED_4GBIT, "4 Gbit" },
262 { FC_PORTSPEED_10GBIT, "10 Gbit" },
263 { FC_PORTSPEED_8GBIT, "8 Gbit" },
264 { FC_PORTSPEED_16GBIT, "16 Gbit" },
265 { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" },
266};
267fc_bitfield_name_search(port_speed, fc_port_speed_names)
268
269
270static int
271show_fc_fc4s (char *buf, u8 *fc4_list)
272{
273 int i, len=0;
274
275 for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++)
276 len += sprintf(buf + len , "0x%02x ", *fc4_list);
277 len += sprintf(buf + len, "\n");
278 return len;
279}
280
281
282
283static const struct {
284 u32 value;
285 char *name;
286} fc_port_role_names[] = {
287 { FC_PORT_ROLE_FCP_TARGET, "FCP Target" },
288 { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" },
289 { FC_PORT_ROLE_IP_PORT, "IP Port" },
290};
291fc_bitfield_name_search(port_roles, fc_port_role_names)
292
293
294
295
296#define FC_WELLKNOWN_PORTID_MASK 0xfffff0
297#define FC_WELLKNOWN_ROLE_MASK 0x00000f
298#define FC_FPORT_PORTID 0x00000e
299#define FC_FABCTLR_PORTID 0x00000d
300#define FC_DIRSRVR_PORTID 0x00000c
301#define FC_TIMESRVR_PORTID 0x00000b
302#define FC_MGMTSRVR_PORTID 0x00000a
303
304
305static void fc_timeout_deleted_rport(struct work_struct *work);
306static void fc_timeout_fail_rport_io(struct work_struct *work);
307static void fc_scsi_scan_rport(struct work_struct *work);
308
309
310
311
312
313#define FC_STARGET_NUM_ATTRS 3
314#define FC_RPORT_NUM_ATTRS 10
315#define FC_VPORT_NUM_ATTRS 9
316#define FC_HOST_NUM_ATTRS 22
317
318struct fc_internal {
319 struct scsi_transport_template t;
320 struct fc_function_template *f;
321
322
323
324
325
326
327
328
329
330
331
332 struct device_attribute private_starget_attrs[
333 FC_STARGET_NUM_ATTRS];
334 struct device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1];
335
336 struct device_attribute private_host_attrs[FC_HOST_NUM_ATTRS];
337 struct device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1];
338
339 struct transport_container rport_attr_cont;
340 struct device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS];
341 struct device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1];
342
343 struct transport_container vport_attr_cont;
344 struct device_attribute private_vport_attrs[FC_VPORT_NUM_ATTRS];
345 struct device_attribute *vport_attrs[FC_VPORT_NUM_ATTRS + 1];
346};
347
348#define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t)
349
350static int fc_target_setup(struct transport_container *tc, struct device *dev,
351 struct device *cdev)
352{
353 struct scsi_target *starget = to_scsi_target(dev);
354 struct fc_rport *rport = starget_to_rport(starget);
355
356
357
358
359
360
361 if (rport) {
362 fc_starget_node_name(starget) = rport->node_name;
363 fc_starget_port_name(starget) = rport->port_name;
364 fc_starget_port_id(starget) = rport->port_id;
365 } else {
366 fc_starget_node_name(starget) = -1;
367 fc_starget_port_name(starget) = -1;
368 fc_starget_port_id(starget) = -1;
369 }
370
371 return 0;
372}
373
374static DECLARE_TRANSPORT_CLASS(fc_transport_class,
375 "fc_transport",
376 fc_target_setup,
377 NULL,
378 NULL);
379
380static int fc_host_setup(struct transport_container *tc, struct device *dev,
381 struct device *cdev)
382{
383 struct Scsi_Host *shost = dev_to_shost(dev);
384 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
385
386
387
388
389
390
391 fc_host->node_name = -1;
392 fc_host->port_name = -1;
393 fc_host->permanent_port_name = -1;
394 fc_host->supported_classes = FC_COS_UNSPECIFIED;
395 memset(fc_host->supported_fc4s, 0,
396 sizeof(fc_host->supported_fc4s));
397 fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN;
398 fc_host->maxframe_size = -1;
399 fc_host->max_npiv_vports = 0;
400 memset(fc_host->serial_number, 0,
401 sizeof(fc_host->serial_number));
402
403 fc_host->port_id = -1;
404 fc_host->port_type = FC_PORTTYPE_UNKNOWN;
405 fc_host->port_state = FC_PORTSTATE_UNKNOWN;
406 memset(fc_host->active_fc4s, 0,
407 sizeof(fc_host->active_fc4s));
408 fc_host->speed = FC_PORTSPEED_UNKNOWN;
409 fc_host->fabric_name = -1;
410 memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name));
411 memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname));
412
413 fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN;
414
415 INIT_LIST_HEAD(&fc_host->rports);
416 INIT_LIST_HEAD(&fc_host->rport_bindings);
417 INIT_LIST_HEAD(&fc_host->vports);
418 fc_host->next_rport_number = 0;
419 fc_host->next_target_id = 0;
420 fc_host->next_vport_number = 0;
421 fc_host->npiv_vports_inuse = 0;
422
423 snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
424 "fc_wq_%d", shost->host_no);
425 fc_host->work_q = create_singlethread_workqueue(
426 fc_host->work_q_name);
427 if (!fc_host->work_q)
428 return -ENOMEM;
429
430 fc_host->dev_loss_tmo = fc_dev_loss_tmo;
431 snprintf(fc_host->devloss_work_q_name,
432 sizeof(fc_host->devloss_work_q_name),
433 "fc_dl_%d", shost->host_no);
434 fc_host->devloss_work_q = create_singlethread_workqueue(
435 fc_host->devloss_work_q_name);
436 if (!fc_host->devloss_work_q) {
437 destroy_workqueue(fc_host->work_q);
438 fc_host->work_q = NULL;
439 return -ENOMEM;
440 }
441
442 fc_bsg_hostadd(shost, fc_host);
443
444
445 return 0;
446}
447
448static int fc_host_remove(struct transport_container *tc, struct device *dev,
449 struct device *cdev)
450{
451 struct Scsi_Host *shost = dev_to_shost(dev);
452 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
453
454 fc_bsg_remove(fc_host->rqst_q);
455 return 0;
456}
457
458static DECLARE_TRANSPORT_CLASS(fc_host_class,
459 "fc_host",
460 fc_host_setup,
461 fc_host_remove,
462 NULL);
463
464
465
466
467
468static DECLARE_TRANSPORT_CLASS(fc_rport_class,
469 "fc_remote_ports",
470 NULL,
471 NULL,
472 NULL);
473
474
475
476
477
478static DECLARE_TRANSPORT_CLASS(fc_vport_class,
479 "fc_vports",
480 NULL,
481 NULL,
482 NULL);
483
484
485
486
487
488static atomic_t fc_event_seq;
489
490
491
492
493
494
495
496
497
498u32
499fc_get_event_number(void)
500{
501 return atomic_add_return(1, &fc_event_seq);
502}
503EXPORT_SYMBOL(fc_get_event_number);
504
505
506
507
508
509
510
511
512
513
514
515
516void
517fc_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);
555 event->event_num = event_number;
556 event->event_code = event_code;
557 event->event_data = event_data;
558
559 nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
560 GFP_KERNEL);
561 return;
562
563send_fail_skb:
564 kfree_skb(skb);
565send_fail:
566 name = get_fc_host_event_code_name(event_code);
567 printk(KERN_WARNING
568 "%s: Dropped Event : host %d %s data 0x%08x - err %d\n",
569 __func__, shost->host_no,
570 (name) ? name : "<unknown>", event_data, err);
571 return;
572}
573EXPORT_SYMBOL(fc_host_post_event);
574
575
576
577
578
579
580
581
582
583
584
585
586
587void
588fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
589 u32 data_len, char * data_buf, u64 vendor_id)
590{
591 struct sk_buff *skb;
592 struct nlmsghdr *nlh;
593 struct fc_nl_event *event;
594 u32 len, skblen;
595 int err;
596
597 if (!scsi_nl_sock) {
598 err = -ENOENT;
599 goto send_vendor_fail;
600 }
601
602 len = FC_NL_MSGALIGN(sizeof(*event) + data_len);
603 skblen = NLMSG_SPACE(len);
604
605 skb = alloc_skb(skblen, GFP_KERNEL);
606 if (!skb) {
607 err = -ENOBUFS;
608 goto send_vendor_fail;
609 }
610
611 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG,
612 skblen - sizeof(*nlh), 0);
613 if (!nlh) {
614 err = -ENOBUFS;
615 goto send_vendor_fail_skb;
616 }
617 event = NLMSG_DATA(nlh);
618
619 INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
620 FC_NL_ASYNC_EVENT, len);
621 event->seconds = get_seconds();
622 event->vendor_id = vendor_id;
623 event->host_no = shost->host_no;
624 event->event_datalen = data_len;
625 event->event_num = event_number;
626 event->event_code = FCH_EVT_VENDOR_UNIQUE;
627 memcpy(&event->event_data, data_buf, data_len);
628
629 nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
630 GFP_KERNEL);
631 return;
632
633send_vendor_fail_skb:
634 kfree_skb(skb);
635send_vendor_fail:
636 printk(KERN_WARNING
637 "%s: Dropped Event : host %d vendor_unique - err %d\n",
638 __func__, shost->host_no, err);
639 return;
640}
641EXPORT_SYMBOL(fc_host_post_vendor_event);
642
643
644
645static __init int fc_transport_init(void)
646{
647 int error;
648
649 atomic_set(&fc_event_seq, 0);
650
651 error = transport_class_register(&fc_host_class);
652 if (error)
653 return error;
654 error = transport_class_register(&fc_vport_class);
655 if (error)
656 goto unreg_host_class;
657 error = transport_class_register(&fc_rport_class);
658 if (error)
659 goto unreg_vport_class;
660 error = transport_class_register(&fc_transport_class);
661 if (error)
662 goto unreg_rport_class;
663 return 0;
664
665unreg_rport_class:
666 transport_class_unregister(&fc_rport_class);
667unreg_vport_class:
668 transport_class_unregister(&fc_vport_class);
669unreg_host_class:
670 transport_class_unregister(&fc_host_class);
671 return error;
672}
673
674static void __exit fc_transport_exit(void)
675{
676 transport_class_unregister(&fc_transport_class);
677 transport_class_unregister(&fc_rport_class);
678 transport_class_unregister(&fc_host_class);
679 transport_class_unregister(&fc_vport_class);
680}
681
682
683
684
685
686#define fc_rport_show_function(field, format_string, sz, cast) \
687static ssize_t \
688show_fc_rport_##field (struct device *dev, \
689 struct device_attribute *attr, char *buf) \
690{ \
691 struct fc_rport *rport = transport_class_to_rport(dev); \
692 struct Scsi_Host *shost = rport_to_shost(rport); \
693 struct fc_internal *i = to_fc_internal(shost->transportt); \
694 if ((i->f->get_rport_##field) && \
695 !((rport->port_state == FC_PORTSTATE_BLOCKED) || \
696 (rport->port_state == FC_PORTSTATE_DELETED) || \
697 (rport->port_state == FC_PORTSTATE_NOTPRESENT))) \
698 i->f->get_rport_##field(rport); \
699 return snprintf(buf, sz, format_string, cast rport->field); \
700}
701
702#define fc_rport_store_function(field) \
703static ssize_t \
704store_fc_rport_##field(struct device *dev, \
705 struct device_attribute *attr, \
706 const char *buf, size_t count) \
707{ \
708 int val; \
709 struct fc_rport *rport = transport_class_to_rport(dev); \
710 struct Scsi_Host *shost = rport_to_shost(rport); \
711 struct fc_internal *i = to_fc_internal(shost->transportt); \
712 char *cp; \
713 if ((rport->port_state == FC_PORTSTATE_BLOCKED) || \
714 (rport->port_state == FC_PORTSTATE_DELETED) || \
715 (rport->port_state == FC_PORTSTATE_NOTPRESENT)) \
716 return -EBUSY; \
717 val = simple_strtoul(buf, &cp, 0); \
718 if (*cp && (*cp != '\n')) \
719 return -EINVAL; \
720 i->f->set_rport_##field(rport, val); \
721 return count; \
722}
723
724#define fc_rport_rd_attr(field, format_string, sz) \
725 fc_rport_show_function(field, format_string, sz, ) \
726static FC_DEVICE_ATTR(rport, field, S_IRUGO, \
727 show_fc_rport_##field, NULL)
728
729#define fc_rport_rd_attr_cast(field, format_string, sz, cast) \
730 fc_rport_show_function(field, format_string, sz, (cast)) \
731static FC_DEVICE_ATTR(rport, field, S_IRUGO, \
732 show_fc_rport_##field, NULL)
733
734#define fc_rport_rw_attr(field, format_string, sz) \
735 fc_rport_show_function(field, format_string, sz, ) \
736 fc_rport_store_function(field) \
737static FC_DEVICE_ATTR(rport, field, S_IRUGO | S_IWUSR, \
738 show_fc_rport_##field, \
739 store_fc_rport_##field)
740
741
742#define fc_private_rport_show_function(field, format_string, sz, cast) \
743static ssize_t \
744show_fc_rport_##field (struct device *dev, \
745 struct device_attribute *attr, char *buf) \
746{ \
747 struct fc_rport *rport = transport_class_to_rport(dev); \
748 return snprintf(buf, sz, format_string, cast rport->field); \
749}
750
751#define fc_private_rport_rd_attr(field, format_string, sz) \
752 fc_private_rport_show_function(field, format_string, sz, ) \
753static FC_DEVICE_ATTR(rport, field, S_IRUGO, \
754 show_fc_rport_##field, NULL)
755
756#define fc_private_rport_rd_attr_cast(field, format_string, sz, cast) \
757 fc_private_rport_show_function(field, format_string, sz, (cast)) \
758static FC_DEVICE_ATTR(rport, field, S_IRUGO, \
759 show_fc_rport_##field, NULL)
760
761
762#define fc_private_rport_rd_enum_attr(title, maxlen) \
763static ssize_t \
764show_fc_rport_##title (struct device *dev, \
765 struct device_attribute *attr, char *buf) \
766{ \
767 struct fc_rport *rport = transport_class_to_rport(dev); \
768 const char *name; \
769 name = get_fc_##title##_name(rport->title); \
770 if (!name) \
771 return -EINVAL; \
772 return snprintf(buf, maxlen, "%s\n", name); \
773} \
774static FC_DEVICE_ATTR(rport, title, S_IRUGO, \
775 show_fc_rport_##title, NULL)
776
777
778#define SETUP_RPORT_ATTRIBUTE_RD(field) \
779 i->private_rport_attrs[count] = device_attr_rport_##field; \
780 i->private_rport_attrs[count].attr.mode = S_IRUGO; \
781 i->private_rport_attrs[count].store = NULL; \
782 i->rport_attrs[count] = &i->private_rport_attrs[count]; \
783 if (i->f->show_rport_##field) \
784 count++
785
786#define SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(field) \
787 i->private_rport_attrs[count] = device_attr_rport_##field; \
788 i->private_rport_attrs[count].attr.mode = S_IRUGO; \
789 i->private_rport_attrs[count].store = NULL; \
790 i->rport_attrs[count] = &i->private_rport_attrs[count]; \
791 count++
792
793#define SETUP_RPORT_ATTRIBUTE_RW(field) \
794 i->private_rport_attrs[count] = device_attr_rport_##field; \
795 if (!i->f->set_rport_##field) { \
796 i->private_rport_attrs[count].attr.mode = S_IRUGO; \
797 i->private_rport_attrs[count].store = NULL; \
798 } \
799 i->rport_attrs[count] = &i->private_rport_attrs[count]; \
800 if (i->f->show_rport_##field) \
801 count++
802
803#define SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(field) \
804{ \
805 i->private_rport_attrs[count] = device_attr_rport_##field; \
806 i->rport_attrs[count] = &i->private_rport_attrs[count]; \
807 count++; \
808}
809
810
811
812
813
814
815fc_private_rport_rd_attr(maxframe_size, "%u bytes\n", 20);
816
817static ssize_t
818show_fc_rport_supported_classes (struct device *dev,
819 struct device_attribute *attr, char *buf)
820{
821 struct fc_rport *rport = transport_class_to_rport(dev);
822 if (rport->supported_classes == FC_COS_UNSPECIFIED)
823 return snprintf(buf, 20, "unspecified\n");
824 return get_fc_cos_names(rport->supported_classes, buf);
825}
826static FC_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
827 show_fc_rport_supported_classes, NULL);
828
829
830
831
832
833
834static int fc_str_to_dev_loss(const char *buf, unsigned long *val)
835{
836 char *cp;
837
838 *val = simple_strtoul(buf, &cp, 0);
839 if ((*cp && (*cp != '\n')) || (*val < 0))
840 return -EINVAL;
841
842
843
844 if (*val > UINT_MAX)
845 return -EINVAL;
846
847 return 0;
848}
849
850static int fc_rport_set_dev_loss_tmo(struct fc_rport *rport,
851 unsigned long val)
852{
853 struct Scsi_Host *shost = rport_to_shost(rport);
854 struct fc_internal *i = to_fc_internal(shost->transportt);
855
856 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
857 (rport->port_state == FC_PORTSTATE_DELETED) ||
858 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
859 return -EBUSY;
860
861
862
863 if (val > UINT_MAX)
864 return -EINVAL;
865
866
867
868
869
870 if (rport->fast_io_fail_tmo == -1 &&
871 val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT)
872 return -EINVAL;
873
874 i->f->set_rport_dev_loss_tmo(rport, val);
875 return 0;
876}
877
878fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
879static ssize_t
880store_fc_rport_dev_loss_tmo(struct device *dev, struct device_attribute *attr,
881 const char *buf, size_t count)
882{
883 struct fc_rport *rport = transport_class_to_rport(dev);
884 unsigned long val;
885 int rc;
886
887 rc = fc_str_to_dev_loss(buf, &val);
888 if (rc)
889 return rc;
890
891 rc = fc_rport_set_dev_loss_tmo(rport, val);
892 if (rc)
893 return rc;
894 return count;
895}
896static FC_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
897 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo);
898
899
900
901
902fc_private_rport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
903fc_private_rport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
904fc_private_rport_rd_attr(port_id, "0x%06x\n", 20);
905
906static ssize_t
907show_fc_rport_roles (struct device *dev, struct device_attribute *attr,
908 char *buf)
909{
910 struct fc_rport *rport = transport_class_to_rport(dev);
911
912
913 if ((rport->port_id != -1) &&
914 (rport->port_id & FC_WELLKNOWN_PORTID_MASK) ==
915 FC_WELLKNOWN_PORTID_MASK) {
916 switch (rport->port_id & FC_WELLKNOWN_ROLE_MASK) {
917 case FC_FPORT_PORTID:
918 return snprintf(buf, 30, "Fabric Port\n");
919 case FC_FABCTLR_PORTID:
920 return snprintf(buf, 30, "Fabric Controller\n");
921 case FC_DIRSRVR_PORTID:
922 return snprintf(buf, 30, "Directory Server\n");
923 case FC_TIMESRVR_PORTID:
924 return snprintf(buf, 30, "Time Server\n");
925 case FC_MGMTSRVR_PORTID:
926 return snprintf(buf, 30, "Management Server\n");
927 default:
928 return snprintf(buf, 30, "Unknown Fabric Entity\n");
929 }
930 } else {
931 if (rport->roles == FC_PORT_ROLE_UNKNOWN)
932 return snprintf(buf, 20, "unknown\n");
933 return get_fc_port_roles_names(rport->roles, buf);
934 }
935}
936static FC_DEVICE_ATTR(rport, roles, S_IRUGO,
937 show_fc_rport_roles, NULL);
938
939fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
940fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20);
941
942
943
944
945static ssize_t
946show_fc_rport_fast_io_fail_tmo (struct device *dev,
947 struct device_attribute *attr, char *buf)
948{
949 struct fc_rport *rport = transport_class_to_rport(dev);
950
951 if (rport->fast_io_fail_tmo == -1)
952 return snprintf(buf, 5, "off\n");
953 return snprintf(buf, 20, "%d\n", rport->fast_io_fail_tmo);
954}
955
956static ssize_t
957store_fc_rport_fast_io_fail_tmo(struct device *dev,
958 struct device_attribute *attr, const char *buf,
959 size_t count)
960{
961 int val;
962 char *cp;
963 struct fc_rport *rport = transport_class_to_rport(dev);
964
965 if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
966 (rport->port_state == FC_PORTSTATE_DELETED) ||
967 (rport->port_state == FC_PORTSTATE_NOTPRESENT))
968 return -EBUSY;
969 if (strncmp(buf, "off", 3) == 0)
970 rport->fast_io_fail_tmo = -1;
971 else {
972 val = simple_strtoul(buf, &cp, 0);
973 if ((*cp && (*cp != '\n')) || (val < 0))
974 return -EINVAL;
975
976
977
978
979 if ((val >= rport->dev_loss_tmo) ||
980 (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
981 return -EINVAL;
982
983 rport->fast_io_fail_tmo = val;
984 }
985 return count;
986}
987static FC_DEVICE_ATTR(rport, fast_io_fail_tmo, S_IRUGO | S_IWUSR,
988 show_fc_rport_fast_io_fail_tmo, store_fc_rport_fast_io_fail_tmo);
989
990
991
992
993
994
995
996
997
998
999
1000
1001#define fc_starget_show_function(field, format_string, sz, cast) \
1002static ssize_t \
1003show_fc_starget_##field (struct device *dev, \
1004 struct device_attribute *attr, char *buf) \
1005{ \
1006 struct scsi_target *starget = transport_class_to_starget(dev); \
1007 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \
1008 struct fc_internal *i = to_fc_internal(shost->transportt); \
1009 struct fc_rport *rport = starget_to_rport(starget); \
1010 if (rport) \
1011 fc_starget_##field(starget) = rport->field; \
1012 else if (i->f->get_starget_##field) \
1013 i->f->get_starget_##field(starget); \
1014 return snprintf(buf, sz, format_string, \
1015 cast fc_starget_##field(starget)); \
1016}
1017
1018#define fc_starget_rd_attr(field, format_string, sz) \
1019 fc_starget_show_function(field, format_string, sz, ) \
1020static FC_DEVICE_ATTR(starget, field, S_IRUGO, \
1021 show_fc_starget_##field, NULL)
1022
1023#define fc_starget_rd_attr_cast(field, format_string, sz, cast) \
1024 fc_starget_show_function(field, format_string, sz, (cast)) \
1025static FC_DEVICE_ATTR(starget, field, S_IRUGO, \
1026 show_fc_starget_##field, NULL)
1027
1028#define SETUP_STARGET_ATTRIBUTE_RD(field) \
1029 i->private_starget_attrs[count] = device_attr_starget_##field; \
1030 i->private_starget_attrs[count].attr.mode = S_IRUGO; \
1031 i->private_starget_attrs[count].store = NULL; \
1032 i->starget_attrs[count] = &i->private_starget_attrs[count]; \
1033 if (i->f->show_starget_##field) \
1034 count++
1035
1036#define SETUP_STARGET_ATTRIBUTE_RW(field) \
1037 i->private_starget_attrs[count] = device_attr_starget_##field; \
1038 if (!i->f->set_starget_##field) { \
1039 i->private_starget_attrs[count].attr.mode = S_IRUGO; \
1040 i->private_starget_attrs[count].store = NULL; \
1041 } \
1042 i->starget_attrs[count] = &i->private_starget_attrs[count]; \
1043 if (i->f->show_starget_##field) \
1044 count++
1045
1046
1047fc_starget_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
1048fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
1049fc_starget_rd_attr(port_id, "0x%06x\n", 20);
1050
1051
1052
1053
1054
1055
1056#define fc_vport_show_function(field, format_string, sz, cast) \
1057static ssize_t \
1058show_fc_vport_##field (struct device *dev, \
1059 struct device_attribute *attr, char *buf) \
1060{ \
1061 struct fc_vport *vport = transport_class_to_vport(dev); \
1062 struct Scsi_Host *shost = vport_to_shost(vport); \
1063 struct fc_internal *i = to_fc_internal(shost->transportt); \
1064 if ((i->f->get_vport_##field) && \
1065 !(vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))) \
1066 i->f->get_vport_##field(vport); \
1067 return snprintf(buf, sz, format_string, cast vport->field); \
1068}
1069
1070#define fc_vport_store_function(field) \
1071static ssize_t \
1072store_fc_vport_##field(struct device *dev, \
1073 struct device_attribute *attr, \
1074 const char *buf, size_t count) \
1075{ \
1076 int val; \
1077 struct fc_vport *vport = transport_class_to_vport(dev); \
1078 struct Scsi_Host *shost = vport_to_shost(vport); \
1079 struct fc_internal *i = to_fc_internal(shost->transportt); \
1080 char *cp; \
1081 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) \
1082 return -EBUSY; \
1083 val = simple_strtoul(buf, &cp, 0); \
1084 if (*cp && (*cp != '\n')) \
1085 return -EINVAL; \
1086 i->f->set_vport_##field(vport, val); \
1087 return count; \
1088}
1089
1090#define fc_vport_store_str_function(field, slen) \
1091static ssize_t \
1092store_fc_vport_##field(struct device *dev, \
1093 struct device_attribute *attr, \
1094 const char *buf, size_t count) \
1095{ \
1096 struct fc_vport *vport = transport_class_to_vport(dev); \
1097 struct Scsi_Host *shost = vport_to_shost(vport); \
1098 struct fc_internal *i = to_fc_internal(shost->transportt); \
1099 unsigned int cnt=count; \
1100 \
1101 \
1102 if (buf[cnt-1] == '\n') \
1103 cnt--; \
1104 if (cnt > ((slen) - 1)) \
1105 return -EINVAL; \
1106 memcpy(vport->field, buf, cnt); \
1107 i->f->set_vport_##field(vport); \
1108 return count; \
1109}
1110
1111#define fc_vport_rd_attr(field, format_string, sz) \
1112 fc_vport_show_function(field, format_string, sz, ) \
1113static FC_DEVICE_ATTR(vport, field, S_IRUGO, \
1114 show_fc_vport_##field, NULL)
1115
1116#define fc_vport_rd_attr_cast(field, format_string, sz, cast) \
1117 fc_vport_show_function(field, format_string, sz, (cast)) \
1118static FC_DEVICE_ATTR(vport, field, S_IRUGO, \
1119 show_fc_vport_##field, NULL)
1120
1121#define fc_vport_rw_attr(field, format_string, sz) \
1122 fc_vport_show_function(field, format_string, sz, ) \
1123 fc_vport_store_function(field) \
1124static FC_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR, \
1125 show_fc_vport_##field, \
1126 store_fc_vport_##field)
1127
1128#define fc_private_vport_show_function(field, format_string, sz, cast) \
1129static ssize_t \
1130show_fc_vport_##field (struct device *dev, \
1131 struct device_attribute *attr, char *buf) \
1132{ \
1133 struct fc_vport *vport = transport_class_to_vport(dev); \
1134 return snprintf(buf, sz, format_string, cast vport->field); \
1135}
1136
1137#define fc_private_vport_store_u32_function(field) \
1138static ssize_t \
1139store_fc_vport_##field(struct device *dev, \
1140 struct device_attribute *attr, \
1141 const char *buf, size_t count) \
1142{ \
1143 u32 val; \
1144 struct fc_vport *vport = transport_class_to_vport(dev); \
1145 char *cp; \
1146 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) \
1147 return -EBUSY; \
1148 val = simple_strtoul(buf, &cp, 0); \
1149 if (*cp && (*cp != '\n')) \
1150 return -EINVAL; \
1151 vport->field = val; \
1152 return count; \
1153}
1154
1155
1156#define fc_private_vport_rd_attr(field, format_string, sz) \
1157 fc_private_vport_show_function(field, format_string, sz, ) \
1158static FC_DEVICE_ATTR(vport, field, S_IRUGO, \
1159 show_fc_vport_##field, NULL)
1160
1161#define fc_private_vport_rd_attr_cast(field, format_string, sz, cast) \
1162 fc_private_vport_show_function(field, format_string, sz, (cast)) \
1163static FC_DEVICE_ATTR(vport, field, S_IRUGO, \
1164 show_fc_vport_##field, NULL)
1165
1166#define fc_private_vport_rw_u32_attr(field, format_string, sz) \
1167 fc_private_vport_show_function(field, format_string, sz, ) \
1168 fc_private_vport_store_u32_function(field) \
1169static FC_DEVICE_ATTR(vport, field, S_IRUGO | S_IWUSR, \
1170 show_fc_vport_##field, \
1171 store_fc_vport_##field)
1172
1173
1174#define fc_private_vport_rd_enum_attr(title, maxlen) \
1175static ssize_t \
1176show_fc_vport_##title (struct device *dev, \
1177 struct device_attribute *attr, \
1178 char *buf) \
1179{ \
1180 struct fc_vport *vport = transport_class_to_vport(dev); \
1181 const char *name; \
1182 name = get_fc_##title##_name(vport->title); \
1183 if (!name) \
1184 return -EINVAL; \
1185 return snprintf(buf, maxlen, "%s\n", name); \
1186} \
1187static FC_DEVICE_ATTR(vport, title, S_IRUGO, \
1188 show_fc_vport_##title, NULL)
1189
1190
1191#define SETUP_VPORT_ATTRIBUTE_RD(field) \
1192 i->private_vport_attrs[count] = device_attr_vport_##field; \
1193 i->private_vport_attrs[count].attr.mode = S_IRUGO; \
1194 i->private_vport_attrs[count].store = NULL; \
1195 i->vport_attrs[count] = &i->private_vport_attrs[count]; \
1196 if (i->f->get_##field) \
1197 count++
1198
1199
1200#define SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(field) \
1201 i->private_vport_attrs[count] = device_attr_vport_##field; \
1202 i->private_vport_attrs[count].attr.mode = S_IRUGO; \
1203 i->private_vport_attrs[count].store = NULL; \
1204 i->vport_attrs[count] = &i->private_vport_attrs[count]; \
1205 count++
1206
1207#define SETUP_VPORT_ATTRIBUTE_WR(field) \
1208 i->private_vport_attrs[count] = device_attr_vport_##field; \
1209 i->vport_attrs[count] = &i->private_vport_attrs[count]; \
1210 if (i->f->field) \
1211 count++
1212
1213
1214#define SETUP_VPORT_ATTRIBUTE_RW(field) \
1215 i->private_vport_attrs[count] = device_attr_vport_##field; \
1216 if (!i->f->set_vport_##field) { \
1217 i->private_vport_attrs[count].attr.mode = S_IRUGO; \
1218 i->private_vport_attrs[count].store = NULL; \
1219 } \
1220 i->vport_attrs[count] = &i->private_vport_attrs[count]; \
1221 count++
1222
1223
1224#define SETUP_PRIVATE_VPORT_ATTRIBUTE_RW(field) \
1225{ \
1226 i->private_vport_attrs[count] = device_attr_vport_##field; \
1227 i->vport_attrs[count] = &i->private_vport_attrs[count]; \
1228 count++; \
1229}
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240fc_private_vport_rd_enum_attr(vport_state, FC_VPORTSTATE_MAX_NAMELEN);
1241fc_private_vport_rd_enum_attr(vport_last_state, FC_VPORTSTATE_MAX_NAMELEN);
1242fc_private_vport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
1243fc_private_vport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
1244
1245static ssize_t
1246show_fc_vport_roles (struct device *dev, struct device_attribute *attr,
1247 char *buf)
1248{
1249 struct fc_vport *vport = transport_class_to_vport(dev);
1250
1251 if (vport->roles == FC_PORT_ROLE_UNKNOWN)
1252 return snprintf(buf, 20, "unknown\n");
1253 return get_fc_port_roles_names(vport->roles, buf);
1254}
1255static FC_DEVICE_ATTR(vport, roles, S_IRUGO, show_fc_vport_roles, NULL);
1256
1257fc_private_vport_rd_enum_attr(vport_type, FC_PORTTYPE_MAX_NAMELEN);
1258
1259fc_private_vport_show_function(symbolic_name, "%s\n",
1260 FC_VPORT_SYMBOLIC_NAMELEN + 1, )
1261fc_vport_store_str_function(symbolic_name, FC_VPORT_SYMBOLIC_NAMELEN)
1262static FC_DEVICE_ATTR(vport, symbolic_name, S_IRUGO | S_IWUSR,
1263 show_fc_vport_symbolic_name, store_fc_vport_symbolic_name);
1264
1265static ssize_t
1266store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
1267 const char *buf, size_t count)
1268{
1269 struct fc_vport *vport = transport_class_to_vport(dev);
1270 struct Scsi_Host *shost = vport_to_shost(vport);
1271 unsigned long flags;
1272
1273 spin_lock_irqsave(shost->host_lock, flags);
1274 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
1275 spin_unlock_irqrestore(shost->host_lock, flags);
1276 return -EBUSY;
1277 }
1278 vport->flags |= FC_VPORT_DELETING;
1279 spin_unlock_irqrestore(shost->host_lock, flags);
1280
1281 fc_queue_work(shost, &vport->vport_delete_work);
1282 return count;
1283}
1284static FC_DEVICE_ATTR(vport, vport_delete, S_IWUSR,
1285 NULL, store_fc_vport_delete);
1286
1287
1288
1289
1290
1291
1292static ssize_t
1293store_fc_vport_disable(struct device *dev, struct device_attribute *attr,
1294 const char *buf,
1295 size_t count)
1296{
1297 struct fc_vport *vport = transport_class_to_vport(dev);
1298 struct Scsi_Host *shost = vport_to_shost(vport);
1299 struct fc_internal *i = to_fc_internal(shost->transportt);
1300 int stat;
1301
1302 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
1303 return -EBUSY;
1304
1305 if (*buf == '0') {
1306 if (vport->vport_state != FC_VPORT_DISABLED)
1307 return -EALREADY;
1308 } else if (*buf == '1') {
1309 if (vport->vport_state == FC_VPORT_DISABLED)
1310 return -EALREADY;
1311 } else
1312 return -EINVAL;
1313
1314 stat = i->f->vport_disable(vport, ((*buf == '0') ? false : true));
1315 return stat ? stat : count;
1316}
1317static FC_DEVICE_ATTR(vport, vport_disable, S_IWUSR,
1318 NULL, store_fc_vport_disable);
1319
1320
1321
1322
1323
1324
1325#define fc_host_show_function(field, format_string, sz, cast) \
1326static ssize_t \
1327show_fc_host_##field (struct device *dev, \
1328 struct device_attribute *attr, char *buf) \
1329{ \
1330 struct Scsi_Host *shost = transport_class_to_shost(dev); \
1331 struct fc_internal *i = to_fc_internal(shost->transportt); \
1332 if (i->f->get_host_##field) \
1333 i->f->get_host_##field(shost); \
1334 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
1335}
1336
1337#define fc_host_store_function(field) \
1338static ssize_t \
1339store_fc_host_##field(struct device *dev, \
1340 struct device_attribute *attr, \
1341 const char *buf, size_t count) \
1342{ \
1343 int val; \
1344 struct Scsi_Host *shost = transport_class_to_shost(dev); \
1345 struct fc_internal *i = to_fc_internal(shost->transportt); \
1346 char *cp; \
1347 \
1348 val = simple_strtoul(buf, &cp, 0); \
1349 if (*cp && (*cp != '\n')) \
1350 return -EINVAL; \
1351 i->f->set_host_##field(shost, val); \
1352 return count; \
1353}
1354
1355#define fc_host_store_str_function(field, slen) \
1356static ssize_t \
1357store_fc_host_##field(struct device *dev, \
1358 struct device_attribute *attr, \
1359 const char *buf, size_t count) \
1360{ \
1361 struct Scsi_Host *shost = transport_class_to_shost(dev); \
1362 struct fc_internal *i = to_fc_internal(shost->transportt); \
1363 unsigned int cnt=count; \
1364 \
1365 \
1366 if (buf[cnt-1] == '\n') \
1367 cnt--; \
1368 if (cnt > ((slen) - 1)) \
1369 return -EINVAL; \
1370 memcpy(fc_host_##field(shost), buf, cnt); \
1371 i->f->set_host_##field(shost); \
1372 return count; \
1373}
1374
1375#define fc_host_rd_attr(field, format_string, sz) \
1376 fc_host_show_function(field, format_string, sz, ) \
1377static FC_DEVICE_ATTR(host, field, S_IRUGO, \
1378 show_fc_host_##field, NULL)
1379
1380#define fc_host_rd_attr_cast(field, format_string, sz, cast) \
1381 fc_host_show_function(field, format_string, sz, (cast)) \
1382static FC_DEVICE_ATTR(host, field, S_IRUGO, \
1383 show_fc_host_##field, NULL)
1384
1385#define fc_host_rw_attr(field, format_string, sz) \
1386 fc_host_show_function(field, format_string, sz, ) \
1387 fc_host_store_function(field) \
1388static FC_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR, \
1389 show_fc_host_##field, \
1390 store_fc_host_##field)
1391
1392#define fc_host_rd_enum_attr(title, maxlen) \
1393static ssize_t \
1394show_fc_host_##title (struct device *dev, \
1395 struct device_attribute *attr, char *buf) \
1396{ \
1397 struct Scsi_Host *shost = transport_class_to_shost(dev); \
1398 struct fc_internal *i = to_fc_internal(shost->transportt); \
1399 const char *name; \
1400 if (i->f->get_host_##title) \
1401 i->f->get_host_##title(shost); \
1402 name = get_fc_##title##_name(fc_host_##title(shost)); \
1403 if (!name) \
1404 return -EINVAL; \
1405 return snprintf(buf, maxlen, "%s\n", name); \
1406} \
1407static FC_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL)
1408
1409#define SETUP_HOST_ATTRIBUTE_RD(field) \
1410 i->private_host_attrs[count] = device_attr_host_##field; \
1411 i->private_host_attrs[count].attr.mode = S_IRUGO; \
1412 i->private_host_attrs[count].store = NULL; \
1413 i->host_attrs[count] = &i->private_host_attrs[count]; \
1414 if (i->f->show_host_##field) \
1415 count++
1416
1417#define SETUP_HOST_ATTRIBUTE_RD_NS(field) \
1418 i->private_host_attrs[count] = device_attr_host_##field; \
1419 i->private_host_attrs[count].attr.mode = S_IRUGO; \
1420 i->private_host_attrs[count].store = NULL; \
1421 i->host_attrs[count] = &i->private_host_attrs[count]; \
1422 count++
1423
1424#define SETUP_HOST_ATTRIBUTE_RW(field) \
1425 i->private_host_attrs[count] = device_attr_host_##field; \
1426 if (!i->f->set_host_##field) { \
1427 i->private_host_attrs[count].attr.mode = S_IRUGO; \
1428 i->private_host_attrs[count].store = NULL; \
1429 } \
1430 i->host_attrs[count] = &i->private_host_attrs[count]; \
1431 if (i->f->show_host_##field) \
1432 count++
1433
1434
1435#define fc_private_host_show_function(field, format_string, sz, cast) \
1436static ssize_t \
1437show_fc_host_##field (struct device *dev, \
1438 struct device_attribute *attr, char *buf) \
1439{ \
1440 struct Scsi_Host *shost = transport_class_to_shost(dev); \
1441 return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
1442}
1443
1444#define fc_private_host_rd_attr(field, format_string, sz) \
1445 fc_private_host_show_function(field, format_string, sz, ) \
1446static FC_DEVICE_ATTR(host, field, S_IRUGO, \
1447 show_fc_host_##field, NULL)
1448
1449#define fc_private_host_rd_attr_cast(field, format_string, sz, cast) \
1450 fc_private_host_show_function(field, format_string, sz, (cast)) \
1451static FC_DEVICE_ATTR(host, field, S_IRUGO, \
1452 show_fc_host_##field, NULL)
1453
1454#define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field) \
1455 i->private_host_attrs[count] = device_attr_host_##field; \
1456 i->private_host_attrs[count].attr.mode = S_IRUGO; \
1457 i->private_host_attrs[count].store = NULL; \
1458 i->host_attrs[count] = &i->private_host_attrs[count]; \
1459 count++
1460
1461#define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field) \
1462{ \
1463 i->private_host_attrs[count] = device_attr_host_##field; \
1464 i->host_attrs[count] = &i->private_host_attrs[count]; \
1465 count++; \
1466}
1467
1468
1469
1470
1471static ssize_t
1472show_fc_host_supported_classes (struct device *dev,
1473 struct device_attribute *attr, char *buf)
1474{
1475 struct Scsi_Host *shost = transport_class_to_shost(dev);
1476
1477 if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED)
1478 return snprintf(buf, 20, "unspecified\n");
1479
1480 return get_fc_cos_names(fc_host_supported_classes(shost), buf);
1481}
1482static FC_DEVICE_ATTR(host, supported_classes, S_IRUGO,
1483 show_fc_host_supported_classes, NULL);
1484
1485static ssize_t
1486show_fc_host_supported_fc4s (struct device *dev,
1487 struct device_attribute *attr, char *buf)
1488{
1489 struct Scsi_Host *shost = transport_class_to_shost(dev);
1490 return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost));
1491}
1492static FC_DEVICE_ATTR(host, supported_fc4s, S_IRUGO,
1493 show_fc_host_supported_fc4s, NULL);
1494
1495static ssize_t
1496show_fc_host_supported_speeds (struct device *dev,
1497 struct device_attribute *attr, char *buf)
1498{
1499 struct Scsi_Host *shost = transport_class_to_shost(dev);
1500
1501 if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN)
1502 return snprintf(buf, 20, "unknown\n");
1503
1504 return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf);
1505}
1506static FC_DEVICE_ATTR(host, supported_speeds, S_IRUGO,
1507 show_fc_host_supported_speeds, NULL);
1508
1509
1510fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
1511fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
1512fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,
1513 unsigned long long);
1514fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
1515fc_private_host_rd_attr(max_npiv_vports, "%u\n", 20);
1516fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
1517
1518
1519
1520
1521static ssize_t
1522show_fc_host_active_fc4s (struct device *dev,
1523 struct device_attribute *attr, char *buf)
1524{
1525 struct Scsi_Host *shost = transport_class_to_shost(dev);
1526 struct fc_internal *i = to_fc_internal(shost->transportt);
1527
1528 if (i->f->get_host_active_fc4s)
1529 i->f->get_host_active_fc4s(shost);
1530
1531 return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost));
1532}
1533static FC_DEVICE_ATTR(host, active_fc4s, S_IRUGO,
1534 show_fc_host_active_fc4s, NULL);
1535
1536static ssize_t
1537show_fc_host_speed (struct device *dev,
1538 struct device_attribute *attr, char *buf)
1539{
1540 struct Scsi_Host *shost = transport_class_to_shost(dev);
1541 struct fc_internal *i = to_fc_internal(shost->transportt);
1542
1543 if (i->f->get_host_speed)
1544 i->f->get_host_speed(shost);
1545
1546 if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN)
1547 return snprintf(buf, 20, "unknown\n");
1548
1549 return get_fc_port_speed_names(fc_host_speed(shost), buf);
1550}
1551static FC_DEVICE_ATTR(host, speed, S_IRUGO,
1552 show_fc_host_speed, NULL);
1553
1554
1555fc_host_rd_attr(port_id, "0x%06x\n", 20);
1556fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN);
1557fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
1558fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long);
1559fc_host_rd_attr(symbolic_name, "%s\n", FC_SYMBOLIC_NAME_SIZE + 1);
1560
1561fc_private_host_show_function(system_hostname, "%s\n",
1562 FC_SYMBOLIC_NAME_SIZE + 1, )
1563fc_host_store_str_function(system_hostname, FC_SYMBOLIC_NAME_SIZE)
1564static FC_DEVICE_ATTR(host, system_hostname, S_IRUGO | S_IWUSR,
1565 show_fc_host_system_hostname, store_fc_host_system_hostname);
1566
1567
1568
1569
1570static ssize_t
1571show_fc_private_host_tgtid_bind_type(struct device *dev,
1572 struct device_attribute *attr, char *buf)
1573{
1574 struct Scsi_Host *shost = transport_class_to_shost(dev);
1575 const char *name;
1576
1577 name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost));
1578 if (!name)
1579 return -EINVAL;
1580 return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name);
1581}
1582
1583#define get_list_head_entry(pos, head, member) \
1584 pos = list_entry((head)->next, typeof(*pos), member)
1585
1586static ssize_t
1587store_fc_private_host_tgtid_bind_type(struct device *dev,
1588 struct device_attribute *attr, const char *buf, size_t count)
1589{
1590 struct Scsi_Host *shost = transport_class_to_shost(dev);
1591 struct fc_rport *rport;
1592 enum fc_tgtid_binding_type val;
1593 unsigned long flags;
1594
1595 if (get_fc_tgtid_bind_type_match(buf, &val))
1596 return -EINVAL;
1597
1598
1599 if (val != fc_host_tgtid_bind_type(shost)) {
1600 spin_lock_irqsave(shost->host_lock, flags);
1601 while (!list_empty(&fc_host_rport_bindings(shost))) {
1602 get_list_head_entry(rport,
1603 &fc_host_rport_bindings(shost), peers);
1604 list_del(&rport->peers);
1605 rport->port_state = FC_PORTSTATE_DELETED;
1606 fc_queue_work(shost, &rport->rport_delete_work);
1607 }
1608 spin_unlock_irqrestore(shost->host_lock, flags);
1609 }
1610
1611 fc_host_tgtid_bind_type(shost) = val;
1612 return count;
1613}
1614
1615static FC_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
1616 show_fc_private_host_tgtid_bind_type,
1617 store_fc_private_host_tgtid_bind_type);
1618
1619static ssize_t
1620store_fc_private_host_issue_lip(struct device *dev,
1621 struct device_attribute *attr, const char *buf, size_t count)
1622{
1623 struct Scsi_Host *shost = transport_class_to_shost(dev);
1624 struct fc_internal *i = to_fc_internal(shost->transportt);
1625 int ret;
1626
1627
1628 if (i->f->issue_fc_host_lip) {
1629 ret = i->f->issue_fc_host_lip(shost);
1630 return ret ? ret: count;
1631 }
1632
1633 return -ENOENT;
1634}
1635
1636static FC_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
1637 store_fc_private_host_issue_lip);
1638
1639static ssize_t
1640store_fc_private_host_dev_loss_tmo(struct device *dev,
1641 struct device_attribute *attr,
1642 const char *buf, size_t count)
1643{
1644 struct Scsi_Host *shost = transport_class_to_shost(dev);
1645 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1646 struct fc_rport *rport;
1647 unsigned long val, flags;
1648 int rc;
1649
1650 rc = fc_str_to_dev_loss(buf, &val);
1651 if (rc)
1652 return rc;
1653
1654 fc_host_dev_loss_tmo(shost) = val;
1655 spin_lock_irqsave(shost->host_lock, flags);
1656 list_for_each_entry(rport, &fc_host->rports, peers)
1657 fc_rport_set_dev_loss_tmo(rport, val);
1658 spin_unlock_irqrestore(shost->host_lock, flags);
1659 return count;
1660}
1661
1662fc_private_host_show_function(dev_loss_tmo, "%d\n", 20, );
1663static FC_DEVICE_ATTR(host, dev_loss_tmo, S_IRUGO | S_IWUSR,
1664 show_fc_host_dev_loss_tmo,
1665 store_fc_private_host_dev_loss_tmo);
1666
1667fc_private_host_rd_attr(npiv_vports_inuse, "%u\n", 20);
1668
1669
1670
1671
1672
1673
1674static ssize_t
1675fc_stat_show(const struct device *dev, char *buf, unsigned long offset)
1676{
1677 struct Scsi_Host *shost = transport_class_to_shost(dev);
1678 struct fc_internal *i = to_fc_internal(shost->transportt);
1679 struct fc_host_statistics *stats;
1680 ssize_t ret = -ENOENT;
1681
1682 if (offset > sizeof(struct fc_host_statistics) ||
1683 offset % sizeof(u64) != 0)
1684 WARN_ON(1);
1685
1686 if (i->f->get_fc_host_stats) {
1687 stats = (i->f->get_fc_host_stats)(shost);
1688 if (stats)
1689 ret = snprintf(buf, 20, "0x%llx\n",
1690 (unsigned long long)*(u64 *)(((u8 *) stats) + offset));
1691 }
1692 return ret;
1693}
1694
1695
1696
1697#define fc_host_statistic(name) \
1698static ssize_t show_fcstat_##name(struct device *cd, \
1699 struct device_attribute *attr, \
1700 char *buf) \
1701{ \
1702 return fc_stat_show(cd, buf, \
1703 offsetof(struct fc_host_statistics, name)); \
1704} \
1705static FC_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL)
1706
1707fc_host_statistic(seconds_since_last_reset);
1708fc_host_statistic(tx_frames);
1709fc_host_statistic(tx_words);
1710fc_host_statistic(rx_frames);
1711fc_host_statistic(rx_words);
1712fc_host_statistic(lip_count);
1713fc_host_statistic(nos_count);
1714fc_host_statistic(error_frames);
1715fc_host_statistic(dumped_frames);
1716fc_host_statistic(link_failure_count);
1717fc_host_statistic(loss_of_sync_count);
1718fc_host_statistic(loss_of_signal_count);
1719fc_host_statistic(prim_seq_protocol_err_count);
1720fc_host_statistic(invalid_tx_word_count);
1721fc_host_statistic(invalid_crc_count);
1722fc_host_statistic(fcp_input_requests);
1723fc_host_statistic(fcp_output_requests);
1724fc_host_statistic(fcp_control_requests);
1725fc_host_statistic(fcp_input_megabytes);
1726fc_host_statistic(fcp_output_megabytes);
1727
1728static ssize_t
1729fc_reset_statistics(struct device *dev, struct device_attribute *attr,
1730 const char *buf, size_t count)
1731{
1732 struct Scsi_Host *shost = transport_class_to_shost(dev);
1733 struct fc_internal *i = to_fc_internal(shost->transportt);
1734
1735
1736 if (i->f->reset_fc_host_stats) {
1737 i->f->reset_fc_host_stats(shost);
1738 return count;
1739 }
1740
1741 return -ENOENT;
1742}
1743static FC_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL,
1744 fc_reset_statistics);
1745
1746static struct attribute *fc_statistics_attrs[] = {
1747 &device_attr_host_seconds_since_last_reset.attr,
1748 &device_attr_host_tx_frames.attr,
1749 &device_attr_host_tx_words.attr,
1750 &device_attr_host_rx_frames.attr,
1751 &device_attr_host_rx_words.attr,
1752 &device_attr_host_lip_count.attr,
1753 &device_attr_host_nos_count.attr,
1754 &device_attr_host_error_frames.attr,
1755 &device_attr_host_dumped_frames.attr,
1756 &device_attr_host_link_failure_count.attr,
1757 &device_attr_host_loss_of_sync_count.attr,
1758 &device_attr_host_loss_of_signal_count.attr,
1759 &device_attr_host_prim_seq_protocol_err_count.attr,
1760 &device_attr_host_invalid_tx_word_count.attr,
1761 &device_attr_host_invalid_crc_count.attr,
1762 &device_attr_host_fcp_input_requests.attr,
1763 &device_attr_host_fcp_output_requests.attr,
1764 &device_attr_host_fcp_control_requests.attr,
1765 &device_attr_host_fcp_input_megabytes.attr,
1766 &device_attr_host_fcp_output_megabytes.attr,
1767 &device_attr_host_reset_statistics.attr,
1768 NULL
1769};
1770
1771static struct attribute_group fc_statistics_group = {
1772 .name = "statistics",
1773 .attrs = fc_statistics_attrs,
1774};
1775
1776
1777
1778
1779static int
1780fc_parse_wwn(const char *ns, u64 *nm)
1781{
1782 unsigned int i, j;
1783 u8 wwn[8];
1784
1785 memset(wwn, 0, sizeof(wwn));
1786
1787
1788 for (i=0, j=0; i < 16; i++) {
1789 int value;
1790
1791 value = hex_to_bin(*ns++);
1792 if (value >= 0)
1793 j = (j << 4) | value;
1794 else
1795 return -EINVAL;
1796 if (i % 2) {
1797 wwn[i/2] = j & 0xff;
1798 j = 0;
1799 }
1800 }
1801
1802 *nm = wwn_to_u64(wwn);
1803
1804 return 0;
1805}
1806
1807
1808
1809
1810
1811
1812
1813
1814static ssize_t
1815store_fc_host_vport_create(struct device *dev, struct device_attribute *attr,
1816 const char *buf, size_t count)
1817{
1818 struct Scsi_Host *shost = transport_class_to_shost(dev);
1819 struct fc_vport_identifiers vid;
1820 struct fc_vport *vport;
1821 unsigned int cnt=count;
1822 int stat;
1823
1824 memset(&vid, 0, sizeof(vid));
1825
1826
1827 if (buf[cnt-1] == '\n')
1828 cnt--;
1829
1830
1831 if ((cnt != (16+1+16)) || (buf[16] != ':'))
1832 return -EINVAL;
1833
1834 stat = fc_parse_wwn(&buf[0], &vid.port_name);
1835 if (stat)
1836 return stat;
1837
1838 stat = fc_parse_wwn(&buf[17], &vid.node_name);
1839 if (stat)
1840 return stat;
1841
1842 vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
1843 vid.vport_type = FC_PORTTYPE_NPIV;
1844
1845 vid.disable = false;
1846
1847
1848 stat = fc_vport_setup(shost, 0, &shost->shost_gendev, &vid, &vport);
1849 return stat ? stat : count;
1850}
1851static FC_DEVICE_ATTR(host, vport_create, S_IWUSR, NULL,
1852 store_fc_host_vport_create);
1853
1854
1855
1856
1857
1858
1859
1860
1861static ssize_t
1862store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr,
1863 const char *buf, size_t count)
1864{
1865 struct Scsi_Host *shost = transport_class_to_shost(dev);
1866 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1867 struct fc_vport *vport;
1868 u64 wwpn, wwnn;
1869 unsigned long flags;
1870 unsigned int cnt=count;
1871 int stat, match;
1872
1873
1874 if (buf[cnt-1] == '\n')
1875 cnt--;
1876
1877
1878 if ((cnt != (16+1+16)) || (buf[16] != ':'))
1879 return -EINVAL;
1880
1881 stat = fc_parse_wwn(&buf[0], &wwpn);
1882 if (stat)
1883 return stat;
1884
1885 stat = fc_parse_wwn(&buf[17], &wwnn);
1886 if (stat)
1887 return stat;
1888
1889 spin_lock_irqsave(shost->host_lock, flags);
1890 match = 0;
1891
1892 list_for_each_entry(vport, &fc_host->vports, peers) {
1893 if ((vport->channel == 0) &&
1894 (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
1895 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
1896 break;
1897 vport->flags |= FC_VPORT_DELETING;
1898 match = 1;
1899 break;
1900 }
1901 }
1902 spin_unlock_irqrestore(shost->host_lock, flags);
1903
1904 if (!match)
1905 return -ENODEV;
1906
1907 stat = fc_vport_terminate(vport);
1908 return stat ? stat : count;
1909}
1910static FC_DEVICE_ATTR(host, vport_delete, S_IWUSR, NULL,
1911 store_fc_host_vport_delete);
1912
1913
1914static int fc_host_match(struct attribute_container *cont,
1915 struct device *dev)
1916{
1917 struct Scsi_Host *shost;
1918 struct fc_internal *i;
1919
1920 if (!scsi_is_host_device(dev))
1921 return 0;
1922
1923 shost = dev_to_shost(dev);
1924 if (!shost->transportt || shost->transportt->host_attrs.ac.class
1925 != &fc_host_class.class)
1926 return 0;
1927
1928 i = to_fc_internal(shost->transportt);
1929
1930 return &i->t.host_attrs.ac == cont;
1931}
1932
1933static int fc_target_match(struct attribute_container *cont,
1934 struct device *dev)
1935{
1936 struct Scsi_Host *shost;
1937 struct fc_internal *i;
1938
1939 if (!scsi_is_target_device(dev))
1940 return 0;
1941
1942 shost = dev_to_shost(dev->parent);
1943 if (!shost->transportt || shost->transportt->host_attrs.ac.class
1944 != &fc_host_class.class)
1945 return 0;
1946
1947 i = to_fc_internal(shost->transportt);
1948
1949 return &i->t.target_attrs.ac == cont;
1950}
1951
1952static void fc_rport_dev_release(struct device *dev)
1953{
1954 struct fc_rport *rport = dev_to_rport(dev);
1955 put_device(dev->parent);
1956 kfree(rport);
1957}
1958
1959int scsi_is_fc_rport(const struct device *dev)
1960{
1961 return dev->release == fc_rport_dev_release;
1962}
1963EXPORT_SYMBOL(scsi_is_fc_rport);
1964
1965static int fc_rport_match(struct attribute_container *cont,
1966 struct device *dev)
1967{
1968 struct Scsi_Host *shost;
1969 struct fc_internal *i;
1970
1971 if (!scsi_is_fc_rport(dev))
1972 return 0;
1973
1974 shost = dev_to_shost(dev->parent);
1975 if (!shost->transportt || shost->transportt->host_attrs.ac.class
1976 != &fc_host_class.class)
1977 return 0;
1978
1979 i = to_fc_internal(shost->transportt);
1980
1981 return &i->rport_attr_cont.ac == cont;
1982}
1983
1984
1985static void fc_vport_dev_release(struct device *dev)
1986{
1987 struct fc_vport *vport = dev_to_vport(dev);
1988 put_device(dev->parent);
1989 kfree(vport);
1990}
1991
1992int scsi_is_fc_vport(const struct device *dev)
1993{
1994 return dev->release == fc_vport_dev_release;
1995}
1996EXPORT_SYMBOL(scsi_is_fc_vport);
1997
1998static int fc_vport_match(struct attribute_container *cont,
1999 struct device *dev)
2000{
2001 struct fc_vport *vport;
2002 struct Scsi_Host *shost;
2003 struct fc_internal *i;
2004
2005 if (!scsi_is_fc_vport(dev))
2006 return 0;
2007 vport = dev_to_vport(dev);
2008
2009 shost = vport_to_shost(vport);
2010 if (!shost->transportt || shost->transportt->host_attrs.ac.class
2011 != &fc_host_class.class)
2012 return 0;
2013
2014 i = to_fc_internal(shost->transportt);
2015 return &i->vport_attr_cont.ac == cont;
2016}
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041static enum blk_eh_timer_return
2042fc_timed_out(struct scsi_cmnd *scmd)
2043{
2044 struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device));
2045
2046 if (rport->port_state == FC_PORTSTATE_BLOCKED)
2047 return BLK_EH_RESET_TIMER;
2048
2049 return BLK_EH_NOT_HANDLED;
2050}
2051
2052
2053
2054
2055
2056
2057static void
2058fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, uint lun)
2059{
2060 struct fc_rport *rport;
2061 unsigned long flags;
2062
2063 spin_lock_irqsave(shost->host_lock, flags);
2064
2065 list_for_each_entry(rport, &fc_host_rports(shost), peers) {
2066 if (rport->scsi_target_id == -1)
2067 continue;
2068
2069 if (rport->port_state != FC_PORTSTATE_ONLINE)
2070 continue;
2071
2072 if ((channel == rport->channel) &&
2073 (id == rport->scsi_target_id)) {
2074 spin_unlock_irqrestore(shost->host_lock, flags);
2075 scsi_scan_target(&rport->dev, channel, id, lun, 1);
2076 return;
2077 }
2078 }
2079
2080 spin_unlock_irqrestore(shost->host_lock, flags);
2081}
2082
2083
2084
2085
2086
2087
2088
2089static int
2090fc_user_scan(struct Scsi_Host *shost, uint channel, uint id, uint lun)
2091{
2092 uint chlo, chhi;
2093 uint tgtlo, tgthi;
2094
2095 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
2096 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
2097 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
2098 return -EINVAL;
2099
2100 if (channel == SCAN_WILD_CARD) {
2101 chlo = 0;
2102 chhi = shost->max_channel + 1;
2103 } else {
2104 chlo = channel;
2105 chhi = channel + 1;
2106 }
2107
2108 if (id == SCAN_WILD_CARD) {
2109 tgtlo = 0;
2110 tgthi = shost->max_id;
2111 } else {
2112 tgtlo = id;
2113 tgthi = id + 1;
2114 }
2115
2116 for ( ; chlo < chhi; chlo++)
2117 for ( ; tgtlo < tgthi; tgtlo++)
2118 fc_user_scan_tgt(shost, chlo, tgtlo, lun);
2119
2120 return 0;
2121}
2122
2123static int fc_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id,
2124 int result)
2125{
2126 struct fc_internal *i = to_fc_internal(shost->transportt);
2127 return i->f->tsk_mgmt_response(shost, nexus, tm_id, result);
2128}
2129
2130static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result)
2131{
2132 struct fc_internal *i = to_fc_internal(shost->transportt);
2133 return i->f->it_nexus_response(shost, nexus, result);
2134}
2135
2136struct scsi_transport_template *
2137fc_attach_transport(struct fc_function_template *ft)
2138{
2139 int count;
2140 struct fc_internal *i = kzalloc(sizeof(struct fc_internal),
2141 GFP_KERNEL);
2142
2143 if (unlikely(!i))
2144 return NULL;
2145
2146 i->t.target_attrs.ac.attrs = &i->starget_attrs[0];
2147 i->t.target_attrs.ac.class = &fc_transport_class.class;
2148 i->t.target_attrs.ac.match = fc_target_match;
2149 i->t.target_size = sizeof(struct fc_starget_attrs);
2150 transport_container_register(&i->t.target_attrs);
2151
2152 i->t.host_attrs.ac.attrs = &i->host_attrs[0];
2153 i->t.host_attrs.ac.class = &fc_host_class.class;
2154 i->t.host_attrs.ac.match = fc_host_match;
2155 i->t.host_size = sizeof(struct fc_host_attrs);
2156 if (ft->get_fc_host_stats)
2157 i->t.host_attrs.statistics = &fc_statistics_group;
2158 transport_container_register(&i->t.host_attrs);
2159
2160 i->rport_attr_cont.ac.attrs = &i->rport_attrs[0];
2161 i->rport_attr_cont.ac.class = &fc_rport_class.class;
2162 i->rport_attr_cont.ac.match = fc_rport_match;
2163 transport_container_register(&i->rport_attr_cont);
2164
2165 i->vport_attr_cont.ac.attrs = &i->vport_attrs[0];
2166 i->vport_attr_cont.ac.class = &fc_vport_class.class;
2167 i->vport_attr_cont.ac.match = fc_vport_match;
2168 transport_container_register(&i->vport_attr_cont);
2169
2170 i->f = ft;
2171
2172
2173 i->t.create_work_queue = 1;
2174
2175 i->t.eh_timed_out = fc_timed_out;
2176
2177 i->t.user_scan = fc_user_scan;
2178
2179
2180 i->t.tsk_mgmt_response = fc_tsk_mgmt_response;
2181 i->t.it_nexus_response = fc_it_nexus_response;
2182
2183
2184
2185
2186 count = 0;
2187 SETUP_STARGET_ATTRIBUTE_RD(node_name);
2188 SETUP_STARGET_ATTRIBUTE_RD(port_name);
2189 SETUP_STARGET_ATTRIBUTE_RD(port_id);
2190
2191 BUG_ON(count > FC_STARGET_NUM_ATTRS);
2192
2193 i->starget_attrs[count] = NULL;
2194
2195
2196
2197
2198
2199 count=0;
2200 SETUP_HOST_ATTRIBUTE_RD(node_name);
2201 SETUP_HOST_ATTRIBUTE_RD(port_name);
2202 SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
2203 SETUP_HOST_ATTRIBUTE_RD(supported_classes);
2204 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
2205 SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
2206 SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
2207 if (ft->vport_create) {
2208 SETUP_HOST_ATTRIBUTE_RD_NS(max_npiv_vports);
2209 SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse);
2210 }
2211 SETUP_HOST_ATTRIBUTE_RD(serial_number);
2212
2213 SETUP_HOST_ATTRIBUTE_RD(port_id);
2214 SETUP_HOST_ATTRIBUTE_RD(port_type);
2215 SETUP_HOST_ATTRIBUTE_RD(port_state);
2216 SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
2217 SETUP_HOST_ATTRIBUTE_RD(speed);
2218 SETUP_HOST_ATTRIBUTE_RD(fabric_name);
2219 SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
2220 SETUP_HOST_ATTRIBUTE_RW(system_hostname);
2221
2222
2223 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(dev_loss_tmo);
2224 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
2225 if (ft->issue_fc_host_lip)
2226 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
2227 if (ft->vport_create)
2228 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_create);
2229 if (ft->vport_delete)
2230 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_delete);
2231
2232 BUG_ON(count > FC_HOST_NUM_ATTRS);
2233
2234 i->host_attrs[count] = NULL;
2235
2236
2237
2238
2239 count=0;
2240 SETUP_RPORT_ATTRIBUTE_RD(maxframe_size);
2241 SETUP_RPORT_ATTRIBUTE_RD(supported_classes);
2242 SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo);
2243 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name);
2244 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name);
2245 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id);
2246 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
2247 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
2248 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
2249 SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
2250
2251 BUG_ON(count > FC_RPORT_NUM_ATTRS);
2252
2253 i->rport_attrs[count] = NULL;
2254
2255
2256
2257
2258 count=0;
2259 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_state);
2260 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_last_state);
2261 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(node_name);
2262 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(port_name);
2263 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(roles);
2264 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_type);
2265 SETUP_VPORT_ATTRIBUTE_RW(symbolic_name);
2266 SETUP_VPORT_ATTRIBUTE_WR(vport_delete);
2267 SETUP_VPORT_ATTRIBUTE_WR(vport_disable);
2268
2269 BUG_ON(count > FC_VPORT_NUM_ATTRS);
2270
2271 i->vport_attrs[count] = NULL;
2272
2273 return &i->t;
2274}
2275EXPORT_SYMBOL(fc_attach_transport);
2276
2277void fc_release_transport(struct scsi_transport_template *t)
2278{
2279 struct fc_internal *i = to_fc_internal(t);
2280
2281 transport_container_unregister(&i->t.target_attrs);
2282 transport_container_unregister(&i->t.host_attrs);
2283 transport_container_unregister(&i->rport_attr_cont);
2284 transport_container_unregister(&i->vport_attr_cont);
2285
2286 kfree(i);
2287}
2288EXPORT_SYMBOL(fc_release_transport);
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300static int
2301fc_queue_work(struct Scsi_Host *shost, struct work_struct *work)
2302{
2303 if (unlikely(!fc_host_work_q(shost))) {
2304 printk(KERN_ERR
2305 "ERROR: FC host '%s' attempted to queue work, "
2306 "when no workqueue created.\n", shost->hostt->name);
2307 dump_stack();
2308
2309 return -EINVAL;
2310 }
2311
2312 return queue_work(fc_host_work_q(shost), work);
2313}
2314
2315
2316
2317
2318
2319static void
2320fc_flush_work(struct Scsi_Host *shost)
2321{
2322 if (!fc_host_work_q(shost)) {
2323 printk(KERN_ERR
2324 "ERROR: FC host '%s' attempted to flush work, "
2325 "when no workqueue created.\n", shost->hostt->name);
2326 dump_stack();
2327 return;
2328 }
2329
2330 flush_workqueue(fc_host_work_q(shost));
2331}
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342static int
2343fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work,
2344 unsigned long delay)
2345{
2346 if (unlikely(!fc_host_devloss_work_q(shost))) {
2347 printk(KERN_ERR
2348 "ERROR: FC host '%s' attempted to queue work, "
2349 "when no workqueue created.\n", shost->hostt->name);
2350 dump_stack();
2351
2352 return -EINVAL;
2353 }
2354
2355 return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay);
2356}
2357
2358
2359
2360
2361
2362static void
2363fc_flush_devloss(struct Scsi_Host *shost)
2364{
2365 if (!fc_host_devloss_work_q(shost)) {
2366 printk(KERN_ERR
2367 "ERROR: FC host '%s' attempted to flush work, "
2368 "when no workqueue created.\n", shost->hostt->name);
2369 dump_stack();
2370 return;
2371 }
2372
2373 flush_workqueue(fc_host_devloss_work_q(shost));
2374}
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392void
2393fc_remove_host(struct Scsi_Host *shost)
2394{
2395 struct fc_vport *vport = NULL, *next_vport = NULL;
2396 struct fc_rport *rport = NULL, *next_rport = NULL;
2397 struct workqueue_struct *work_q;
2398 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2399 unsigned long flags;
2400
2401 spin_lock_irqsave(shost->host_lock, flags);
2402
2403
2404 list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers)
2405 fc_queue_work(shost, &vport->vport_delete_work);
2406
2407
2408 list_for_each_entry_safe(rport, next_rport,
2409 &fc_host->rports, peers) {
2410 list_del(&rport->peers);
2411 rport->port_state = FC_PORTSTATE_DELETED;
2412 fc_queue_work(shost, &rport->rport_delete_work);
2413 }
2414
2415 list_for_each_entry_safe(rport, next_rport,
2416 &fc_host->rport_bindings, peers) {
2417 list_del(&rport->peers);
2418 rport->port_state = FC_PORTSTATE_DELETED;
2419 fc_queue_work(shost, &rport->rport_delete_work);
2420 }
2421
2422 spin_unlock_irqrestore(shost->host_lock, flags);
2423
2424
2425 scsi_flush_work(shost);
2426
2427
2428 if (fc_host->work_q) {
2429 work_q = fc_host->work_q;
2430 fc_host->work_q = NULL;
2431 destroy_workqueue(work_q);
2432 }
2433
2434
2435 if (fc_host->devloss_work_q) {
2436 work_q = fc_host->devloss_work_q;
2437 fc_host->devloss_work_q = NULL;
2438 destroy_workqueue(work_q);
2439 }
2440}
2441EXPORT_SYMBOL(fc_remove_host);
2442
2443static void fc_terminate_rport_io(struct fc_rport *rport)
2444{
2445 struct Scsi_Host *shost = rport_to_shost(rport);
2446 struct fc_internal *i = to_fc_internal(shost->transportt);
2447
2448
2449 if (i->f->terminate_rport_io)
2450 i->f->terminate_rport_io(rport);
2451
2452
2453
2454
2455
2456
2457 scsi_target_unblock(&rport->dev);
2458}
2459
2460
2461
2462
2463
2464
2465
2466static void
2467fc_starget_delete(struct work_struct *work)
2468{
2469 struct fc_rport *rport =
2470 container_of(work, struct fc_rport, stgt_delete_work);
2471
2472 fc_terminate_rport_io(rport);
2473 scsi_remove_target(&rport->dev);
2474}
2475
2476
2477
2478
2479
2480
2481static void
2482fc_rport_final_delete(struct work_struct *work)
2483{
2484 struct fc_rport *rport =
2485 container_of(work, struct fc_rport, rport_delete_work);
2486 struct device *dev = &rport->dev;
2487 struct Scsi_Host *shost = rport_to_shost(rport);
2488 struct fc_internal *i = to_fc_internal(shost->transportt);
2489 unsigned long flags;
2490 int do_callback = 0;
2491
2492
2493
2494
2495
2496 if (rport->flags & FC_RPORT_SCAN_PENDING)
2497 scsi_flush_work(shost);
2498
2499 fc_terminate_rport_io(rport);
2500
2501
2502
2503
2504
2505
2506 spin_lock_irqsave(shost->host_lock, flags);
2507 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
2508 spin_unlock_irqrestore(shost->host_lock, flags);
2509 if (!cancel_delayed_work(&rport->fail_io_work))
2510 fc_flush_devloss(shost);
2511 if (!cancel_delayed_work(&rport->dev_loss_work))
2512 fc_flush_devloss(shost);
2513 spin_lock_irqsave(shost->host_lock, flags);
2514 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
2515 }
2516 spin_unlock_irqrestore(shost->host_lock, flags);
2517
2518
2519 if (rport->scsi_target_id != -1)
2520 fc_starget_delete(&rport->stgt_delete_work);
2521
2522
2523
2524
2525
2526
2527
2528
2529 spin_lock_irqsave(shost->host_lock, flags);
2530 if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) &&
2531 (i->f->dev_loss_tmo_callbk)) {
2532 rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
2533 do_callback = 1;
2534 }
2535 spin_unlock_irqrestore(shost->host_lock, flags);
2536
2537 if (do_callback)
2538 i->f->dev_loss_tmo_callbk(rport);
2539
2540 fc_bsg_remove(rport->rqst_q);
2541
2542 transport_remove_device(dev);
2543 device_del(dev);
2544 transport_destroy_device(dev);
2545 put_device(&shost->shost_gendev);
2546 put_device(dev);
2547}
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563static struct fc_rport *
2564fc_rport_create(struct Scsi_Host *shost, int channel,
2565 struct fc_rport_identifiers *ids)
2566{
2567 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2568 struct fc_internal *fci = to_fc_internal(shost->transportt);
2569 struct fc_rport *rport;
2570 struct device *dev;
2571 unsigned long flags;
2572 int error;
2573 size_t size;
2574
2575 size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size);
2576 rport = kzalloc(size, GFP_KERNEL);
2577 if (unlikely(!rport)) {
2578 printk(KERN_ERR "%s: allocation failure\n", __func__);
2579 return NULL;
2580 }
2581
2582 rport->maxframe_size = -1;
2583 rport->supported_classes = FC_COS_UNSPECIFIED;
2584 rport->dev_loss_tmo = fc_host->dev_loss_tmo;
2585 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
2586 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
2587 rport->port_id = ids->port_id;
2588 rport->roles = ids->roles;
2589 rport->port_state = FC_PORTSTATE_ONLINE;
2590 if (fci->f->dd_fcrport_size)
2591 rport->dd_data = &rport[1];
2592 rport->channel = channel;
2593 rport->fast_io_fail_tmo = -1;
2594
2595 INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport);
2596 INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io);
2597 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport);
2598 INIT_WORK(&rport->stgt_delete_work, fc_starget_delete);
2599 INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete);
2600
2601 spin_lock_irqsave(shost->host_lock, flags);
2602
2603 rport->number = fc_host->next_rport_number++;
2604 if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
2605 rport->scsi_target_id = fc_host->next_target_id++;
2606 else
2607 rport->scsi_target_id = -1;
2608 list_add_tail(&rport->peers, &fc_host->rports);
2609 get_device(&shost->shost_gendev);
2610
2611 spin_unlock_irqrestore(shost->host_lock, flags);
2612
2613 dev = &rport->dev;
2614 device_initialize(dev);
2615 dev->parent = get_device(&shost->shost_gendev);
2616 dev->release = fc_rport_dev_release;
2617 dev_set_name(dev, "rport-%d:%d-%d",
2618 shost->host_no, channel, rport->number);
2619 transport_setup_device(dev);
2620
2621 error = device_add(dev);
2622 if (error) {
2623 printk(KERN_ERR "FC Remote Port device_add failed\n");
2624 goto delete_rport;
2625 }
2626 transport_add_device(dev);
2627 transport_configure_device(dev);
2628
2629 fc_bsg_rportadd(shost, rport);
2630
2631
2632 if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
2633
2634 rport->flags |= FC_RPORT_SCAN_PENDING;
2635 scsi_queue_work(shost, &rport->scan_work);
2636 }
2637
2638 return rport;
2639
2640delete_rport:
2641 transport_destroy_device(dev);
2642 spin_lock_irqsave(shost->host_lock, flags);
2643 list_del(&rport->peers);
2644 put_device(&shost->shost_gendev);
2645 spin_unlock_irqrestore(shost->host_lock, flags);
2646 put_device(dev->parent);
2647 kfree(rport);
2648 return NULL;
2649}
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689struct fc_rport *
2690fc_remote_port_add(struct Scsi_Host *shost, int channel,
2691 struct fc_rport_identifiers *ids)
2692{
2693 struct fc_internal *fci = to_fc_internal(shost->transportt);
2694 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2695 struct fc_rport *rport;
2696 unsigned long flags;
2697 int match = 0;
2698
2699
2700 fc_flush_work(shost);
2701
2702
2703
2704
2705
2706
2707 spin_lock_irqsave(shost->host_lock, flags);
2708
2709 list_for_each_entry(rport, &fc_host->rports, peers) {
2710
2711 if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
2712 (rport->channel == channel)) {
2713
2714 switch (fc_host->tgtid_bind_type) {
2715 case FC_TGTID_BIND_BY_WWPN:
2716 case FC_TGTID_BIND_NONE:
2717 if (rport->port_name == ids->port_name)
2718 match = 1;
2719 break;
2720 case FC_TGTID_BIND_BY_WWNN:
2721 if (rport->node_name == ids->node_name)
2722 match = 1;
2723 break;
2724 case FC_TGTID_BIND_BY_ID:
2725 if (rport->port_id == ids->port_id)
2726 match = 1;
2727 break;
2728 }
2729
2730 if (match) {
2731
2732 memcpy(&rport->node_name, &ids->node_name,
2733 sizeof(rport->node_name));
2734 memcpy(&rport->port_name, &ids->port_name,
2735 sizeof(rport->port_name));
2736 rport->port_id = ids->port_id;
2737
2738 rport->port_state = FC_PORTSTATE_ONLINE;
2739 rport->roles = ids->roles;
2740
2741 spin_unlock_irqrestore(shost->host_lock, flags);
2742
2743 if (fci->f->dd_fcrport_size)
2744 memset(rport->dd_data, 0,
2745 fci->f->dd_fcrport_size);
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764 if ((rport->scsi_target_id != -1) &&
2765 (!(ids->roles & FC_PORT_ROLE_FCP_TARGET)))
2766 return rport;
2767
2768
2769
2770
2771
2772
2773 if (!cancel_delayed_work(&rport->fail_io_work))
2774 fc_flush_devloss(shost);
2775 if (!cancel_delayed_work(&rport->dev_loss_work))
2776 fc_flush_devloss(shost);
2777
2778 spin_lock_irqsave(shost->host_lock, flags);
2779
2780 rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
2781 FC_RPORT_DEVLOSS_PENDING |
2782 FC_RPORT_DEVLOSS_CALLBK_DONE);
2783
2784
2785 if (rport->scsi_target_id != -1) {
2786 rport->flags |= FC_RPORT_SCAN_PENDING;
2787 scsi_queue_work(shost,
2788 &rport->scan_work);
2789 spin_unlock_irqrestore(shost->host_lock,
2790 flags);
2791 scsi_target_unblock(&rport->dev);
2792 } else
2793 spin_unlock_irqrestore(shost->host_lock,
2794 flags);
2795
2796 fc_bsg_goose_queue(rport);
2797
2798 return rport;
2799 }
2800 }
2801 }
2802
2803
2804
2805
2806
2807 if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) {
2808
2809
2810
2811 list_for_each_entry(rport, &fc_host->rport_bindings,
2812 peers) {
2813 if (rport->channel != channel)
2814 continue;
2815
2816 switch (fc_host->tgtid_bind_type) {
2817 case FC_TGTID_BIND_BY_WWPN:
2818 if (rport->port_name == ids->port_name)
2819 match = 1;
2820 break;
2821 case FC_TGTID_BIND_BY_WWNN:
2822 if (rport->node_name == ids->node_name)
2823 match = 1;
2824 break;
2825 case FC_TGTID_BIND_BY_ID:
2826 if (rport->port_id == ids->port_id)
2827 match = 1;
2828 break;
2829 case FC_TGTID_BIND_NONE:
2830 break;
2831 }
2832
2833 if (match) {
2834 list_move_tail(&rport->peers, &fc_host->rports);
2835 break;
2836 }
2837 }
2838
2839 if (match) {
2840 memcpy(&rport->node_name, &ids->node_name,
2841 sizeof(rport->node_name));
2842 memcpy(&rport->port_name, &ids->port_name,
2843 sizeof(rport->port_name));
2844 rport->port_id = ids->port_id;
2845 rport->roles = ids->roles;
2846 rport->port_state = FC_PORTSTATE_ONLINE;
2847 rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
2848
2849 if (fci->f->dd_fcrport_size)
2850 memset(rport->dd_data, 0,
2851 fci->f->dd_fcrport_size);
2852
2853 if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
2854
2855 rport->flags |= FC_RPORT_SCAN_PENDING;
2856 scsi_queue_work(shost, &rport->scan_work);
2857 spin_unlock_irqrestore(shost->host_lock, flags);
2858 scsi_target_unblock(&rport->dev);
2859 } else
2860 spin_unlock_irqrestore(shost->host_lock, flags);
2861
2862 return rport;
2863 }
2864 }
2865
2866 spin_unlock_irqrestore(shost->host_lock, flags);
2867
2868
2869 rport = fc_rport_create(shost, channel, ids);
2870
2871 return rport;
2872}
2873EXPORT_SYMBOL(fc_remote_port_add);
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926void
2927fc_remote_port_delete(struct fc_rport *rport)
2928{
2929 struct Scsi_Host *shost = rport_to_shost(rport);
2930 unsigned long timeout = rport->dev_loss_tmo;
2931 unsigned long flags;
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941 spin_lock_irqsave(shost->host_lock, flags);
2942
2943 if (rport->port_state != FC_PORTSTATE_ONLINE) {
2944 spin_unlock_irqrestore(shost->host_lock, flags);
2945 return;
2946 }
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961 rport->port_state = FC_PORTSTATE_BLOCKED;
2962
2963 rport->flags |= FC_RPORT_DEVLOSS_PENDING;
2964
2965 spin_unlock_irqrestore(shost->host_lock, flags);
2966
2967 if (rport->roles & FC_PORT_ROLE_FCP_INITIATOR &&
2968 shost->active_mode & MODE_TARGET)
2969 fc_tgt_it_nexus_destroy(shost, (unsigned long)rport);
2970
2971 scsi_target_block(&rport->dev);
2972
2973
2974 if ((rport->fast_io_fail_tmo != -1) &&
2975 (rport->fast_io_fail_tmo < timeout))
2976 fc_queue_devloss_work(shost, &rport->fail_io_work,
2977 rport->fast_io_fail_tmo * HZ);
2978
2979
2980 fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ);
2981}
2982EXPORT_SYMBOL(fc_remote_port_delete);
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004void
3005fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
3006{
3007 struct Scsi_Host *shost = rport_to_shost(rport);
3008 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3009 unsigned long flags;
3010 int create = 0;
3011 int ret;
3012
3013 spin_lock_irqsave(shost->host_lock, flags);
3014 if (roles & FC_PORT_ROLE_FCP_TARGET) {
3015 if (rport->scsi_target_id == -1) {
3016 rport->scsi_target_id = fc_host->next_target_id++;
3017 create = 1;
3018 } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET))
3019 create = 1;
3020 } else if (shost->active_mode & MODE_TARGET) {
3021 ret = fc_tgt_it_nexus_create(shost, (unsigned long)rport,
3022 (char *)&rport->node_name);
3023 if (ret)
3024 printk(KERN_ERR "FC Remore Port tgt nexus failed %d\n",
3025 ret);
3026 }
3027
3028 rport->roles = roles;
3029
3030 spin_unlock_irqrestore(shost->host_lock, flags);
3031
3032 if (create) {
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045 if (!cancel_delayed_work(&rport->fail_io_work))
3046 fc_flush_devloss(shost);
3047 if (!cancel_delayed_work(&rport->dev_loss_work))
3048 fc_flush_devloss(shost);
3049
3050 spin_lock_irqsave(shost->host_lock, flags);
3051 rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
3052 FC_RPORT_DEVLOSS_PENDING);
3053 spin_unlock_irqrestore(shost->host_lock, flags);
3054
3055
3056 fc_flush_work(shost);
3057
3058
3059 spin_lock_irqsave(shost->host_lock, flags);
3060 rport->flags |= FC_RPORT_SCAN_PENDING;
3061 scsi_queue_work(shost, &rport->scan_work);
3062 spin_unlock_irqrestore(shost->host_lock, flags);
3063 scsi_target_unblock(&rport->dev);
3064 }
3065}
3066EXPORT_SYMBOL(fc_remote_port_rolechg);
3067
3068
3069
3070
3071
3072
3073
3074
3075static void
3076fc_timeout_deleted_rport(struct work_struct *work)
3077{
3078 struct fc_rport *rport =
3079 container_of(work, struct fc_rport, dev_loss_work.work);
3080 struct Scsi_Host *shost = rport_to_shost(rport);
3081 struct fc_internal *i = to_fc_internal(shost->transportt);
3082 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3083 unsigned long flags;
3084 int do_callback = 0;
3085
3086 spin_lock_irqsave(shost->host_lock, flags);
3087
3088 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
3089
3090
3091
3092
3093
3094
3095 if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
3096 (rport->scsi_target_id != -1) &&
3097 !(rport->roles & FC_PORT_ROLE_FCP_TARGET)) {
3098 dev_printk(KERN_ERR, &rport->dev,
3099 "blocked FC remote port time out: no longer"
3100 " a FCP target, removing starget\n");
3101 spin_unlock_irqrestore(shost->host_lock, flags);
3102 scsi_target_unblock(&rport->dev);
3103 fc_queue_work(shost, &rport->stgt_delete_work);
3104 return;
3105 }
3106
3107
3108 if (rport->port_state != FC_PORTSTATE_BLOCKED) {
3109 spin_unlock_irqrestore(shost->host_lock, flags);
3110 dev_printk(KERN_ERR, &rport->dev,
3111 "blocked FC remote port time out: leaving"
3112 " rport%s alone\n",
3113 (rport->scsi_target_id != -1) ? " and starget" : "");
3114 return;
3115 }
3116
3117 if ((fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) ||
3118 (rport->scsi_target_id == -1)) {
3119 list_del(&rport->peers);
3120 rport->port_state = FC_PORTSTATE_DELETED;
3121 dev_printk(KERN_ERR, &rport->dev,
3122 "blocked FC remote port time out: removing"
3123 " rport%s\n",
3124 (rport->scsi_target_id != -1) ? " and starget" : "");
3125 fc_queue_work(shost, &rport->rport_delete_work);
3126 spin_unlock_irqrestore(shost->host_lock, flags);
3127 return;
3128 }
3129
3130 dev_printk(KERN_ERR, &rport->dev,
3131 "blocked FC remote port time out: removing target and "
3132 "saving binding\n");
3133
3134 list_move_tail(&rport->peers, &fc_host->rport_bindings);
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145 rport->maxframe_size = -1;
3146 rport->supported_classes = FC_COS_UNSPECIFIED;
3147 rport->roles = FC_PORT_ROLE_UNKNOWN;
3148 rport->port_state = FC_PORTSTATE_NOTPRESENT;
3149 rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
3150
3151
3152
3153
3154
3155
3156 spin_unlock_irqrestore(shost->host_lock, flags);
3157 fc_terminate_rport_io(rport);
3158
3159 spin_lock_irqsave(shost->host_lock, flags);
3160
3161 if (rport->port_state == FC_PORTSTATE_NOTPRESENT) {
3162
3163
3164 switch (fc_host->tgtid_bind_type) {
3165 case FC_TGTID_BIND_BY_WWPN:
3166 rport->node_name = -1;
3167 rport->port_id = -1;
3168 break;
3169 case FC_TGTID_BIND_BY_WWNN:
3170 rport->port_name = -1;
3171 rport->port_id = -1;
3172 break;
3173 case FC_TGTID_BIND_BY_ID:
3174 rport->node_name = -1;
3175 rport->port_name = -1;
3176 break;
3177 case FC_TGTID_BIND_NONE:
3178 break;
3179 }
3180
3181
3182
3183
3184
3185
3186 rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
3187 fc_queue_work(shost, &rport->stgt_delete_work);
3188
3189 do_callback = 1;
3190 }
3191
3192 spin_unlock_irqrestore(shost->host_lock, flags);
3193
3194
3195
3196
3197
3198
3199
3200 if (do_callback && i->f->dev_loss_tmo_callbk)
3201 i->f->dev_loss_tmo_callbk(rport);
3202}
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212static void
3213fc_timeout_fail_rport_io(struct work_struct *work)
3214{
3215 struct fc_rport *rport =
3216 container_of(work, struct fc_rport, fail_io_work.work);
3217
3218 if (rport->port_state != FC_PORTSTATE_BLOCKED)
3219 return;
3220
3221 rport->flags |= FC_RPORT_FAST_FAIL_TIMEDOUT;
3222 fc_terminate_rport_io(rport);
3223}
3224
3225
3226
3227
3228
3229static void
3230fc_scsi_scan_rport(struct work_struct *work)
3231{
3232 struct fc_rport *rport =
3233 container_of(work, struct fc_rport, scan_work);
3234 struct Scsi_Host *shost = rport_to_shost(rport);
3235 struct fc_internal *i = to_fc_internal(shost->transportt);
3236 unsigned long flags;
3237
3238 if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
3239 (rport->roles & FC_PORT_ROLE_FCP_TARGET) &&
3240 !(i->f->disable_target_scan)) {
3241 scsi_scan_target(&rport->dev, rport->channel,
3242 rport->scsi_target_id, SCAN_WILD_CARD, 1);
3243 }
3244
3245 spin_lock_irqsave(shost->host_lock, flags);
3246 rport->flags &= ~FC_RPORT_SCAN_PENDING;
3247 spin_unlock_irqrestore(shost->host_lock, flags);
3248}
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
3265{
3266 struct Scsi_Host *shost = cmnd->device->host;
3267 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
3268 unsigned long flags;
3269
3270 spin_lock_irqsave(shost->host_lock, flags);
3271 while (rport->port_state == FC_PORTSTATE_BLOCKED &&
3272 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)) {
3273 spin_unlock_irqrestore(shost->host_lock, flags);
3274 msleep(1000);
3275 spin_lock_irqsave(shost->host_lock, flags);
3276 }
3277 spin_unlock_irqrestore(shost->host_lock, flags);
3278
3279 if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
3280 return FAST_IO_FAIL;
3281
3282 return 0;
3283}
3284EXPORT_SYMBOL(fc_block_scsi_eh);
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301static int
3302fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev,
3303 struct fc_vport_identifiers *ids, struct fc_vport **ret_vport)
3304{
3305 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3306 struct fc_internal *fci = to_fc_internal(shost->transportt);
3307 struct fc_vport *vport;
3308 struct device *dev;
3309 unsigned long flags;
3310 size_t size;
3311 int error;
3312
3313 *ret_vport = NULL;
3314
3315 if ( ! fci->f->vport_create)
3316 return -ENOENT;
3317
3318 size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size);
3319 vport = kzalloc(size, GFP_KERNEL);
3320 if (unlikely(!vport)) {
3321 printk(KERN_ERR "%s: allocation failure\n", __func__);
3322 return -ENOMEM;
3323 }
3324
3325 vport->vport_state = FC_VPORT_UNKNOWN;
3326 vport->vport_last_state = FC_VPORT_UNKNOWN;
3327 vport->node_name = ids->node_name;
3328 vport->port_name = ids->port_name;
3329 vport->roles = ids->roles;
3330 vport->vport_type = ids->vport_type;
3331 if (fci->f->dd_fcvport_size)
3332 vport->dd_data = &vport[1];
3333 vport->shost = shost;
3334 vport->channel = channel;
3335 vport->flags = FC_VPORT_CREATING;
3336 INIT_WORK(&vport->vport_delete_work, fc_vport_sched_delete);
3337
3338 spin_lock_irqsave(shost->host_lock, flags);
3339
3340 if (fc_host->npiv_vports_inuse >= fc_host->max_npiv_vports) {
3341 spin_unlock_irqrestore(shost->host_lock, flags);
3342 kfree(vport);
3343 return -ENOSPC;
3344 }
3345 fc_host->npiv_vports_inuse++;
3346 vport->number = fc_host->next_vport_number++;
3347 list_add_tail(&vport->peers, &fc_host->vports);
3348 get_device(&shost->shost_gendev);
3349
3350 spin_unlock_irqrestore(shost->host_lock, flags);
3351
3352 dev = &vport->dev;
3353 device_initialize(dev);
3354 dev->parent = get_device(pdev);
3355 dev->release = fc_vport_dev_release;
3356 dev_set_name(dev, "vport-%d:%d-%d",
3357 shost->host_no, channel, vport->number);
3358 transport_setup_device(dev);
3359
3360 error = device_add(dev);
3361 if (error) {
3362 printk(KERN_ERR "FC Virtual Port device_add failed\n");
3363 goto delete_vport;
3364 }
3365 transport_add_device(dev);
3366 transport_configure_device(dev);
3367
3368 error = fci->f->vport_create(vport, ids->disable);
3369 if (error) {
3370 printk(KERN_ERR "FC Virtual Port LLDD Create failed\n");
3371 goto delete_vport_all;
3372 }
3373
3374
3375
3376
3377
3378 if (pdev != &shost->shost_gendev) {
3379 error = sysfs_create_link(&shost->shost_gendev.kobj,
3380 &dev->kobj, dev_name(dev));
3381 if (error)
3382 printk(KERN_ERR
3383 "%s: Cannot create vport symlinks for "
3384 "%s, err=%d\n",
3385 __func__, dev_name(dev), error);
3386 }
3387 spin_lock_irqsave(shost->host_lock, flags);
3388 vport->flags &= ~FC_VPORT_CREATING;
3389 spin_unlock_irqrestore(shost->host_lock, flags);
3390
3391 dev_printk(KERN_NOTICE, pdev,
3392 "%s created via shost%d channel %d\n", dev_name(dev),
3393 shost->host_no, channel);
3394
3395 *ret_vport = vport;
3396
3397 return 0;
3398
3399delete_vport_all:
3400 transport_remove_device(dev);
3401 device_del(dev);
3402delete_vport:
3403 transport_destroy_device(dev);
3404 spin_lock_irqsave(shost->host_lock, flags);
3405 list_del(&vport->peers);
3406 put_device(&shost->shost_gendev);
3407 fc_host->npiv_vports_inuse--;
3408 spin_unlock_irqrestore(shost->host_lock, flags);
3409 put_device(dev->parent);
3410 kfree(vport);
3411
3412 return error;
3413}
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425struct fc_vport *
3426fc_vport_create(struct Scsi_Host *shost, int channel,
3427 struct fc_vport_identifiers *ids)
3428{
3429 int stat;
3430 struct fc_vport *vport;
3431
3432 stat = fc_vport_setup(shost, channel, &shost->shost_gendev,
3433 ids, &vport);
3434 return stat ? NULL : vport;
3435}
3436EXPORT_SYMBOL(fc_vport_create);
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448int
3449fc_vport_terminate(struct fc_vport *vport)
3450{
3451 struct Scsi_Host *shost = vport_to_shost(vport);
3452 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3453 struct fc_internal *i = to_fc_internal(shost->transportt);
3454 struct device *dev = &vport->dev;
3455 unsigned long flags;
3456 int stat;
3457
3458 if (i->f->vport_delete)
3459 stat = i->f->vport_delete(vport);
3460 else
3461 stat = -ENOENT;
3462
3463 spin_lock_irqsave(shost->host_lock, flags);
3464 vport->flags &= ~FC_VPORT_DELETING;
3465 if (!stat) {
3466 vport->flags |= FC_VPORT_DELETED;
3467 list_del(&vport->peers);
3468 fc_host->npiv_vports_inuse--;
3469 put_device(&shost->shost_gendev);
3470 }
3471 spin_unlock_irqrestore(shost->host_lock, flags);
3472
3473 if (stat)
3474 return stat;
3475
3476 if (dev->parent != &shost->shost_gendev)
3477 sysfs_remove_link(&shost->shost_gendev.kobj, dev_name(dev));
3478 transport_remove_device(dev);
3479 device_del(dev);
3480 transport_destroy_device(dev);
3481
3482
3483
3484
3485
3486
3487 put_device(dev);
3488
3489 return 0;
3490}
3491EXPORT_SYMBOL(fc_vport_terminate);
3492
3493
3494
3495
3496
3497static void
3498fc_vport_sched_delete(struct work_struct *work)
3499{
3500 struct fc_vport *vport =
3501 container_of(work, struct fc_vport, vport_delete_work);
3502 int stat;
3503
3504 stat = fc_vport_terminate(vport);
3505 if (stat)
3506 dev_printk(KERN_ERR, vport->dev.parent,
3507 "%s: %s could not be deleted created via "
3508 "shost%d channel %d - error %d\n", __func__,
3509 dev_name(&vport->dev), vport->shost->host_no,
3510 vport->channel, stat);
3511}
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523static void
3524fc_destroy_bsgjob(struct fc_bsg_job *job)
3525{
3526 unsigned long flags;
3527
3528 spin_lock_irqsave(&job->job_lock, flags);
3529 if (job->ref_cnt) {
3530 spin_unlock_irqrestore(&job->job_lock, flags);
3531 return;
3532 }
3533 spin_unlock_irqrestore(&job->job_lock, flags);
3534
3535 put_device(job->dev);
3536
3537 kfree(job->request_payload.sg_list);
3538 kfree(job->reply_payload.sg_list);
3539 kfree(job);
3540}
3541
3542
3543
3544
3545
3546
3547static void
3548fc_bsg_jobdone(struct fc_bsg_job *job)
3549{
3550 struct request *req = job->req;
3551 struct request *rsp = req->next_rq;
3552 int err;
3553
3554 err = job->req->errors = job->reply->result;
3555
3556 if (err < 0)
3557
3558 job->req->sense_len = sizeof(uint32_t);
3559 else
3560 job->req->sense_len = job->reply_len;
3561
3562
3563 req->resid_len = 0;
3564
3565 if (rsp) {
3566 WARN_ON(job->reply->reply_payload_rcv_len > rsp->resid_len);
3567
3568
3569 rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
3570 rsp->resid_len);
3571 }
3572 blk_complete_request(req);
3573}
3574
3575
3576
3577
3578
3579static void fc_bsg_softirq_done(struct request *rq)
3580{
3581 struct fc_bsg_job *job = rq->special;
3582 unsigned long flags;
3583
3584 spin_lock_irqsave(&job->job_lock, flags);
3585 job->state_flags |= FC_RQST_STATE_DONE;
3586 job->ref_cnt--;
3587 spin_unlock_irqrestore(&job->job_lock, flags);
3588
3589 blk_end_request_all(rq, rq->errors);
3590 fc_destroy_bsgjob(job);
3591}
3592
3593
3594
3595
3596
3597static enum blk_eh_timer_return
3598fc_bsg_job_timeout(struct request *req)
3599{
3600 struct fc_bsg_job *job = (void *) req->special;
3601 struct Scsi_Host *shost = job->shost;
3602 struct fc_internal *i = to_fc_internal(shost->transportt);
3603 unsigned long flags;
3604 int err = 0, done = 0;
3605
3606 if (job->rport && job->rport->port_state == FC_PORTSTATE_BLOCKED)
3607 return BLK_EH_RESET_TIMER;
3608
3609 spin_lock_irqsave(&job->job_lock, flags);
3610 if (job->state_flags & FC_RQST_STATE_DONE)
3611 done = 1;
3612 else
3613 job->ref_cnt++;
3614 spin_unlock_irqrestore(&job->job_lock, flags);
3615
3616 if (!done && i->f->bsg_timeout) {
3617
3618 err = i->f->bsg_timeout(job);
3619 if (err == -EAGAIN) {
3620 job->ref_cnt--;
3621 return BLK_EH_RESET_TIMER;
3622 } else if (err)
3623 printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
3624 "abort failed with status %d\n", err);
3625 }
3626
3627
3628 if (done)
3629 return BLK_EH_NOT_HANDLED;
3630 else
3631 return BLK_EH_HANDLED;
3632}
3633
3634static int
3635fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req)
3636{
3637 size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);
3638
3639 BUG_ON(!req->nr_phys_segments);
3640
3641 buf->sg_list = kzalloc(sz, GFP_KERNEL);
3642 if (!buf->sg_list)
3643 return -ENOMEM;
3644 sg_init_table(buf->sg_list, req->nr_phys_segments);
3645 buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
3646 buf->payload_len = blk_rq_bytes(req);
3647 return 0;
3648}
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658static int
3659fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
3660 struct request *req)
3661{
3662 struct fc_internal *i = to_fc_internal(shost->transportt);
3663 struct request *rsp = req->next_rq;
3664 struct fc_bsg_job *job;
3665 int ret;
3666
3667 BUG_ON(req->special);
3668
3669 job = kzalloc(sizeof(struct fc_bsg_job) + i->f->dd_bsg_size,
3670 GFP_KERNEL);
3671 if (!job)
3672 return -ENOMEM;
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683 req->special = job;
3684 job->shost = shost;
3685 job->rport = rport;
3686 job->req = req;
3687 if (i->f->dd_bsg_size)
3688 job->dd_data = (void *)&job[1];
3689 spin_lock_init(&job->job_lock);
3690 job->request = (struct fc_bsg_request *)req->cmd;
3691 job->request_len = req->cmd_len;
3692 job->reply = req->sense;
3693 job->reply_len = SCSI_SENSE_BUFFERSIZE;
3694
3695 if (req->bio) {
3696 ret = fc_bsg_map_buffer(&job->request_payload, req);
3697 if (ret)
3698 goto failjob_rls_job;
3699 }
3700 if (rsp && rsp->bio) {
3701 ret = fc_bsg_map_buffer(&job->reply_payload, rsp);
3702 if (ret)
3703 goto failjob_rls_rqst_payload;
3704 }
3705 job->job_done = fc_bsg_jobdone;
3706 if (rport)
3707 job->dev = &rport->dev;
3708 else
3709 job->dev = &shost->shost_gendev;
3710 get_device(job->dev);
3711
3712 job->ref_cnt = 1;
3713
3714 return 0;
3715
3716
3717failjob_rls_rqst_payload:
3718 kfree(job->request_payload.sg_list);
3719failjob_rls_job:
3720 kfree(job);
3721 return -ENOMEM;
3722}
3723
3724
3725enum fc_dispatch_result {
3726 FC_DISPATCH_BREAK,
3727 FC_DISPATCH_LOCKED,
3728 FC_DISPATCH_UNLOCKED,
3729};
3730
3731
3732
3733
3734
3735
3736
3737
3738static enum fc_dispatch_result
3739fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
3740 struct fc_bsg_job *job)
3741{
3742 struct fc_internal *i = to_fc_internal(shost->transportt);
3743 int cmdlen = sizeof(uint32_t);
3744 int ret;
3745
3746
3747 switch (job->request->msgcode) {
3748 case FC_BSG_HST_ADD_RPORT:
3749 cmdlen += sizeof(struct fc_bsg_host_add_rport);
3750 break;
3751
3752 case FC_BSG_HST_DEL_RPORT:
3753 cmdlen += sizeof(struct fc_bsg_host_del_rport);
3754 break;
3755
3756 case FC_BSG_HST_ELS_NOLOGIN:
3757 cmdlen += sizeof(struct fc_bsg_host_els);
3758
3759 if ((!job->request_payload.payload_len) ||
3760 (!job->reply_payload.payload_len)) {
3761 ret = -EINVAL;
3762 goto fail_host_msg;
3763 }
3764 break;
3765
3766 case FC_BSG_HST_CT:
3767 cmdlen += sizeof(struct fc_bsg_host_ct);
3768
3769 if ((!job->request_payload.payload_len) ||
3770 (!job->reply_payload.payload_len)) {
3771 ret = -EINVAL;
3772 goto fail_host_msg;
3773 }
3774 break;
3775
3776 case FC_BSG_HST_VENDOR:
3777 cmdlen += sizeof(struct fc_bsg_host_vendor);
3778 if ((shost->hostt->vendor_id == 0L) ||
3779 (job->request->rqst_data.h_vendor.vendor_id !=
3780 shost->hostt->vendor_id)) {
3781 ret = -ESRCH;
3782 goto fail_host_msg;
3783 }
3784 break;
3785
3786 default:
3787 ret = -EBADR;
3788 goto fail_host_msg;
3789 }
3790
3791
3792 if (job->request_len < cmdlen) {
3793 ret = -ENOMSG;
3794 goto fail_host_msg;
3795 }
3796
3797 ret = i->f->bsg_request(job);
3798 if (!ret)
3799 return FC_DISPATCH_UNLOCKED;
3800
3801fail_host_msg:
3802
3803 BUG_ON(job->reply_len < sizeof(uint32_t));
3804 job->reply->reply_payload_rcv_len = 0;
3805 job->reply->result = ret;
3806 job->reply_len = sizeof(uint32_t);
3807 fc_bsg_jobdone(job);
3808 return FC_DISPATCH_UNLOCKED;
3809}
3810
3811
3812
3813
3814
3815
3816static void
3817fc_bsg_goose_queue(struct fc_rport *rport)
3818{
3819 if (!rport->rqst_q)
3820 return;
3821
3822
3823
3824
3825 get_device(&rport->dev);
3826 blk_run_queue_async(rport->rqst_q);
3827 put_device(&rport->dev);
3828}
3829
3830
3831
3832
3833
3834
3835
3836
3837static enum fc_dispatch_result
3838fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
3839 struct fc_rport *rport, struct fc_bsg_job *job)
3840{
3841 struct fc_internal *i = to_fc_internal(shost->transportt);
3842 int cmdlen = sizeof(uint32_t);
3843 int ret;
3844
3845
3846 switch (job->request->msgcode) {
3847 case FC_BSG_RPT_ELS:
3848 cmdlen += sizeof(struct fc_bsg_rport_els);
3849 goto check_bidi;
3850
3851 case FC_BSG_RPT_CT:
3852 cmdlen += sizeof(struct fc_bsg_rport_ct);
3853check_bidi:
3854
3855 if ((!job->request_payload.payload_len) ||
3856 (!job->reply_payload.payload_len)) {
3857 ret = -EINVAL;
3858 goto fail_rport_msg;
3859 }
3860 break;
3861 default:
3862 ret = -EBADR;
3863 goto fail_rport_msg;
3864 }
3865
3866
3867 if (job->request_len < cmdlen) {
3868 ret = -ENOMSG;
3869 goto fail_rport_msg;
3870 }
3871
3872 ret = i->f->bsg_request(job);
3873 if (!ret)
3874 return FC_DISPATCH_UNLOCKED;
3875
3876fail_rport_msg:
3877
3878 BUG_ON(job->reply_len < sizeof(uint32_t));
3879 job->reply->reply_payload_rcv_len = 0;
3880 job->reply->result = ret;
3881 job->reply_len = sizeof(uint32_t);
3882 fc_bsg_jobdone(job);
3883 return FC_DISPATCH_UNLOCKED;
3884}
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894static void
3895fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3896 struct fc_rport *rport, struct device *dev)
3897{
3898 struct request *req;
3899 struct fc_bsg_job *job;
3900 enum fc_dispatch_result ret;
3901
3902 if (!get_device(dev))
3903 return;
3904
3905 while (1) {
3906 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
3907 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
3908 break;
3909
3910 req = blk_fetch_request(q);
3911 if (!req)
3912 break;
3913
3914 if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
3915 req->errors = -ENXIO;
3916 spin_unlock_irq(q->queue_lock);
3917 blk_end_request_all(req, -ENXIO);
3918 spin_lock_irq(q->queue_lock);
3919 continue;
3920 }
3921
3922 spin_unlock_irq(q->queue_lock);
3923
3924 ret = fc_req_to_bsgjob(shost, rport, req);
3925 if (ret) {
3926 req->errors = ret;
3927 blk_end_request_all(req, ret);
3928 spin_lock_irq(q->queue_lock);
3929 continue;
3930 }
3931
3932 job = req->special;
3933
3934
3935 if (job->request_len < sizeof(uint32_t)) {
3936 BUG_ON(job->reply_len < sizeof(uint32_t));
3937 job->reply->reply_payload_rcv_len = 0;
3938 job->reply->result = -ENOMSG;
3939 job->reply_len = sizeof(uint32_t);
3940 fc_bsg_jobdone(job);
3941 spin_lock_irq(q->queue_lock);
3942 continue;
3943 }
3944
3945
3946 if (rport)
3947 ret = fc_bsg_rport_dispatch(q, shost, rport, job);
3948 else
3949 ret = fc_bsg_host_dispatch(q, shost, job);
3950
3951
3952 if (ret == FC_DISPATCH_BREAK)
3953 break;
3954
3955
3956 if (ret == FC_DISPATCH_UNLOCKED)
3957 spin_lock_irq(q->queue_lock);
3958 }
3959
3960 spin_unlock_irq(q->queue_lock);
3961 put_device(dev);
3962 spin_lock_irq(q->queue_lock);
3963}
3964
3965
3966
3967
3968
3969
3970static void
3971fc_bsg_host_handler(struct request_queue *q)
3972{
3973 struct Scsi_Host *shost = q->queuedata;
3974
3975 fc_bsg_request_handler(q, shost, NULL, &shost->shost_gendev);
3976}
3977
3978
3979
3980
3981
3982
3983static void
3984fc_bsg_rport_handler(struct request_queue *q)
3985{
3986 struct fc_rport *rport = q->queuedata;
3987 struct Scsi_Host *shost = rport_to_shost(rport);
3988
3989 fc_bsg_request_handler(q, shost, rport, &rport->dev);
3990}
3991
3992
3993
3994
3995
3996
3997
3998static int
3999fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
4000{
4001 struct device *dev = &shost->shost_gendev;
4002 struct fc_internal *i = to_fc_internal(shost->transportt);
4003 struct request_queue *q;
4004 int err;
4005 char bsg_name[20];
4006
4007 fc_host->rqst_q = NULL;
4008
4009 if (!i->f->bsg_request)
4010 return -ENOTSUPP;
4011
4012 snprintf(bsg_name, sizeof(bsg_name),
4013 "fc_host%d", shost->host_no);
4014
4015 q = __scsi_alloc_queue(shost, fc_bsg_host_handler);
4016 if (!q) {
4017 printk(KERN_ERR "fc_host%d: bsg interface failed to "
4018 "initialize - no request queue\n",
4019 shost->host_no);
4020 return -ENOMEM;
4021 }
4022
4023 q->queuedata = shost;
4024 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
4025 blk_queue_softirq_done(q, fc_bsg_softirq_done);
4026 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
4027 blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
4028
4029 err = bsg_register_queue(q, dev, bsg_name, NULL);
4030 if (err) {
4031 printk(KERN_ERR "fc_host%d: bsg interface failed to "
4032 "initialize - register queue\n",
4033 shost->host_no);
4034 blk_cleanup_queue(q);
4035 return err;
4036 }
4037
4038 fc_host->rqst_q = q;
4039 return 0;
4040}
4041
4042
4043
4044
4045
4046
4047
4048static int
4049fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
4050{
4051 struct device *dev = &rport->dev;
4052 struct fc_internal *i = to_fc_internal(shost->transportt);
4053 struct request_queue *q;
4054 int err;
4055
4056 rport->rqst_q = NULL;
4057
4058 if (!i->f->bsg_request)
4059 return -ENOTSUPP;
4060
4061 q = __scsi_alloc_queue(shost, fc_bsg_rport_handler);
4062 if (!q) {
4063 printk(KERN_ERR "%s: bsg interface failed to "
4064 "initialize - no request queue\n",
4065 dev->kobj.name);
4066 return -ENOMEM;
4067 }
4068
4069 q->queuedata = rport;
4070 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
4071 blk_queue_softirq_done(q, fc_bsg_softirq_done);
4072 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
4073 blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
4074
4075 err = bsg_register_queue(q, dev, NULL, NULL);
4076 if (err) {
4077 printk(KERN_ERR "%s: bsg interface failed to "
4078 "initialize - register queue\n",
4079 dev->kobj.name);
4080 blk_cleanup_queue(q);
4081 return err;
4082 }
4083
4084 rport->rqst_q = q;
4085 return 0;
4086}
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098static void
4099fc_bsg_remove(struct request_queue *q)
4100{
4101 struct request *req;
4102 int counts;
4103
4104 if (q) {
4105
4106 spin_lock_irq(q->queue_lock);
4107 blk_stop_queue(q);
4108
4109
4110 while (1) {
4111
4112
4113
4114 req = blk_fetch_request(q);
4115
4116 counts = q->rq.count[0] + q->rq.count[1] +
4117 q->rq.starved[0] + q->rq.starved[1];
4118 spin_unlock_irq(q->queue_lock);
4119
4120 if (counts == 0)
4121 break;
4122
4123
4124
4125
4126
4127
4128 if (req) {
4129
4130
4131
4132 req->errors = -ENXIO;
4133 blk_end_request_all(req, -ENXIO);
4134 }
4135
4136 msleep(200);
4137 spin_lock_irq(q->queue_lock);
4138 }
4139
4140 bsg_unregister_queue(q);
4141 blk_cleanup_queue(q);
4142 }
4143}
4144
4145
4146
4147MODULE_AUTHOR("James Smart");
4148MODULE_DESCRIPTION("FC Transport Attributes");
4149MODULE_LICENSE("GPL");
4150
4151module_init(fc_transport_init);
4152module_exit(fc_transport_exit);
4153