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 2008 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;		/* packet cache */
520 
521 	/*
522 	 * fp_statec_busy tracks the progression of state change
523 	 * callbacks within the fp driver. It follows unsolicited callbacks
524 	 * and things like the port startup which happens during the attach.
525 	 * The value increments when a state change is active and decrements
526 	 * when it completes.
527 	 *
528 	 * The benefit of this is that we should be processing only the
529 	 * latest state change and drop the existing one.  Coalescing of
530 	 * multiple outstanding state changes is NOT performed.
531 	 *
532 	 * This is accessed in many places in the code, and also is buried
533 	 * in some macros (see fp_soft_state above).
534 	 *
535 	 * IMPORTANT: The code currently permits nested state changes,
536 	 * and there is no limitation on the allowed level of nesting.
537 	 */
538 	int			fp_statec_busy;
539 
540 	int			fp_port_num;		/* port number */
541 	struct fp_cmd		*fp_els_resp_pkt;	/* ready response pkt */
542 	int			fp_instance;		/* instance number */
543 
544 	/*
545 	 * Flag to indicate whether or not the ULP attach is in progress. Used
546 	 * to synchronize execution of various functions. Seems intended to
547 	 * have a value of either zero or one.
548 	 */
549 	int			fp_ulp_attach;		/* ULP attach done ? */
550 
551 	int			fp_dev_count;		/* number of devices */
552 	int			fp_ptpt_master;		/* my WWN is greater */
553 	int			fp_ulp_nload;		/* count of ULPs */
554 	int			fp_total_devices; 	/* total count */
555 
556 	/*
557 	 * Another "busy/not busy" flag. Value is either 0 or 1.
558 	 */
559 	int			fp_els_resp_pkt_busy;
560 
561 	/*
562 	 * This is the "state" of the link on the local port, as reported
563 	 * by the underlying FCA driver at bind time. This uses the same
564 	 * values as fp_state above, including FC_STATE_OFFLINE, FC_STATE_LOOP,
565 	 * and FC_PORT_STATE_MASK(port->fp_bind_state).
566 	 */
567 	uint32_t		fp_bind_state;		/* at bind time */
568 
569 	/*
570 	 * Bit field of various parameterized behaviors for the local port.
571 	 * CAUTION: there is also an fp global variable called "fp_options"
572 	 * that is used to initialize this field during DDI_ATTACH.
573 	 */
574 	uint32_t		fp_options;
575 
576 	/*
577 	 * Apparently intended to facilitate reporting the FC_HBA type
578 	 * for the local port.  Legal values are in fcgs2.h. The
579 	 * fc_porttype_t typedef is in fc_types.h
580 	 */
581 	fc_porttype_t		fp_port_type;
582 
583 	uint32_t		fp_ub_count;		/* Number of UBs */
584 	int			fp_active_ubs;		/* outstanding UBs */
585 	uint64_t		*fp_ub_tokens;		/* UB tokens */
586 
587 	/*
588 	 * CV to inform fp "job" thread that there is work to do.
589 	 * See fp_job_handler() function.
590 	 */
591 	kcondvar_t		fp_cv;
592 
593 	/*
594 	 * Apparently intended to prevent race conditions by holding off any
595 	 * DDI_DETACHes for the local port while a ULP attach is in progress.
596 	 */
597 	kcondvar_t		fp_attach_cv;		/* ULP attach cv */
598 
599 	/*
600 	 * Save up the devinfo pointers from Solaris, for performing
601 	 * pm_raise_power(), pm_busy_component(), and other DDI friends.
602 	 */
603 	dev_info_t		*fp_port_dip;		/* port dip */
604 	dev_info_t		*fp_fca_dip;		/* FCA dip */
605 
606 	/* This is a real Solaris DDI taskq (not the fp "job" queue) */
607 	taskq_t			*fp_taskq;		/* callback queue */
608 
609 	timeout_id_t		fp_wait_tid;		/* retry timer */
610 	timeout_id_t		fp_offline_tid;		/* Offline timeout ID */
611 	fc_lilpmap_t 		fp_lilp_map;		/* LILP map */
612 	la_els_logi_t		fp_service_params;	/* service parameters */
613 	fc_fcp_dma_t		fp_fcp_dma;		/* FCP DVMA space */
614 	fc_reset_action_t	fp_reset_action;	/* FCA reset behavior */
615 	fc_dma_behavior_t	fp_dma_behavior;	/* FCA DMA behavior */
616 	uchar_t			fp_sym_node_namelen;	/* Sym node name len */
617 	uchar_t			fp_ipa[8];		/* initial proc assoc */
618 	uchar_t			fp_ip_addr[16];		/* IP address */
619 	uint32_t		fp_fc4_types[8];	/* fc4 types */
620 	struct fc_orphan	*fp_orphan_list;	/* orphan list */
621 	int			fp_orphan_count;	/* number of orphans */
622 
623 	/*
624 	 * Current PM power level of the local port device. Values
625 	 * are given in fc_portif.h
626 	 */
627 	int			fp_pm_level;		/* power level */
628 
629 	/* Increment/decrement in fctl_busy_port() and fctl_idle_port() */
630 	int			fp_pm_busy;		/* port busy */
631 
632 	int			fp_pm_busy_nocomp;	/* busy (no comp) */
633 	fc_hardaddr_t		fp_hard_addr;		/* Hard Address */
634 	char			fp_sym_port_name[255];	/* Symb port name */
635 	char			fp_sym_node_name[255];	/* Symb node name */
636 
637 	/*
638 	 * Opaque data for CALLB_CPR_* macros used by the per-local-port
639 	 * job thread.  Required for safe thread shutdown during PM operations.
640 	 */
641 	callb_cpr_t		fp_cpr_info;		/* CPR info */
642 
643 	char			fp_jindex;		/* Not used */
644 	char			fp_jbuf[15];		/* Not used */
645 
646 	char			fp_ibuf[15];		/* instance buf  */
647 	char			fp_rnid_init;		/* init done */
648 	fc_rnid_t		fp_rnid_params;		/* node id data */
649 
650 	/* T11 FC-HBA data */
651 	fca_port_attrs_t	fp_hba_port_attrs;
652 	fc_hba_state_change_t	fp_last_change;
653 	uint8_t			fp_port_supported_fc4_types[32];
654 	uint8_t			fp_port_active_fc4_types[32];
655 	uint32_t		fp_port_speed;
656 	la_wwn_t		fp_fabric_name;
657 	uint32_t		fp_rscn_count;
658 	int			fp_npiv_portnum;
659 #define	FC_NPIV_DISABLE	0
660 #define	FC_NPIV_ENABLE	1
661 	int			fp_npiv_flag;
662 #define	FC_NPIV_DELETING 1
663 	int			fp_npiv_state;
664 #define	FC_PHY_PORT	0
665 #define	FC_NPIV_PORT	1
666 	int			fp_npiv_type;
667 	int			fp_npiv_portindex[FC_NPIV_MAX_PORT];
668 	struct	fc_local_port	*fp_port_next;
669 	struct	fc_local_port	*fp_port_prev;
670 } fc_local_port_t;
671 
672 
673 /*
674  * Struct for the d_id hash table in the fc_local_port_t struct.  The code
675  * allocates memory for an array of D_ID_HASH_TABLE_SIZE elements at
676  * attach time.  The array pointer is saved at the fp_did_table member
677  * in the fc_local_port_t struct.
678  *  Each hash chain is a singly-linked list of fc_remote_port_t
679  * structs, using the pd_did_hnext pointer in the fc_remote_port_t struct.
680  */
681 struct d_id_hash {
682 	struct fc_remote_port 	*d_id_head;	/* Head of linked list */
683 	int 			d_id_count;	/* Count of list entries */
684 };
685 
686 
687 /*
688  * Struct for the pwwn hash table in the fc_local_port_t struct.  The code
689  * allocates memory for an array of PWWN_HASH_TABLE_SIZE elements at
690  * attach time.  The array pointer is saved at the fp_pwwn_table member
691  * in the fc_local_port_t struct.
692  * Each hash chain is a singly-linked list of fc_remote_port_t
693  * structs, using the pd_wwn_hnext pointer in the fc_remote_port_t struct.
694  */
695 struct pwwn_hash {
696 	struct fc_remote_port 	*pwwn_head;	/* Head of linked list */
697 	int 			pwwn_count;	/* Count of list entries */
698 };
699 
700 
701 /* Function prototypes */
702 static dev_info_t *
703 fctl_findchild(dev_info_t *pdip, char *cname, char *caddr);
704 int fctl_fca_create_npivport(dev_info_t *parent,
705     dev_info_t *phydip, char *nwwn, char *pwwn, uint32_t *vindex);
706 static int fctl_fca_bus_ctl(dev_info_t *fca_dip, dev_info_t *rip,
707     ddi_ctl_enum_t op, void *arg, void *result);
708 static int fctl_initchild(dev_info_t *fca_dip, dev_info_t *port_dip);
709 static int fctl_uninitchild(dev_info_t *fca_dip, dev_info_t *port_dip);
710 static int fctl_cache_constructor(void *buf, void *cdarg, int size);
711 static void fctl_cache_destructor(void *buf, void *cdarg);
712 static int fctl_pre_attach(fc_ulp_ports_t *ulp_port, fc_attach_cmd_t cmd);
713 static void fctl_post_attach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
714     fc_attach_cmd_t cmd, int rval);
715 static int fctl_pre_detach(fc_ulp_ports_t *ulp_port, fc_detach_cmd_t cmd);
716 static void fctl_post_detach(fc_ulp_module_t *mod, fc_ulp_ports_t *ulp_port,
717     fc_detach_cmd_t cmd, int rval);
718 static fc_ulp_ports_t *fctl_add_ulp_port(fc_ulp_module_t *ulp_module,
719     fc_local_port_t *port_handle, int sleep);
720 static fc_ulp_ports_t *fctl_alloc_ulp_port(int sleep);
721 static int fctl_remove_ulp_port(struct ulp_module *ulp_module,
722     fc_local_port_t *port_handle);
723 static void fctl_dealloc_ulp_port(fc_ulp_ports_t *next);
724 static fc_ulp_ports_t *fctl_get_ulp_port(struct ulp_module *ulp_module,
725     fc_local_port_t *port_handle);
726 static int fctl_update_host_ns_values(fc_local_port_t *port,
727     fc_ns_cmd_t *ns_req);
728 static int fctl_retrieve_host_ns_values(fc_local_port_t *port,
729     fc_ns_cmd_t *ns_req);
730 static void fctl_print_if_not_orphan(fc_local_port_t *port,
731     fc_remote_port_t *pd);
732 static void fctl_link_reset_done(opaque_t port_handle, uchar_t result);
733 static int fctl_error(int fc_errno, char **errmsg);
734 static int fctl_pkt_error(fc_packet_t *pkt, char **state, char **reason,
735     char **action, char **expln);
736 static void fctl_check_alpa_list(fc_local_port_t *port, fc_remote_port_t *pd);
737 static int fctl_is_alpa_present(fc_local_port_t *port, uchar_t alpa);
738 static void fc_trace_freemsg(fc_trace_logq_t *logq);
739 static void fctl_init_dma_attr(fc_local_port_t *port, fc_ulp_module_t *mod,
740     fc_ulp_port_info_t  *info);
741 fc_local_port_t *fc_get_npiv_port(fc_local_port_t *phyport, la_wwn_t *pwwn);
742 fc_local_port_t *fc_delete_npiv_port(fc_local_port_t *phyport, la_wwn_t *pwwn);
743 
744 
745 #ifdef	__cplusplus
746 }
747 #endif
748 
749 #endif	/* _FCTL_PRIVATE_H */
750