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 <net/netlink.h>
39#include <scsi/scsi_netlink_fc.h>
40#include <scsi/scsi_bsg_fc.h>
41#include "scsi_priv.h"
42
43static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
44static void fc_vport_sched_delete(struct work_struct *work);
45static int fc_vport_setup(struct Scsi_Host *shost, int channel,
46 struct device *pdev, struct fc_vport_identifiers *ids,
47 struct fc_vport **vport);
48static int fc_bsg_hostadd(struct Scsi_Host *, struct fc_host_attrs *);
49static int fc_bsg_rportadd(struct Scsi_Host *, struct fc_rport *);
50static void fc_bsg_remove(struct request_queue *);
51static void fc_bsg_goose_queue(struct fc_rport *);
52
53
54
55
56
57
58
59
60
61
62static unsigned int fc_dev_loss_tmo = 60;
63
64module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR);
65MODULE_PARM_DESC(dev_loss_tmo,
66 "Maximum number of seconds that the FC transport should"
67 " insulate the loss of a remote port. Once this value is"
68 " exceeded, the scsi target is removed. Value should be"
69 " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT if"
70 " fast_io_fail_tmo is not set.");
71
72
73
74
75
76#define FC_DEVICE_ATTR(_prefix,_name,_mode,_show,_store) \
77struct device_attribute device_attr_##_prefix##_##_name = \
78 __ATTR(_name,_mode,_show,_store)
79
80#define fc_enum_name_search(title, table_type, table) \
81static const char *get_fc_##title##_name(enum table_type table_key) \
82{ \
83 int i; \
84 char *name = NULL; \
85 \
86 for (i = 0; i < ARRAY_SIZE(table); i++) { \
87 if (table[i].value == table_key) { \
88 name = table[i].name; \
89 break; \
90 } \
91 } \
92 return name; \
93}
94
95#define fc_enum_name_match(title, table_type, table) \
96static int get_fc_##title##_match(const char *table_key, \
97 enum table_type *value) \
98{ \
99 int i; \
100 \
101 for (i = 0; i < ARRAY_SIZE(table); i++) { \
102 if (strncmp(table_key, table[i].name, \
103 table[i].matchlen) == 0) { \
104 *value = table[i].value; \
105 return 0; \
106 } \
107 } \
108 return 1; \
109}
110
111
112
113static struct {
114 enum fc_port_type value;
115 char *name;
116} fc_port_type_names[] = {
117 { FC_PORTTYPE_UNKNOWN, "Unknown" },
118 { FC_PORTTYPE_OTHER, "Other" },
119 { FC_PORTTYPE_NOTPRESENT, "Not Present" },
120 { FC_PORTTYPE_NPORT, "NPort (fabric via point-to-point)" },
121 { FC_PORTTYPE_NLPORT, "NLPort (fabric via loop)" },
122 { FC_PORTTYPE_LPORT, "LPort (private loop)" },
123 { FC_PORTTYPE_PTP, "Point-To-Point (direct nport connection)" },
124 { FC_PORTTYPE_NPIV, "NPIV VPORT" },
125};
126fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
127#define FC_PORTTYPE_MAX_NAMELEN 50
128
129
130#define get_fc_vport_type_name get_fc_port_type_name
131
132
133
134static const struct {
135 enum fc_host_event_code value;
136 char *name;
137} fc_host_event_code_names[] = {
138 { FCH_EVT_LIP, "lip" },
139 { FCH_EVT_LINKUP, "link_up" },
140 { FCH_EVT_LINKDOWN, "link_down" },
141 { FCH_EVT_LIPRESET, "lip_reset" },
142 { FCH_EVT_RSCN, "rscn" },
143 { FCH_EVT_ADAPTER_CHANGE, "adapter_chg" },
144 { FCH_EVT_PORT_UNKNOWN, "port_unknown" },
145 { FCH_EVT_PORT_ONLINE, "port_online" },
146 { FCH_EVT_PORT_OFFLINE, "port_offline" },
147 { FCH_EVT_PORT_FABRIC, "port_fabric" },
148 { FCH_EVT_LINK_UNKNOWN, "link_unknown" },
149 { FCH_EVT_VENDOR_UNIQUE, "vendor_unique" },
150};
151fc_enum_name_search(host_event_code, fc_host_event_code,
152 fc_host_event_code_names)
153#define FC_HOST_EVENT_CODE_MAX_NAMELEN 30
154
155
156
157static struct {
158 enum fc_port_state value;
159 char *name;
160} fc_port_state_names[] = {
161 { FC_PORTSTATE_UNKNOWN, "Unknown" },
162 { FC_PORTSTATE_NOTPRESENT, "Not Present" },
163 { FC_PORTSTATE_ONLINE, "Online" },
164 { FC_PORTSTATE_OFFLINE, "Offline" },
165 { FC_PORTSTATE_BLOCKED, "Blocked" },
166 { FC_PORTSTATE_BYPASSED, "Bypassed" },
167 { FC_PORTSTATE_DIAGNOSTICS, "Diagnostics" },
168 { FC_PORTSTATE_LINKDOWN, "Linkdown" },
169 { FC_PORTSTATE_ERROR, "Error" },
170 { FC_PORTSTATE_LOOPBACK, "Loopback" },
171 { FC_PORTSTATE_DELETED, "Deleted" },
172};
173fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
174#define FC_PORTSTATE_MAX_NAMELEN 20
175
176
177
178static struct {
179 enum fc_vport_state value;
180 char *name;
181} fc_vport_state_names[] = {
182 { FC_VPORT_UNKNOWN, "Unknown" },
183 { FC_VPORT_ACTIVE, "Active" },
184 { FC_VPORT_DISABLED, "Disabled" },
185 { FC_VPORT_LINKDOWN, "Linkdown" },
186 { FC_VPORT_INITIALIZING, "Initializing" },
187 { FC_VPORT_NO_FABRIC_SUPP, "No Fabric Support" },
188 { FC_VPORT_NO_FABRIC_RSCS, "No Fabric Resources" },
189 { FC_VPORT_FABRIC_LOGOUT, "Fabric Logout" },
190 { FC_VPORT_FABRIC_REJ_WWN, "Fabric Rejected WWN" },
191 { FC_VPORT_FAILED, "VPort Failed" },
192};
193fc_enum_name_search(vport_state, fc_vport_state, fc_vport_state_names)
194#define FC_VPORTSTATE_MAX_NAMELEN 24
195
196
197#define get_fc_vport_last_state_name get_fc_vport_state_name
198
199
200
201static const struct {
202 enum fc_tgtid_binding_type value;
203 char *name;
204 int matchlen;
205} fc_tgtid_binding_type_names[] = {
206 { FC_TGTID_BIND_NONE, "none", 4 },
207 { FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 },
208 { FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 },
209 { FC_TGTID_BIND_BY_ID, "port_id (FC Address)", 7 },
210};
211fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type,
212 fc_tgtid_binding_type_names)
213fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type,
214 fc_tgtid_binding_type_names)
215#define FC_BINDTYPE_MAX_NAMELEN 30
216
217
218#define fc_bitfield_name_search(title, table) \
219static ssize_t \
220get_fc_##title##_names(u32 table_key, char *buf) \
221{ \
222 char *prefix = ""; \
223 ssize_t len = 0; \
224 int i; \
225 \
226 for (i = 0; i < ARRAY_SIZE(table); i++) { \
227 if (table[i].value & table_key) { \
228 len += sprintf(buf + len, "%s%s", \
229 prefix, table[i].name); \
230 prefix = ", "; \
231 } \
232 } \
233 len += sprintf(buf + len, "\n"); \
234 return len; \
235}
236
237
238
239static const struct {
240 u32 value;
241 char *name;
242} fc_cos_names[] = {
243 { FC_COS_CLASS1, "Class 1" },
244 { FC_COS_CLASS2, "Class 2" },
245 { FC_COS_CLASS3, "Class 3" },
246 { FC_COS_CLASS4, "Class 4" },
247 { FC_COS_CLASS6, "Class 6" },
248};
249fc_bitfield_name_search(cos, fc_cos_names)
250
251
252
253static const struct {
254 u32 value;
255 char *name;
256} fc_port_speed_names[] = {
257 { FC_PORTSPEED_1GBIT, "1 Gbit" },
258 { FC_PORTSPEED_2GBIT, "2 Gbit" },
259 { FC_PORTSPEED_4GBIT, "4 Gbit" },
260 { FC_PORTSPEED_10GBIT, "10 Gbit" },
261 { FC_PORTSPEED_8GBIT, "8 Gbit" },
262 { FC_PORTSPEED_16GBIT, "16 Gbit" },
263 { FC_PORTSPEED_32GBIT, "32 Gbit" },
264 { FC_PORTSPEED_20GBIT, "20 Gbit" },
265 { FC_PORTSPEED_40GBIT, "40 Gbit" },
266 { FC_PORTSPEED_50GBIT, "50 Gbit" },
267 { FC_PORTSPEED_100GBIT, "100 Gbit" },
268 { FC_PORTSPEED_25GBIT, "25 Gbit" },
269 { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" },
270};
271fc_bitfield_name_search(port_speed, fc_port_speed_names)
272
273
274static int
275show_fc_fc4s (char *buf, u8 *fc4_list)
276{
277 int i, len=0;
278
279 for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++)
280 len += sprintf(buf + len , "0x%02x ", *fc4_list);
281 len += sprintf(buf + len, "\n");
282 return len;
283}
284
285
286
287static const struct {
288 u32 value;
289 char *name;
290} fc_port_role_names[] = {
291 { FC_PORT_ROLE_FCP_TARGET, "FCP Target" },
292 { FC_PORT_ROLE_FCP_INITIATOR, "FCP Initiator" },
293 { FC_PORT_ROLE_IP_PORT, "IP Port" },
294};
295fc_bitfield_name_search(port_roles, fc_port_role_names)
296
297
298
299
300#define FC_WELLKNOWN_PORTID_MASK 0xfffff0
301#define FC_WELLKNOWN_ROLE_MASK 0x00000f
302#define FC_FPORT_PORTID 0x00000e
303#define FC_FABCTLR_PORTID 0x00000d
304#define FC_DIRSRVR_PORTID 0x00000c
305#define FC_TIMESRVR_PORTID 0x00000b
306#define FC_MGMTSRVR_PORTID 0x00000a
307
308
309static void fc_timeout_deleted_rport(struct work_struct *work);
310static void fc_timeout_fail_rport_io(struct work_struct *work);
311static void fc_scsi_scan_rport(struct work_struct *work);
312
313
314
315
316
317#define FC_STARGET_NUM_ATTRS 3
318#define FC_RPORT_NUM_ATTRS 10
319#define FC_VPORT_NUM_ATTRS 9
320#define FC_HOST_NUM_ATTRS 29
321
322struct fc_internal {
323 struct scsi_transport_template t;
324 struct fc_function_template *f;
325
326
327
328
329
330
331
332
333
334
335
336 struct device_attribute private_starget_attrs[
337 FC_STARGET_NUM_ATTRS];
338 struct device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1];
339
340 struct device_attribute private_host_attrs[FC_HOST_NUM_ATTRS];
341 struct device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1];
342
343 struct transport_container rport_attr_cont;
344 struct device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS];
345 struct device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1];
346
347 struct transport_container vport_attr_cont;
348 struct device_attribute private_vport_attrs[FC_VPORT_NUM_ATTRS];
349 struct device_attribute *vport_attrs[FC_VPORT_NUM_ATTRS + 1];
350};
351
352#define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t)
353
354static int fc_target_setup(struct transport_container *tc, struct device *dev,
355 struct device *cdev)
356{
357 struct scsi_target *starget = to_scsi_target(dev);
358 struct fc_rport *rport = starget_to_rport(starget);
359
360
361
362
363
364
365 if (rport) {
366 fc_starget_node_name(starget) = rport->node_name;
367 fc_starget_port_name(starget) = rport->port_name;
368 fc_starget_port_id(starget) = rport->port_id;
369 } else {
370 fc_starget_node_name(starget) = -1;
371 fc_starget_port_name(starget) = -1;
372 fc_starget_port_id(starget) = -1;
373 }
374
375 return 0;
376}
377
378static DECLARE_TRANSPORT_CLASS(fc_transport_class,
379 "fc_transport",
380 fc_target_setup,
381 NULL,
382 NULL);
383
384static int fc_host_setup(struct transport_container *tc, struct device *dev,
385 struct device *cdev)
386{
387 struct Scsi_Host *shost = dev_to_shost(dev);
388 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
389
390
391
392
393
394
395 fc_host->node_name = -1;
396 fc_host->port_name = -1;
397 fc_host->permanent_port_name = -1;
398 fc_host->supported_classes = FC_COS_UNSPECIFIED;
399 memset(fc_host->supported_fc4s, 0,
400 sizeof(fc_host->supported_fc4s));
401 fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN;
402 fc_host->maxframe_size = -1;
403 fc_host->max_npiv_vports = 0;
404 memset(fc_host->serial_number, 0,
405 sizeof(fc_host->serial_number));
406 memset(fc_host->manufacturer, 0,
407 sizeof(fc_host->manufacturer));
408 memset(fc_host->model, 0,
409 sizeof(fc_host->model));
410 memset(fc_host->model_description, 0,
411 sizeof(fc_host->model_description));
412 memset(fc_host->hardware_version, 0,
413 sizeof(fc_host->hardware_version));
414 memset(fc_host->driver_version, 0,
415 sizeof(fc_host->driver_version));
416 memset(fc_host->firmware_version, 0,
417 sizeof(fc_host->firmware_version));
418 memset(fc_host->optionrom_version, 0,
419 sizeof(fc_host->optionrom_version));
420
421 fc_host->port_id = -1;
422 fc_host->port_type = FC_PORTTYPE_UNKNOWN;
423 fc_host->port_state = FC_PORTSTATE_UNKNOWN;
424 memset(fc_host->active_fc4s, 0,
425 sizeof(fc_host->active_fc4s));
426 fc_host->speed = FC_PORTSPEED_UNKNOWN;
427 fc_host->fabric_name = -1;
428 memset(fc_host->symbolic_name, 0, sizeof(fc_host->symbolic_name));
429 memset(fc_host->system_hostname, 0, sizeof(fc_host->system_hostname));
430
431 fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN;
432
433 INIT_LIST_HEAD(&fc_host->rports);
434 INIT_LIST_HEAD(&fc_host->rport_bindings);
435 INIT_LIST_HEAD(&fc_host->vports);
436 fc_host->next_rport_number = 0;
437 fc_host->next_target_id = 0;
438 fc_host->next_vport_number = 0;
439 fc_host->npiv_vports_inuse = 0;
440
441 snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
442 "fc_wq_%d", shost->host_no);
443 fc_host->work_q = alloc_workqueue("%s", 0, 0, fc_host->work_q_name);
444 if (!fc_host->work_q)
445 return -ENOMEM;
446
447 fc_host->dev_loss_tmo = fc_dev_loss_tmo;
448 snprintf(fc_host->devloss_work_q_name,
449 sizeof(fc_host->devloss_work_q_name),
450 "fc_dl_%d", shost->host_no);
451 fc_host->devloss_work_q = alloc_workqueue("%s", 0, 0,
452 fc_host->devloss_work_q_name);
453 if (!fc_host->devloss_work_q) {
454 destroy_workqueue(fc_host->work_q);
455 fc_host->work_q = NULL;
456 return -ENOMEM;
457 }
458
459 fc_bsg_hostadd(shost, fc_host);
460
461
462 return 0;
463}
464
465static int fc_host_remove(struct transport_container *tc, struct device *dev,
466 struct device *cdev)
467{
468 struct Scsi_Host *shost = dev_to_shost(dev);
469 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
470
471 fc_bsg_remove(fc_host->rqst_q);
472 return 0;
473}
474
475static DECLARE_TRANSPORT_CLASS(fc_host_class,
476 "fc_host",
477 fc_host_setup,
478 fc_host_remove,
479 NULL);
480
481
482
483
484
485static DECLARE_TRANSPORT_CLASS(fc_rport_class,
486 "fc_remote_ports",
487 NULL,
488 NULL,
489 NULL);
490
491
492
493
494
495static DECLARE_TRANSPORT_CLASS(fc_vport_class,
496 "fc_vports",
497 NULL,
498 NULL,
499 NULL);
500
501
502
503
504
505static atomic_t fc_event_seq;
506
507
508
509
510
511
512
513
514
515u32
516fc_get_event_number(void)
517{
518 return atomic_add_return(1, &fc_event_seq);
519}
520EXPORT_SYMBOL(fc_get_event_number);
521
522
523
524
525
526
527
528
529
530
531
532
533void
534fc_host_post_event(struct Scsi_Host *shost, u32 event_number,
535 enum fc_host_event_code event_code, u32 event_data)
536{
537 struct sk_buff *skb;
538 struct nlmsghdr *nlh;
539 struct fc_nl_event *event;
540 const char *name;
541 u32 len;
542 int err;
543
544 if (!scsi_nl_sock) {
545 err = -ENOENT;
546 goto send_fail;
547 }
548
549 len = FC_NL_MSGALIGN(sizeof(*event));
550
551 skb = nlmsg_new(len, GFP_KERNEL);
552 if (!skb) {
553 err = -ENOBUFS;
554 goto send_fail;
555 }
556
557 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG, len, 0);
558 if (!nlh) {
559 err = -ENOBUFS;
560 goto send_fail_skb;
561 }
562 event = nlmsg_data(nlh);
563
564 INIT_SCSI_NL_HDR(&event->snlh, SCSI_NL_TRANSPORT_FC,
565 FC_NL_ASYNC_EVENT, len);
566 event->seconds = get_seconds();
567 event->vendor_id = 0;
568 event->host_no = shost->host_no;
569 event->event_datalen = sizeof(u32);
570 event->event_num = event_number;
571 event->event_code = event_code;
572 event->event_data = event_data;
573
574 nlmsg_multicast(scsi_nl_sock, skb, 0, SCSI_NL_GRP_FC_EVENTS,
575 GFP_KERNEL);
576 return;
577
578send_fail_skb:
579 kfree_skb(skb);
580send_fail:
581 name = get_fc_host_event_code_name(event_code);
582 printk(KERN_WARNING
583 "%s: Dropped Event : host %d %s data 0x%08x - err %d\n",
584 __func__, shost->host_no,
585 (name) ? name : "<unknown>", event_data, err);
586 return;
587}
588EXPORT_SYMBOL(fc_host_post_event);
589
590
591
592
593
594
595
596
597
598
599
600
601
602void
603fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
604 u32 data_len, char * data_buf, u64 vendor_id)
605{
606 struct sk_buff *skb;
607 struct nlmsghdr *nlh;
608 struct fc_nl_event *event;
609 u32 len;
610 int err;
611
612 if (!scsi_nl_sock) {
613 err = -ENOENT;
614 goto send_vendor_fail;
615 }
616
617 len = FC_NL_MSGALIGN(sizeof(*event) + data_len);
618
619 skb = nlmsg_new(len, GFP_KERNEL);
620 if (!skb) {
621 err = -ENOBUFS;
622 goto send_vendor_fail;
623 }
624
625 nlh = nlmsg_put(skb, 0, 0, SCSI_TRANSPORT_MSG, len, 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);
1747fc_host_statistic(fcp_packet_alloc_failures);
1748fc_host_statistic(fcp_packet_aborts);
1749fc_host_statistic(fcp_frame_alloc_failures);
1750fc_host_statistic(fc_no_free_exch);
1751fc_host_statistic(fc_no_free_exch_xid);
1752fc_host_statistic(fc_xid_not_found);
1753fc_host_statistic(fc_xid_busy);
1754fc_host_statistic(fc_seq_not_found);
1755fc_host_statistic(fc_non_bls_resp);
1756
1757static ssize_t
1758fc_reset_statistics(struct device *dev, struct device_attribute *attr,
1759 const char *buf, size_t count)
1760{
1761 struct Scsi_Host *shost = transport_class_to_shost(dev);
1762 struct fc_internal *i = to_fc_internal(shost->transportt);
1763
1764
1765 if (i->f->reset_fc_host_stats) {
1766 i->f->reset_fc_host_stats(shost);
1767 return count;
1768 }
1769
1770 return -ENOENT;
1771}
1772static FC_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL,
1773 fc_reset_statistics);
1774
1775static struct attribute *fc_statistics_attrs[] = {
1776 &device_attr_host_seconds_since_last_reset.attr,
1777 &device_attr_host_tx_frames.attr,
1778 &device_attr_host_tx_words.attr,
1779 &device_attr_host_rx_frames.attr,
1780 &device_attr_host_rx_words.attr,
1781 &device_attr_host_lip_count.attr,
1782 &device_attr_host_nos_count.attr,
1783 &device_attr_host_error_frames.attr,
1784 &device_attr_host_dumped_frames.attr,
1785 &device_attr_host_link_failure_count.attr,
1786 &device_attr_host_loss_of_sync_count.attr,
1787 &device_attr_host_loss_of_signal_count.attr,
1788 &device_attr_host_prim_seq_protocol_err_count.attr,
1789 &device_attr_host_invalid_tx_word_count.attr,
1790 &device_attr_host_invalid_crc_count.attr,
1791 &device_attr_host_fcp_input_requests.attr,
1792 &device_attr_host_fcp_output_requests.attr,
1793 &device_attr_host_fcp_control_requests.attr,
1794 &device_attr_host_fcp_input_megabytes.attr,
1795 &device_attr_host_fcp_output_megabytes.attr,
1796 &device_attr_host_fcp_packet_alloc_failures.attr,
1797 &device_attr_host_fcp_packet_aborts.attr,
1798 &device_attr_host_fcp_frame_alloc_failures.attr,
1799 &device_attr_host_fc_no_free_exch.attr,
1800 &device_attr_host_fc_no_free_exch_xid.attr,
1801 &device_attr_host_fc_xid_not_found.attr,
1802 &device_attr_host_fc_xid_busy.attr,
1803 &device_attr_host_fc_seq_not_found.attr,
1804 &device_attr_host_fc_non_bls_resp.attr,
1805 &device_attr_host_reset_statistics.attr,
1806 NULL
1807};
1808
1809static struct attribute_group fc_statistics_group = {
1810 .name = "statistics",
1811 .attrs = fc_statistics_attrs,
1812};
1813
1814
1815
1816
1817static int
1818fc_parse_wwn(const char *ns, u64 *nm)
1819{
1820 unsigned int i, j;
1821 u8 wwn[8];
1822
1823 memset(wwn, 0, sizeof(wwn));
1824
1825
1826 for (i=0, j=0; i < 16; i++) {
1827 int value;
1828
1829 value = hex_to_bin(*ns++);
1830 if (value >= 0)
1831 j = (j << 4) | value;
1832 else
1833 return -EINVAL;
1834 if (i % 2) {
1835 wwn[i/2] = j & 0xff;
1836 j = 0;
1837 }
1838 }
1839
1840 *nm = wwn_to_u64(wwn);
1841
1842 return 0;
1843}
1844
1845
1846
1847
1848
1849
1850
1851
1852static ssize_t
1853store_fc_host_vport_create(struct device *dev, struct device_attribute *attr,
1854 const char *buf, size_t count)
1855{
1856 struct Scsi_Host *shost = transport_class_to_shost(dev);
1857 struct fc_vport_identifiers vid;
1858 struct fc_vport *vport;
1859 unsigned int cnt=count;
1860 int stat;
1861
1862 memset(&vid, 0, sizeof(vid));
1863
1864
1865 if (buf[cnt-1] == '\n')
1866 cnt--;
1867
1868
1869 if ((cnt != (16+1+16)) || (buf[16] != ':'))
1870 return -EINVAL;
1871
1872 stat = fc_parse_wwn(&buf[0], &vid.port_name);
1873 if (stat)
1874 return stat;
1875
1876 stat = fc_parse_wwn(&buf[17], &vid.node_name);
1877 if (stat)
1878 return stat;
1879
1880 vid.roles = FC_PORT_ROLE_FCP_INITIATOR;
1881 vid.vport_type = FC_PORTTYPE_NPIV;
1882
1883 vid.disable = false;
1884
1885
1886 stat = fc_vport_setup(shost, 0, &shost->shost_gendev, &vid, &vport);
1887 return stat ? stat : count;
1888}
1889static FC_DEVICE_ATTR(host, vport_create, S_IWUSR, NULL,
1890 store_fc_host_vport_create);
1891
1892
1893
1894
1895
1896
1897
1898
1899static ssize_t
1900store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr,
1901 const char *buf, size_t count)
1902{
1903 struct Scsi_Host *shost = transport_class_to_shost(dev);
1904 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1905 struct fc_vport *vport;
1906 u64 wwpn, wwnn;
1907 unsigned long flags;
1908 unsigned int cnt=count;
1909 int stat, match;
1910
1911
1912 if (buf[cnt-1] == '\n')
1913 cnt--;
1914
1915
1916 if ((cnt != (16+1+16)) || (buf[16] != ':'))
1917 return -EINVAL;
1918
1919 stat = fc_parse_wwn(&buf[0], &wwpn);
1920 if (stat)
1921 return stat;
1922
1923 stat = fc_parse_wwn(&buf[17], &wwnn);
1924 if (stat)
1925 return stat;
1926
1927 spin_lock_irqsave(shost->host_lock, flags);
1928 match = 0;
1929
1930 list_for_each_entry(vport, &fc_host->vports, peers) {
1931 if ((vport->channel == 0) &&
1932 (vport->port_name == wwpn) && (vport->node_name == wwnn)) {
1933 if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING))
1934 break;
1935 vport->flags |= FC_VPORT_DELETING;
1936 match = 1;
1937 break;
1938 }
1939 }
1940 spin_unlock_irqrestore(shost->host_lock, flags);
1941
1942 if (!match)
1943 return -ENODEV;
1944
1945 stat = fc_vport_terminate(vport);
1946 return stat ? stat : count;
1947}
1948static FC_DEVICE_ATTR(host, vport_delete, S_IWUSR, NULL,
1949 store_fc_host_vport_delete);
1950
1951
1952static int fc_host_match(struct attribute_container *cont,
1953 struct device *dev)
1954{
1955 struct Scsi_Host *shost;
1956 struct fc_internal *i;
1957
1958 if (!scsi_is_host_device(dev))
1959 return 0;
1960
1961 shost = dev_to_shost(dev);
1962 if (!shost->transportt || shost->transportt->host_attrs.ac.class
1963 != &fc_host_class.class)
1964 return 0;
1965
1966 i = to_fc_internal(shost->transportt);
1967
1968 return &i->t.host_attrs.ac == cont;
1969}
1970
1971static int fc_target_match(struct attribute_container *cont,
1972 struct device *dev)
1973{
1974 struct Scsi_Host *shost;
1975 struct fc_internal *i;
1976
1977 if (!scsi_is_target_device(dev))
1978 return 0;
1979
1980 shost = dev_to_shost(dev->parent);
1981 if (!shost->transportt || shost->transportt->host_attrs.ac.class
1982 != &fc_host_class.class)
1983 return 0;
1984
1985 i = to_fc_internal(shost->transportt);
1986
1987 return &i->t.target_attrs.ac == cont;
1988}
1989
1990static void fc_rport_dev_release(struct device *dev)
1991{
1992 struct fc_rport *rport = dev_to_rport(dev);
1993 put_device(dev->parent);
1994 kfree(rport);
1995}
1996
1997int scsi_is_fc_rport(const struct device *dev)
1998{
1999 return dev->release == fc_rport_dev_release;
2000}
2001EXPORT_SYMBOL(scsi_is_fc_rport);
2002
2003static int fc_rport_match(struct attribute_container *cont,
2004 struct device *dev)
2005{
2006 struct Scsi_Host *shost;
2007 struct fc_internal *i;
2008
2009 if (!scsi_is_fc_rport(dev))
2010 return 0;
2011
2012 shost = dev_to_shost(dev->parent);
2013 if (!shost->transportt || shost->transportt->host_attrs.ac.class
2014 != &fc_host_class.class)
2015 return 0;
2016
2017 i = to_fc_internal(shost->transportt);
2018
2019 return &i->rport_attr_cont.ac == cont;
2020}
2021
2022
2023static void fc_vport_dev_release(struct device *dev)
2024{
2025 struct fc_vport *vport = dev_to_vport(dev);
2026 put_device(dev->parent);
2027 kfree(vport);
2028}
2029
2030static int scsi_is_fc_vport(const struct device *dev)
2031{
2032 return dev->release == fc_vport_dev_release;
2033}
2034
2035static int fc_vport_match(struct attribute_container *cont,
2036 struct device *dev)
2037{
2038 struct fc_vport *vport;
2039 struct Scsi_Host *shost;
2040 struct fc_internal *i;
2041
2042 if (!scsi_is_fc_vport(dev))
2043 return 0;
2044 vport = dev_to_vport(dev);
2045
2046 shost = vport_to_shost(vport);
2047 if (!shost->transportt || shost->transportt->host_attrs.ac.class
2048 != &fc_host_class.class)
2049 return 0;
2050
2051 i = to_fc_internal(shost->transportt);
2052 return &i->vport_attr_cont.ac == cont;
2053}
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078static enum blk_eh_timer_return
2079fc_timed_out(struct scsi_cmnd *scmd)
2080{
2081 struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device));
2082
2083 if (rport->port_state == FC_PORTSTATE_BLOCKED)
2084 return BLK_EH_RESET_TIMER;
2085
2086 return BLK_EH_NOT_HANDLED;
2087}
2088
2089
2090
2091
2092
2093
2094static void
2095fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, u64 lun)
2096{
2097 struct fc_rport *rport;
2098 unsigned long flags;
2099
2100 spin_lock_irqsave(shost->host_lock, flags);
2101
2102 list_for_each_entry(rport, &fc_host_rports(shost), peers) {
2103 if (rport->scsi_target_id == -1)
2104 continue;
2105
2106 if (rport->port_state != FC_PORTSTATE_ONLINE)
2107 continue;
2108
2109 if ((channel == rport->channel) &&
2110 (id == rport->scsi_target_id)) {
2111 spin_unlock_irqrestore(shost->host_lock, flags);
2112 scsi_scan_target(&rport->dev, channel, id, lun,
2113 SCSI_SCAN_MANUAL);
2114 return;
2115 }
2116 }
2117
2118 spin_unlock_irqrestore(shost->host_lock, flags);
2119}
2120
2121
2122
2123
2124
2125
2126
2127static int
2128fc_user_scan(struct Scsi_Host *shost, uint channel, uint id, u64 lun)
2129{
2130 uint chlo, chhi;
2131 uint tgtlo, tgthi;
2132
2133 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
2134 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
2135 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
2136 return -EINVAL;
2137
2138 if (channel == SCAN_WILD_CARD) {
2139 chlo = 0;
2140 chhi = shost->max_channel + 1;
2141 } else {
2142 chlo = channel;
2143 chhi = channel + 1;
2144 }
2145
2146 if (id == SCAN_WILD_CARD) {
2147 tgtlo = 0;
2148 tgthi = shost->max_id;
2149 } else {
2150 tgtlo = id;
2151 tgthi = id + 1;
2152 }
2153
2154 for ( ; chlo < chhi; chlo++)
2155 for ( ; tgtlo < tgthi; tgtlo++)
2156 fc_user_scan_tgt(shost, chlo, tgtlo, lun);
2157
2158 return 0;
2159}
2160
2161static int fc_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id,
2162 int result)
2163{
2164 struct fc_internal *i = to_fc_internal(shost->transportt);
2165 return i->f->tsk_mgmt_response(shost, nexus, tm_id, result);
2166}
2167
2168static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result)
2169{
2170 struct fc_internal *i = to_fc_internal(shost->transportt);
2171 return i->f->it_nexus_response(shost, nexus, result);
2172}
2173
2174struct scsi_transport_template *
2175fc_attach_transport(struct fc_function_template *ft)
2176{
2177 int count;
2178 struct fc_internal *i = kzalloc(sizeof(struct fc_internal),
2179 GFP_KERNEL);
2180
2181 if (unlikely(!i))
2182 return NULL;
2183
2184 i->t.target_attrs.ac.attrs = &i->starget_attrs[0];
2185 i->t.target_attrs.ac.class = &fc_transport_class.class;
2186 i->t.target_attrs.ac.match = fc_target_match;
2187 i->t.target_size = sizeof(struct fc_starget_attrs);
2188 transport_container_register(&i->t.target_attrs);
2189
2190 i->t.host_attrs.ac.attrs = &i->host_attrs[0];
2191 i->t.host_attrs.ac.class = &fc_host_class.class;
2192 i->t.host_attrs.ac.match = fc_host_match;
2193 i->t.host_size = sizeof(struct fc_host_attrs);
2194 if (ft->get_fc_host_stats)
2195 i->t.host_attrs.statistics = &fc_statistics_group;
2196 transport_container_register(&i->t.host_attrs);
2197
2198 i->rport_attr_cont.ac.attrs = &i->rport_attrs[0];
2199 i->rport_attr_cont.ac.class = &fc_rport_class.class;
2200 i->rport_attr_cont.ac.match = fc_rport_match;
2201 transport_container_register(&i->rport_attr_cont);
2202
2203 i->vport_attr_cont.ac.attrs = &i->vport_attrs[0];
2204 i->vport_attr_cont.ac.class = &fc_vport_class.class;
2205 i->vport_attr_cont.ac.match = fc_vport_match;
2206 transport_container_register(&i->vport_attr_cont);
2207
2208 i->f = ft;
2209
2210
2211 i->t.create_work_queue = 1;
2212
2213 i->t.eh_timed_out = fc_timed_out;
2214
2215 i->t.user_scan = fc_user_scan;
2216
2217
2218 i->t.tsk_mgmt_response = fc_tsk_mgmt_response;
2219 i->t.it_nexus_response = fc_it_nexus_response;
2220
2221
2222
2223
2224 count = 0;
2225 SETUP_STARGET_ATTRIBUTE_RD(node_name);
2226 SETUP_STARGET_ATTRIBUTE_RD(port_name);
2227 SETUP_STARGET_ATTRIBUTE_RD(port_id);
2228
2229 BUG_ON(count > FC_STARGET_NUM_ATTRS);
2230
2231 i->starget_attrs[count] = NULL;
2232
2233
2234
2235
2236
2237 count=0;
2238 SETUP_HOST_ATTRIBUTE_RD(node_name);
2239 SETUP_HOST_ATTRIBUTE_RD(port_name);
2240 SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
2241 SETUP_HOST_ATTRIBUTE_RD(supported_classes);
2242 SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
2243 SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
2244 SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
2245 if (ft->vport_create) {
2246 SETUP_HOST_ATTRIBUTE_RD_NS(max_npiv_vports);
2247 SETUP_HOST_ATTRIBUTE_RD_NS(npiv_vports_inuse);
2248 }
2249 SETUP_HOST_ATTRIBUTE_RD(serial_number);
2250 SETUP_HOST_ATTRIBUTE_RD(manufacturer);
2251 SETUP_HOST_ATTRIBUTE_RD(model);
2252 SETUP_HOST_ATTRIBUTE_RD(model_description);
2253 SETUP_HOST_ATTRIBUTE_RD(hardware_version);
2254 SETUP_HOST_ATTRIBUTE_RD(driver_version);
2255 SETUP_HOST_ATTRIBUTE_RD(firmware_version);
2256 SETUP_HOST_ATTRIBUTE_RD(optionrom_version);
2257
2258 SETUP_HOST_ATTRIBUTE_RD(port_id);
2259 SETUP_HOST_ATTRIBUTE_RD(port_type);
2260 SETUP_HOST_ATTRIBUTE_RD(port_state);
2261 SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
2262 SETUP_HOST_ATTRIBUTE_RD(speed);
2263 SETUP_HOST_ATTRIBUTE_RD(fabric_name);
2264 SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
2265 SETUP_HOST_ATTRIBUTE_RW(system_hostname);
2266
2267
2268 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(dev_loss_tmo);
2269 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
2270 if (ft->issue_fc_host_lip)
2271 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
2272 if (ft->vport_create)
2273 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_create);
2274 if (ft->vport_delete)
2275 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(vport_delete);
2276
2277 BUG_ON(count > FC_HOST_NUM_ATTRS);
2278
2279 i->host_attrs[count] = NULL;
2280
2281
2282
2283
2284 count=0;
2285 SETUP_RPORT_ATTRIBUTE_RD(maxframe_size);
2286 SETUP_RPORT_ATTRIBUTE_RD(supported_classes);
2287 SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo);
2288 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name);
2289 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name);
2290 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id);
2291 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
2292 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
2293 SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
2294 SETUP_PRIVATE_RPORT_ATTRIBUTE_RW(fast_io_fail_tmo);
2295
2296 BUG_ON(count > FC_RPORT_NUM_ATTRS);
2297
2298 i->rport_attrs[count] = NULL;
2299
2300
2301
2302
2303 count=0;
2304 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_state);
2305 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_last_state);
2306 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(node_name);
2307 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(port_name);
2308 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(roles);
2309 SETUP_PRIVATE_VPORT_ATTRIBUTE_RD(vport_type);
2310 SETUP_VPORT_ATTRIBUTE_RW(symbolic_name);
2311 SETUP_VPORT_ATTRIBUTE_WR(vport_delete);
2312 SETUP_VPORT_ATTRIBUTE_WR(vport_disable);
2313
2314 BUG_ON(count > FC_VPORT_NUM_ATTRS);
2315
2316 i->vport_attrs[count] = NULL;
2317
2318 return &i->t;
2319}
2320EXPORT_SYMBOL(fc_attach_transport);
2321
2322void fc_release_transport(struct scsi_transport_template *t)
2323{
2324 struct fc_internal *i = to_fc_internal(t);
2325
2326 transport_container_unregister(&i->t.target_attrs);
2327 transport_container_unregister(&i->t.host_attrs);
2328 transport_container_unregister(&i->rport_attr_cont);
2329 transport_container_unregister(&i->vport_attr_cont);
2330
2331 kfree(i);
2332}
2333EXPORT_SYMBOL(fc_release_transport);
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345static int
2346fc_queue_work(struct Scsi_Host *shost, struct work_struct *work)
2347{
2348 if (unlikely(!fc_host_work_q(shost))) {
2349 printk(KERN_ERR
2350 "ERROR: FC host '%s' attempted to queue work, "
2351 "when no workqueue created.\n", shost->hostt->name);
2352 dump_stack();
2353
2354 return -EINVAL;
2355 }
2356
2357 return queue_work(fc_host_work_q(shost), work);
2358}
2359
2360
2361
2362
2363
2364static void
2365fc_flush_work(struct Scsi_Host *shost)
2366{
2367 if (!fc_host_work_q(shost)) {
2368 printk(KERN_ERR
2369 "ERROR: FC host '%s' attempted to flush work, "
2370 "when no workqueue created.\n", shost->hostt->name);
2371 dump_stack();
2372 return;
2373 }
2374
2375 flush_workqueue(fc_host_work_q(shost));
2376}
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387static int
2388fc_queue_devloss_work(struct Scsi_Host *shost, struct delayed_work *work,
2389 unsigned long delay)
2390{
2391 if (unlikely(!fc_host_devloss_work_q(shost))) {
2392 printk(KERN_ERR
2393 "ERROR: FC host '%s' attempted to queue work, "
2394 "when no workqueue created.\n", shost->hostt->name);
2395 dump_stack();
2396
2397 return -EINVAL;
2398 }
2399
2400 return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay);
2401}
2402
2403
2404
2405
2406
2407static void
2408fc_flush_devloss(struct Scsi_Host *shost)
2409{
2410 if (!fc_host_devloss_work_q(shost)) {
2411 printk(KERN_ERR
2412 "ERROR: FC host '%s' attempted to flush work, "
2413 "when no workqueue created.\n", shost->hostt->name);
2414 dump_stack();
2415 return;
2416 }
2417
2418 flush_workqueue(fc_host_devloss_work_q(shost));
2419}
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437void
2438fc_remove_host(struct Scsi_Host *shost)
2439{
2440 struct fc_vport *vport = NULL, *next_vport = NULL;
2441 struct fc_rport *rport = NULL, *next_rport = NULL;
2442 struct workqueue_struct *work_q;
2443 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2444 unsigned long flags;
2445
2446 spin_lock_irqsave(shost->host_lock, flags);
2447
2448
2449 list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers)
2450 fc_queue_work(shost, &vport->vport_delete_work);
2451
2452
2453 list_for_each_entry_safe(rport, next_rport,
2454 &fc_host->rports, peers) {
2455 list_del(&rport->peers);
2456 rport->port_state = FC_PORTSTATE_DELETED;
2457 fc_queue_work(shost, &rport->rport_delete_work);
2458 }
2459
2460 list_for_each_entry_safe(rport, next_rport,
2461 &fc_host->rport_bindings, peers) {
2462 list_del(&rport->peers);
2463 rport->port_state = FC_PORTSTATE_DELETED;
2464 fc_queue_work(shost, &rport->rport_delete_work);
2465 }
2466
2467 spin_unlock_irqrestore(shost->host_lock, flags);
2468
2469
2470 scsi_flush_work(shost);
2471
2472
2473 if (fc_host->work_q) {
2474 work_q = fc_host->work_q;
2475 fc_host->work_q = NULL;
2476 destroy_workqueue(work_q);
2477 }
2478
2479
2480 if (fc_host->devloss_work_q) {
2481 work_q = fc_host->devloss_work_q;
2482 fc_host->devloss_work_q = NULL;
2483 destroy_workqueue(work_q);
2484 }
2485}
2486EXPORT_SYMBOL(fc_remove_host);
2487
2488static void fc_terminate_rport_io(struct fc_rport *rport)
2489{
2490 struct Scsi_Host *shost = rport_to_shost(rport);
2491 struct fc_internal *i = to_fc_internal(shost->transportt);
2492
2493
2494 if (i->f->terminate_rport_io)
2495 i->f->terminate_rport_io(rport);
2496
2497
2498
2499
2500 scsi_target_unblock(&rport->dev, SDEV_TRANSPORT_OFFLINE);
2501}
2502
2503
2504
2505
2506
2507
2508
2509static void
2510fc_starget_delete(struct work_struct *work)
2511{
2512 struct fc_rport *rport =
2513 container_of(work, struct fc_rport, stgt_delete_work);
2514
2515 fc_terminate_rport_io(rport);
2516 scsi_remove_target(&rport->dev);
2517}
2518
2519
2520
2521
2522
2523
2524static void
2525fc_rport_final_delete(struct work_struct *work)
2526{
2527 struct fc_rport *rport =
2528 container_of(work, struct fc_rport, rport_delete_work);
2529 struct device *dev = &rport->dev;
2530 struct Scsi_Host *shost = rport_to_shost(rport);
2531 struct fc_internal *i = to_fc_internal(shost->transportt);
2532 unsigned long flags;
2533 int do_callback = 0;
2534
2535 fc_terminate_rport_io(rport);
2536
2537
2538
2539
2540
2541 if (rport->flags & FC_RPORT_SCAN_PENDING)
2542 scsi_flush_work(shost);
2543
2544
2545
2546
2547
2548
2549 spin_lock_irqsave(shost->host_lock, flags);
2550 if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
2551 spin_unlock_irqrestore(shost->host_lock, flags);
2552 if (!cancel_delayed_work(&rport->fail_io_work))
2553 fc_flush_devloss(shost);
2554 if (!cancel_delayed_work(&rport->dev_loss_work))
2555 fc_flush_devloss(shost);
2556 cancel_work_sync(&rport->scan_work);
2557 spin_lock_irqsave(shost->host_lock, flags);
2558 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
2559 }
2560 spin_unlock_irqrestore(shost->host_lock, flags);
2561
2562
2563 if (rport->scsi_target_id != -1)
2564 fc_starget_delete(&rport->stgt_delete_work);
2565
2566
2567
2568
2569
2570
2571
2572
2573 spin_lock_irqsave(shost->host_lock, flags);
2574 if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) &&
2575 (i->f->dev_loss_tmo_callbk)) {
2576 rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
2577 do_callback = 1;
2578 }
2579 spin_unlock_irqrestore(shost->host_lock, flags);
2580
2581 if (do_callback)
2582 i->f->dev_loss_tmo_callbk(rport);
2583
2584 fc_bsg_remove(rport->rqst_q);
2585
2586 transport_remove_device(dev);
2587 device_del(dev);
2588 transport_destroy_device(dev);
2589 scsi_host_put(shost);
2590 put_device(dev);
2591}
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607static struct fc_rport *
2608fc_rport_create(struct Scsi_Host *shost, int channel,
2609 struct fc_rport_identifiers *ids)
2610{
2611 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2612 struct fc_internal *fci = to_fc_internal(shost->transportt);
2613 struct fc_rport *rport;
2614 struct device *dev;
2615 unsigned long flags;
2616 int error;
2617 size_t size;
2618
2619 size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size);
2620 rport = kzalloc(size, GFP_KERNEL);
2621 if (unlikely(!rport)) {
2622 printk(KERN_ERR "%s: allocation failure\n", __func__);
2623 return NULL;
2624 }
2625
2626 rport->maxframe_size = -1;
2627 rport->supported_classes = FC_COS_UNSPECIFIED;
2628 rport->dev_loss_tmo = fc_host->dev_loss_tmo;
2629 memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
2630 memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
2631 rport->port_id = ids->port_id;
2632 rport->roles = ids->roles;
2633 rport->port_state = FC_PORTSTATE_ONLINE;
2634 if (fci->f->dd_fcrport_size)
2635 rport->dd_data = &rport[1];
2636 rport->channel = channel;
2637 rport->fast_io_fail_tmo = -1;
2638
2639 INIT_DELAYED_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport);
2640 INIT_DELAYED_WORK(&rport->fail_io_work, fc_timeout_fail_rport_io);
2641 INIT_WORK(&rport->scan_work, fc_scsi_scan_rport);
2642 INIT_WORK(&rport->stgt_delete_work, fc_starget_delete);
2643 INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete);
2644
2645 spin_lock_irqsave(shost->host_lock, flags);
2646
2647 rport->number = fc_host->next_rport_number++;
2648 if (rport->roles & FC_PORT_ROLE_FCP_TARGET)
2649 rport->scsi_target_id = fc_host->next_target_id++;
2650 else
2651 rport->scsi_target_id = -1;
2652 list_add_tail(&rport->peers, &fc_host->rports);
2653 scsi_host_get(shost);
2654
2655 spin_unlock_irqrestore(shost->host_lock, flags);
2656
2657 dev = &rport->dev;
2658 device_initialize(dev);
2659 dev->parent = get_device(&shost->shost_gendev);
2660 dev->release = fc_rport_dev_release;
2661 dev_set_name(dev, "rport-%d:%d-%d",
2662 shost->host_no, channel, rport->number);
2663 transport_setup_device(dev);
2664
2665 error = device_add(dev);
2666 if (error) {
2667 printk(KERN_ERR "FC Remote Port device_add failed\n");
2668 goto delete_rport;
2669 }
2670 transport_add_device(dev);
2671 transport_configure_device(dev);
2672
2673 fc_bsg_rportadd(shost, rport);
2674
2675
2676 if (rport->roles & FC_PORT_ROLE_FCP_TARGET) {
2677
2678 rport->flags |= FC_RPORT_SCAN_PENDING;
2679 scsi_queue_work(shost, &rport->scan_work);
2680 }
2681
2682 return rport;
2683
2684delete_rport:
2685 transport_destroy_device(dev);
2686 spin_lock_irqsave(shost->host_lock, flags);
2687 list_del(&rport->peers);
2688 scsi_host_put(shost);
2689 spin_unlock_irqrestore(shost->host_lock, flags);
2690 put_device(dev->parent);
2691 kfree(rport);
2692 return NULL;
2693}
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733struct fc_rport *
2734fc_remote_port_add(struct Scsi_Host *shost, int channel,
2735 struct fc_rport_identifiers *ids)
2736{
2737 struct fc_internal *fci = to_fc_internal(shost->transportt);
2738 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2739 struct fc_rport *rport;
2740 unsigned long flags;
2741 int match = 0;
2742
2743
2744 fc_flush_work(shost);
2745
2746
2747
2748
2749
2750
2751 spin_lock_irqsave(shost->host_lock, flags);
2752
2753 list_for_each_entry(rport, &fc_host->rports, peers) {
2754
2755 if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
2756 (rport->channel == channel)) {
2757
2758 switch (fc_host->tgtid_bind_type) {
2759 case FC_TGTID_BIND_BY_WWPN:
2760 case FC_TGTID_BIND_NONE:
2761 if (rport->port_name == ids->port_name)
2762 match = 1;
2763 break;
2764 case FC_TGTID_BIND_BY_WWNN:
2765 if (rport->node_name == ids->node_name)
2766 match = 1;
2767 break;
2768 case FC_TGTID_BIND_BY_ID:
2769 if (rport->port_id == ids->port_id)
2770 match = 1;
2771 break;
2772 }
2773
2774 if (match) {
2775
2776 memcpy(&rport->node_name, &ids->node_name,
2777 sizeof(rport->node_name));
2778 memcpy(&rport->port_name, &ids->port_name,
2779 sizeof(rport->port_name));
2780 rport->port_id = ids->port_id;
2781
2782 rport->port_state = FC_PORTSTATE_ONLINE;
2783 rport->roles = ids->roles;
2784
2785 spin_unlock_irqrestore(shost->host_lock, flags);
2786
2787 if (fci->f->dd_fcrport_size)
2788 memset(rport->dd_data, 0,
2789 fci->f->dd_fcrport_size);
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808 if ((rport->scsi_target_id != -1) &&
2809 (!(ids->roles & FC_PORT_ROLE_FCP_TARGET)))
2810 return rport;
2811
2812
2813
2814
2815
2816
2817 if (!cancel_delayed_work(&rport->fail_io_work))
2818 fc_flush_devloss(shost);
2819 if (!cancel_delayed_work(&rport->dev_loss_work))
2820 fc_flush_devloss(shost);
2821
2822 spin_lock_irqsave(shost->host_lock, flags);
2823
2824 rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
2825 FC_RPORT_DEVLOSS_PENDING |
2826 FC_RPORT_DEVLOSS_CALLBK_DONE);
2827
2828 spin_unlock_irqrestore(shost->host_lock, flags);
2829
2830
2831 if (rport->scsi_target_id != -1) {
2832 scsi_target_unblock(&rport->dev,
2833 SDEV_RUNNING);
2834 spin_lock_irqsave(shost->host_lock,
2835 flags);
2836 rport->flags |= FC_RPORT_SCAN_PENDING;
2837 scsi_queue_work(shost,
2838 &rport->scan_work);
2839 spin_unlock_irqrestore(shost->host_lock,
2840 flags);
2841 }
2842
2843 fc_bsg_goose_queue(rport);
2844
2845 return rport;
2846 }
2847 }
2848 }
2849
2850
2851
2852
2853
2854 if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) {
2855
2856
2857
2858 list_for_each_entry(rport, &fc_host->rport_bindings,
2859 peers) {
2860 if (rport->channel != channel)
2861 continue;
2862
2863 switch (fc_host->tgtid_bind_type) {
2864 case FC_TGTID_BIND_BY_WWPN:
2865 if (rport->port_name == ids->port_name)
2866 match = 1;
2867 break;
2868 case FC_TGTID_BIND_BY_WWNN:
2869 if (rport->node_name == ids->node_name)
2870 match = 1;
2871 break;
2872 case FC_TGTID_BIND_BY_ID:
2873 if (rport->port_id == ids->port_id)
2874 match = 1;
2875 break;
2876 case FC_TGTID_BIND_NONE:
2877 break;
2878 }
2879
2880 if (match) {
2881 list_move_tail(&rport->peers, &fc_host->rports);
2882 break;
2883 }
2884 }
2885
2886 if (match) {
2887 memcpy(&rport->node_name, &ids->node_name,
2888 sizeof(rport->node_name));
2889 memcpy(&rport->port_name, &ids->port_name,
2890 sizeof(rport->port_name));
2891 rport->port_id = ids->port_id;
2892 rport->roles = ids->roles;
2893 rport->port_state = FC_PORTSTATE_ONLINE;
2894 rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
2895
2896 if (fci->f->dd_fcrport_size)
2897 memset(rport->dd_data, 0,
2898 fci->f->dd_fcrport_size);
2899 spin_unlock_irqrestore(shost->host_lock, flags);
2900
2901 if (ids->roles & FC_PORT_ROLE_FCP_TARGET) {
2902 scsi_target_unblock(&rport->dev, SDEV_RUNNING);
2903
2904
2905 spin_lock_irqsave(shost->host_lock, flags);
2906 rport->flags |= FC_RPORT_SCAN_PENDING;
2907 scsi_queue_work(shost, &rport->scan_work);
2908 spin_unlock_irqrestore(shost->host_lock, flags);
2909 }
2910 return rport;
2911 }
2912 }
2913
2914 spin_unlock_irqrestore(shost->host_lock, flags);
2915
2916
2917 rport = fc_rport_create(shost, channel, ids);
2918
2919 return rport;
2920}
2921EXPORT_SYMBOL(fc_remote_port_add);
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
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974void
2975fc_remote_port_delete(struct fc_rport *rport)
2976{
2977 struct Scsi_Host *shost = rport_to_shost(rport);
2978 unsigned long timeout = rport->dev_loss_tmo;
2979 unsigned long flags;
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989 spin_lock_irqsave(shost->host_lock, flags);
2990
2991 if (rport->port_state != FC_PORTSTATE_ONLINE) {
2992 spin_unlock_irqrestore(shost->host_lock, flags);
2993 return;
2994 }
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009 rport->port_state = FC_PORTSTATE_BLOCKED;
3010
3011 rport->flags |= FC_RPORT_DEVLOSS_PENDING;
3012
3013 spin_unlock_irqrestore(shost->host_lock, flags);
3014
3015 scsi_target_block(&rport->dev);
3016
3017
3018 if ((rport->fast_io_fail_tmo != -1) &&
3019 (rport->fast_io_fail_tmo < timeout))
3020 fc_queue_devloss_work(shost, &rport->fail_io_work,
3021 rport->fast_io_fail_tmo * HZ);
3022
3023
3024 fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ);
3025}
3026EXPORT_SYMBOL(fc_remote_port_delete);
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048void
3049fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
3050{
3051 struct Scsi_Host *shost = rport_to_shost(rport);
3052 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3053 unsigned long flags;
3054 int create = 0;
3055
3056 spin_lock_irqsave(shost->host_lock, flags);
3057 if (roles & FC_PORT_ROLE_FCP_TARGET) {
3058 if (rport->scsi_target_id == -1) {
3059 rport->scsi_target_id = fc_host->next_target_id++;
3060 create = 1;
3061 } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET))
3062 create = 1;
3063 }
3064
3065 rport->roles = roles;
3066
3067 spin_unlock_irqrestore(shost->host_lock, flags);
3068
3069 if (create) {
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082 if (!cancel_delayed_work(&rport->fail_io_work))
3083 fc_flush_devloss(shost);
3084 if (!cancel_delayed_work(&rport->dev_loss_work))
3085 fc_flush_devloss(shost);
3086
3087 spin_lock_irqsave(shost->host_lock, flags);
3088 rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT |
3089 FC_RPORT_DEVLOSS_PENDING |
3090 FC_RPORT_DEVLOSS_CALLBK_DONE);
3091 spin_unlock_irqrestore(shost->host_lock, flags);
3092
3093
3094 fc_flush_work(shost);
3095
3096 scsi_target_unblock(&rport->dev, SDEV_RUNNING);
3097
3098 spin_lock_irqsave(shost->host_lock, flags);
3099 rport->flags |= FC_RPORT_SCAN_PENDING;
3100 scsi_queue_work(shost, &rport->scan_work);
3101 spin_unlock_irqrestore(shost->host_lock, flags);
3102 }
3103}
3104EXPORT_SYMBOL(fc_remote_port_rolechg);
3105
3106
3107
3108
3109
3110
3111
3112
3113static void
3114fc_timeout_deleted_rport(struct work_struct *work)
3115{
3116 struct fc_rport *rport =
3117 container_of(work, struct fc_rport, dev_loss_work.work);
3118 struct Scsi_Host *shost = rport_to_shost(rport);
3119 struct fc_internal *i = to_fc_internal(shost->transportt);
3120 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3121 unsigned long flags;
3122 int do_callback = 0;
3123
3124 spin_lock_irqsave(shost->host_lock, flags);
3125
3126 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
3127
3128
3129
3130
3131
3132
3133 if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
3134 (rport->scsi_target_id != -1) &&
3135 !(rport->roles & FC_PORT_ROLE_FCP_TARGET)) {
3136 dev_printk(KERN_ERR, &rport->dev,
3137 "blocked FC remote port time out: no longer"
3138 " a FCP target, removing starget\n");
3139 spin_unlock_irqrestore(shost->host_lock, flags);
3140 scsi_target_unblock(&rport->dev, SDEV_TRANSPORT_OFFLINE);
3141 fc_queue_work(shost, &rport->stgt_delete_work);
3142 return;
3143 }
3144
3145
3146 if (rport->port_state != FC_PORTSTATE_BLOCKED) {
3147 spin_unlock_irqrestore(shost->host_lock, flags);
3148 dev_printk(KERN_ERR, &rport->dev,
3149 "blocked FC remote port time out: leaving"
3150 " rport%s alone\n",
3151 (rport->scsi_target_id != -1) ? " and starget" : "");
3152 return;
3153 }
3154
3155 if ((fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) ||
3156 (rport->scsi_target_id == -1)) {
3157 list_del(&rport->peers);
3158 rport->port_state = FC_PORTSTATE_DELETED;
3159 dev_printk(KERN_ERR, &rport->dev,
3160 "blocked FC remote port time out: removing"
3161 " rport%s\n",
3162 (rport->scsi_target_id != -1) ? " and starget" : "");
3163 fc_queue_work(shost, &rport->rport_delete_work);
3164 spin_unlock_irqrestore(shost->host_lock, flags);
3165 return;
3166 }
3167
3168 dev_printk(KERN_ERR, &rport->dev,
3169 "blocked FC remote port time out: removing target and "
3170 "saving binding\n");
3171
3172 list_move_tail(&rport->peers, &fc_host->rport_bindings);
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183 rport->maxframe_size = -1;
3184 rport->supported_classes = FC_COS_UNSPECIFIED;
3185 rport->roles = FC_PORT_ROLE_UNKNOWN;
3186 rport->port_state = FC_PORTSTATE_NOTPRESENT;
3187 rport->flags &= ~FC_RPORT_FAST_FAIL_TIMEDOUT;
3188
3189
3190
3191
3192
3193
3194 spin_unlock_irqrestore(shost->host_lock, flags);
3195 fc_terminate_rport_io(rport);
3196
3197 spin_lock_irqsave(shost->host_lock, flags);
3198
3199 if (rport->port_state == FC_PORTSTATE_NOTPRESENT) {
3200
3201
3202 switch (fc_host->tgtid_bind_type) {
3203 case FC_TGTID_BIND_BY_WWPN:
3204 rport->node_name = -1;
3205 rport->port_id = -1;
3206 break;
3207 case FC_TGTID_BIND_BY_WWNN:
3208 rport->port_name = -1;
3209 rport->port_id = -1;
3210 break;
3211 case FC_TGTID_BIND_BY_ID:
3212 rport->node_name = -1;
3213 rport->port_name = -1;
3214 break;
3215 case FC_TGTID_BIND_NONE:
3216 break;
3217 }
3218
3219
3220
3221
3222
3223
3224 rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE;
3225 fc_queue_work(shost, &rport->stgt_delete_work);
3226
3227 do_callback = 1;
3228 }
3229
3230 spin_unlock_irqrestore(shost->host_lock, flags);
3231
3232
3233
3234
3235
3236
3237
3238 if (do_callback && i->f->dev_loss_tmo_callbk)
3239 i->f->dev_loss_tmo_callbk(rport);
3240}
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250static void
3251fc_timeout_fail_rport_io(struct work_struct *work)
3252{
3253 struct fc_rport *rport =
3254 container_of(work, struct fc_rport, fail_io_work.work);
3255
3256 if (rport->port_state != FC_PORTSTATE_BLOCKED)
3257 return;
3258
3259 rport->flags |= FC_RPORT_FAST_FAIL_TIMEDOUT;
3260 fc_terminate_rport_io(rport);
3261}
3262
3263
3264
3265
3266
3267static void
3268fc_scsi_scan_rport(struct work_struct *work)
3269{
3270 struct fc_rport *rport =
3271 container_of(work, struct fc_rport, scan_work);
3272 struct Scsi_Host *shost = rport_to_shost(rport);
3273 struct fc_internal *i = to_fc_internal(shost->transportt);
3274 unsigned long flags;
3275
3276 if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
3277 (rport->roles & FC_PORT_ROLE_FCP_TARGET) &&
3278 !(i->f->disable_target_scan)) {
3279 scsi_scan_target(&rport->dev, rport->channel,
3280 rport->scsi_target_id, SCAN_WILD_CARD,
3281 SCSI_SCAN_RESCAN);
3282 }
3283
3284 spin_lock_irqsave(shost->host_lock, flags);
3285 rport->flags &= ~FC_RPORT_SCAN_PENDING;
3286 spin_unlock_irqrestore(shost->host_lock, flags);
3287}
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
3304{
3305 struct Scsi_Host *shost = cmnd->device->host;
3306 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
3307 unsigned long flags;
3308
3309 spin_lock_irqsave(shost->host_lock, flags);
3310 while (rport->port_state == FC_PORTSTATE_BLOCKED &&
3311 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)) {
3312 spin_unlock_irqrestore(shost->host_lock, flags);
3313 msleep(1000);
3314 spin_lock_irqsave(shost->host_lock, flags);
3315 }
3316 spin_unlock_irqrestore(shost->host_lock, flags);
3317
3318 if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
3319 return FAST_IO_FAIL;
3320
3321 return 0;
3322}
3323EXPORT_SYMBOL(fc_block_scsi_eh);
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340static int
3341fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev,
3342 struct fc_vport_identifiers *ids, struct fc_vport **ret_vport)
3343{
3344 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3345 struct fc_internal *fci = to_fc_internal(shost->transportt);
3346 struct fc_vport *vport;
3347 struct device *dev;
3348 unsigned long flags;
3349 size_t size;
3350 int error;
3351
3352 *ret_vport = NULL;
3353
3354 if ( ! fci->f->vport_create)
3355 return -ENOENT;
3356
3357 size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size);
3358 vport = kzalloc(size, GFP_KERNEL);
3359 if (unlikely(!vport)) {
3360 printk(KERN_ERR "%s: allocation failure\n", __func__);
3361 return -ENOMEM;
3362 }
3363
3364 vport->vport_state = FC_VPORT_UNKNOWN;
3365 vport->vport_last_state = FC_VPORT_UNKNOWN;
3366 vport->node_name = ids->node_name;
3367 vport->port_name = ids->port_name;
3368 vport->roles = ids->roles;
3369 vport->vport_type = ids->vport_type;
3370 if (fci->f->dd_fcvport_size)
3371 vport->dd_data = &vport[1];
3372 vport->shost = shost;
3373 vport->channel = channel;
3374 vport->flags = FC_VPORT_CREATING;
3375 INIT_WORK(&vport->vport_delete_work, fc_vport_sched_delete);
3376
3377 spin_lock_irqsave(shost->host_lock, flags);
3378
3379 if (fc_host->npiv_vports_inuse >= fc_host->max_npiv_vports) {
3380 spin_unlock_irqrestore(shost->host_lock, flags);
3381 kfree(vport);
3382 return -ENOSPC;
3383 }
3384 fc_host->npiv_vports_inuse++;
3385 vport->number = fc_host->next_vport_number++;
3386 list_add_tail(&vport->peers, &fc_host->vports);
3387 scsi_host_get(shost);
3388
3389 spin_unlock_irqrestore(shost->host_lock, flags);
3390
3391 dev = &vport->dev;
3392 device_initialize(dev);
3393 dev->parent = get_device(pdev);
3394 dev->release = fc_vport_dev_release;
3395 dev_set_name(dev, "vport-%d:%d-%d",
3396 shost->host_no, channel, vport->number);
3397 transport_setup_device(dev);
3398
3399 error = device_add(dev);
3400 if (error) {
3401 printk(KERN_ERR "FC Virtual Port device_add failed\n");
3402 goto delete_vport;
3403 }
3404 transport_add_device(dev);
3405 transport_configure_device(dev);
3406
3407 error = fci->f->vport_create(vport, ids->disable);
3408 if (error) {
3409 printk(KERN_ERR "FC Virtual Port LLDD Create failed\n");
3410 goto delete_vport_all;
3411 }
3412
3413
3414
3415
3416
3417 if (pdev != &shost->shost_gendev) {
3418 error = sysfs_create_link(&shost->shost_gendev.kobj,
3419 &dev->kobj, dev_name(dev));
3420 if (error)
3421 printk(KERN_ERR
3422 "%s: Cannot create vport symlinks for "
3423 "%s, err=%d\n",
3424 __func__, dev_name(dev), error);
3425 }
3426 spin_lock_irqsave(shost->host_lock, flags);
3427 vport->flags &= ~FC_VPORT_CREATING;
3428 spin_unlock_irqrestore(shost->host_lock, flags);
3429
3430 dev_printk(KERN_NOTICE, pdev,
3431 "%s created via shost%d channel %d\n", dev_name(dev),
3432 shost->host_no, channel);
3433
3434 *ret_vport = vport;
3435
3436 return 0;
3437
3438delete_vport_all:
3439 transport_remove_device(dev);
3440 device_del(dev);
3441delete_vport:
3442 transport_destroy_device(dev);
3443 spin_lock_irqsave(shost->host_lock, flags);
3444 list_del(&vport->peers);
3445 scsi_host_put(shost);
3446 fc_host->npiv_vports_inuse--;
3447 spin_unlock_irqrestore(shost->host_lock, flags);
3448 put_device(dev->parent);
3449 kfree(vport);
3450
3451 return error;
3452}
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464struct fc_vport *
3465fc_vport_create(struct Scsi_Host *shost, int channel,
3466 struct fc_vport_identifiers *ids)
3467{
3468 int stat;
3469 struct fc_vport *vport;
3470
3471 stat = fc_vport_setup(shost, channel, &shost->shost_gendev,
3472 ids, &vport);
3473 return stat ? NULL : vport;
3474}
3475EXPORT_SYMBOL(fc_vport_create);
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487int
3488fc_vport_terminate(struct fc_vport *vport)
3489{
3490 struct Scsi_Host *shost = vport_to_shost(vport);
3491 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3492 struct fc_internal *i = to_fc_internal(shost->transportt);
3493 struct device *dev = &vport->dev;
3494 unsigned long flags;
3495 int stat;
3496
3497 if (i->f->vport_delete)
3498 stat = i->f->vport_delete(vport);
3499 else
3500 stat = -ENOENT;
3501
3502 spin_lock_irqsave(shost->host_lock, flags);
3503 vport->flags &= ~FC_VPORT_DELETING;
3504 if (!stat) {
3505 vport->flags |= FC_VPORT_DELETED;
3506 list_del(&vport->peers);
3507 fc_host->npiv_vports_inuse--;
3508 scsi_host_put(shost);
3509 }
3510 spin_unlock_irqrestore(shost->host_lock, flags);
3511
3512 if (stat)
3513 return stat;
3514
3515 if (dev->parent != &shost->shost_gendev)
3516 sysfs_remove_link(&shost->shost_gendev.kobj, dev_name(dev));
3517 transport_remove_device(dev);
3518 device_del(dev);
3519 transport_destroy_device(dev);
3520
3521
3522
3523
3524
3525
3526 put_device(dev);
3527
3528 return 0;
3529}
3530EXPORT_SYMBOL(fc_vport_terminate);
3531
3532
3533
3534
3535
3536static void
3537fc_vport_sched_delete(struct work_struct *work)
3538{
3539 struct fc_vport *vport =
3540 container_of(work, struct fc_vport, vport_delete_work);
3541 int stat;
3542
3543 stat = fc_vport_terminate(vport);
3544 if (stat)
3545 dev_printk(KERN_ERR, vport->dev.parent,
3546 "%s: %s could not be deleted created via "
3547 "shost%d channel %d - error %d\n", __func__,
3548 dev_name(&vport->dev), vport->shost->host_no,
3549 vport->channel, stat);
3550}
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562static void
3563fc_destroy_bsgjob(struct fc_bsg_job *job)
3564{
3565 unsigned long flags;
3566
3567 spin_lock_irqsave(&job->job_lock, flags);
3568 if (job->ref_cnt) {
3569 spin_unlock_irqrestore(&job->job_lock, flags);
3570 return;
3571 }
3572 spin_unlock_irqrestore(&job->job_lock, flags);
3573
3574 put_device(job->dev);
3575
3576 kfree(job->request_payload.sg_list);
3577 kfree(job->reply_payload.sg_list);
3578 kfree(job);
3579}
3580
3581
3582
3583
3584
3585
3586static void
3587fc_bsg_jobdone(struct fc_bsg_job *job)
3588{
3589 struct request *req = job->req;
3590 struct request *rsp = req->next_rq;
3591 int err;
3592
3593 err = job->req->errors = job->reply->result;
3594
3595 if (err < 0)
3596
3597 job->req->sense_len = sizeof(uint32_t);
3598 else
3599 job->req->sense_len = job->reply_len;
3600
3601
3602 req->resid_len = 0;
3603
3604 if (rsp) {
3605 WARN_ON(job->reply->reply_payload_rcv_len > rsp->resid_len);
3606
3607
3608 rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
3609 rsp->resid_len);
3610 }
3611 blk_complete_request(req);
3612}
3613
3614
3615
3616
3617
3618static void fc_bsg_softirq_done(struct request *rq)
3619{
3620 struct fc_bsg_job *job = rq->special;
3621 unsigned long flags;
3622
3623 spin_lock_irqsave(&job->job_lock, flags);
3624 job->state_flags |= FC_RQST_STATE_DONE;
3625 job->ref_cnt--;
3626 spin_unlock_irqrestore(&job->job_lock, flags);
3627
3628 blk_end_request_all(rq, rq->errors);
3629 fc_destroy_bsgjob(job);
3630}
3631
3632
3633
3634
3635
3636static enum blk_eh_timer_return
3637fc_bsg_job_timeout(struct request *req)
3638{
3639 struct fc_bsg_job *job = (void *) req->special;
3640 struct Scsi_Host *shost = job->shost;
3641 struct fc_internal *i = to_fc_internal(shost->transportt);
3642 unsigned long flags;
3643 int err = 0, done = 0;
3644
3645 if (job->rport && job->rport->port_state == FC_PORTSTATE_BLOCKED)
3646 return BLK_EH_RESET_TIMER;
3647
3648 spin_lock_irqsave(&job->job_lock, flags);
3649 if (job->state_flags & FC_RQST_STATE_DONE)
3650 done = 1;
3651 else
3652 job->ref_cnt++;
3653 spin_unlock_irqrestore(&job->job_lock, flags);
3654
3655 if (!done && i->f->bsg_timeout) {
3656
3657 err = i->f->bsg_timeout(job);
3658 if (err == -EAGAIN) {
3659 job->ref_cnt--;
3660 return BLK_EH_RESET_TIMER;
3661 } else if (err)
3662 printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
3663 "abort failed with status %d\n", err);
3664 }
3665
3666
3667 if (done)
3668 return BLK_EH_NOT_HANDLED;
3669 else
3670 return BLK_EH_HANDLED;
3671}
3672
3673static int
3674fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req)
3675{
3676 size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);
3677
3678 BUG_ON(!req->nr_phys_segments);
3679
3680 buf->sg_list = kzalloc(sz, GFP_KERNEL);
3681 if (!buf->sg_list)
3682 return -ENOMEM;
3683 sg_init_table(buf->sg_list, req->nr_phys_segments);
3684 buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
3685 buf->payload_len = blk_rq_bytes(req);
3686 return 0;
3687}
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697static int
3698fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
3699 struct request *req)
3700{
3701 struct fc_internal *i = to_fc_internal(shost->transportt);
3702 struct request *rsp = req->next_rq;
3703 struct fc_bsg_job *job;
3704 int ret;
3705
3706 BUG_ON(req->special);
3707
3708 job = kzalloc(sizeof(struct fc_bsg_job) + i->f->dd_bsg_size,
3709 GFP_KERNEL);
3710 if (!job)
3711 return -ENOMEM;
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722 req->special = job;
3723 job->shost = shost;
3724 job->rport = rport;
3725 job->req = req;
3726 if (i->f->dd_bsg_size)
3727 job->dd_data = (void *)&job[1];
3728 spin_lock_init(&job->job_lock);
3729 job->request = (struct fc_bsg_request *)req->cmd;
3730 job->request_len = req->cmd_len;
3731 job->reply = req->sense;
3732 job->reply_len = SCSI_SENSE_BUFFERSIZE;
3733
3734 if (req->bio) {
3735 ret = fc_bsg_map_buffer(&job->request_payload, req);
3736 if (ret)
3737 goto failjob_rls_job;
3738 }
3739 if (rsp && rsp->bio) {
3740 ret = fc_bsg_map_buffer(&job->reply_payload, rsp);
3741 if (ret)
3742 goto failjob_rls_rqst_payload;
3743 }
3744 job->job_done = fc_bsg_jobdone;
3745 if (rport)
3746 job->dev = &rport->dev;
3747 else
3748 job->dev = &shost->shost_gendev;
3749 get_device(job->dev);
3750
3751 job->ref_cnt = 1;
3752
3753 return 0;
3754
3755
3756failjob_rls_rqst_payload:
3757 kfree(job->request_payload.sg_list);
3758failjob_rls_job:
3759 kfree(job);
3760 return -ENOMEM;
3761}
3762
3763
3764enum fc_dispatch_result {
3765 FC_DISPATCH_BREAK,
3766 FC_DISPATCH_LOCKED,
3767 FC_DISPATCH_UNLOCKED,
3768};
3769
3770
3771
3772
3773
3774
3775
3776
3777static enum fc_dispatch_result
3778fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
3779 struct fc_bsg_job *job)
3780{
3781 struct fc_internal *i = to_fc_internal(shost->transportt);
3782 int cmdlen = sizeof(uint32_t);
3783 int ret;
3784
3785
3786 switch (job->request->msgcode) {
3787 case FC_BSG_HST_ADD_RPORT:
3788 cmdlen += sizeof(struct fc_bsg_host_add_rport);
3789 break;
3790
3791 case FC_BSG_HST_DEL_RPORT:
3792 cmdlen += sizeof(struct fc_bsg_host_del_rport);
3793 break;
3794
3795 case FC_BSG_HST_ELS_NOLOGIN:
3796 cmdlen += sizeof(struct fc_bsg_host_els);
3797
3798 if ((!job->request_payload.payload_len) ||
3799 (!job->reply_payload.payload_len)) {
3800 ret = -EINVAL;
3801 goto fail_host_msg;
3802 }
3803 break;
3804
3805 case FC_BSG_HST_CT:
3806 cmdlen += sizeof(struct fc_bsg_host_ct);
3807
3808 if ((!job->request_payload.payload_len) ||
3809 (!job->reply_payload.payload_len)) {
3810 ret = -EINVAL;
3811 goto fail_host_msg;
3812 }
3813 break;
3814
3815 case FC_BSG_HST_VENDOR:
3816 cmdlen += sizeof(struct fc_bsg_host_vendor);
3817 if ((shost->hostt->vendor_id == 0L) ||
3818 (job->request->rqst_data.h_vendor.vendor_id !=
3819 shost->hostt->vendor_id)) {
3820 ret = -ESRCH;
3821 goto fail_host_msg;
3822 }
3823 break;
3824
3825 default:
3826 ret = -EBADR;
3827 goto fail_host_msg;
3828 }
3829
3830
3831 if (job->request_len < cmdlen) {
3832 ret = -ENOMSG;
3833 goto fail_host_msg;
3834 }
3835
3836 ret = i->f->bsg_request(job);
3837 if (!ret)
3838 return FC_DISPATCH_UNLOCKED;
3839
3840fail_host_msg:
3841
3842 BUG_ON(job->reply_len < sizeof(uint32_t));
3843 job->reply->reply_payload_rcv_len = 0;
3844 job->reply->result = ret;
3845 job->reply_len = sizeof(uint32_t);
3846 fc_bsg_jobdone(job);
3847 return FC_DISPATCH_UNLOCKED;
3848}
3849
3850
3851
3852
3853
3854
3855static void
3856fc_bsg_goose_queue(struct fc_rport *rport)
3857{
3858 if (!rport->rqst_q)
3859 return;
3860
3861
3862
3863
3864 get_device(&rport->dev);
3865 blk_run_queue_async(rport->rqst_q);
3866 put_device(&rport->dev);
3867}
3868
3869
3870
3871
3872
3873
3874
3875
3876static enum fc_dispatch_result
3877fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
3878 struct fc_rport *rport, struct fc_bsg_job *job)
3879{
3880 struct fc_internal *i = to_fc_internal(shost->transportt);
3881 int cmdlen = sizeof(uint32_t);
3882 int ret;
3883
3884
3885 switch (job->request->msgcode) {
3886 case FC_BSG_RPT_ELS:
3887 cmdlen += sizeof(struct fc_bsg_rport_els);
3888 goto check_bidi;
3889
3890 case FC_BSG_RPT_CT:
3891 cmdlen += sizeof(struct fc_bsg_rport_ct);
3892check_bidi:
3893
3894 if ((!job->request_payload.payload_len) ||
3895 (!job->reply_payload.payload_len)) {
3896 ret = -EINVAL;
3897 goto fail_rport_msg;
3898 }
3899 break;
3900 default:
3901 ret = -EBADR;
3902 goto fail_rport_msg;
3903 }
3904
3905
3906 if (job->request_len < cmdlen) {
3907 ret = -ENOMSG;
3908 goto fail_rport_msg;
3909 }
3910
3911 ret = i->f->bsg_request(job);
3912 if (!ret)
3913 return FC_DISPATCH_UNLOCKED;
3914
3915fail_rport_msg:
3916
3917 BUG_ON(job->reply_len < sizeof(uint32_t));
3918 job->reply->reply_payload_rcv_len = 0;
3919 job->reply->result = ret;
3920 job->reply_len = sizeof(uint32_t);
3921 fc_bsg_jobdone(job);
3922 return FC_DISPATCH_UNLOCKED;
3923}
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933static void
3934fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3935 struct fc_rport *rport, struct device *dev)
3936{
3937 struct request *req;
3938 struct fc_bsg_job *job;
3939 enum fc_dispatch_result ret;
3940
3941 if (!get_device(dev))
3942 return;
3943
3944 while (1) {
3945 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
3946 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
3947 break;
3948
3949 req = blk_fetch_request(q);
3950 if (!req)
3951 break;
3952
3953 if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
3954 req->errors = -ENXIO;
3955 spin_unlock_irq(q->queue_lock);
3956 blk_end_request_all(req, -ENXIO);
3957 spin_lock_irq(q->queue_lock);
3958 continue;
3959 }
3960
3961 spin_unlock_irq(q->queue_lock);
3962
3963 ret = fc_req_to_bsgjob(shost, rport, req);
3964 if (ret) {
3965 req->errors = ret;
3966 blk_end_request_all(req, ret);
3967 spin_lock_irq(q->queue_lock);
3968 continue;
3969 }
3970
3971 job = req->special;
3972
3973
3974 if (job->request_len < sizeof(uint32_t)) {
3975 BUG_ON(job->reply_len < sizeof(uint32_t));
3976 job->reply->reply_payload_rcv_len = 0;
3977 job->reply->result = -ENOMSG;
3978 job->reply_len = sizeof(uint32_t);
3979 fc_bsg_jobdone(job);
3980 spin_lock_irq(q->queue_lock);
3981 continue;
3982 }
3983
3984
3985 if (rport)
3986 ret = fc_bsg_rport_dispatch(q, shost, rport, job);
3987 else
3988 ret = fc_bsg_host_dispatch(q, shost, job);
3989
3990
3991 if (ret == FC_DISPATCH_BREAK)
3992 break;
3993
3994
3995 if (ret == FC_DISPATCH_UNLOCKED)
3996 spin_lock_irq(q->queue_lock);
3997 }
3998
3999 spin_unlock_irq(q->queue_lock);
4000 put_device(dev);
4001 spin_lock_irq(q->queue_lock);
4002}
4003
4004
4005
4006
4007
4008
4009static void
4010fc_bsg_host_handler(struct request_queue *q)
4011{
4012 struct Scsi_Host *shost = q->queuedata;
4013
4014 fc_bsg_request_handler(q, shost, NULL, &shost->shost_gendev);
4015}
4016
4017
4018
4019
4020
4021
4022static void
4023fc_bsg_rport_handler(struct request_queue *q)
4024{
4025 struct fc_rport *rport = q->queuedata;
4026 struct Scsi_Host *shost = rport_to_shost(rport);
4027
4028 fc_bsg_request_handler(q, shost, rport, &rport->dev);
4029}
4030
4031
4032
4033
4034
4035
4036
4037static int
4038fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
4039{
4040 struct device *dev = &shost->shost_gendev;
4041 struct fc_internal *i = to_fc_internal(shost->transportt);
4042 struct request_queue *q;
4043 int err;
4044 char bsg_name[20];
4045
4046 fc_host->rqst_q = NULL;
4047
4048 if (!i->f->bsg_request)
4049 return -ENOTSUPP;
4050
4051 snprintf(bsg_name, sizeof(bsg_name),
4052 "fc_host%d", shost->host_no);
4053
4054 q = __scsi_alloc_queue(shost, fc_bsg_host_handler);
4055 if (!q) {
4056 printk(KERN_ERR "fc_host%d: bsg interface failed to "
4057 "initialize - no request queue\n",
4058 shost->host_no);
4059 return -ENOMEM;
4060 }
4061
4062 q->queuedata = shost;
4063 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
4064 blk_queue_softirq_done(q, fc_bsg_softirq_done);
4065 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
4066 blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
4067
4068 err = bsg_register_queue(q, dev, bsg_name, NULL);
4069 if (err) {
4070 printk(KERN_ERR "fc_host%d: bsg interface failed to "
4071 "initialize - register queue\n",
4072 shost->host_no);
4073 blk_cleanup_queue(q);
4074 return err;
4075 }
4076
4077 fc_host->rqst_q = q;
4078 return 0;
4079}
4080
4081
4082
4083
4084
4085
4086
4087static int
4088fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
4089{
4090 struct device *dev = &rport->dev;
4091 struct fc_internal *i = to_fc_internal(shost->transportt);
4092 struct request_queue *q;
4093 int err;
4094
4095 rport->rqst_q = NULL;
4096
4097 if (!i->f->bsg_request)
4098 return -ENOTSUPP;
4099
4100 q = __scsi_alloc_queue(shost, fc_bsg_rport_handler);
4101 if (!q) {
4102 printk(KERN_ERR "%s: bsg interface failed to "
4103 "initialize - no request queue\n",
4104 dev->kobj.name);
4105 return -ENOMEM;
4106 }
4107
4108 q->queuedata = rport;
4109 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
4110 blk_queue_softirq_done(q, fc_bsg_softirq_done);
4111 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
4112 blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
4113
4114 err = bsg_register_queue(q, dev, NULL, NULL);
4115 if (err) {
4116 printk(KERN_ERR "%s: bsg interface failed to "
4117 "initialize - register queue\n",
4118 dev->kobj.name);
4119 blk_cleanup_queue(q);
4120 return err;
4121 }
4122
4123 rport->rqst_q = q;
4124 return 0;
4125}
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137static void
4138fc_bsg_remove(struct request_queue *q)
4139{
4140 if (q) {
4141 bsg_unregister_queue(q);
4142 blk_cleanup_queue(q);
4143 }
4144}
4145
4146
4147
4148MODULE_AUTHOR("James Smart");
4149MODULE_DESCRIPTION("FC Transport Attributes");
4150MODULE_LICENSE("GPL");
4151
4152module_init(fc_transport_init);
4153module_exit(fc_transport_exit);
4154