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