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