1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef	_FCTL_PRIVATE_H
27 #define	_FCTL_PRIVATE_H
28 
29 
30 #include <sys/note.h>
31 
32 #include <sys/fibre-channel/impl/fc_ulpif.h>
33 
34 #ifdef	__cplusplus
35 extern "C" {
36 #endif
37 
38 /*
39  * Stuff strictly internal to fctl that
40  * isn't exposed to any other modules.
41  */
42 #define	PWWN_HASH_TABLE_SIZE	(32)		/* 2^n */
43 #define	D_ID_HASH_TABLE_SIZE	(32)		/* 2^n */
44 #define	NWWN_HASH_TABLE_SIZE	(32)		/* 2^n */
45 #define	HASH_FUNC(key, size)	((key) & (size - 1))
46 #define	WWN_HASH_KEY(x)		((x)[0] + (x)[1] + (x)[2] +\
47 				    (x)[3] + (x)[4] + (x)[5] +\
48 				    (x)[6] + (x)[7])
49 #define	D_ID_HASH_FUNC(x, size)	((x) & (size - 1))
50 #define	FC4_TYPE_WORD_POS(x)	((uchar_t)(x) >> 5)
51 #define	FC4_TYPE_BIT_POS(x)	((uchar_t)(x) & 0x1F)
52 #define	FC_ACTION_INVALID	-1
53 #define	FC_REASON_INVALID	-1
54 #define	FC_EXPLN_INVALID	-1
55 
56 /*
57  * Internally translated and used state change values to ULPs
58  */
59 #define	FC_ULP_STATEC_DONT_CARE		0
60 #define	FC_ULP_STATEC_ONLINE		1
61 #define	FC_ULP_STATEC_OFFLINE		2
62 #define	FC_ULP_STATEC_OFFLINE_TIMEOUT	3
63 
64 #define	FC_ULP_ADD_RETRY_COUNT		90
65 #define	FC_MAX_TRACE_BUF_LEN		512
66 
67 
68 #define	FC_NPIV_MAX_PORT		255
69 
70 /*
71  * port_dstate values
72  */
73 #define	ULP_PORT_ATTACH			0x01
74 #define	ULP_PORT_SUSPEND		0x02
75 #define	ULP_PORT_POWER_DOWN		0x04
76 #define	ULP_PORT_BUSY			0x08
77 #define	FCTL_DISALLOW_CALLBACKS(x)	(!((x) & ULP_PORT_ATTACH) ||\
78 					((x) & ULP_PORT_BUSY))
79 
80 typedef struct ulp_ports {
81 	struct ulp_ports	*port_next;
82 	int			port_dstate;
83 	uint32_t		port_statec;
84 	kmutex_t		port_mutex;
85 	struct fc_local_port	*port_handle;
86 } fc_ulp_ports_t;
87 
88 
89 typedef struct ulp_module {
90 	struct ulp_module	*mod_next;
91 	fc_ulp_modinfo_t	*mod_info;
92 	fc_ulp_ports_t		*mod_ports;
93 } fc_ulp_module_t;
94 
95 
96 typedef struct ulp_list {
97 	fc_ulp_modinfo_t	*ulp_info;
98 	struct ulp_list		*ulp_next;
99 } fc_ulp_list_t;
100 
101 
102 typedef struct fca_port {
103 	struct fca_port		*port_next;
104 	struct fc_local_port	*port_handle;
105 } fc_fca_port_t;
106 
107 typedef struct timed_counter {
108 	struct timed_counter	*sig;
109 	uint32_t		counter;
110 	uint32_t		max_value;
111 	boolean_t		maxed_out;
112 	kmutex_t		mutex;
113 	boolean_t		active;
114 	clock_t			timer;
115 	timeout_id_t		tid;
116 } timed_counter_t;
117 
118 /*
119  * Struct describing a remote node. A remote node is associated with one
120  * or more remote ports (fc_remote_port_t structs) that are all accessible
121  * through one local port (fc_local_port_t struct).
122  *
123  * Each fc_remote_node_t struct is also referenced by nwwn in the global
124  * nwwn_hash_table[] list.
125  */
126 typedef struct fc_remote_node {
127 	/*
128 	 * Mutex lock to protect access to all members of this struct.
129 	 * Current implementation dictates acquisition of fd_mutex before
130 	 * pd_mutex can be acquired (when both locks must be acquired).
131 	 */
132 	kmutex_t		fd_mutex;
133 
134 	/* Node WWN for the remote node */
135 	la_wwn_t		fd_node_name;
136 
137 	/*
138 	 * This is the number of (active) fc_remote_port_t structs that
139 	 * are associated with this remote node.
140 	 */
141 	int			fd_numports;
142 
143 	/*
144 	 * Tracks whether this struct is "valid" or "invalid", using the
145 	 * FC_REMOTE_NODE_* values given above.
146 	 */
147 	int			fd_flags;
148 
149 	/* Linked list of remote ports associated with this remote node. */
150 	struct fc_remote_port	*fd_portlistp;
151 
152 	uchar_t			fd_ipa[8];	/* Initial proc assoc */
153 	uchar_t			fd_vv[16];	/* Vendor Version */
154 	uchar_t			fd_snn_len;	/* node symbolic name len */
155 	uchar_t			fd_snn[255];	/* node symbolic name */
156 } fc_remote_node_t;
157 
158 /*
159  * Stack depth for troubleshooting (only used in debug code)
160  */
161 #define	FC_STACK_DEPTH			14
162 
163 /*
164  * The fc_remote_port_t struct represents a remote FC port that is
165  * accessible via the local FC port (fc_local_port_t). Each remote
166  * FC port is associated with one FC local port (fc_local_port_t,
167  * above) and one remote FC node (fc_remote_node_t, see below).
168  * fc_remote_port_t structs are created and destroyed as needed to
169  * correspond with changing conditions out on the link.
170  */
171 typedef struct fc_remote_port {
172 	/*
173 	 * Ah, the infamous 'pd_mutex' that has given developers so much
174 	 * joy over the years....
175 	 * (Gotta love the original, extremely helpful comment.)
176 	 */
177 	kmutex_t		pd_mutex;	/* mutex */
178 
179 	fc_portid_t		pd_port_id;	/* Port Identifier */
180 	la_wwn_t		pd_port_name;	/* the port WWN */
181 
182 	/*
183 	 * Reference count of the # of logins initiated by a ULP
184 	 * (i.e., this is the # of ULPs accessing the struct). See
185 	 * fp_plogi_group() for more info.
186 	 */
187 	int			pd_login_count;
188 
189 	/*
190 	 * This appears to track the login state of the remote FC port.
191 	 * Used with the PORT_DEVICE_* macros in fc_appif.h.
192 	 */
193 	uint32_t		pd_state;
194 
195 	/*
196 	 * Link pointers for the port wwn and D_ID hash lists. These point
197 	 * to the next remote port in the current hash chain.
198 	 */
199 	struct fc_remote_port	*pd_wwn_hnext;
200 	struct fc_remote_port	*pd_did_hnext;
201 
202 	/*
203 	 * Link pointer for list of *all* fc_remote_port_t structs
204 	 * associated with the same fc_local_port_t struct.
205 	 */
206 	struct fc_remote_port	*pd_port_next;
207 
208 	/*
209 	 * Pointer to the fc_remote_node_t struct for the remote node
210 	 * associated with the remote port.
211 	 */
212 	struct fc_remote_node	*pd_remote_nodep;
213 
214 	/* port type for the remote port */
215 	fc_porttype_t		pd_porttype;
216 
217 	fc_hardaddr_t		pd_hard_addr;	/* Hard Address */
218 
219 	/*
220 	 * Back pointer to the fc_local_port_t struct for the local port
221 	 * associated with this remote port.
222 	 */
223 	struct fc_local_port	*pd_port;
224 
225 	/*
226 	 * (Sigh) this actually doesn't have anything to do with the "type"
227 	 * of the remote port per se.  It's really more an indicator of the
228 	 * most recently known state/status of the remote port. It's intended
229 	 * to help figure out if/how the remote port has either gone away or
230 	 * changed somehow after an event has occurred on the link.
231 	 * There also seems to be some connection to the "changed map".
232 	 *
233 	 * The legal values for this are the PORT_DEVICE_* definitions
234 	 * earlier in this file.
235 	 */
236 	uchar_t			pd_type;	/* new or old */
237 
238 	/*
239 	 * This tracks the current state/status of a login attempt at the
240 	 * remote port.	 Legal values are given above.
241 	 * See also the pd_state field.
242 	 */
243 	uchar_t			pd_flags;	/* login in progress */
244 
245 	uchar_t			pd_login_class;	/* Logi Class */
246 
247 	/* Legal values are given above (beware of the mipselling) */
248 	uchar_t			pd_recepient;	/* who did PLOGI? */
249 
250 	uchar_t			pd_ip_addr[8];	/* IP address */
251 	uint32_t		pd_fc4types[8];	/* FC-4 types */
252 	uint32_t		pd_cos;		/* class of service */
253 	struct common_service	pd_csp;		/* common service */
254 	struct service_param	pd_clsp1;	/* Class 1 */
255 	struct service_param	pd_clsp2;	/* Class 2 */
256 	struct service_param	pd_clsp3;	/* Class 3 */
257 
258 	/* This is _SO_ private that even we don't use it */
259 	caddr_t			pd_private;	/* private data */
260 
261 	/*
262 	 * This is a count of the number of references to (or holds on)
263 	 * this remote port.
264 	 */
265 	int			pd_ref_count;	/* number of references */
266 
267 	/*
268 	 * Re-login disable for FCP-2 error recovery.  This is intended to
269 	 * help with tape devices when an RSCN or Link Reset occurs during
270 	 * a long write operations (like backup). fp's default action is
271 	 * to try to log in again, but that forces a rewind on the LUN
272 	 * and corrupts its state.
273 	 *
274 	 * The legal bit values are given below. Some specific definitions
275 	 * are as follows:
276 	 *
277 	 *   PD_IN_DID_QUEUE: The fc_remote_port_t is present in the d_id
278 	 *		    hash list of the associated fc_local_port_t.  (This
279 	 *		    is apparently meant to cover some races).
280 	 *   PD_LOGGED_OUT: This is a directive to ignore the NORELOGIN if
281 	 *		    an actual logout occurred
282 	 */
283 	uchar_t			pd_aux_flags;	/* relogin disable */
284 
285 	uchar_t			pd_spn_len;	/* length of sym name */
286 	char			pd_spn[255];	/* symbolic port name */
287 
288 	/*
289 	 * Count of the # of unsolicited LOGOs received. See the definition
290 	 * of FC_LOGO_TOLERANCE_LIMIT in fp.c.
291 	 */
292 	timed_counter_t		pd_logo_tc;
293 
294 #ifdef	DEBUG
295 	int			pd_w_depth;	/* for WWN hash table */
296 	pc_t			pd_w_stack[FC_STACK_DEPTH];
297 	int			pd_d_depth;	/* for D_ID hash table */
298 	pc_t			pd_d_stack[FC_STACK_DEPTH];
299 #endif
300 } fc_remote_port_t;
301 
302 
303 /*
304  * Structs for the global nwwn_hash_table[] entries.
305  *
306  * At _init() time, fctl allocates an array of fctl_nwwn_list_t structs that
307  * has nwwn_table_size entries.	 The hash_head member anchors a linked
308  * list of fctl_nwwn_elem_t structs that are linked via the fne_next pointer.
309  * Each fctl_nwwn_elem_t also contains a pointer to one fc_remote_node_t struct.
310  */
311 typedef struct fctl_nwwn_elem fctl_nwwn_elem_t;
312 
313 struct fctl_nwwn_elem {
314 	fctl_nwwn_elem_t	*fne_nextp;
315 	fc_remote_node_t	*fne_nodep;
316 };
317 
318 typedef struct fctl_nwwn_list {
319 	fctl_nwwn_elem_t	*fnl_headp;
320 } fctl_nwwn_list_t;
321 
322 
323 
324 typedef struct fc_errmap {
325 	int	fc_errno;
326 	char	*fc_errname;
327 } fc_errmap_t;
328 
329 
330 typedef struct fc_pkt_reason {
331 	int	reason_val;
332 	char	*reason_msg;
333 } fc_pkt_reason_t;
334 
335 
336 typedef struct fc_pkt_action {
337 	int	action_val;
338 	char	*action_msg;
339 } fc_pkt_action_t;
340 
341 
342 typedef struct fc_pkt_expln {
343 	int	expln_val;
344 	char	*expln_msg;
345 } fc_pkt_expln_t;
346 
347 
348 typedef struct fc_pkt_error {
349 	int			pkt_state;
350 	char			*pkt_msg;
351 	fc_pkt_reason_t		*pkt_reason;
352 	fc_pkt_action_t		*pkt_action;
353 	fc_pkt_expln_t		*pkt_expln;
354 } fc_pkt_error_t;
355 
356 
357 /*
358  * Values for the fd_flags field in the fc_remote_node_t struct.
359  * Note, the code seems to rely on the struct initialization using
360  * kmem_zalloc() to set all the bits to zero, since FC_REMOTE_NODE_INVALID
361  * is never explicitly set anywhere.
362  */
363 #define	FC_REMOTE_NODE_INVALID	0
364 #define	FC_REMOTE_NODE_VALID	1
365 
366 
367 /*
368  * Values for the pd_flags field in the fc_remote_port_t struct.  These
369  * are used in a _lot_ of places. NOTE: these are values, not bit flags.
370  */
371 #define	PD_IDLE			0x00
372 #define	PD_ELS_IN_PROGRESS	0x01
373 #define	PD_ELS_MARK		0x02
374 
375 
376 /*
377  * Bit values for the pd_aux_flags field in the fc_remote_port_t struct.
378  */
379 #define	PD_IN_DID_QUEUE		0x01	/* The fc_remote_port_t is present */
380 					/* in the D_ID hash list of the */
381 					/* associated fc_local_port_t. (This */
382 					/* is apparently meant to narrow */
383 					/* some race windows). */
384 #define	PD_DISABLE_RELOGIN	0x02
385 #define	PD_NEEDS_REMOVAL	0x04
386 #define	PD_LOGGED_OUT		0x08	/* This is a directive to ignore */
387 					/* the NORELOGIN if an actual logout */
388 					/* occurred */
389 #define	PD_GIVEN_TO_ULPS	0x10	/* A reference to this pd has been */
390 					/* given to one or more ULPs. */
391 
392 /*
393  * Values for the pd_recepient field in the fc_remote_port_t struct.
394  * Tries to describe where a PLOGI attempt originated.
395  */
396 #define	PD_PLOGI_INITIATOR		0
397 #define	PD_PLOGI_RECEPIENT		1
398 
399 
400 /*
401  * The fc_local_port_t struct represents a local FC port. It is the softstate
402  * struct for each fp instance, so it comes into existence at DDI_ATTACH
403  * and is deleted during DDI_DETACH.
404  */
405 typedef struct fc_local_port {
406 	/*
407 	 * Mutex to protect certain data fields in this struct.
408 	 */
409 	kmutex_t		fp_mutex;
410 
411 	/*
412 	 * fp_state sort of tracks the state of the link at the local port.
413 	 * The actual 'state' is kept in the lower byte, and the port speed
414 	 * is kept in the next most significant byte.  The code makes
415 	 * extensive use of the FC_PORT_SPEED_MASK() and FC_PORT_STATE_MASK()
416 	 * macros to separate these two items.	The current link topology
417 	 * is actually kept separately in the fp_topology field.
418 	 * The legal values for fp_state are given above.
419 	 */
420 	volatile uint32_t	fp_state;
421 
422 	/*
423 	 * The S_ID for the local port. See fc_types.h for the fc_portid_t
424 	 * definition.
425 	 */
426 	fc_portid_t		fp_port_id;
427 
428 	/*
429 	 * Opaque reference handle for the local port device. This value
430 	 * is supplied by the FCA driver and is passed unaltered to
431 	 * various FCA driver entry point functions.
432 	 */
433 	opaque_t		fp_fca_handle;
434 
435 	/* Entry point vectors for the FCA driver at this FC port */
436 	struct fca_tran		*fp_fca_tran;
437 
438 	/*
439 	 * fp's homegrown "job" threading mechanism (not a Solaris DDI taskq).
440 	 *
441 	 * Head/tail pointers for a linked list of requests to be executed
442 	 * in a driver-private thread.	One thread per fc_local_port_t struct.
443 	 * The thread is created during DDI_ATTACH for the instance.
444 	 */
445 	struct job_request	*fp_job_head;
446 	struct job_request	*fp_job_tail;
447 
448 	struct fp_cmd		*fp_wait_head;		/* waitQ head */
449 	struct fp_cmd		*fp_wait_tail;		/* waitQ tail */
450 
451 	/*
452 	 * Current port topology. Uses the FC_TOP_* values defined in
453 	 * fc_appif.h.	This is used with the FC_IS_TOP_SWITCH() macro and
454 	 * is also used with the FC_TOP_EXTERNAL() macro in the ULPs.
455 	 */
456 	uint32_t		fp_topology;		/* topology */
457 
458 	/*
459 	 * The fp_task and fp_last_task fields are used mainly in the
460 	 * fp_job_handler() function.  These are used to indicate when a job
461 	 * is executing.  They also allow a second job to be issued while
462 	 * the current job is still in progress, but only one level of nesting
463 	 * is permitted.
464 	 *
465 	 * The legal values for these fields are given in fp.h
466 	 *
467 	 * This should not be confused with the Solaris DDI taskq mechanism,
468 	 * altho also fp makes use of that in some places (just to keep life
469 	 * interesting).
470 	 */
471 	int			fp_task;		/* current task */
472 	int			fp_last_task;		/* last task */
473 
474 	/*
475 	 * fp_soft_state actually tracks the progression of the fp driver
476 	 * in various code paths, particularly in attach, detach, suspend,
477 	 * resume, and state change callbacks.
478 	 *
479 	 * The values for this are defined in fc_portif.h.
480 	 *
481 	 * This is sometimes used in conjunction with the fp_statec_busy
482 	 * field (see below), but there is no direct, 1-to-1 correlation
483 	 * in how these are used together.
484 	 */
485 	volatile uint16_t	fp_soft_state;
486 
487 
488 	/*
489 	 * Software restoration bit fields for (PM)SUSPEND/(PM)RESUME (??)
490 	 * Legal values are FP_RESTORE_* in fp.h
491 	 */
492 	uint16_t		fp_restore;
493 
494 	/*
495 	 * Open/Close bit flags. Used in fp_open(), fp_close(), fp_ioctl()
496 	 * and fp_fciocmd(). See fp.h for legal values.
497 	 */
498 	uchar_t			fp_flag;		/* open/close flag */
499 
500 	uchar_t			fp_verbose;
501 	uchar_t			fp_ns_login_class;	/* NS Logi Class */
502 	uchar_t			fp_sym_port_namelen;	/* Symb port name len */
503 	uint32_t		fp_cos;			/* class of service */
504 
505 	/*
506 	 * Base pointer for hash table of fc_remote_port_t structs (remote
507 	 * ports) accessible thru the local port. The table is hashed by
508 	 * the D_ID of the remote port.
509 	 */
510 	struct d_id_hash	*fp_did_table;
511 
512 	/*
513 	 * Base pointer for hash table of fc_remote_port_t structs (remote
514 	 * ports) accessible thru the local port. The table is hashed by
515 	 * the port WWN of the remote port.
516 	 */
517 	struct pwwn_hash	*fp_pwwn_table;
518 
519 	struct kmem_cache	*fp_pkt_cache;
520 	int			fp_out_fpcmds;	/* outstanding fp_cmd # */
521 
522 	/*
523 	 * fp_statec_busy tracks the progression of state change
524 	 * callbacks within the fp driver. It follows unsolicited callbacks
525 	 * and things like the port startup which happens during the attach.
526 	 * The value increments when a state change is active and decrements
527 	 * when it completes.
528 	 *
529 	 * The benefit of this is that we should be processing only the
530 	 * latest state change and drop the existing one.  Coalescing of
531 	 * multiple outstanding state changes is NOT performed.
532 	 *
533 	 * This is accessed in many places in the code, and also is buried
534 	 * in some macros (see fp_soft_state above).
535 	 *
536 	 * IMPORTANT: The code currently permits nested state changes,
537 	 * and there is no limitation on the allowed level of nesting.
538 	 */
539 	int			fp_statec_busy;
540 
541 	int			fp_port_num;		/* port number */
542 	struct fp_cmd		*fp_els_resp_pkt;	/* ready response pkt */
543 	int			fp_instance;		/* instance number */
544 
545 	/*
546 	 * Flag to indicate whether or not the ULP attach is in progress. Used
547 	 * to synchronize execution of various functions. Seems intended to
548 	 * have a value of either zero or one.
549 	 */
550 	int			fp_ulp_attach;		/* ULP attach done ? */
551 
552 	int			fp_dev_count;		/* number of devices */
553 	int			fp_ptpt_master;		/* my WWN is greater */
554 	int			fp_ulp_nload;		/* count of ULPs */
555 	int			fp_total_devices;	/* total count */
556 
557 	/*
558 	 * Another "busy/not busy" flag. Value is either 0 or 1.
559 	 */
560 	int			fp_els_resp_pkt_busy;
561 
562 	/*
563 	 * This is the "state" of the link on the local port, as reported
564 	 * by the underlying FCA driver at bind time. This uses the same
565 	 * values as fp_state above, including FC_STATE_OFFLINE, FC_STATE_LOOP,
566 	 * and FC_PORT_STATE_MASK(port->fp_bind_state).
567 	 */
568 	uint32_t		fp_bind_state;		/* at bind time */
569 
570 	/*
571 	 * Bit field of various parameterized behaviors for the local port.
572 	 * CAUTION: there is also an fp global variable called "fp_options"
573 	 * that is used to initialize this field during DDI_ATTACH.
574 	 */
575 	uint32_t		fp_options;
576 
577 	/*
578 	 * Apparently intended to facilitate reporting the FC_HBA type
579 	 * for the local port.	Legal values are in fcgs2.h. The
580 	 * fc_porttype_t typedef is in fc_types.h
581 	 */
582 	fc_porttype_t		fp_port_type;
583 
584 	uint32_t		fp_ub_count;		/* Number of UBs */
585 	int			fp_active_ubs;		/* outstanding UBs */
586 	uint64_t		*fp_ub_tokens;		/* UB tokens */
587 
588 	/*
589 	 * CV to inform fp "job" thread that there is work to do.
590 	 * See fp_job_handler() function.
591 	 */
592 	kcondvar_t		fp_cv;
593 
594 	/*
595 	 * Apparently intended to prevent race conditions by holding off any
596 	 * DDI_DETACHes for the local port while a ULP attach is in progress.
597 	 */
598 	kcondvar_t		fp_attach_cv;		/* ULP attach cv */
599 
600 	/*
601 	 * Save up the devinfo pointers from Solaris, for performing
602 	 * pm_raise_power(), pm_busy_component(), and other DDI friends.
603 	 */
604 	dev_info_t		*fp_port_dip;		/* port dip */
605 	dev_info_t		*fp_fca_dip;		/* FCA dip */
606 
607 	/* This is a real Solaris DDI taskq (not the fp "job" queue) */
608 	taskq_t			*fp_taskq;		/* callback queue */
609 
610 	timeout_id_t		fp_wait_tid;		/* retry timer */
611 	timeout_id_t		fp_offline_tid;		/* Offline timeout ID */
612 	fc_lilpmap_t		fp_lilp_map;		/* LILP map */
613 	la_els_logi_t		fp_service_params;	/* service parameters */
614 	fc_fcp_dma_t		fp_fcp_dma;		/* FCP DVMA space */
615 	fc_reset_action_t	fp_reset_action;	/* FCA reset behavior */
616 	fc_dma_behavior_t	fp_dma_behavior;	/* FCA DMA behavior */
617 	uchar_t			fp_sym_node_namelen;	/* Sym node name len */
618 	uchar_t			fp_ipa[8];		/* initial proc assoc */
619 	uchar_t			fp_ip_addr[16];		/* IP address */
620 	uint32_t		fp_fc4_types[8];	/* fc4 types */
621 	struct fc_orphan	*fp_orphan_list;	/* orphan list */
622 	int			fp_orphan_count;	/* number of orphans */
623 
624 	/*
625 	 * Current PM power level of the local port device. Values
626 	 * are given in fc_portif.h
627 	 */
628 	int			fp_pm_level;		/* power level */
629 
630 	/* Increment/decrement in fctl_busy_port() and fctl_idle_port() */
631 	int			fp_pm_busy;		/* port busy */
632 
633 	int			fp_pm_busy_nocomp;	/* busy (no comp) */
634 	fc_hardaddr_t		fp_hard_addr;		/* Hard Address */
635 	char			fp_sym_port_name[255];	/* Symb port name */
636 	char			fp_sym_node_name[255];	/* Symb node name */
637 
638 	/*
639 	 * Opaque data for CALLB_CPR_* macros used by the per-local-port
640 	 * job thread.	Required for safe thread shutdown during PM operations.
641 	 */
642 	callb_cpr_t		fp_cpr_info;		/* CPR info */
643 
644 	char			fp_jindex;		/* Not used */
645 	char			fp_jbuf[15];		/* Not used */
646 
647 	char			fp_ibuf[15];		/* instance buf	 */
648 	char			fp_rnid_init;		/* init done */
649 	fc_rnid_t		fp_rnid_params;		/* node id data */
650 
651 	/* T11 FC-HBA data */
652 	fca_port_attrs_t	fp_hba_port_attrs;
653 	fc_hba_state_change_t	fp_last_change;
654 	uint8_t			fp_port_supported_fc4_types[32];
655 	uint8_t			fp_port_active_fc4_types[32];
656 	uint32_t		fp_port_speed;
657 	la_wwn_t		fp_fabric_name;
658 	uint32_t		fp_rscn_count;
659 	int			fp_npiv_portnum;
660 #define	FC_NPIV_DISABLE	0
661 #define	FC_NPIV_ENABLE	1
662 	int			fp_npiv_flag;
663 #define	FC_NPIV_DELETING 1
664 	int			fp_npiv_state;
665 #define	FC_PHY_PORT	0
666 #define	FC_NPIV_PORT	1
667 	int			fp_npiv_type;
668 	int			fp_npiv_portindex[FC_NPIV_MAX_PORT];
669 	struct	fc_local_port	*fp_port_next;
670 	struct	fc_local_port	*fp_port_prev;
671 } fc_local_port_t;
672 
673 
674 /*
675  * Struct for the d_id hash table in the fc_local_port_t struct.  The code
676  * allocates memory for an array of D_ID_HASH_TABLE_SIZE elements at
677  * attach time.	 The array pointer is saved at the fp_did_table member
678  * in the fc_local_port_t struct.
679  *  Each hash chain is a singly-linked list of fc_remote_port_t
680  * structs, using the pd_did_hnext pointer in the fc_remote_port_t struct.
681  */
682 struct d_id_hash {
683 	struct fc_remote_port	*d_id_head;	/* Head of linked list */
684 	int			d_id_count;	/* Count of list entries */
685 };
686 
687 
688 /*
689  * Struct for the pwwn hash table in the fc_local_port_t struct.  The code
690  * allocates memory for an array of PWWN_HASH_TABLE_SIZE elements at
691  * attach time.	 The array pointer is saved at the fp_pwwn_table member
692  * in the fc_local_port_t struct.
693  * Each hash chain is a singly-linked list of fc_remote_port_t
694  * structs, using the pd_wwn_hnext pointer in the fc_remote_port_t struct.
695  */
696 struct pwwn_hash {
697 	struct fc_remote_port	*pwwn_head;	/* Head of linked list */
698 	int			pwwn_count;	/* Count of list entries */
699 };
700 
701 
702 /* Function prototypes */
703 static dev_info_t *
704 fctl_findchild(dev_info_t *pdip, char *cname, char *caddr);
705 int fctl_fca_create_npivport(dev_info_t *parent,
706     dev_info_t *phydip, char *nwwn, char *pwwn, uint32_t *vindex);
707 static int fctl_fca_bus_ctl(dev_info_t *fca_dip, dev_info_t *rip,
708     ddi_ctl_enum_t op, void *arg, void *result);
709 static int fctl_initchild(dev_info_t *fca_dip, dev_info_t *port_dip);
710 static int fctl_uninitchild(dev_info_t *fca_dip, dev_info_t *port_dip);
711 static int fctl_cache_constructor(void *buf, void *cdarg, int size);
712 static void fctl_cache_destructor(void *buf, void *cdarg);
713 static int fctl_pre_attach(fc_ulp_ports_t *ulp_port, fc_attach_cmd_t cmd);
714 static void fctl_post_attach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
715     fc_attach_cmd_t cmd, int rval);
716 static int fctl_pre_detach(fc_ulp_ports_t *ulp_port, fc_detach_cmd_t cmd);
717 static void fctl_post_detach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
718     fc_detach_cmd_t cmd, int rval);
719 static fc_ulp_ports_t *fctl_add_ulp_port(fc_ulp_module_t *ulp_module,
720     fc_local_port_t *port_handle, int sleep);
721 static fc_ulp_ports_t *fctl_alloc_ulp_port(int sleep);
722 static int fctl_remove_ulp_port(struct ulp_module *ulp_module,
723     fc_local_port_t *port_handle);
724 static void fctl_dealloc_ulp_port(fc_ulp_ports_t *next);
725 static fc_ulp_ports_t *fctl_get_ulp_port(struct ulp_module *ulp_module,
726     fc_local_port_t *port_handle);
727 static int fctl_update_host_ns_values(fc_local_port_t *port,
728     fc_ns_cmd_t *ns_req);
729 static int fctl_retrieve_host_ns_values(fc_local_port_t *port,
730     fc_ns_cmd_t *ns_req);
731 static void fctl_print_if_not_orphan(fc_local_port_t *port,
732     fc_remote_port_t *pd);
733 static void fctl_link_reset_done(opaque_t port_handle, uchar_t result);
734 static int fctl_error(int fc_errno, char **errmsg);
735 static int fctl_pkt_error(fc_packet_t *pkt, char **state, char **reason,
736     char **action, char **expln);
737 static void fctl_check_alpa_list(fc_local_port_t *port, fc_remote_port_t *pd);
738 static int fctl_is_alpa_present(fc_local_port_t *port, uchar_t alpa);
739 static void fc_trace_freemsg(fc_trace_logq_t *logq);
740 static void fctl_init_dma_attr(fc_local_port_t *port, fc_ulp_module_t *mod,
741     fc_ulp_port_info_t	*info);
742 fc_local_port_t *fc_get_npiv_port(fc_local_port_t *phyport, la_wwn_t *pwwn);
743 fc_local_port_t *fc_delete_npiv_port(fc_local_port_t *phyport, la_wwn_t *pwwn);
744 
745 
746 #ifdef	__cplusplus
747 }
748 #endif
749 
750 #endif	/* _FCTL_PRIVATE_H */
751