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
2030int scsi_is_fc_vport(const struct device *dev)
2031{
2032 return dev->release == fc_vport_dev_release;
2033}
2034EXPORT_SYMBOL(scsi_is_fc_vport);
2035
2036static int fc_vport_match(struct attribute_container *cont,
2037 struct device *dev)
2038{
2039 struct fc_vport *vport;
2040 struct Scsi_Host *shost;
2041 struct fc_internal *i;
2042
2043 if (!scsi_is_fc_vport(dev))
2044 return 0;
2045 vport = dev_to_vport(dev);
2046
2047 shost = vport_to_shost(vport);
2048 if (!shost->transportt || shost->transportt->host_attrs.ac.class
2049 != &fc_host_class.class)
2050 return 0;
2051
2052 i = to_fc_internal(shost->transportt);
2053 return &i->vport_attr_cont.ac == cont;
2054}
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079static enum blk_eh_timer_return
2080fc_timed_out(struct scsi_cmnd *scmd)
2081{
2082 struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device));
2083
2084 if (rport->port_state == FC_PORTSTATE_BLOCKED)
2085 return BLK_EH_RESET_TIMER;
2086
2087 return BLK_EH_NOT_HANDLED;
2088}
2089
2090
2091
2092
2093
2094
2095static void
2096fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, u64 lun)
2097{
2098 struct fc_rport *rport;
2099 unsigned long flags;
2100
2101 spin_lock_irqsave(shost->host_lock, flags);
2102
2103 list_for_each_entry(rport, &fc_host_rports(shost), peers) {
2104 if (rport->scsi_target_id == -1)
2105 continue;
2106
2107 if (rport->port_state != FC_PORTSTATE_ONLINE)
2108 continue;
2109
2110 if ((channel == rport->channel) &&
2111 (id == rport->scsi_target_id)) {
2112 spin_unlock_irqrestore(shost->host_lock, flags);
2113 scsi_scan_target(&rport->dev, channel, id, lun, 1);
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, 1);
3281 }
3282
3283 spin_lock_irqsave(shost->host_lock, flags);
3284 rport->flags &= ~FC_RPORT_SCAN_PENDING;
3285 spin_unlock_irqrestore(shost->host_lock, flags);
3286}
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
3303{
3304 struct Scsi_Host *shost = cmnd->device->host;
3305 struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
3306 unsigned long flags;
3307
3308 spin_lock_irqsave(shost->host_lock, flags);
3309 while (rport->port_state == FC_PORTSTATE_BLOCKED &&
3310 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)) {
3311 spin_unlock_irqrestore(shost->host_lock, flags);
3312 msleep(1000);
3313 spin_lock_irqsave(shost->host_lock, flags);
3314 }
3315 spin_unlock_irqrestore(shost->host_lock, flags);
3316
3317 if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
3318 return FAST_IO_FAIL;
3319
3320 return 0;
3321}
3322EXPORT_SYMBOL(fc_block_scsi_eh);
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339static int
3340fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev,
3341 struct fc_vport_identifiers *ids, struct fc_vport **ret_vport)
3342{
3343 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3344 struct fc_internal *fci = to_fc_internal(shost->transportt);
3345 struct fc_vport *vport;
3346 struct device *dev;
3347 unsigned long flags;
3348 size_t size;
3349 int error;
3350
3351 *ret_vport = NULL;
3352
3353 if ( ! fci->f->vport_create)
3354 return -ENOENT;
3355
3356 size = (sizeof(struct fc_vport) + fci->f->dd_fcvport_size);
3357 vport = kzalloc(size, GFP_KERNEL);
3358 if (unlikely(!vport)) {
3359 printk(KERN_ERR "%s: allocation failure\n", __func__);
3360 return -ENOMEM;
3361 }
3362
3363 vport->vport_state = FC_VPORT_UNKNOWN;
3364 vport->vport_last_state = FC_VPORT_UNKNOWN;
3365 vport->node_name = ids->node_name;
3366 vport->port_name = ids->port_name;
3367 vport->roles = ids->roles;
3368 vport->vport_type = ids->vport_type;
3369 if (fci->f->dd_fcvport_size)
3370 vport->dd_data = &vport[1];
3371 vport->shost = shost;
3372 vport->channel = channel;
3373 vport->flags = FC_VPORT_CREATING;
3374 INIT_WORK(&vport->vport_delete_work, fc_vport_sched_delete);
3375
3376 spin_lock_irqsave(shost->host_lock, flags);
3377
3378 if (fc_host->npiv_vports_inuse >= fc_host->max_npiv_vports) {
3379 spin_unlock_irqrestore(shost->host_lock, flags);
3380 kfree(vport);
3381 return -ENOSPC;
3382 }
3383 fc_host->npiv_vports_inuse++;
3384 vport->number = fc_host->next_vport_number++;
3385 list_add_tail(&vport->peers, &fc_host->vports);
3386 scsi_host_get(shost);
3387
3388 spin_unlock_irqrestore(shost->host_lock, flags);
3389
3390 dev = &vport->dev;
3391 device_initialize(dev);
3392 dev->parent = get_device(pdev);
3393 dev->release = fc_vport_dev_release;
3394 dev_set_name(dev, "vport-%d:%d-%d",
3395 shost->host_no, channel, vport->number);
3396 transport_setup_device(dev);
3397
3398 error = device_add(dev);
3399 if (error) {
3400 printk(KERN_ERR "FC Virtual Port device_add failed\n");
3401 goto delete_vport;
3402 }
3403 transport_add_device(dev);
3404 transport_configure_device(dev);
3405
3406 error = fci->f->vport_create(vport, ids->disable);
3407 if (error) {
3408 printk(KERN_ERR "FC Virtual Port LLDD Create failed\n");
3409 goto delete_vport_all;
3410 }
3411
3412
3413
3414
3415
3416 if (pdev != &shost->shost_gendev) {
3417 error = sysfs_create_link(&shost->shost_gendev.kobj,
3418 &dev->kobj, dev_name(dev));
3419 if (error)
3420 printk(KERN_ERR
3421 "%s: Cannot create vport symlinks for "
3422 "%s, err=%d\n",
3423 __func__, dev_name(dev), error);
3424 }
3425 spin_lock_irqsave(shost->host_lock, flags);
3426 vport->flags &= ~FC_VPORT_CREATING;
3427 spin_unlock_irqrestore(shost->host_lock, flags);
3428
3429 dev_printk(KERN_NOTICE, pdev,
3430 "%s created via shost%d channel %d\n", dev_name(dev),
3431 shost->host_no, channel);
3432
3433 *ret_vport = vport;
3434
3435 return 0;
3436
3437delete_vport_all:
3438 transport_remove_device(dev);
3439 device_del(dev);
3440delete_vport:
3441 transport_destroy_device(dev);
3442 spin_lock_irqsave(shost->host_lock, flags);
3443 list_del(&vport->peers);
3444 scsi_host_put(shost);
3445 fc_host->npiv_vports_inuse--;
3446 spin_unlock_irqrestore(shost->host_lock, flags);
3447 put_device(dev->parent);
3448 kfree(vport);
3449
3450 return error;
3451}
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463struct fc_vport *
3464fc_vport_create(struct Scsi_Host *shost, int channel,
3465 struct fc_vport_identifiers *ids)
3466{
3467 int stat;
3468 struct fc_vport *vport;
3469
3470 stat = fc_vport_setup(shost, channel, &shost->shost_gendev,
3471 ids, &vport);
3472 return stat ? NULL : vport;
3473}
3474EXPORT_SYMBOL(fc_vport_create);
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486int
3487fc_vport_terminate(struct fc_vport *vport)
3488{
3489 struct Scsi_Host *shost = vport_to_shost(vport);
3490 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
3491 struct fc_internal *i = to_fc_internal(shost->transportt);
3492 struct device *dev = &vport->dev;
3493 unsigned long flags;
3494 int stat;
3495
3496 if (i->f->vport_delete)
3497 stat = i->f->vport_delete(vport);
3498 else
3499 stat = -ENOENT;
3500
3501 spin_lock_irqsave(shost->host_lock, flags);
3502 vport->flags &= ~FC_VPORT_DELETING;
3503 if (!stat) {
3504 vport->flags |= FC_VPORT_DELETED;
3505 list_del(&vport->peers);
3506 fc_host->npiv_vports_inuse--;
3507 scsi_host_put(shost);
3508 }
3509 spin_unlock_irqrestore(shost->host_lock, flags);
3510
3511 if (stat)
3512 return stat;
3513
3514 if (dev->parent != &shost->shost_gendev)
3515 sysfs_remove_link(&shost->shost_gendev.kobj, dev_name(dev));
3516 transport_remove_device(dev);
3517 device_del(dev);
3518 transport_destroy_device(dev);
3519
3520
3521
3522
3523
3524
3525 put_device(dev);
3526
3527 return 0;
3528}
3529EXPORT_SYMBOL(fc_vport_terminate);
3530
3531
3532
3533
3534
3535static void
3536fc_vport_sched_delete(struct work_struct *work)
3537{
3538 struct fc_vport *vport =
3539 container_of(work, struct fc_vport, vport_delete_work);
3540 int stat;
3541
3542 stat = fc_vport_terminate(vport);
3543 if (stat)
3544 dev_printk(KERN_ERR, vport->dev.parent,
3545 "%s: %s could not be deleted created via "
3546 "shost%d channel %d - error %d\n", __func__,
3547 dev_name(&vport->dev), vport->shost->host_no,
3548 vport->channel, stat);
3549}
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561static void
3562fc_destroy_bsgjob(struct fc_bsg_job *job)
3563{
3564 unsigned long flags;
3565
3566 spin_lock_irqsave(&job->job_lock, flags);
3567 if (job->ref_cnt) {
3568 spin_unlock_irqrestore(&job->job_lock, flags);
3569 return;
3570 }
3571 spin_unlock_irqrestore(&job->job_lock, flags);
3572
3573 put_device(job->dev);
3574
3575 kfree(job->request_payload.sg_list);
3576 kfree(job->reply_payload.sg_list);
3577 kfree(job);
3578}
3579
3580
3581
3582
3583
3584
3585static void
3586fc_bsg_jobdone(struct fc_bsg_job *job)
3587{
3588 struct request *req = job->req;
3589 struct request *rsp = req->next_rq;
3590 int err;
3591
3592 err = job->req->errors = job->reply->result;
3593
3594 if (err < 0)
3595
3596 job->req->sense_len = sizeof(uint32_t);
3597 else
3598 job->req->sense_len = job->reply_len;
3599
3600
3601 req->resid_len = 0;
3602
3603 if (rsp) {
3604 WARN_ON(job->reply->reply_payload_rcv_len > rsp->resid_len);
3605
3606
3607 rsp->resid_len -= min(job->reply->reply_payload_rcv_len,
3608 rsp->resid_len);
3609 }
3610 blk_complete_request(req);
3611}
3612
3613
3614
3615
3616
3617static void fc_bsg_softirq_done(struct request *rq)
3618{
3619 struct fc_bsg_job *job = rq->special;
3620 unsigned long flags;
3621
3622 spin_lock_irqsave(&job->job_lock, flags);
3623 job->state_flags |= FC_RQST_STATE_DONE;
3624 job->ref_cnt--;
3625 spin_unlock_irqrestore(&job->job_lock, flags);
3626
3627 blk_end_request_all(rq, rq->errors);
3628 fc_destroy_bsgjob(job);
3629}
3630
3631
3632
3633
3634
3635static enum blk_eh_timer_return
3636fc_bsg_job_timeout(struct request *req)
3637{
3638 struct fc_bsg_job *job = (void *) req->special;
3639 struct Scsi_Host *shost = job->shost;
3640 struct fc_internal *i = to_fc_internal(shost->transportt);
3641 unsigned long flags;
3642 int err = 0, done = 0;
3643
3644 if (job->rport && job->rport->port_state == FC_PORTSTATE_BLOCKED)
3645 return BLK_EH_RESET_TIMER;
3646
3647 spin_lock_irqsave(&job->job_lock, flags);
3648 if (job->state_flags & FC_RQST_STATE_DONE)
3649 done = 1;
3650 else
3651 job->ref_cnt++;
3652 spin_unlock_irqrestore(&job->job_lock, flags);
3653
3654 if (!done && i->f->bsg_timeout) {
3655
3656 err = i->f->bsg_timeout(job);
3657 if (err == -EAGAIN) {
3658 job->ref_cnt--;
3659 return BLK_EH_RESET_TIMER;
3660 } else if (err)
3661 printk(KERN_ERR "ERROR: FC BSG request timeout - LLD "
3662 "abort failed with status %d\n", err);
3663 }
3664
3665
3666 if (done)
3667 return BLK_EH_NOT_HANDLED;
3668 else
3669 return BLK_EH_HANDLED;
3670}
3671
3672static int
3673fc_bsg_map_buffer(struct fc_bsg_buffer *buf, struct request *req)
3674{
3675 size_t sz = (sizeof(struct scatterlist) * req->nr_phys_segments);
3676
3677 BUG_ON(!req->nr_phys_segments);
3678
3679 buf->sg_list = kzalloc(sz, GFP_KERNEL);
3680 if (!buf->sg_list)
3681 return -ENOMEM;
3682 sg_init_table(buf->sg_list, req->nr_phys_segments);
3683 buf->sg_cnt = blk_rq_map_sg(req->q, req, buf->sg_list);
3684 buf->payload_len = blk_rq_bytes(req);
3685 return 0;
3686}
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696static int
3697fc_req_to_bsgjob(struct Scsi_Host *shost, struct fc_rport *rport,
3698 struct request *req)
3699{
3700 struct fc_internal *i = to_fc_internal(shost->transportt);
3701 struct request *rsp = req->next_rq;
3702 struct fc_bsg_job *job;
3703 int ret;
3704
3705 BUG_ON(req->special);
3706
3707 job = kzalloc(sizeof(struct fc_bsg_job) + i->f->dd_bsg_size,
3708 GFP_KERNEL);
3709 if (!job)
3710 return -ENOMEM;
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721 req->special = job;
3722 job->shost = shost;
3723 job->rport = rport;
3724 job->req = req;
3725 if (i->f->dd_bsg_size)
3726 job->dd_data = (void *)&job[1];
3727 spin_lock_init(&job->job_lock);
3728 job->request = (struct fc_bsg_request *)req->cmd;
3729 job->request_len = req->cmd_len;
3730 job->reply = req->sense;
3731 job->reply_len = SCSI_SENSE_BUFFERSIZE;
3732
3733 if (req->bio) {
3734 ret = fc_bsg_map_buffer(&job->request_payload, req);
3735 if (ret)
3736 goto failjob_rls_job;
3737 }
3738 if (rsp && rsp->bio) {
3739 ret = fc_bsg_map_buffer(&job->reply_payload, rsp);
3740 if (ret)
3741 goto failjob_rls_rqst_payload;
3742 }
3743 job->job_done = fc_bsg_jobdone;
3744 if (rport)
3745 job->dev = &rport->dev;
3746 else
3747 job->dev = &shost->shost_gendev;
3748 get_device(job->dev);
3749
3750 job->ref_cnt = 1;
3751
3752 return 0;
3753
3754
3755failjob_rls_rqst_payload:
3756 kfree(job->request_payload.sg_list);
3757failjob_rls_job:
3758 kfree(job);
3759 return -ENOMEM;
3760}
3761
3762
3763enum fc_dispatch_result {
3764 FC_DISPATCH_BREAK,
3765 FC_DISPATCH_LOCKED,
3766 FC_DISPATCH_UNLOCKED,
3767};
3768
3769
3770
3771
3772
3773
3774
3775
3776static enum fc_dispatch_result
3777fc_bsg_host_dispatch(struct request_queue *q, struct Scsi_Host *shost,
3778 struct fc_bsg_job *job)
3779{
3780 struct fc_internal *i = to_fc_internal(shost->transportt);
3781 int cmdlen = sizeof(uint32_t);
3782 int ret;
3783
3784
3785 switch (job->request->msgcode) {
3786 case FC_BSG_HST_ADD_RPORT:
3787 cmdlen += sizeof(struct fc_bsg_host_add_rport);
3788 break;
3789
3790 case FC_BSG_HST_DEL_RPORT:
3791 cmdlen += sizeof(struct fc_bsg_host_del_rport);
3792 break;
3793
3794 case FC_BSG_HST_ELS_NOLOGIN:
3795 cmdlen += sizeof(struct fc_bsg_host_els);
3796
3797 if ((!job->request_payload.payload_len) ||
3798 (!job->reply_payload.payload_len)) {
3799 ret = -EINVAL;
3800 goto fail_host_msg;
3801 }
3802 break;
3803
3804 case FC_BSG_HST_CT:
3805 cmdlen += sizeof(struct fc_bsg_host_ct);
3806
3807 if ((!job->request_payload.payload_len) ||
3808 (!job->reply_payload.payload_len)) {
3809 ret = -EINVAL;
3810 goto fail_host_msg;
3811 }
3812 break;
3813
3814 case FC_BSG_HST_VENDOR:
3815 cmdlen += sizeof(struct fc_bsg_host_vendor);
3816 if ((shost->hostt->vendor_id == 0L) ||
3817 (job->request->rqst_data.h_vendor.vendor_id !=
3818 shost->hostt->vendor_id)) {
3819 ret = -ESRCH;
3820 goto fail_host_msg;
3821 }
3822 break;
3823
3824 default:
3825 ret = -EBADR;
3826 goto fail_host_msg;
3827 }
3828
3829
3830 if (job->request_len < cmdlen) {
3831 ret = -ENOMSG;
3832 goto fail_host_msg;
3833 }
3834
3835 ret = i->f->bsg_request(job);
3836 if (!ret)
3837 return FC_DISPATCH_UNLOCKED;
3838
3839fail_host_msg:
3840
3841 BUG_ON(job->reply_len < sizeof(uint32_t));
3842 job->reply->reply_payload_rcv_len = 0;
3843 job->reply->result = ret;
3844 job->reply_len = sizeof(uint32_t);
3845 fc_bsg_jobdone(job);
3846 return FC_DISPATCH_UNLOCKED;
3847}
3848
3849
3850
3851
3852
3853
3854static void
3855fc_bsg_goose_queue(struct fc_rport *rport)
3856{
3857 if (!rport->rqst_q)
3858 return;
3859
3860
3861
3862
3863 get_device(&rport->dev);
3864 blk_run_queue_async(rport->rqst_q);
3865 put_device(&rport->dev);
3866}
3867
3868
3869
3870
3871
3872
3873
3874
3875static enum fc_dispatch_result
3876fc_bsg_rport_dispatch(struct request_queue *q, struct Scsi_Host *shost,
3877 struct fc_rport *rport, struct fc_bsg_job *job)
3878{
3879 struct fc_internal *i = to_fc_internal(shost->transportt);
3880 int cmdlen = sizeof(uint32_t);
3881 int ret;
3882
3883
3884 switch (job->request->msgcode) {
3885 case FC_BSG_RPT_ELS:
3886 cmdlen += sizeof(struct fc_bsg_rport_els);
3887 goto check_bidi;
3888
3889 case FC_BSG_RPT_CT:
3890 cmdlen += sizeof(struct fc_bsg_rport_ct);
3891check_bidi:
3892
3893 if ((!job->request_payload.payload_len) ||
3894 (!job->reply_payload.payload_len)) {
3895 ret = -EINVAL;
3896 goto fail_rport_msg;
3897 }
3898 break;
3899 default:
3900 ret = -EBADR;
3901 goto fail_rport_msg;
3902 }
3903
3904
3905 if (job->request_len < cmdlen) {
3906 ret = -ENOMSG;
3907 goto fail_rport_msg;
3908 }
3909
3910 ret = i->f->bsg_request(job);
3911 if (!ret)
3912 return FC_DISPATCH_UNLOCKED;
3913
3914fail_rport_msg:
3915
3916 BUG_ON(job->reply_len < sizeof(uint32_t));
3917 job->reply->reply_payload_rcv_len = 0;
3918 job->reply->result = ret;
3919 job->reply_len = sizeof(uint32_t);
3920 fc_bsg_jobdone(job);
3921 return FC_DISPATCH_UNLOCKED;
3922}
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932static void
3933fc_bsg_request_handler(struct request_queue *q, struct Scsi_Host *shost,
3934 struct fc_rport *rport, struct device *dev)
3935{
3936 struct request *req;
3937 struct fc_bsg_job *job;
3938 enum fc_dispatch_result ret;
3939
3940 if (!get_device(dev))
3941 return;
3942
3943 while (1) {
3944 if (rport && (rport->port_state == FC_PORTSTATE_BLOCKED) &&
3945 !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT))
3946 break;
3947
3948 req = blk_fetch_request(q);
3949 if (!req)
3950 break;
3951
3952 if (rport && (rport->port_state != FC_PORTSTATE_ONLINE)) {
3953 req->errors = -ENXIO;
3954 spin_unlock_irq(q->queue_lock);
3955 blk_end_request_all(req, -ENXIO);
3956 spin_lock_irq(q->queue_lock);
3957 continue;
3958 }
3959
3960 spin_unlock_irq(q->queue_lock);
3961
3962 ret = fc_req_to_bsgjob(shost, rport, req);
3963 if (ret) {
3964 req->errors = ret;
3965 blk_end_request_all(req, ret);
3966 spin_lock_irq(q->queue_lock);
3967 continue;
3968 }
3969
3970 job = req->special;
3971
3972
3973 if (job->request_len < sizeof(uint32_t)) {
3974 BUG_ON(job->reply_len < sizeof(uint32_t));
3975 job->reply->reply_payload_rcv_len = 0;
3976 job->reply->result = -ENOMSG;
3977 job->reply_len = sizeof(uint32_t);
3978 fc_bsg_jobdone(job);
3979 spin_lock_irq(q->queue_lock);
3980 continue;
3981 }
3982
3983
3984 if (rport)
3985 ret = fc_bsg_rport_dispatch(q, shost, rport, job);
3986 else
3987 ret = fc_bsg_host_dispatch(q, shost, job);
3988
3989
3990 if (ret == FC_DISPATCH_BREAK)
3991 break;
3992
3993
3994 if (ret == FC_DISPATCH_UNLOCKED)
3995 spin_lock_irq(q->queue_lock);
3996 }
3997
3998 spin_unlock_irq(q->queue_lock);
3999 put_device(dev);
4000 spin_lock_irq(q->queue_lock);
4001}
4002
4003
4004
4005
4006
4007
4008static void
4009fc_bsg_host_handler(struct request_queue *q)
4010{
4011 struct Scsi_Host *shost = q->queuedata;
4012
4013 fc_bsg_request_handler(q, shost, NULL, &shost->shost_gendev);
4014}
4015
4016
4017
4018
4019
4020
4021static void
4022fc_bsg_rport_handler(struct request_queue *q)
4023{
4024 struct fc_rport *rport = q->queuedata;
4025 struct Scsi_Host *shost = rport_to_shost(rport);
4026
4027 fc_bsg_request_handler(q, shost, rport, &rport->dev);
4028}
4029
4030
4031
4032
4033
4034
4035
4036static int
4037fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host)
4038{
4039 struct device *dev = &shost->shost_gendev;
4040 struct fc_internal *i = to_fc_internal(shost->transportt);
4041 struct request_queue *q;
4042 int err;
4043 char bsg_name[20];
4044
4045 fc_host->rqst_q = NULL;
4046
4047 if (!i->f->bsg_request)
4048 return -ENOTSUPP;
4049
4050 snprintf(bsg_name, sizeof(bsg_name),
4051 "fc_host%d", shost->host_no);
4052
4053 q = __scsi_alloc_queue(shost, fc_bsg_host_handler);
4054 if (!q) {
4055 printk(KERN_ERR "fc_host%d: bsg interface failed to "
4056 "initialize - no request queue\n",
4057 shost->host_no);
4058 return -ENOMEM;
4059 }
4060
4061 q->queuedata = shost;
4062 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
4063 blk_queue_softirq_done(q, fc_bsg_softirq_done);
4064 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
4065 blk_queue_rq_timeout(q, FC_DEFAULT_BSG_TIMEOUT);
4066
4067 err = bsg_register_queue(q, dev, bsg_name, NULL);
4068 if (err) {
4069 printk(KERN_ERR "fc_host%d: bsg interface failed to "
4070 "initialize - register queue\n",
4071 shost->host_no);
4072 blk_cleanup_queue(q);
4073 return err;
4074 }
4075
4076 fc_host->rqst_q = q;
4077 return 0;
4078}
4079
4080
4081
4082
4083
4084
4085
4086static int
4087fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
4088{
4089 struct device *dev = &rport->dev;
4090 struct fc_internal *i = to_fc_internal(shost->transportt);
4091 struct request_queue *q;
4092 int err;
4093
4094 rport->rqst_q = NULL;
4095
4096 if (!i->f->bsg_request)
4097 return -ENOTSUPP;
4098
4099 q = __scsi_alloc_queue(shost, fc_bsg_rport_handler);
4100 if (!q) {
4101 printk(KERN_ERR "%s: bsg interface failed to "
4102 "initialize - no request queue\n",
4103 dev->kobj.name);
4104 return -ENOMEM;
4105 }
4106
4107 q->queuedata = rport;
4108 queue_flag_set_unlocked(QUEUE_FLAG_BIDI, q);
4109 blk_queue_softirq_done(q, fc_bsg_softirq_done);
4110 blk_queue_rq_timed_out(q, fc_bsg_job_timeout);
4111 blk_queue_rq_timeout(q, BLK_DEFAULT_SG_TIMEOUT);
4112
4113 err = bsg_register_queue(q, dev, NULL, NULL);
4114 if (err) {
4115 printk(KERN_ERR "%s: bsg interface failed to "
4116 "initialize - register queue\n",
4117 dev->kobj.name);
4118 blk_cleanup_queue(q);
4119 return err;
4120 }
4121
4122 rport->rqst_q = q;
4123 return 0;
4124}
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136static void
4137fc_bsg_remove(struct request_queue *q)
4138{
4139 if (q) {
4140 bsg_unregister_queue(q);
4141 blk_cleanup_queue(q);
4142 }
4143}
4144
4145
4146
4147MODULE_AUTHOR("James Smart");
4148MODULE_DESCRIPTION("FC Transport Attributes");
4149MODULE_LICENSE("GPL");
4150
4151module_init(fc_transport_init);
4152module_exit(fc_transport_exit);
4153