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