[PATCH] libata: replace ap_lock w/ ap->lock in ata_scsi_error()
[linux-2.6] / drivers / scsi / scsi_transport_fc.c
1 /* 
2  *  FiberChannel transport specific attributes exported to sysfs.
3  *
4  *  Copyright (c) 2003 Silicon Graphics, Inc.  All rights reserved.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ========
21  *
22  *  Copyright (C) 2004-2005   James Smart, Emulex Corporation
23  *    Rewrite for host, target, device, and remote port attributes,
24  *    statistics, and service functions...
25  *
26  */
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/sched.h>        /* workqueue stuff, HZ */
30 #include <scsi/scsi_device.h>
31 #include <scsi/scsi_host.h>
32 #include <scsi/scsi_transport.h>
33 #include <scsi/scsi_transport_fc.h>
34 #include <scsi/scsi_cmnd.h>
35 #include "scsi_priv.h"
36
37 static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
38
39 /*
40  * Redefine so that we can have same named attributes in the
41  * sdev/starget/host objects.
42  */
43 #define FC_CLASS_DEVICE_ATTR(_prefix,_name,_mode,_show,_store)          \
44 struct class_device_attribute class_device_attr_##_prefix##_##_name =   \
45         __ATTR(_name,_mode,_show,_store)
46
47 #define fc_enum_name_search(title, table_type, table)                   \
48 static const char *get_fc_##title##_name(enum table_type table_key)     \
49 {                                                                       \
50         int i;                                                          \
51         char *name = NULL;                                              \
52                                                                         \
53         for (i = 0; i < ARRAY_SIZE(table); i++) {                       \
54                 if (table[i].value == table_key) {                      \
55                         name = table[i].name;                           \
56                         break;                                          \
57                 }                                                       \
58         }                                                               \
59         return name;                                                    \
60 }
61
62 #define fc_enum_name_match(title, table_type, table)                    \
63 static int get_fc_##title##_match(const char *table_key,                \
64                 enum table_type *value)                                 \
65 {                                                                       \
66         int i;                                                          \
67                                                                         \
68         for (i = 0; i < ARRAY_SIZE(table); i++) {                       \
69                 if (strncmp(table_key, table[i].name,                   \
70                                 table[i].matchlen) == 0) {              \
71                         *value = table[i].value;                        \
72                         return 0; /* success */                         \
73                 }                                                       \
74         }                                                               \
75         return 1; /* failure */                                         \
76 }
77
78
79 /* Convert fc_port_type values to ascii string name */
80 static struct {
81         enum fc_port_type       value;
82         char                    *name;
83 } fc_port_type_names[] = {
84         { FC_PORTTYPE_UNKNOWN,          "Unknown" },
85         { FC_PORTTYPE_OTHER,            "Other" },
86         { FC_PORTTYPE_NOTPRESENT,       "Not Present" },
87         { FC_PORTTYPE_NPORT,    "NPort (fabric via point-to-point)" },
88         { FC_PORTTYPE_NLPORT,   "NLPort (fabric via loop)" },
89         { FC_PORTTYPE_LPORT,    "LPort (private loop)" },
90         { FC_PORTTYPE_PTP,      "Point-To-Point (direct nport connection" },
91 };
92 fc_enum_name_search(port_type, fc_port_type, fc_port_type_names)
93 #define FC_PORTTYPE_MAX_NAMELEN         50
94
95
96 /* Convert fc_port_state values to ascii string name */
97 static struct {
98         enum fc_port_state      value;
99         char                    *name;
100 } fc_port_state_names[] = {
101         { FC_PORTSTATE_UNKNOWN,         "Unknown" },
102         { FC_PORTSTATE_NOTPRESENT,      "Not Present" },
103         { FC_PORTSTATE_ONLINE,          "Online" },
104         { FC_PORTSTATE_OFFLINE,         "Offline" },
105         { FC_PORTSTATE_BLOCKED,         "Blocked" },
106         { FC_PORTSTATE_BYPASSED,        "Bypassed" },
107         { FC_PORTSTATE_DIAGNOSTICS,     "Diagnostics" },
108         { FC_PORTSTATE_LINKDOWN,        "Linkdown" },
109         { FC_PORTSTATE_ERROR,           "Error" },
110         { FC_PORTSTATE_LOOPBACK,        "Loopback" },
111         { FC_PORTSTATE_DELETED,         "Deleted" },
112 };
113 fc_enum_name_search(port_state, fc_port_state, fc_port_state_names)
114 #define FC_PORTSTATE_MAX_NAMELEN        20
115
116
117 /* Convert fc_tgtid_binding_type values to ascii string name */
118 static const struct {
119         enum fc_tgtid_binding_type      value;
120         char                            *name;
121         int                             matchlen;
122 } fc_tgtid_binding_type_names[] = {
123         { FC_TGTID_BIND_NONE, "none", 4 },
124         { FC_TGTID_BIND_BY_WWPN, "wwpn (World Wide Port Name)", 4 },
125         { FC_TGTID_BIND_BY_WWNN, "wwnn (World Wide Node Name)", 4 },
126         { FC_TGTID_BIND_BY_ID, "port_id (FC Address)", 7 },
127 };
128 fc_enum_name_search(tgtid_bind_type, fc_tgtid_binding_type,
129                 fc_tgtid_binding_type_names)
130 fc_enum_name_match(tgtid_bind_type, fc_tgtid_binding_type,
131                 fc_tgtid_binding_type_names)
132 #define FC_BINDTYPE_MAX_NAMELEN 30
133
134
135 #define fc_bitfield_name_search(title, table)                   \
136 static ssize_t                                                  \
137 get_fc_##title##_names(u32 table_key, char *buf)                \
138 {                                                               \
139         char *prefix = "";                                      \
140         ssize_t len = 0;                                        \
141         int i;                                                  \
142                                                                 \
143         for (i = 0; i < ARRAY_SIZE(table); i++) {               \
144                 if (table[i].value & table_key) {               \
145                         len += sprintf(buf + len, "%s%s",       \
146                                 prefix, table[i].name);         \
147                         prefix = ", ";                          \
148                 }                                               \
149         }                                                       \
150         len += sprintf(buf + len, "\n");                        \
151         return len;                                             \
152 }
153
154
155 /* Convert FC_COS bit values to ascii string name */
156 static const struct {
157         u32                     value;
158         char                    *name;
159 } fc_cos_names[] = {
160         { FC_COS_CLASS1,        "Class 1" },
161         { FC_COS_CLASS2,        "Class 2" },
162         { FC_COS_CLASS3,        "Class 3" },
163         { FC_COS_CLASS4,        "Class 4" },
164         { FC_COS_CLASS6,        "Class 6" },
165 };
166 fc_bitfield_name_search(cos, fc_cos_names)
167
168
169 /* Convert FC_PORTSPEED bit values to ascii string name */
170 static const struct {
171         u32                     value;
172         char                    *name;
173 } fc_port_speed_names[] = {
174         { FC_PORTSPEED_1GBIT,           "1 Gbit" },
175         { FC_PORTSPEED_2GBIT,           "2 Gbit" },
176         { FC_PORTSPEED_4GBIT,           "4 Gbit" },
177         { FC_PORTSPEED_10GBIT,          "10 Gbit" },
178         { FC_PORTSPEED_NOT_NEGOTIATED,  "Not Negotiated" },
179 };
180 fc_bitfield_name_search(port_speed, fc_port_speed_names)
181
182
183 static int
184 show_fc_fc4s (char *buf, u8 *fc4_list)
185 {
186         int i, len=0;
187
188         for (i = 0; i < FC_FC4_LIST_SIZE; i++, fc4_list++)
189                 len += sprintf(buf + len , "0x%02x ", *fc4_list);
190         len += sprintf(buf + len, "\n");
191         return len;
192 }
193
194
195 /* Convert FC_RPORT_ROLE bit values to ascii string name */
196 static const struct {
197         u32                     value;
198         char                    *name;
199 } fc_remote_port_role_names[] = {
200         { FC_RPORT_ROLE_FCP_TARGET,     "FCP Target" },
201         { FC_RPORT_ROLE_FCP_INITIATOR,  "FCP Initiator" },
202         { FC_RPORT_ROLE_IP_PORT,        "IP Port" },
203 };
204 fc_bitfield_name_search(remote_port_roles, fc_remote_port_role_names)
205
206 /*
207  * Define roles that are specific to port_id. Values are relative to ROLE_MASK.
208  */
209 #define FC_WELLKNOWN_PORTID_MASK        0xfffff0
210 #define FC_WELLKNOWN_ROLE_MASK          0x00000f
211 #define FC_FPORT_PORTID                 0x00000e
212 #define FC_FABCTLR_PORTID               0x00000d
213 #define FC_DIRSRVR_PORTID               0x00000c
214 #define FC_TIMESRVR_PORTID              0x00000b
215 #define FC_MGMTSRVR_PORTID              0x00000a
216
217
218 static void fc_timeout_deleted_rport(void *data);
219 static void fc_scsi_scan_rport(void *data);
220
221 /*
222  * Attribute counts pre object type...
223  * Increase these values if you add attributes
224  */
225 #define FC_STARGET_NUM_ATTRS    3
226 #define FC_RPORT_NUM_ATTRS      9
227 #define FC_HOST_NUM_ATTRS       17
228
229 struct fc_internal {
230         struct scsi_transport_template t;
231         struct fc_function_template *f;
232
233         /*
234          * For attributes : each object has :
235          *   An array of the actual attributes structures
236          *   An array of null-terminated pointers to the attribute
237          *     structures - used for mid-layer interaction.
238          *
239          * The attribute containers for the starget and host are are
240          * part of the midlayer. As the remote port is specific to the
241          * fc transport, we must provide the attribute container.
242          */
243         struct class_device_attribute private_starget_attrs[
244                                                         FC_STARGET_NUM_ATTRS];
245         struct class_device_attribute *starget_attrs[FC_STARGET_NUM_ATTRS + 1];
246
247         struct class_device_attribute private_host_attrs[FC_HOST_NUM_ATTRS];
248         struct class_device_attribute *host_attrs[FC_HOST_NUM_ATTRS + 1];
249
250         struct transport_container rport_attr_cont;
251         struct class_device_attribute private_rport_attrs[FC_RPORT_NUM_ATTRS];
252         struct class_device_attribute *rport_attrs[FC_RPORT_NUM_ATTRS + 1];
253 };
254
255 #define to_fc_internal(tmpl)    container_of(tmpl, struct fc_internal, t)
256
257 static int fc_target_setup(struct transport_container *tc, struct device *dev,
258                            struct class_device *cdev)
259 {
260         struct scsi_target *starget = to_scsi_target(dev);
261         struct fc_rport *rport = starget_to_rport(starget);
262
263         /*
264          * if parent is remote port, use values from remote port.
265          * Otherwise, this host uses the fc_transport, but not the
266          * remote port interface. As such, initialize to known non-values.
267          */
268         if (rport) {
269                 fc_starget_node_name(starget) = rport->node_name;
270                 fc_starget_port_name(starget) = rport->port_name;
271                 fc_starget_port_id(starget) = rport->port_id;
272         } else {
273                 fc_starget_node_name(starget) = -1;
274                 fc_starget_port_name(starget) = -1;
275                 fc_starget_port_id(starget) = -1;
276         }
277
278         return 0;
279 }
280
281 static DECLARE_TRANSPORT_CLASS(fc_transport_class,
282                                "fc_transport",
283                                fc_target_setup,
284                                NULL,
285                                NULL);
286
287 static int fc_host_setup(struct transport_container *tc, struct device *dev,
288                          struct class_device *cdev)
289 {
290         struct Scsi_Host *shost = dev_to_shost(dev);
291         struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
292
293         /* 
294          * Set default values easily detected by the midlayer as
295          * failure cases.  The scsi lldd is responsible for initializing
296          * all transport attributes to valid values per host.
297          */
298         fc_host->node_name = -1;
299         fc_host->port_name = -1;
300         fc_host->permanent_port_name = -1;
301         fc_host->supported_classes = FC_COS_UNSPECIFIED;
302         memset(fc_host->supported_fc4s, 0,
303                 sizeof(fc_host->supported_fc4s));
304         memset(fc_host->symbolic_name, 0,
305                 sizeof(fc_host->symbolic_name));
306         fc_host->supported_speeds = FC_PORTSPEED_UNKNOWN;
307         fc_host->maxframe_size = -1;
308         memset(fc_host->serial_number, 0,
309                 sizeof(fc_host->serial_number));
310
311         fc_host->port_id = -1;
312         fc_host->port_type = FC_PORTTYPE_UNKNOWN;
313         fc_host->port_state = FC_PORTSTATE_UNKNOWN;
314         memset(fc_host->active_fc4s, 0,
315                 sizeof(fc_host->active_fc4s));
316         fc_host->speed = FC_PORTSPEED_UNKNOWN;
317         fc_host->fabric_name = -1;
318
319         fc_host->tgtid_bind_type = FC_TGTID_BIND_BY_WWPN;
320
321         INIT_LIST_HEAD(&fc_host->rports);
322         INIT_LIST_HEAD(&fc_host->rport_bindings);
323         fc_host->next_rport_number = 0;
324         fc_host->next_target_id = 0;
325
326         snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d",
327                 shost->host_no);
328         fc_host->work_q = create_singlethread_workqueue(
329                                         fc_host->work_q_name);
330         if (!fc_host->work_q)
331                 return -ENOMEM;
332
333         snprintf(fc_host->devloss_work_q_name, KOBJ_NAME_LEN, "fc_dl_%d",
334                 shost->host_no);
335         fc_host->devloss_work_q = create_singlethread_workqueue(
336                                         fc_host->devloss_work_q_name);
337         if (!fc_host->devloss_work_q) {
338                 destroy_workqueue(fc_host->work_q);
339                 fc_host->work_q = NULL;
340                 return -ENOMEM;
341         }
342
343         return 0;
344 }
345
346 static DECLARE_TRANSPORT_CLASS(fc_host_class,
347                                "fc_host",
348                                fc_host_setup,
349                                NULL,
350                                NULL);
351
352 /*
353  * Setup and Remove actions for remote ports are handled
354  * in the service functions below.
355  */
356 static DECLARE_TRANSPORT_CLASS(fc_rport_class,
357                                "fc_remote_ports",
358                                NULL,
359                                NULL,
360                                NULL);
361
362 /*
363  * Module Parameters
364  */
365
366 /*
367  * dev_loss_tmo: the default number of seconds that the FC transport
368  *   should insulate the loss of a remote port.
369  *   The maximum will be capped by the value of SCSI_DEVICE_BLOCK_MAX_TIMEOUT.
370  */
371 static unsigned int fc_dev_loss_tmo = 60;               /* seconds */
372
373 module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR);
374 MODULE_PARM_DESC(dev_loss_tmo,
375                  "Maximum number of seconds that the FC transport should"
376                  " insulate the loss of a remote port. Once this value is"
377                  " exceeded, the scsi target is removed. Value should be"
378                  " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT.");
379
380
381 static __init int fc_transport_init(void)
382 {
383         int error = transport_class_register(&fc_host_class);
384         if (error)
385                 return error;
386         error = transport_class_register(&fc_rport_class);
387         if (error)
388                 return error;
389         return transport_class_register(&fc_transport_class);
390 }
391
392 static void __exit fc_transport_exit(void)
393 {
394         transport_class_unregister(&fc_transport_class);
395         transport_class_unregister(&fc_rport_class);
396         transport_class_unregister(&fc_host_class);
397 }
398
399 /*
400  * FC Remote Port Attribute Management
401  */
402
403 #define fc_rport_show_function(field, format_string, sz, cast)          \
404 static ssize_t                                                          \
405 show_fc_rport_##field (struct class_device *cdev, char *buf)            \
406 {                                                                       \
407         struct fc_rport *rport = transport_class_to_rport(cdev);        \
408         struct Scsi_Host *shost = rport_to_shost(rport);                \
409         struct fc_internal *i = to_fc_internal(shost->transportt);      \
410         if ((i->f->get_rport_##field) &&                                \
411             !((rport->port_state == FC_PORTSTATE_BLOCKED) ||            \
412               (rport->port_state == FC_PORTSTATE_DELETED) ||            \
413               (rport->port_state == FC_PORTSTATE_NOTPRESENT)))          \
414                 i->f->get_rport_##field(rport);                         \
415         return snprintf(buf, sz, format_string, cast rport->field);     \
416 }
417
418 #define fc_rport_store_function(field)                                  \
419 static ssize_t                                                          \
420 store_fc_rport_##field(struct class_device *cdev, const char *buf,      \
421                            size_t count)                                \
422 {                                                                       \
423         int val;                                                        \
424         struct fc_rport *rport = transport_class_to_rport(cdev);        \
425         struct Scsi_Host *shost = rport_to_shost(rport);                \
426         struct fc_internal *i = to_fc_internal(shost->transportt);      \
427         if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||              \
428             (rport->port_state == FC_PORTSTATE_DELETED) ||              \
429             (rport->port_state == FC_PORTSTATE_NOTPRESENT))             \
430                 return -EBUSY;                                          \
431         val = simple_strtoul(buf, NULL, 0);                             \
432         i->f->set_rport_##field(rport, val);                            \
433         return count;                                                   \
434 }
435
436 #define fc_rport_rd_attr(field, format_string, sz)                      \
437         fc_rport_show_function(field, format_string, sz, )              \
438 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO,                      \
439                          show_fc_rport_##field, NULL)
440
441 #define fc_rport_rd_attr_cast(field, format_string, sz, cast)           \
442         fc_rport_show_function(field, format_string, sz, (cast))        \
443 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO,                      \
444                           show_fc_rport_##field, NULL)
445
446 #define fc_rport_rw_attr(field, format_string, sz)                      \
447         fc_rport_show_function(field, format_string, sz, )              \
448         fc_rport_store_function(field)                                  \
449 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO | S_IWUSR,            \
450                         show_fc_rport_##field,                          \
451                         store_fc_rport_##field)
452
453
454 #define fc_private_rport_show_function(field, format_string, sz, cast)  \
455 static ssize_t                                                          \
456 show_fc_rport_##field (struct class_device *cdev, char *buf)            \
457 {                                                                       \
458         struct fc_rport *rport = transport_class_to_rport(cdev);        \
459         return snprintf(buf, sz, format_string, cast rport->field);     \
460 }
461
462 #define fc_private_rport_rd_attr(field, format_string, sz)              \
463         fc_private_rport_show_function(field, format_string, sz, )      \
464 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO,                      \
465                          show_fc_rport_##field, NULL)
466
467 #define fc_private_rport_rd_attr_cast(field, format_string, sz, cast)   \
468         fc_private_rport_show_function(field, format_string, sz, (cast)) \
469 static FC_CLASS_DEVICE_ATTR(rport, field, S_IRUGO,                      \
470                           show_fc_rport_##field, NULL)
471
472
473 #define fc_private_rport_rd_enum_attr(title, maxlen)                    \
474 static ssize_t                                                          \
475 show_fc_rport_##title (struct class_device *cdev, char *buf)            \
476 {                                                                       \
477         struct fc_rport *rport = transport_class_to_rport(cdev);        \
478         const char *name;                                               \
479         name = get_fc_##title##_name(rport->title);                     \
480         if (!name)                                                      \
481                 return -EINVAL;                                         \
482         return snprintf(buf, maxlen, "%s\n", name);                     \
483 }                                                                       \
484 static FC_CLASS_DEVICE_ATTR(rport, title, S_IRUGO,                      \
485                         show_fc_rport_##title, NULL)
486
487
488 #define SETUP_RPORT_ATTRIBUTE_RD(field)                                 \
489         i->private_rport_attrs[count] = class_device_attr_rport_##field; \
490         i->private_rport_attrs[count].attr.mode = S_IRUGO;              \
491         i->private_rport_attrs[count].store = NULL;                     \
492         i->rport_attrs[count] = &i->private_rport_attrs[count];         \
493         if (i->f->show_rport_##field)                                   \
494                 count++
495
496 #define SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(field)                         \
497         i->private_rport_attrs[count] = class_device_attr_rport_##field; \
498         i->private_rport_attrs[count].attr.mode = S_IRUGO;              \
499         i->private_rport_attrs[count].store = NULL;                     \
500         i->rport_attrs[count] = &i->private_rport_attrs[count];         \
501         count++
502
503 #define SETUP_RPORT_ATTRIBUTE_RW(field)                                 \
504         i->private_rport_attrs[count] = class_device_attr_rport_##field; \
505         if (!i->f->set_rport_##field) {                                 \
506                 i->private_rport_attrs[count].attr.mode = S_IRUGO;      \
507                 i->private_rport_attrs[count].store = NULL;             \
508         }                                                               \
509         i->rport_attrs[count] = &i->private_rport_attrs[count];         \
510         if (i->f->show_rport_##field)                                   \
511                 count++
512
513
514 /* The FC Transport Remote Port Attributes: */
515
516 /* Fixed Remote Port Attributes */
517
518 fc_private_rport_rd_attr(maxframe_size, "%u bytes\n", 20);
519
520 static ssize_t
521 show_fc_rport_supported_classes (struct class_device *cdev, char *buf)
522 {
523         struct fc_rport *rport = transport_class_to_rport(cdev);
524         if (rport->supported_classes == FC_COS_UNSPECIFIED)
525                 return snprintf(buf, 20, "unspecified\n");
526         return get_fc_cos_names(rport->supported_classes, buf);
527 }
528 static FC_CLASS_DEVICE_ATTR(rport, supported_classes, S_IRUGO,
529                 show_fc_rport_supported_classes, NULL);
530
531 /* Dynamic Remote Port Attributes */
532
533 /*
534  * dev_loss_tmo attribute
535  */
536 fc_rport_show_function(dev_loss_tmo, "%d\n", 20, )
537 static ssize_t
538 store_fc_rport_dev_loss_tmo(struct class_device *cdev, const char *buf,
539                            size_t count)
540 {
541         int val;
542         struct fc_rport *rport = transport_class_to_rport(cdev);
543         struct Scsi_Host *shost = rport_to_shost(rport);
544         struct fc_internal *i = to_fc_internal(shost->transportt);
545         if ((rport->port_state == FC_PORTSTATE_BLOCKED) ||
546             (rport->port_state == FC_PORTSTATE_DELETED) ||
547             (rport->port_state == FC_PORTSTATE_NOTPRESENT))
548                 return -EBUSY;
549         val = simple_strtoul(buf, NULL, 0);
550         if ((val < 0) || (val > SCSI_DEVICE_BLOCK_MAX_TIMEOUT))
551                 return -EINVAL;
552         i->f->set_rport_dev_loss_tmo(rport, val);
553         return count;
554 }
555 static FC_CLASS_DEVICE_ATTR(rport, dev_loss_tmo, S_IRUGO | S_IWUSR,
556                 show_fc_rport_dev_loss_tmo, store_fc_rport_dev_loss_tmo);
557
558
559 /* Private Remote Port Attributes */
560
561 fc_private_rport_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
562 fc_private_rport_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
563 fc_private_rport_rd_attr(port_id, "0x%06x\n", 20);
564
565 static ssize_t
566 show_fc_rport_roles (struct class_device *cdev, char *buf)
567 {
568         struct fc_rport *rport = transport_class_to_rport(cdev);
569
570         /* identify any roles that are port_id specific */
571         if ((rport->port_id != -1) &&
572             (rport->port_id & FC_WELLKNOWN_PORTID_MASK) ==
573                                         FC_WELLKNOWN_PORTID_MASK) {
574                 switch (rport->port_id & FC_WELLKNOWN_ROLE_MASK) {
575                 case FC_FPORT_PORTID:
576                         return snprintf(buf, 30, "Fabric Port\n");
577                 case FC_FABCTLR_PORTID:
578                         return snprintf(buf, 30, "Fabric Controller\n");
579                 case FC_DIRSRVR_PORTID:
580                         return snprintf(buf, 30, "Directory Server\n");
581                 case FC_TIMESRVR_PORTID:
582                         return snprintf(buf, 30, "Time Server\n");
583                 case FC_MGMTSRVR_PORTID:
584                         return snprintf(buf, 30, "Management Server\n");
585                 default:
586                         return snprintf(buf, 30, "Unknown Fabric Entity\n");
587                 }
588         } else {
589                 if (rport->roles == FC_RPORT_ROLE_UNKNOWN)
590                         return snprintf(buf, 20, "unknown\n");
591                 return get_fc_remote_port_roles_names(rport->roles, buf);
592         }
593 }
594 static FC_CLASS_DEVICE_ATTR(rport, roles, S_IRUGO,
595                 show_fc_rport_roles, NULL);
596
597 fc_private_rport_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
598 fc_private_rport_rd_attr(scsi_target_id, "%d\n", 20);
599
600
601
602 /*
603  * FC SCSI Target Attribute Management
604  */
605
606 /*
607  * Note: in the target show function we recognize when the remote
608  *  port is in the heirarchy and do not allow the driver to get
609  *  involved in sysfs functions. The driver only gets involved if
610  *  it's the "old" style that doesn't use rports.
611  */
612 #define fc_starget_show_function(field, format_string, sz, cast)        \
613 static ssize_t                                                          \
614 show_fc_starget_##field (struct class_device *cdev, char *buf)          \
615 {                                                                       \
616         struct scsi_target *starget = transport_class_to_starget(cdev); \
617         struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);    \
618         struct fc_internal *i = to_fc_internal(shost->transportt);      \
619         struct fc_rport *rport = starget_to_rport(starget);             \
620         if (rport)                                                      \
621                 fc_starget_##field(starget) = rport->field;             \
622         else if (i->f->get_starget_##field)                             \
623                 i->f->get_starget_##field(starget);                     \
624         return snprintf(buf, sz, format_string,                         \
625                 cast fc_starget_##field(starget));                      \
626 }
627
628 #define fc_starget_rd_attr(field, format_string, sz)                    \
629         fc_starget_show_function(field, format_string, sz, )            \
630 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO,                    \
631                          show_fc_starget_##field, NULL)
632
633 #define fc_starget_rd_attr_cast(field, format_string, sz, cast)         \
634         fc_starget_show_function(field, format_string, sz, (cast))      \
635 static FC_CLASS_DEVICE_ATTR(starget, field, S_IRUGO,                    \
636                           show_fc_starget_##field, NULL)
637
638 #define SETUP_STARGET_ATTRIBUTE_RD(field)                               \
639         i->private_starget_attrs[count] = class_device_attr_starget_##field; \
640         i->private_starget_attrs[count].attr.mode = S_IRUGO;            \
641         i->private_starget_attrs[count].store = NULL;                   \
642         i->starget_attrs[count] = &i->private_starget_attrs[count];     \
643         if (i->f->show_starget_##field)                                 \
644                 count++
645
646 #define SETUP_STARGET_ATTRIBUTE_RW(field)                               \
647         i->private_starget_attrs[count] = class_device_attr_starget_##field; \
648         if (!i->f->set_starget_##field) {                               \
649                 i->private_starget_attrs[count].attr.mode = S_IRUGO;    \
650                 i->private_starget_attrs[count].store = NULL;           \
651         }                                                               \
652         i->starget_attrs[count] = &i->private_starget_attrs[count];     \
653         if (i->f->show_starget_##field)                                 \
654                 count++
655
656 /* The FC Transport SCSI Target Attributes: */
657 fc_starget_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
658 fc_starget_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
659 fc_starget_rd_attr(port_id, "0x%06x\n", 20);
660
661
662 /*
663  * Host Attribute Management
664  */
665
666 #define fc_host_show_function(field, format_string, sz, cast)           \
667 static ssize_t                                                          \
668 show_fc_host_##field (struct class_device *cdev, char *buf)             \
669 {                                                                       \
670         struct Scsi_Host *shost = transport_class_to_shost(cdev);       \
671         struct fc_internal *i = to_fc_internal(shost->transportt);      \
672         if (i->f->get_host_##field)                                     \
673                 i->f->get_host_##field(shost);                          \
674         return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
675 }
676
677 #define fc_host_store_function(field)                                   \
678 static ssize_t                                                          \
679 store_fc_host_##field(struct class_device *cdev, const char *buf,       \
680                            size_t count)                                \
681 {                                                                       \
682         int val;                                                        \
683         struct Scsi_Host *shost = transport_class_to_shost(cdev);       \
684         struct fc_internal *i = to_fc_internal(shost->transportt);      \
685                                                                         \
686         val = simple_strtoul(buf, NULL, 0);                             \
687         i->f->set_host_##field(shost, val);                             \
688         return count;                                                   \
689 }
690
691 #define fc_host_rd_attr(field, format_string, sz)                       \
692         fc_host_show_function(field, format_string, sz, )               \
693 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,                       \
694                          show_fc_host_##field, NULL)
695
696 #define fc_host_rd_attr_cast(field, format_string, sz, cast)            \
697         fc_host_show_function(field, format_string, sz, (cast))         \
698 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,                       \
699                           show_fc_host_##field, NULL)
700
701 #define fc_host_rw_attr(field, format_string, sz)                       \
702         fc_host_show_function(field, format_string, sz, )               \
703         fc_host_store_function(field)                                   \
704 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO | S_IWUSR,             \
705                         show_fc_host_##field,                           \
706                         store_fc_host_##field)
707
708 #define fc_host_rd_enum_attr(title, maxlen)                             \
709 static ssize_t                                                          \
710 show_fc_host_##title (struct class_device *cdev, char *buf)             \
711 {                                                                       \
712         struct Scsi_Host *shost = transport_class_to_shost(cdev);       \
713         struct fc_internal *i = to_fc_internal(shost->transportt);      \
714         const char *name;                                               \
715         if (i->f->get_host_##title)                                     \
716                 i->f->get_host_##title(shost);                          \
717         name = get_fc_##title##_name(fc_host_##title(shost));           \
718         if (!name)                                                      \
719                 return -EINVAL;                                         \
720         return snprintf(buf, maxlen, "%s\n", name);                     \
721 }                                                                       \
722 static FC_CLASS_DEVICE_ATTR(host, title, S_IRUGO, show_fc_host_##title, NULL)
723
724 #define SETUP_HOST_ATTRIBUTE_RD(field)                                  \
725         i->private_host_attrs[count] = class_device_attr_host_##field;  \
726         i->private_host_attrs[count].attr.mode = S_IRUGO;               \
727         i->private_host_attrs[count].store = NULL;                      \
728         i->host_attrs[count] = &i->private_host_attrs[count];           \
729         if (i->f->show_host_##field)                                    \
730                 count++
731
732 #define SETUP_HOST_ATTRIBUTE_RW(field)                                  \
733         i->private_host_attrs[count] = class_device_attr_host_##field;  \
734         if (!i->f->set_host_##field) {                                  \
735                 i->private_host_attrs[count].attr.mode = S_IRUGO;       \
736                 i->private_host_attrs[count].store = NULL;              \
737         }                                                               \
738         i->host_attrs[count] = &i->private_host_attrs[count];           \
739         if (i->f->show_host_##field)                                    \
740                 count++
741
742
743 #define fc_private_host_show_function(field, format_string, sz, cast)   \
744 static ssize_t                                                          \
745 show_fc_host_##field (struct class_device *cdev, char *buf)             \
746 {                                                                       \
747         struct Scsi_Host *shost = transport_class_to_shost(cdev);       \
748         return snprintf(buf, sz, format_string, cast fc_host_##field(shost)); \
749 }
750
751 #define fc_private_host_rd_attr(field, format_string, sz)               \
752         fc_private_host_show_function(field, format_string, sz, )       \
753 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,                       \
754                          show_fc_host_##field, NULL)
755
756 #define fc_private_host_rd_attr_cast(field, format_string, sz, cast)    \
757         fc_private_host_show_function(field, format_string, sz, (cast)) \
758 static FC_CLASS_DEVICE_ATTR(host, field, S_IRUGO,                       \
759                           show_fc_host_##field, NULL)
760
761 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RD(field)                  \
762         i->private_host_attrs[count] = class_device_attr_host_##field;  \
763         i->private_host_attrs[count].attr.mode = S_IRUGO;               \
764         i->private_host_attrs[count].store = NULL;                      \
765         i->host_attrs[count] = &i->private_host_attrs[count];           \
766         count++
767
768 #define SETUP_PRIVATE_HOST_ATTRIBUTE_RW(field)                  \
769 {                                                                       \
770         i->private_host_attrs[count] = class_device_attr_host_##field;  \
771         i->host_attrs[count] = &i->private_host_attrs[count];           \
772         count++;                                                        \
773 }
774
775
776 /* Fixed Host Attributes */
777
778 static ssize_t
779 show_fc_host_supported_classes (struct class_device *cdev, char *buf)
780 {
781         struct Scsi_Host *shost = transport_class_to_shost(cdev);
782
783         if (fc_host_supported_classes(shost) == FC_COS_UNSPECIFIED)
784                 return snprintf(buf, 20, "unspecified\n");
785
786         return get_fc_cos_names(fc_host_supported_classes(shost), buf);
787 }
788 static FC_CLASS_DEVICE_ATTR(host, supported_classes, S_IRUGO,
789                 show_fc_host_supported_classes, NULL);
790
791 static ssize_t
792 show_fc_host_supported_fc4s (struct class_device *cdev, char *buf)
793 {
794         struct Scsi_Host *shost = transport_class_to_shost(cdev);
795         return (ssize_t)show_fc_fc4s(buf, fc_host_supported_fc4s(shost));
796 }
797 static FC_CLASS_DEVICE_ATTR(host, supported_fc4s, S_IRUGO,
798                 show_fc_host_supported_fc4s, NULL);
799
800 static ssize_t
801 show_fc_host_supported_speeds (struct class_device *cdev, char *buf)
802 {
803         struct Scsi_Host *shost = transport_class_to_shost(cdev);
804
805         if (fc_host_supported_speeds(shost) == FC_PORTSPEED_UNKNOWN)
806                 return snprintf(buf, 20, "unknown\n");
807
808         return get_fc_port_speed_names(fc_host_supported_speeds(shost), buf);
809 }
810 static FC_CLASS_DEVICE_ATTR(host, supported_speeds, S_IRUGO,
811                 show_fc_host_supported_speeds, NULL);
812
813
814 fc_private_host_rd_attr_cast(node_name, "0x%llx\n", 20, unsigned long long);
815 fc_private_host_rd_attr_cast(port_name, "0x%llx\n", 20, unsigned long long);
816 fc_private_host_rd_attr_cast(permanent_port_name, "0x%llx\n", 20,
817                              unsigned long long);
818 fc_private_host_rd_attr(symbolic_name, "%s\n", (FC_SYMBOLIC_NAME_SIZE +1));
819 fc_private_host_rd_attr(maxframe_size, "%u bytes\n", 20);
820 fc_private_host_rd_attr(serial_number, "%s\n", (FC_SERIAL_NUMBER_SIZE +1));
821
822
823 /* Dynamic Host Attributes */
824
825 static ssize_t
826 show_fc_host_active_fc4s (struct class_device *cdev, char *buf)
827 {
828         struct Scsi_Host *shost = transport_class_to_shost(cdev);
829         struct fc_internal *i = to_fc_internal(shost->transportt);
830
831         if (i->f->get_host_active_fc4s)
832                 i->f->get_host_active_fc4s(shost);
833
834         return (ssize_t)show_fc_fc4s(buf, fc_host_active_fc4s(shost));
835 }
836 static FC_CLASS_DEVICE_ATTR(host, active_fc4s, S_IRUGO,
837                 show_fc_host_active_fc4s, NULL);
838
839 static ssize_t
840 show_fc_host_speed (struct class_device *cdev, char *buf)
841 {
842         struct Scsi_Host *shost = transport_class_to_shost(cdev);
843         struct fc_internal *i = to_fc_internal(shost->transportt);
844
845         if (i->f->get_host_speed)
846                 i->f->get_host_speed(shost);
847
848         if (fc_host_speed(shost) == FC_PORTSPEED_UNKNOWN)
849                 return snprintf(buf, 20, "unknown\n");
850
851         return get_fc_port_speed_names(fc_host_speed(shost), buf);
852 }
853 static FC_CLASS_DEVICE_ATTR(host, speed, S_IRUGO,
854                 show_fc_host_speed, NULL);
855
856
857 fc_host_rd_attr(port_id, "0x%06x\n", 20);
858 fc_host_rd_enum_attr(port_type, FC_PORTTYPE_MAX_NAMELEN);
859 fc_host_rd_enum_attr(port_state, FC_PORTSTATE_MAX_NAMELEN);
860 fc_host_rd_attr_cast(fabric_name, "0x%llx\n", 20, unsigned long long);
861
862
863 /* Private Host Attributes */
864
865 static ssize_t
866 show_fc_private_host_tgtid_bind_type(struct class_device *cdev, char *buf)
867 {
868         struct Scsi_Host *shost = transport_class_to_shost(cdev);
869         const char *name;
870
871         name = get_fc_tgtid_bind_type_name(fc_host_tgtid_bind_type(shost));
872         if (!name)
873                 return -EINVAL;
874         return snprintf(buf, FC_BINDTYPE_MAX_NAMELEN, "%s\n", name);
875 }
876
877 #define get_list_head_entry(pos, head, member)          \
878         pos = list_entry((head)->next, typeof(*pos), member)
879
880 static ssize_t
881 store_fc_private_host_tgtid_bind_type(struct class_device *cdev,
882         const char *buf, size_t count)
883 {
884         struct Scsi_Host *shost = transport_class_to_shost(cdev);
885         struct fc_rport *rport;
886         enum fc_tgtid_binding_type val;
887         unsigned long flags;
888
889         if (get_fc_tgtid_bind_type_match(buf, &val))
890                 return -EINVAL;
891
892         /* if changing bind type, purge all unused consistent bindings */
893         if (val != fc_host_tgtid_bind_type(shost)) {
894                 spin_lock_irqsave(shost->host_lock, flags);
895                 while (!list_empty(&fc_host_rport_bindings(shost))) {
896                         get_list_head_entry(rport,
897                                 &fc_host_rport_bindings(shost), peers);
898                         list_del(&rport->peers);
899                         rport->port_state = FC_PORTSTATE_DELETED;
900                         fc_queue_work(shost, &rport->rport_delete_work);
901                 }
902                 spin_unlock_irqrestore(shost->host_lock, flags);
903         }
904
905         fc_host_tgtid_bind_type(shost) = val;
906         return count;
907 }
908
909 static FC_CLASS_DEVICE_ATTR(host, tgtid_bind_type, S_IRUGO | S_IWUSR,
910                         show_fc_private_host_tgtid_bind_type,
911                         store_fc_private_host_tgtid_bind_type);
912
913 static ssize_t
914 store_fc_private_host_issue_lip(struct class_device *cdev,
915         const char *buf, size_t count)
916 {
917         struct Scsi_Host *shost = transport_class_to_shost(cdev);
918         struct fc_internal *i = to_fc_internal(shost->transportt);
919         int ret;
920
921         /* ignore any data value written to the attribute */
922         if (i->f->issue_fc_host_lip) {
923                 ret = i->f->issue_fc_host_lip(shost);
924                 return ret ? ret: count;
925         }
926
927         return -ENOENT;
928 }
929
930 static FC_CLASS_DEVICE_ATTR(host, issue_lip, S_IWUSR, NULL,
931                         store_fc_private_host_issue_lip);
932
933 /*
934  * Host Statistics Management
935  */
936
937 /* Show a given an attribute in the statistics group */
938 static ssize_t
939 fc_stat_show(const struct class_device *cdev, char *buf, unsigned long offset)
940 {
941         struct Scsi_Host *shost = transport_class_to_shost(cdev);
942         struct fc_internal *i = to_fc_internal(shost->transportt);
943         struct fc_host_statistics *stats;
944         ssize_t ret = -ENOENT;
945
946         if (offset > sizeof(struct fc_host_statistics) ||
947             offset % sizeof(u64) != 0)
948                 WARN_ON(1);
949
950         if (i->f->get_fc_host_stats) {
951                 stats = (i->f->get_fc_host_stats)(shost);
952                 if (stats)
953                         ret = snprintf(buf, 20, "0x%llx\n",
954                               (unsigned long long)*(u64 *)(((u8 *) stats) + offset));
955         }
956         return ret;
957 }
958
959
960 /* generate a read-only statistics attribute */
961 #define fc_host_statistic(name)                                         \
962 static ssize_t show_fcstat_##name(struct class_device *cd, char *buf)   \
963 {                                                                       \
964         return fc_stat_show(cd, buf,                                    \
965                             offsetof(struct fc_host_statistics, name)); \
966 }                                                                       \
967 static FC_CLASS_DEVICE_ATTR(host, name, S_IRUGO, show_fcstat_##name, NULL)
968
969 fc_host_statistic(seconds_since_last_reset);
970 fc_host_statistic(tx_frames);
971 fc_host_statistic(tx_words);
972 fc_host_statistic(rx_frames);
973 fc_host_statistic(rx_words);
974 fc_host_statistic(lip_count);
975 fc_host_statistic(nos_count);
976 fc_host_statistic(error_frames);
977 fc_host_statistic(dumped_frames);
978 fc_host_statistic(link_failure_count);
979 fc_host_statistic(loss_of_sync_count);
980 fc_host_statistic(loss_of_signal_count);
981 fc_host_statistic(prim_seq_protocol_err_count);
982 fc_host_statistic(invalid_tx_word_count);
983 fc_host_statistic(invalid_crc_count);
984 fc_host_statistic(fcp_input_requests);
985 fc_host_statistic(fcp_output_requests);
986 fc_host_statistic(fcp_control_requests);
987 fc_host_statistic(fcp_input_megabytes);
988 fc_host_statistic(fcp_output_megabytes);
989
990 static ssize_t
991 fc_reset_statistics(struct class_device *cdev, const char *buf,
992                            size_t count)
993 {
994         struct Scsi_Host *shost = transport_class_to_shost(cdev);
995         struct fc_internal *i = to_fc_internal(shost->transportt);
996
997         /* ignore any data value written to the attribute */
998         if (i->f->reset_fc_host_stats) {
999                 i->f->reset_fc_host_stats(shost);
1000                 return count;
1001         }
1002
1003         return -ENOENT;
1004 }
1005 static FC_CLASS_DEVICE_ATTR(host, reset_statistics, S_IWUSR, NULL,
1006                                 fc_reset_statistics);
1007
1008
1009 static struct attribute *fc_statistics_attrs[] = {
1010         &class_device_attr_host_seconds_since_last_reset.attr,
1011         &class_device_attr_host_tx_frames.attr,
1012         &class_device_attr_host_tx_words.attr,
1013         &class_device_attr_host_rx_frames.attr,
1014         &class_device_attr_host_rx_words.attr,
1015         &class_device_attr_host_lip_count.attr,
1016         &class_device_attr_host_nos_count.attr,
1017         &class_device_attr_host_error_frames.attr,
1018         &class_device_attr_host_dumped_frames.attr,
1019         &class_device_attr_host_link_failure_count.attr,
1020         &class_device_attr_host_loss_of_sync_count.attr,
1021         &class_device_attr_host_loss_of_signal_count.attr,
1022         &class_device_attr_host_prim_seq_protocol_err_count.attr,
1023         &class_device_attr_host_invalid_tx_word_count.attr,
1024         &class_device_attr_host_invalid_crc_count.attr,
1025         &class_device_attr_host_fcp_input_requests.attr,
1026         &class_device_attr_host_fcp_output_requests.attr,
1027         &class_device_attr_host_fcp_control_requests.attr,
1028         &class_device_attr_host_fcp_input_megabytes.attr,
1029         &class_device_attr_host_fcp_output_megabytes.attr,
1030         &class_device_attr_host_reset_statistics.attr,
1031         NULL
1032 };
1033
1034 static struct attribute_group fc_statistics_group = {
1035         .name = "statistics",
1036         .attrs = fc_statistics_attrs,
1037 };
1038
1039 static int fc_host_match(struct attribute_container *cont,
1040                           struct device *dev)
1041 {
1042         struct Scsi_Host *shost;
1043         struct fc_internal *i;
1044
1045         if (!scsi_is_host_device(dev))
1046                 return 0;
1047
1048         shost = dev_to_shost(dev);
1049         if (!shost->transportt  || shost->transportt->host_attrs.ac.class
1050             != &fc_host_class.class)
1051                 return 0;
1052
1053         i = to_fc_internal(shost->transportt);
1054
1055         return &i->t.host_attrs.ac == cont;
1056 }
1057
1058 static int fc_target_match(struct attribute_container *cont,
1059                             struct device *dev)
1060 {
1061         struct Scsi_Host *shost;
1062         struct fc_internal *i;
1063
1064         if (!scsi_is_target_device(dev))
1065                 return 0;
1066
1067         shost = dev_to_shost(dev->parent);
1068         if (!shost->transportt  || shost->transportt->host_attrs.ac.class
1069             != &fc_host_class.class)
1070                 return 0;
1071
1072         i = to_fc_internal(shost->transportt);
1073
1074         return &i->t.target_attrs.ac == cont;
1075 }
1076
1077 static void fc_rport_dev_release(struct device *dev)
1078 {
1079         struct fc_rport *rport = dev_to_rport(dev);
1080         put_device(dev->parent);
1081         kfree(rport);
1082 }
1083
1084 int scsi_is_fc_rport(const struct device *dev)
1085 {
1086         return dev->release == fc_rport_dev_release;
1087 }
1088 EXPORT_SYMBOL(scsi_is_fc_rport);
1089
1090 static int fc_rport_match(struct attribute_container *cont,
1091                             struct device *dev)
1092 {
1093         struct Scsi_Host *shost;
1094         struct fc_internal *i;
1095
1096         if (!scsi_is_fc_rport(dev))
1097                 return 0;
1098
1099         shost = dev_to_shost(dev->parent);
1100         if (!shost->transportt  || shost->transportt->host_attrs.ac.class
1101             != &fc_host_class.class)
1102                 return 0;
1103
1104         i = to_fc_internal(shost->transportt);
1105
1106         return &i->rport_attr_cont.ac == cont;
1107 }
1108
1109
1110 /**
1111  * fc_timed_out - FC Transport I/O timeout intercept handler
1112  *
1113  * @scmd:       The SCSI command which timed out
1114  *
1115  * This routine protects against error handlers getting invoked while a
1116  * rport is in a blocked state, typically due to a temporarily loss of
1117  * connectivity. If the error handlers are allowed to proceed, requests
1118  * to abort i/o, reset the target, etc will likely fail as there is no way
1119  * to communicate with the device to perform the requested function. These
1120  * failures may result in the midlayer taking the device offline, requiring
1121  * manual intervention to restore operation.
1122  *
1123  * This routine, called whenever an i/o times out, validates the state of
1124  * the underlying rport. If the rport is blocked, it returns
1125  * EH_RESET_TIMER, which will continue to reschedule the timeout.
1126  * Eventually, either the device will return, or devloss_tmo will fire,
1127  * and when the timeout then fires, it will be handled normally.
1128  * If the rport is not blocked, normal error handling continues.
1129  *
1130  * Notes:
1131  *      This routine assumes no locks are held on entry.
1132  **/
1133 static enum scsi_eh_timer_return
1134 fc_timed_out(struct scsi_cmnd *scmd)
1135 {
1136         struct fc_rport *rport = starget_to_rport(scsi_target(scmd->device));
1137
1138         if (rport->port_state == FC_PORTSTATE_BLOCKED)
1139                 return EH_RESET_TIMER;
1140
1141         return EH_NOT_HANDLED;
1142 }
1143
1144 /*
1145  * Must be called with shost->host_lock held
1146  */
1147 static int fc_user_scan(struct Scsi_Host *shost, uint channel,
1148                 uint id, uint lun)
1149 {
1150         struct fc_rport *rport;
1151
1152         list_for_each_entry(rport, &fc_host_rports(shost), peers) {
1153                 if (rport->scsi_target_id == -1)
1154                         continue;
1155
1156                 if ((channel == SCAN_WILD_CARD || channel == rport->channel) &&
1157                     (id == SCAN_WILD_CARD || id == rport->scsi_target_id)) {
1158                         scsi_scan_target(&rport->dev, rport->channel,
1159                                          rport->scsi_target_id, lun, 1);
1160                 }
1161         }
1162
1163         return 0;
1164 }
1165
1166 struct scsi_transport_template *
1167 fc_attach_transport(struct fc_function_template *ft)
1168 {
1169         int count;
1170         struct fc_internal *i = kzalloc(sizeof(struct fc_internal),
1171                                         GFP_KERNEL);
1172
1173         if (unlikely(!i))
1174                 return NULL;
1175
1176         i->t.target_attrs.ac.attrs = &i->starget_attrs[0];
1177         i->t.target_attrs.ac.class = &fc_transport_class.class;
1178         i->t.target_attrs.ac.match = fc_target_match;
1179         i->t.target_size = sizeof(struct fc_starget_attrs);
1180         transport_container_register(&i->t.target_attrs);
1181
1182         i->t.host_attrs.ac.attrs = &i->host_attrs[0];
1183         i->t.host_attrs.ac.class = &fc_host_class.class;
1184         i->t.host_attrs.ac.match = fc_host_match;
1185         i->t.host_size = sizeof(struct fc_host_attrs);
1186         if (ft->get_fc_host_stats)
1187                 i->t.host_attrs.statistics = &fc_statistics_group;
1188         transport_container_register(&i->t.host_attrs);
1189
1190         i->rport_attr_cont.ac.attrs = &i->rport_attrs[0];
1191         i->rport_attr_cont.ac.class = &fc_rport_class.class;
1192         i->rport_attr_cont.ac.match = fc_rport_match;
1193         transport_container_register(&i->rport_attr_cont);
1194
1195         i->f = ft;
1196
1197         /* Transport uses the shost workq for scsi scanning */
1198         i->t.create_work_queue = 1;
1199
1200         i->t.eh_timed_out = fc_timed_out;
1201
1202         i->t.user_scan = fc_user_scan;
1203         
1204         /*
1205          * Setup SCSI Target Attributes.
1206          */
1207         count = 0;
1208         SETUP_STARGET_ATTRIBUTE_RD(node_name);
1209         SETUP_STARGET_ATTRIBUTE_RD(port_name);
1210         SETUP_STARGET_ATTRIBUTE_RD(port_id);
1211
1212         BUG_ON(count > FC_STARGET_NUM_ATTRS);
1213
1214         i->starget_attrs[count] = NULL;
1215
1216
1217         /*
1218          * Setup SCSI Host Attributes.
1219          */
1220         count=0;
1221         SETUP_HOST_ATTRIBUTE_RD(node_name);
1222         SETUP_HOST_ATTRIBUTE_RD(port_name);
1223         SETUP_HOST_ATTRIBUTE_RD(permanent_port_name);
1224         SETUP_HOST_ATTRIBUTE_RD(supported_classes);
1225         SETUP_HOST_ATTRIBUTE_RD(supported_fc4s);
1226         SETUP_HOST_ATTRIBUTE_RD(symbolic_name);
1227         SETUP_HOST_ATTRIBUTE_RD(supported_speeds);
1228         SETUP_HOST_ATTRIBUTE_RD(maxframe_size);
1229         SETUP_HOST_ATTRIBUTE_RD(serial_number);
1230
1231         SETUP_HOST_ATTRIBUTE_RD(port_id);
1232         SETUP_HOST_ATTRIBUTE_RD(port_type);
1233         SETUP_HOST_ATTRIBUTE_RD(port_state);
1234         SETUP_HOST_ATTRIBUTE_RD(active_fc4s);
1235         SETUP_HOST_ATTRIBUTE_RD(speed);
1236         SETUP_HOST_ATTRIBUTE_RD(fabric_name);
1237
1238         /* Transport-managed attributes */
1239         SETUP_PRIVATE_HOST_ATTRIBUTE_RW(tgtid_bind_type);
1240         if (ft->issue_fc_host_lip)
1241                 SETUP_PRIVATE_HOST_ATTRIBUTE_RW(issue_lip);
1242
1243         BUG_ON(count > FC_HOST_NUM_ATTRS);
1244
1245         i->host_attrs[count] = NULL;
1246
1247         /*
1248          * Setup Remote Port Attributes.
1249          */
1250         count=0;
1251         SETUP_RPORT_ATTRIBUTE_RD(maxframe_size);
1252         SETUP_RPORT_ATTRIBUTE_RD(supported_classes);
1253         SETUP_RPORT_ATTRIBUTE_RW(dev_loss_tmo);
1254         SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(node_name);
1255         SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_name);
1256         SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_id);
1257         SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(roles);
1258         SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(port_state);
1259         SETUP_PRIVATE_RPORT_ATTRIBUTE_RD(scsi_target_id);
1260
1261         BUG_ON(count > FC_RPORT_NUM_ATTRS);
1262
1263         i->rport_attrs[count] = NULL;
1264
1265         return &i->t;
1266 }
1267 EXPORT_SYMBOL(fc_attach_transport);
1268
1269 void fc_release_transport(struct scsi_transport_template *t)
1270 {
1271         struct fc_internal *i = to_fc_internal(t);
1272
1273         transport_container_unregister(&i->t.target_attrs);
1274         transport_container_unregister(&i->t.host_attrs);
1275         transport_container_unregister(&i->rport_attr_cont);
1276
1277         kfree(i);
1278 }
1279 EXPORT_SYMBOL(fc_release_transport);
1280
1281 /**
1282  * fc_queue_work - Queue work to the fc_host workqueue.
1283  * @shost:      Pointer to Scsi_Host bound to fc_host.
1284  * @work:       Work to queue for execution.
1285  *
1286  * Return value:
1287  *      1 - work queued for execution
1288  *      0 - work is already queued
1289  *      -EINVAL - work queue doesn't exist
1290  **/
1291 static int
1292 fc_queue_work(struct Scsi_Host *shost, struct work_struct *work)
1293 {
1294         if (unlikely(!fc_host_work_q(shost))) {
1295                 printk(KERN_ERR
1296                         "ERROR: FC host '%s' attempted to queue work, "
1297                         "when no workqueue created.\n", shost->hostt->name);
1298                 dump_stack();
1299
1300                 return -EINVAL;
1301         }
1302
1303         return queue_work(fc_host_work_q(shost), work);
1304 }
1305
1306 /**
1307  * fc_flush_work - Flush a fc_host's workqueue.
1308  * @shost:      Pointer to Scsi_Host bound to fc_host.
1309  **/
1310 static void
1311 fc_flush_work(struct Scsi_Host *shost)
1312 {
1313         if (!fc_host_work_q(shost)) {
1314                 printk(KERN_ERR
1315                         "ERROR: FC host '%s' attempted to flush work, "
1316                         "when no workqueue created.\n", shost->hostt->name);
1317                 dump_stack();
1318                 return;
1319         }
1320
1321         flush_workqueue(fc_host_work_q(shost));
1322 }
1323
1324 /**
1325  * fc_queue_devloss_work - Schedule work for the fc_host devloss workqueue.
1326  * @shost:      Pointer to Scsi_Host bound to fc_host.
1327  * @work:       Work to queue for execution.
1328  * @delay:      jiffies to delay the work queuing
1329  *
1330  * Return value:
1331  *      0 on success / != 0 for error
1332  **/
1333 static int
1334 fc_queue_devloss_work(struct Scsi_Host *shost, struct work_struct *work,
1335                                 unsigned long delay)
1336 {
1337         if (unlikely(!fc_host_devloss_work_q(shost))) {
1338                 printk(KERN_ERR
1339                         "ERROR: FC host '%s' attempted to queue work, "
1340                         "when no workqueue created.\n", shost->hostt->name);
1341                 dump_stack();
1342
1343                 return -EINVAL;
1344         }
1345
1346         return queue_delayed_work(fc_host_devloss_work_q(shost), work, delay);
1347 }
1348
1349 /**
1350  * fc_flush_devloss - Flush a fc_host's devloss workqueue.
1351  * @shost:      Pointer to Scsi_Host bound to fc_host.
1352  **/
1353 static void
1354 fc_flush_devloss(struct Scsi_Host *shost)
1355 {
1356         if (!fc_host_devloss_work_q(shost)) {
1357                 printk(KERN_ERR
1358                         "ERROR: FC host '%s' attempted to flush work, "
1359                         "when no workqueue created.\n", shost->hostt->name);
1360                 dump_stack();
1361                 return;
1362         }
1363
1364         flush_workqueue(fc_host_devloss_work_q(shost));
1365 }
1366
1367
1368 /**
1369  * fc_remove_host - called to terminate any fc_transport-related elements
1370  *                  for a scsi host.
1371  * @rport:      remote port to be unblocked.
1372  *
1373  * This routine is expected to be called immediately preceeding the
1374  * a driver's call to scsi_remove_host().
1375  *
1376  * WARNING: A driver utilizing the fc_transport, which fails to call
1377  *   this routine prior to scsi_remote_host(), will leave dangling
1378  *   objects in /sys/class/fc_remote_ports. Access to any of these
1379  *   objects can result in a system crash !!!
1380  *
1381  * Notes:
1382  *      This routine assumes no locks are held on entry.
1383  **/
1384 void
1385 fc_remove_host(struct Scsi_Host *shost)
1386 {
1387         struct fc_rport *rport, *next_rport;
1388         struct workqueue_struct *work_q;
1389         struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1390
1391         /* Remove any remote ports */
1392         list_for_each_entry_safe(rport, next_rport,
1393                         &fc_host->rports, peers) {
1394                 list_del(&rport->peers);
1395                 rport->port_state = FC_PORTSTATE_DELETED;
1396                 fc_queue_work(shost, &rport->rport_delete_work);
1397         }
1398
1399         list_for_each_entry_safe(rport, next_rport,
1400                         &fc_host->rport_bindings, peers) {
1401                 list_del(&rport->peers);
1402                 rport->port_state = FC_PORTSTATE_DELETED;
1403                 fc_queue_work(shost, &rport->rport_delete_work);
1404         }
1405
1406         /* flush all scan work items */
1407         scsi_flush_work(shost);
1408
1409         /* flush all stgt delete, and rport delete work items, then kill it  */
1410         if (fc_host->work_q) {
1411                 work_q = fc_host->work_q;
1412                 fc_host->work_q = NULL;
1413                 destroy_workqueue(work_q);
1414         }
1415
1416         /* flush all devloss work items, then kill it  */
1417         if (fc_host->devloss_work_q) {
1418                 work_q = fc_host->devloss_work_q;
1419                 fc_host->devloss_work_q = NULL;
1420                 destroy_workqueue(work_q);
1421         }
1422 }
1423 EXPORT_SYMBOL(fc_remove_host);
1424
1425
1426 /**
1427  * fc_starget_delete - called to delete the scsi decendents of an rport
1428  *                  (target and all sdevs)
1429  *
1430  * @data:       remote port to be operated on.
1431  **/
1432 static void
1433 fc_starget_delete(void *data)
1434 {
1435         struct fc_rport *rport = (struct fc_rport *)data;
1436         struct Scsi_Host *shost = rport_to_shost(rport);
1437         unsigned long flags;
1438
1439         spin_lock_irqsave(shost->host_lock, flags);
1440         if (rport->flags & FC_RPORT_DEVLOSS_PENDING) {
1441                 spin_unlock_irqrestore(shost->host_lock, flags);
1442                 if (!cancel_delayed_work(&rport->dev_loss_work))
1443                         fc_flush_devloss(shost);
1444                 spin_lock_irqsave(shost->host_lock, flags);
1445                 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
1446         }
1447         spin_unlock_irqrestore(shost->host_lock, flags);
1448
1449         scsi_remove_target(&rport->dev);
1450 }
1451
1452
1453 /**
1454  * fc_rport_final_delete - finish rport termination and delete it.
1455  *
1456  * @data:       remote port to be deleted.
1457  **/
1458 static void
1459 fc_rport_final_delete(void *data)
1460 {
1461         struct fc_rport *rport = (struct fc_rport *)data;
1462         struct device *dev = &rport->dev;
1463         struct Scsi_Host *shost = rport_to_shost(rport);
1464
1465         /* Delete SCSI target and sdevs */
1466         if (rport->scsi_target_id != -1)
1467                 fc_starget_delete(data);
1468
1469         /*
1470          * if a scan is pending, flush the SCSI Host work_q so that 
1471          * that we can reclaim the rport scan work element.
1472          */
1473         if (rport->flags & FC_RPORT_SCAN_PENDING)
1474                 scsi_flush_work(shost);
1475
1476         transport_remove_device(dev);
1477         device_del(dev);
1478         transport_destroy_device(dev);
1479         put_device(&shost->shost_gendev);       /* for fc_host->rport list */
1480         put_device(dev);                        /* for self-reference */
1481 }
1482
1483
1484 /**
1485  * fc_rport_create - allocates and creates a remote FC port.
1486  * @shost:      scsi host the remote port is connected to.
1487  * @channel:    Channel on shost port connected to.
1488  * @ids:        The world wide names, fc address, and FC4 port
1489  *              roles for the remote port.
1490  *
1491  * Allocates and creates the remoter port structure, including the
1492  * class and sysfs creation.
1493  *
1494  * Notes:
1495  *      This routine assumes no locks are held on entry.
1496  **/
1497 struct fc_rport *
1498 fc_rport_create(struct Scsi_Host *shost, int channel,
1499         struct fc_rport_identifiers  *ids)
1500 {
1501         struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1502         struct fc_internal *fci = to_fc_internal(shost->transportt);
1503         struct fc_rport *rport;
1504         struct device *dev;
1505         unsigned long flags;
1506         int error;
1507         size_t size;
1508
1509         size = (sizeof(struct fc_rport) + fci->f->dd_fcrport_size);
1510         rport = kzalloc(size, GFP_KERNEL);
1511         if (unlikely(!rport)) {
1512                 printk(KERN_ERR "%s: allocation failure\n", __FUNCTION__);
1513                 return NULL;
1514         }
1515
1516         rport->maxframe_size = -1;
1517         rport->supported_classes = FC_COS_UNSPECIFIED;
1518         rport->dev_loss_tmo = fc_dev_loss_tmo;
1519         memcpy(&rport->node_name, &ids->node_name, sizeof(rport->node_name));
1520         memcpy(&rport->port_name, &ids->port_name, sizeof(rport->port_name));
1521         rport->port_id = ids->port_id;
1522         rport->roles = ids->roles;
1523         rport->port_state = FC_PORTSTATE_ONLINE;
1524         if (fci->f->dd_fcrport_size)
1525                 rport->dd_data = &rport[1];
1526         rport->channel = channel;
1527
1528         INIT_WORK(&rport->dev_loss_work, fc_timeout_deleted_rport, rport);
1529         INIT_WORK(&rport->scan_work, fc_scsi_scan_rport, rport);
1530         INIT_WORK(&rport->stgt_delete_work, fc_starget_delete, rport);
1531         INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete, rport);
1532
1533         spin_lock_irqsave(shost->host_lock, flags);
1534
1535         rport->number = fc_host->next_rport_number++;
1536         if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
1537                 rport->scsi_target_id = fc_host->next_target_id++;
1538         else
1539                 rport->scsi_target_id = -1;
1540         list_add_tail(&rport->peers, &fc_host->rports);
1541         get_device(&shost->shost_gendev);       /* for fc_host->rport list */
1542
1543         spin_unlock_irqrestore(shost->host_lock, flags);
1544
1545         dev = &rport->dev;
1546         device_initialize(dev);                 /* takes self reference */
1547         dev->parent = get_device(&shost->shost_gendev); /* parent reference */
1548         dev->release = fc_rport_dev_release;
1549         sprintf(dev->bus_id, "rport-%d:%d-%d",
1550                 shost->host_no, channel, rport->number);
1551         transport_setup_device(dev);
1552
1553         error = device_add(dev);
1554         if (error) {
1555                 printk(KERN_ERR "FC Remote Port device_add failed\n");
1556                 goto delete_rport;
1557         }
1558         transport_add_device(dev);
1559         transport_configure_device(dev);
1560
1561         if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) {
1562                 /* initiate a scan of the target */
1563                 rport->flags |= FC_RPORT_SCAN_PENDING;
1564                 scsi_queue_work(shost, &rport->scan_work);
1565         }
1566
1567         return rport;
1568
1569 delete_rport:
1570         transport_destroy_device(dev);
1571         spin_lock_irqsave(shost->host_lock, flags);
1572         list_del(&rport->peers);
1573         put_device(&shost->shost_gendev);       /* for fc_host->rport list */
1574         spin_unlock_irqrestore(shost->host_lock, flags);
1575         put_device(dev->parent);
1576         kfree(rport);
1577         return NULL;
1578 }
1579
1580 /**
1581  * fc_remote_port_add - notifies the fc transport of the existence
1582  *              of a remote FC port.
1583  * @shost:      scsi host the remote port is connected to.
1584  * @channel:    Channel on shost port connected to.
1585  * @ids:        The world wide names, fc address, and FC4 port
1586  *              roles for the remote port.
1587  *
1588  * The LLDD calls this routine to notify the transport of the existence
1589  * of a remote port. The LLDD provides the unique identifiers (wwpn,wwn)
1590  * of the port, it's FC address (port_id), and the FC4 roles that are
1591  * active for the port.
1592  *
1593  * For ports that are FCP targets (aka scsi targets), the FC transport
1594  * maintains consistent target id bindings on behalf of the LLDD.
1595  * A consistent target id binding is an assignment of a target id to
1596  * a remote port identifier, which persists while the scsi host is
1597  * attached. The remote port can disappear, then later reappear, and
1598  * it's target id assignment remains the same. This allows for shifts
1599  * in FC addressing (if binding by wwpn or wwnn) with no apparent
1600  * changes to the scsi subsystem which is based on scsi host number and
1601  * target id values.  Bindings are only valid during the attachment of
1602  * the scsi host. If the host detaches, then later re-attaches, target
1603  * id bindings may change.
1604  *
1605  * This routine is responsible for returning a remote port structure.
1606  * The routine will search the list of remote ports it maintains
1607  * internally on behalf of consistent target id mappings. If found, the
1608  * remote port structure will be reused. Otherwise, a new remote port
1609  * structure will be allocated.
1610  *
1611  * Whenever a remote port is allocated, a new fc_remote_port class
1612  * device is created.
1613  *
1614  * Should not be called from interrupt context.
1615  *
1616  * Notes:
1617  *      This routine assumes no locks are held on entry.
1618  **/
1619 struct fc_rport *
1620 fc_remote_port_add(struct Scsi_Host *shost, int channel,
1621         struct fc_rport_identifiers  *ids)
1622 {
1623         struct fc_internal *fci = to_fc_internal(shost->transportt);
1624         struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1625         struct fc_rport *rport;
1626         unsigned long flags;
1627         int match = 0;
1628
1629         /* ensure any stgt delete functions are done */
1630         fc_flush_work(shost);
1631
1632         /*
1633          * Search the list of "active" rports, for an rport that has been
1634          * deleted, but we've held off the real delete while the target
1635          * is in a "blocked" state.
1636          */
1637         spin_lock_irqsave(shost->host_lock, flags);
1638
1639         list_for_each_entry(rport, &fc_host->rports, peers) {
1640
1641                 if ((rport->port_state == FC_PORTSTATE_BLOCKED) &&
1642                         (rport->channel == channel)) {
1643
1644                         switch (fc_host->tgtid_bind_type) {
1645                         case FC_TGTID_BIND_BY_WWPN:
1646                         case FC_TGTID_BIND_NONE:
1647                                 if (rport->port_name == ids->port_name)
1648                                         match = 1;
1649                                 break;
1650                         case FC_TGTID_BIND_BY_WWNN:
1651                                 if (rport->node_name == ids->node_name)
1652                                         match = 1;
1653                                 break;
1654                         case FC_TGTID_BIND_BY_ID:
1655                                 if (rport->port_id == ids->port_id)
1656                                         match = 1;
1657                                 break;
1658                         }
1659
1660                         if (match) {
1661                                 struct work_struct *work = 
1662                                                         &rport->dev_loss_work;
1663
1664                                 memcpy(&rport->node_name, &ids->node_name,
1665                                         sizeof(rport->node_name));
1666                                 memcpy(&rport->port_name, &ids->port_name,
1667                                         sizeof(rport->port_name));
1668                                 rport->port_id = ids->port_id;
1669
1670                                 rport->port_state = FC_PORTSTATE_ONLINE;
1671                                 rport->roles = ids->roles;
1672
1673                                 spin_unlock_irqrestore(shost->host_lock, flags);
1674
1675                                 if (fci->f->dd_fcrport_size)
1676                                         memset(rport->dd_data, 0,
1677                                                 fci->f->dd_fcrport_size);
1678
1679                                 /*
1680                                  * If we were blocked, we were a target.
1681                                  * If no longer a target, we leave the timer
1682                                  * running in case the port changes roles
1683                                  * prior to the timer expiring. If the timer
1684                                  * fires, the target will be torn down.
1685                                  */
1686                                 if (!(ids->roles & FC_RPORT_ROLE_FCP_TARGET))
1687                                         return rport;
1688
1689                                 /* restart the target */
1690
1691                                 /*
1692                                  * Stop the target timer first. Take no action
1693                                  * on the del_timer failure as the state
1694                                  * machine state change will validate the
1695                                  * transaction.
1696                                  */
1697                                 if (!cancel_delayed_work(work))
1698                                         fc_flush_devloss(shost);
1699
1700                                 spin_lock_irqsave(shost->host_lock, flags);
1701
1702                                 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
1703
1704                                 /* initiate a scan of the target */
1705                                 rport->flags |= FC_RPORT_SCAN_PENDING;
1706                                 scsi_queue_work(shost, &rport->scan_work);
1707
1708                                 spin_unlock_irqrestore(shost->host_lock, flags);
1709
1710                                 scsi_target_unblock(&rport->dev);
1711
1712                                 return rport;
1713                         }
1714                 }
1715         }
1716
1717         /* Search the bindings array */
1718         if (fc_host->tgtid_bind_type != FC_TGTID_BIND_NONE) {
1719
1720                 /* search for a matching consistent binding */
1721
1722                 list_for_each_entry(rport, &fc_host->rport_bindings,
1723                                         peers) {
1724                         if (rport->channel != channel)
1725                                 continue;
1726
1727                         switch (fc_host->tgtid_bind_type) {
1728                         case FC_TGTID_BIND_BY_WWPN:
1729                                 if (rport->port_name == ids->port_name)
1730                                         match = 1;
1731                                 break;
1732                         case FC_TGTID_BIND_BY_WWNN:
1733                                 if (rport->node_name == ids->node_name)
1734                                         match = 1;
1735                                 break;
1736                         case FC_TGTID_BIND_BY_ID:
1737                                 if (rport->port_id == ids->port_id)
1738                                         match = 1;
1739                                 break;
1740                         case FC_TGTID_BIND_NONE: /* to keep compiler happy */
1741                                 break;
1742                         }
1743
1744                         if (match) {
1745                                 list_move_tail(&rport->peers, &fc_host->rports);
1746                                 break;
1747                         }
1748                 }
1749
1750                 if (match) {
1751                         memcpy(&rport->node_name, &ids->node_name,
1752                                 sizeof(rport->node_name));
1753                         memcpy(&rport->port_name, &ids->port_name,
1754                                 sizeof(rport->port_name));
1755                         rport->port_id = ids->port_id;
1756                         rport->roles = ids->roles;
1757                         rport->port_state = FC_PORTSTATE_ONLINE;
1758
1759                         if (fci->f->dd_fcrport_size)
1760                                 memset(rport->dd_data, 0,
1761                                                 fci->f->dd_fcrport_size);
1762
1763                         if (rport->roles & FC_RPORT_ROLE_FCP_TARGET) {
1764                                 /* initiate a scan of the target */
1765                                 rport->flags |= FC_RPORT_SCAN_PENDING;
1766                                 scsi_queue_work(shost, &rport->scan_work);
1767                                 spin_unlock_irqrestore(shost->host_lock, flags);
1768                                 scsi_target_unblock(&rport->dev);
1769                         } else
1770                                 spin_unlock_irqrestore(shost->host_lock, flags);
1771
1772                         return rport;
1773                 }
1774         }
1775
1776         spin_unlock_irqrestore(shost->host_lock, flags);
1777
1778         /* No consistent binding found - create new remote port entry */
1779         rport = fc_rport_create(shost, channel, ids);
1780
1781         return rport;
1782 }
1783 EXPORT_SYMBOL(fc_remote_port_add);
1784
1785
1786 /**
1787  * fc_remote_port_delete - notifies the fc transport that a remote
1788  *              port is no longer in existence.
1789  * @rport:      The remote port that no longer exists
1790  *
1791  * The LLDD calls this routine to notify the transport that a remote
1792  * port is no longer part of the topology. Note: Although a port
1793  * may no longer be part of the topology, it may persist in the remote
1794  * ports displayed by the fc_host. We do this under 2 conditions:
1795  * - If the port was a scsi target, we delay its deletion by "blocking" it.
1796  *   This allows the port to temporarily disappear, then reappear without
1797  *   disrupting the SCSI device tree attached to it. During the "blocked"
1798  *   period the port will still exist.
1799  * - If the port was a scsi target and disappears for longer than we
1800  *   expect, we'll delete the port and the tear down the SCSI device tree
1801  *   attached to it. However, we want to semi-persist the target id assigned
1802  *   to that port if it eventually does exist. The port structure will
1803  *   remain (although with minimal information) so that the target id
1804  *   bindings remails.
1805  *
1806  * If the remote port is not an FCP Target, it will be fully torn down
1807  * and deallocated, including the fc_remote_port class device.
1808  *
1809  * If the remote port is an FCP Target, the port will be placed in a
1810  * temporary blocked state. From the LLDD's perspective, the rport no
1811  * longer exists. From the SCSI midlayer's perspective, the SCSI target
1812  * exists, but all sdevs on it are blocked from further I/O. The following
1813  * is then expected:
1814  *   If the remote port does not return (signaled by a LLDD call to
1815  *   fc_remote_port_add()) within the dev_loss_tmo timeout, then the
1816  *   scsi target is removed - killing all outstanding i/o and removing the
1817  *   scsi devices attached ot it. The port structure will be marked Not
1818  *   Present and be partially cleared, leaving only enough information to
1819  *   recognize the remote port relative to the scsi target id binding if
1820  *   it later appears.  The port will remain as long as there is a valid
1821  *   binding (e.g. until the user changes the binding type or unloads the
1822  *   scsi host with the binding).
1823  *
1824  *   If the remote port returns within the dev_loss_tmo value (and matches
1825  *   according to the target id binding type), the port structure will be
1826  *   reused. If it is no longer a SCSI target, the target will be torn
1827  *   down. If it continues to be a SCSI target, then the target will be
1828  *   unblocked (allowing i/o to be resumed), and a scan will be activated
1829  *   to ensure that all luns are detected.
1830  *
1831  * Called from normal process context only - cannot be called from interrupt.
1832  *
1833  * Notes:
1834  *      This routine assumes no locks are held on entry.
1835  **/
1836 void
1837 fc_remote_port_delete(struct fc_rport  *rport)
1838 {
1839         struct Scsi_Host *shost = rport_to_shost(rport);
1840         int timeout = rport->dev_loss_tmo;
1841         unsigned long flags;
1842
1843         /*
1844          * No need to flush the fc_host work_q's, as all adds are synchronous.
1845          *
1846          * We do need to reclaim the rport scan work element, so eventually
1847          * (in fc_rport_final_delete()) we'll flush the scsi host work_q if
1848          * there's still a scan pending.
1849          */
1850
1851         spin_lock_irqsave(shost->host_lock, flags);
1852
1853         /* If no scsi target id mapping, delete it */
1854         if (rport->scsi_target_id == -1) {
1855                 list_del(&rport->peers);
1856                 rport->port_state = FC_PORTSTATE_DELETED;
1857                 fc_queue_work(shost, &rport->rport_delete_work);
1858                 spin_unlock_irqrestore(shost->host_lock, flags);
1859                 return;
1860         }
1861
1862         rport->port_state = FC_PORTSTATE_BLOCKED;
1863
1864         rport->flags |= FC_RPORT_DEVLOSS_PENDING;
1865
1866         spin_unlock_irqrestore(shost->host_lock, flags);
1867
1868         scsi_target_block(&rport->dev);
1869
1870         /* cap the length the devices can be blocked until they are deleted */
1871         fc_queue_devloss_work(shost, &rport->dev_loss_work, timeout * HZ);
1872 }
1873 EXPORT_SYMBOL(fc_remote_port_delete);
1874
1875 /**
1876  * fc_remote_port_rolechg - notifies the fc transport that the roles
1877  *              on a remote may have changed.
1878  * @rport:      The remote port that changed.
1879  *
1880  * The LLDD calls this routine to notify the transport that the roles
1881  * on a remote port may have changed. The largest effect of this is
1882  * if a port now becomes a FCP Target, it must be allocated a
1883  * scsi target id.  If the port is no longer a FCP target, any
1884  * scsi target id value assigned to it will persist in case the
1885  * role changes back to include FCP Target. No changes in the scsi
1886  * midlayer will be invoked if the role changes (in the expectation
1887  * that the role will be resumed. If it doesn't normal error processing
1888  * will take place).
1889  *
1890  * Should not be called from interrupt context.
1891  *
1892  * Notes:
1893  *      This routine assumes no locks are held on entry.
1894  **/
1895 void
1896 fc_remote_port_rolechg(struct fc_rport  *rport, u32 roles)
1897 {
1898         struct Scsi_Host *shost = rport_to_shost(rport);
1899         struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1900         unsigned long flags;
1901         int create = 0;
1902
1903         spin_lock_irqsave(shost->host_lock, flags);
1904         if (roles & FC_RPORT_ROLE_FCP_TARGET) {
1905                 if (rport->scsi_target_id == -1) {
1906                         rport->scsi_target_id = fc_host->next_target_id++;
1907                         create = 1;
1908                 } else if (!(rport->roles & FC_RPORT_ROLE_FCP_TARGET))
1909                         create = 1;
1910         }
1911
1912         rport->roles = roles;
1913
1914         spin_unlock_irqrestore(shost->host_lock, flags);
1915
1916         if (create) {
1917                 /*
1918                  * There may have been a delete timer running on the
1919                  * port. Ensure that it is cancelled as we now know
1920                  * the port is an FCP Target.
1921                  * Note: we know the rport is exists and in an online
1922                  *  state as the LLDD would not have had an rport
1923                  *  reference to pass us.
1924                  *
1925                  * Take no action on the del_timer failure as the state
1926                  * machine state change will validate the
1927                  * transaction.
1928                  */
1929                 if (!cancel_delayed_work(&rport->dev_loss_work))
1930                         fc_flush_devloss(shost);
1931
1932                 spin_lock_irqsave(shost->host_lock, flags);
1933                 rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
1934                 spin_unlock_irqrestore(shost->host_lock, flags);
1935
1936                 /* ensure any stgt delete functions are done */
1937                 fc_flush_work(shost);
1938
1939                 /* initiate a scan of the target */
1940                 spin_lock_irqsave(shost->host_lock, flags);
1941                 rport->flags |= FC_RPORT_SCAN_PENDING;
1942                 scsi_queue_work(shost, &rport->scan_work);
1943                 spin_unlock_irqrestore(shost->host_lock, flags);
1944                 scsi_target_unblock(&rport->dev);
1945         }
1946 }
1947 EXPORT_SYMBOL(fc_remote_port_rolechg);
1948
1949 /**
1950  * fc_timeout_deleted_rport - Timeout handler for a deleted remote port that
1951  *                       was a SCSI target (thus was blocked), and failed
1952  *                       to return in the alloted time.
1953  * 
1954  * @data:       rport target that failed to reappear in the alloted time.
1955  **/
1956 static void
1957 fc_timeout_deleted_rport(void  *data)
1958 {
1959         struct fc_rport *rport = (struct fc_rport *)data;
1960         struct Scsi_Host *shost = rport_to_shost(rport);
1961         struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
1962         unsigned long flags;
1963
1964         spin_lock_irqsave(shost->host_lock, flags);
1965
1966         rport->flags &= ~FC_RPORT_DEVLOSS_PENDING;
1967
1968         /*
1969          * If the port is ONLINE, then it came back. Validate it's still an
1970          * FCP target. If not, tear down the scsi_target on it.
1971          */
1972         if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
1973             !(rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
1974                 dev_printk(KERN_ERR, &rport->dev,
1975                         "blocked FC remote port time out: no longer"
1976                         " a FCP target, removing starget\n");
1977                 spin_unlock_irqrestore(shost->host_lock, flags);
1978                 scsi_target_unblock(&rport->dev);
1979                 fc_queue_work(shost, &rport->stgt_delete_work);
1980                 return;
1981         }
1982
1983         if (rport->port_state != FC_PORTSTATE_BLOCKED) {
1984                 spin_unlock_irqrestore(shost->host_lock, flags);
1985                 dev_printk(KERN_ERR, &rport->dev,
1986                         "blocked FC remote port time out: leaving target alone\n");
1987                 return;
1988         }
1989
1990         if (fc_host->tgtid_bind_type == FC_TGTID_BIND_NONE) {
1991                 list_del(&rport->peers);
1992                 rport->port_state = FC_PORTSTATE_DELETED;
1993                 dev_printk(KERN_ERR, &rport->dev,
1994                         "blocked FC remote port time out: removing target\n");
1995                 fc_queue_work(shost, &rport->rport_delete_work);
1996                 spin_unlock_irqrestore(shost->host_lock, flags);
1997                 return;
1998         }
1999
2000         dev_printk(KERN_ERR, &rport->dev,
2001                 "blocked FC remote port time out: removing target and "
2002                 "saving binding\n");
2003
2004         list_move_tail(&rport->peers, &fc_host->rport_bindings);
2005
2006         /*
2007          * Note: We do not remove or clear the hostdata area. This allows
2008          *   host-specific target data to persist along with the
2009          *   scsi_target_id. It's up to the host to manage it's hostdata area.
2010          */
2011
2012         /*
2013          * Reinitialize port attributes that may change if the port comes back.
2014          */
2015         rport->maxframe_size = -1;
2016         rport->supported_classes = FC_COS_UNSPECIFIED;
2017         rport->roles = FC_RPORT_ROLE_UNKNOWN;
2018         rport->port_state = FC_PORTSTATE_NOTPRESENT;
2019
2020         /* remove the identifiers that aren't used in the consisting binding */
2021         switch (fc_host->tgtid_bind_type) {
2022         case FC_TGTID_BIND_BY_WWPN:
2023                 rport->node_name = -1;
2024                 rport->port_id = -1;
2025                 break;
2026         case FC_TGTID_BIND_BY_WWNN:
2027                 rport->port_name = -1;
2028                 rport->port_id = -1;
2029                 break;
2030         case FC_TGTID_BIND_BY_ID:
2031                 rport->node_name = -1;
2032                 rport->port_name = -1;
2033                 break;
2034         case FC_TGTID_BIND_NONE:        /* to keep compiler happy */
2035                 break;
2036         }
2037
2038         /*
2039          * As this only occurs if the remote port (scsi target)
2040          * went away and didn't come back - we'll remove
2041          * all attached scsi devices.
2042          */
2043         spin_unlock_irqrestore(shost->host_lock, flags);
2044
2045         scsi_target_unblock(&rport->dev);
2046         fc_queue_work(shost, &rport->stgt_delete_work);
2047 }
2048
2049 /**
2050  * fc_scsi_scan_rport - called to perform a scsi scan on a remote port.
2051  *
2052  * @data:       remote port to be scanned.
2053  **/
2054 static void
2055 fc_scsi_scan_rport(void *data)
2056 {
2057         struct fc_rport *rport = (struct fc_rport *)data;
2058         struct Scsi_Host *shost = rport_to_shost(rport);
2059         unsigned long flags;
2060
2061         if ((rport->port_state == FC_PORTSTATE_ONLINE) &&
2062             (rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
2063                 scsi_scan_target(&rport->dev, rport->channel,
2064                         rport->scsi_target_id, SCAN_WILD_CARD, 1);
2065         }
2066
2067         spin_lock_irqsave(shost->host_lock, flags);
2068         rport->flags &= ~FC_RPORT_SCAN_PENDING;
2069         spin_unlock_irqrestore(shost->host_lock, flags);
2070 }
2071
2072
2073 MODULE_AUTHOR("Martin Hicks");
2074 MODULE_DESCRIPTION("FC Transport Attributes");
2075 MODULE_LICENSE("GPL");
2076
2077 module_init(fc_transport_init);
2078 module_exit(fc_transport_exit);