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