xref: /onnv-gate/usr/src/uts/common/sys/fibre-channel/ulp/fcpvar.h (revision 10264:1196af6129ec)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
228493SReed.Liu@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #ifndef	_FCPVAR_H
277836SJohn.Forte@Sun.COM #define	_FCPVAR_H
287836SJohn.Forte@Sun.COM 
297836SJohn.Forte@Sun.COM #ifdef	__cplusplus
307836SJohn.Forte@Sun.COM extern "C" {
317836SJohn.Forte@Sun.COM #endif
327836SJohn.Forte@Sun.COM 
337836SJohn.Forte@Sun.COM #include <sys/types.h>
347836SJohn.Forte@Sun.COM 
357836SJohn.Forte@Sun.COM /*
367836SJohn.Forte@Sun.COM  * Maximum number of times FCP will re-issue a REPORTS_LUNS command if the
377836SJohn.Forte@Sun.COM  * device couldn't return all of them in the submitted buffer.
387836SJohn.Forte@Sun.COM  */
397836SJohn.Forte@Sun.COM #define	FCP_MAX_REPORTLUNS_ATTEMPTS	2
407836SJohn.Forte@Sun.COM /*
417836SJohn.Forte@Sun.COM  * Maximum number of LUNs supported.  This limit is enforced to accommodate
427836SJohn.Forte@Sun.COM  * certain HBAs.
437836SJohn.Forte@Sun.COM  */
447836SJohn.Forte@Sun.COM #define	FCP_MAX_LUNS_SUPPORTED		65535
457836SJohn.Forte@Sun.COM 
467836SJohn.Forte@Sun.COM /*
477836SJohn.Forte@Sun.COM  * Stuff to be defined in fc_ulpif.h FIXIT
487836SJohn.Forte@Sun.COM  */
497836SJohn.Forte@Sun.COM #define	PORT_DEVICE_CREATE	0x40
507836SJohn.Forte@Sun.COM #define	SCMD_REPORT_LUN		0xa0	/* SCSI cmd to report on LUNs */
517836SJohn.Forte@Sun.COM #define	SCMD_INQUIRY_LWWN_SIZE	32	/* Max WWN size */
527836SJohn.Forte@Sun.COM #define	SCMD_INQUIRY_PAGE83	0xF0	/* Internal opcode for page 0x83 */
537836SJohn.Forte@Sun.COM #define	FC4_SCSI_FCP		0x08	/* our (SCSI) FC4 type number */
547836SJohn.Forte@Sun.COM 
557836SJohn.Forte@Sun.COM #define	FCP_QUEUE_DELAY	(4)
567836SJohn.Forte@Sun.COM #define	FCP_FAILED_DELAY	20
577836SJohn.Forte@Sun.COM #define	FCP_RESET_DELAY		3	/* target reset delay of 3 secs */
587836SJohn.Forte@Sun.COM #define	FCP_OFFLINE_DELAY	20	/* 20 seconds is 2*RA_TOV_els */
597836SJohn.Forte@Sun.COM 
607836SJohn.Forte@Sun.COM /*
617836SJohn.Forte@Sun.COM  * Highest possible timeout value to indicate
627836SJohn.Forte@Sun.COM  * the watch thread to return the I/O
637836SJohn.Forte@Sun.COM  */
647836SJohn.Forte@Sun.COM #define	FCP_INVALID_TIMEOUT	(0xFFFFFFFF)
657836SJohn.Forte@Sun.COM 
667836SJohn.Forte@Sun.COM /*
677836SJohn.Forte@Sun.COM  * The max inquiry page 83 size as expected in the code today
687836SJohn.Forte@Sun.COM  * is 0xf0 bytes. Defining a constant to make it easy incase
697836SJohn.Forte@Sun.COM  * this needs to be changed at a later time.
707836SJohn.Forte@Sun.COM  */
717836SJohn.Forte@Sun.COM #define	SCMD_MAX_INQUIRY_PAGE83_SIZE	0xF0
727836SJohn.Forte@Sun.COM /*
737836SJohn.Forte@Sun.COM  * Events generated for Target drivers; "SUNW,sf:" prefix
747836SJohn.Forte@Sun.COM  * is a legacy fcal stuff hardcoded into ssd via the use of
757836SJohn.Forte@Sun.COM  * FCAL_INSERT_EVENT defined in an fcal header file; We
767836SJohn.Forte@Sun.COM  * just need to continue to use this.
777836SJohn.Forte@Sun.COM  */
787836SJohn.Forte@Sun.COM #define	FCAL_INSERT_EVENT	"SUNW,sf:DEVICE-INSERTION.1"
797836SJohn.Forte@Sun.COM #define	FCAL_REMOVE_EVENT	"SUNW,sf:DEVICE-REMOVAL.1"
807836SJohn.Forte@Sun.COM 
817836SJohn.Forte@Sun.COM /*
827836SJohn.Forte@Sun.COM  * for debug trace
837836SJohn.Forte@Sun.COM  */
847836SJohn.Forte@Sun.COM #define	FCP_STACK_DEPTH	14
857836SJohn.Forte@Sun.COM 
867836SJohn.Forte@Sun.COM 
877836SJohn.Forte@Sun.COM /*
887836SJohn.Forte@Sun.COM  * All the stuff above needs to move intp appropriate header files.
897836SJohn.Forte@Sun.COM  */
907836SJohn.Forte@Sun.COM 
917836SJohn.Forte@Sun.COM #define	FCP_NUM_HASH			128
927836SJohn.Forte@Sun.COM 
937836SJohn.Forte@Sun.COM #define	FCP_HASH(x)			((x[0] + x[1] + x[2] + x[3] +\
947836SJohn.Forte@Sun.COM 					x[4] + x[5] + x[6] + x[7]) & \
957836SJohn.Forte@Sun.COM 					(FCP_NUM_HASH-1))
967836SJohn.Forte@Sun.COM 
977836SJohn.Forte@Sun.COM #define	FCP_STATEC_MASK			(FC_STATE_OFFLINE | FC_STATE_ONLINE |\
987836SJohn.Forte@Sun.COM 					FC_STATE_LOOP | FC_STATE_NAMESERVICE |\
997836SJohn.Forte@Sun.COM 					FC_STATE_RESET |\
1007836SJohn.Forte@Sun.COM 					FC_STATE_RESET_REQUESTED |\
1017836SJohn.Forte@Sun.COM 					FC_STATE_LIP | FC_STATE_DEVICE_CHANGE)
1027836SJohn.Forte@Sun.COM 
1037836SJohn.Forte@Sun.COM #define	PKT_PRIV_SIZE			2
1047836SJohn.Forte@Sun.COM 
1057836SJohn.Forte@Sun.COM #ifdef	KSTATS_CODE
1067836SJohn.Forte@Sun.COM /*
1077836SJohn.Forte@Sun.COM  * fcp_stats : Statistics provided for fcp.
1087836SJohn.Forte@Sun.COM  */
1097836SJohn.Forte@Sun.COM struct fcp_stats {
1108493SReed.Liu@Sun.COM 	uint_t	version;		/* version of this struct */
1118493SReed.Liu@Sun.COM 	uint_t	lip_count;		/* lips forced by fcp */
1128493SReed.Liu@Sun.COM 	uint_t	link_reset_count;	/* lip failures, ie, no ONLINE */
1137836SJohn.Forte@Sun.COM 					/* response after forcing lip */
1148493SReed.Liu@Sun.COM 	uint_t	ncmds;			/* outstanding commands */
1158493SReed.Liu@Sun.COM 	uint_t	throttle_limit;		/* current throttle limit */
1167836SJohn.Forte@Sun.COM 	char	drvr_name[MAXNAMELEN];	/* Name of driver, NULL term. */
1177836SJohn.Forte@Sun.COM };
1187836SJohn.Forte@Sun.COM #endif
1197836SJohn.Forte@Sun.COM 
1207836SJohn.Forte@Sun.COM /*
1217836SJohn.Forte@Sun.COM  * Structure fcp_port
1227836SJohn.Forte@Sun.COM  * --------------------
1237836SJohn.Forte@Sun.COM  *
1247836SJohn.Forte@Sun.COM  * This structure is the FCP representation of an N_Port on a local FC HBA card.
1257836SJohn.Forte@Sun.COM  * This is the master structure off of which all the others will be hanging at
1267836SJohn.Forte@Sun.COM  * some point and is the Solaris per-instance soft-state structure.
1277836SJohn.Forte@Sun.COM  */
128*10264SZhong.Wang@Sun.COM typedef struct fcp_port {
1297836SJohn.Forte@Sun.COM 	/*
1307836SJohn.Forte@Sun.COM 	 * This mutex protects the access to this structure (or most of its
1317836SJohn.Forte@Sun.COM 	 * fields).
1327836SJohn.Forte@Sun.COM 	 */
1337836SJohn.Forte@Sun.COM 	kmutex_t		port_mutex;
1347836SJohn.Forte@Sun.COM 	/*
1357836SJohn.Forte@Sun.COM 	 * This is the link to the next fcp_port structure in the global
1367836SJohn.Forte@Sun.COM 	 * list.  The head of the global list is fcp_port_head and is
1377836SJohn.Forte@Sun.COM 	 * defined in fcp.c.  This field is NULL for the last element of
1387836SJohn.Forte@Sun.COM 	 * the global list.
1397836SJohn.Forte@Sun.COM 	 */
1407836SJohn.Forte@Sun.COM 	struct fcp_port		*port_next;
1417836SJohn.Forte@Sun.COM 	/*
1427836SJohn.Forte@Sun.COM 	 * This field points to the head of a list of internal requests that
1437836SJohn.Forte@Sun.COM 	 * will be retried later.  Examples of internal requests are:
1447836SJohn.Forte@Sun.COM 	 * 'Send a PRLI ELS', 'Send a PRLO ELS', 'Send a PLOGI ELS' or
1457836SJohn.Forte@Sun.COM 	 * 'Send an Inquiry command'.  If the submission of the request to the
1467836SJohn.Forte@Sun.COM 	 * fp/fctl module failed (for a set of specific reasons) and the
1478493SReed.Liu@Sun.COM 	 * request can be resubmitted later, it is queued here.	 The watchdog
1487836SJohn.Forte@Sun.COM 	 * timer (fcp_watch()) will walk this queue and resubmit the requests.
1497836SJohn.Forte@Sun.COM 	 */
1507836SJohn.Forte@Sun.COM 	struct fcp_ipkt		*port_ipkt_list;
1517836SJohn.Forte@Sun.COM 	/*
1527836SJohn.Forte@Sun.COM 	 * This seems to be used as a temporary device counter during a
1537836SJohn.Forte@Sun.COM 	 * discovery process (or reconfiguration as some comments put it).
1547836SJohn.Forte@Sun.COM 	 * It seems to be initialized in fcp_statec_callback() with the
1557836SJohn.Forte@Sun.COM 	 * number of devices that fp/fctl saw after the line came up and
1567836SJohn.Forte@Sun.COM 	 * is supposed to reached zero when the reconfiguration process is
1577836SJohn.Forte@Sun.COM 	 * over.
1587836SJohn.Forte@Sun.COM 	 */
1597836SJohn.Forte@Sun.COM 	int			port_tmp_cnt;
1607836SJohn.Forte@Sun.COM 	/*
1618493SReed.Liu@Sun.COM 	 * This is supposed to indicate the state of this port.	 It is a
1627836SJohn.Forte@Sun.COM 	 * bitmap which means several bits can be set simultaneously.  The list
1637836SJohn.Forte@Sun.COM 	 * of the different bits and their meaning is given further down in
1647836SJohn.Forte@Sun.COM 	 * this file.
1657836SJohn.Forte@Sun.COM 	 */
1667836SJohn.Forte@Sun.COM 	uint32_t		port_state;
1677836SJohn.Forte@Sun.COM 	/*
1687836SJohn.Forte@Sun.COM 	 * This field is initialized at the very end of the function
1697836SJohn.Forte@Sun.COM 	 * fcp_handle_port_attach() if the attachment of the port was
1708493SReed.Liu@Sun.COM 	 * successful.	It is set to the value stored in lbolt64 at the
1717836SJohn.Forte@Sun.COM 	 * time of the attachment.  This value is only used in the function
1727836SJohn.Forte@Sun.COM 	 * fcp_scsi_bus_config().  It is used to determine the value of the
1737836SJohn.Forte@Sun.COM 	 * parameter timeout when ndi_busop_bus_config() and cv_wait() are
1747836SJohn.Forte@Sun.COM 	 * called.  It actually serves to figure out how long the enumeration
1757836SJohn.Forte@Sun.COM 	 * can be delayed (the max value being FCP_INIT_WAIT_TIMEOUT).
1767836SJohn.Forte@Sun.COM 	 */
1777836SJohn.Forte@Sun.COM 	int64_t			port_attach_time;
1787836SJohn.Forte@Sun.COM 	/*
1797836SJohn.Forte@Sun.COM 	 * This field contains the topology of the SAN the port is connected
1807836SJohn.Forte@Sun.COM 	 * to.
1817836SJohn.Forte@Sun.COM 	 */
1827836SJohn.Forte@Sun.COM 	uint32_t		port_topology;
1837836SJohn.Forte@Sun.COM 	/*
1847836SJohn.Forte@Sun.COM 	 * This field contains the local port ID.  It is provided by fp/fctl
1857836SJohn.Forte@Sun.COM 	 * when calling fcp_statec_callback() and fcp_port_attach().  This
1867836SJohn.Forte@Sun.COM 	 * value is used to build Fibre Channel headers (like for PLOGI or
1877836SJohn.Forte@Sun.COM 	 * PRLI).
1887836SJohn.Forte@Sun.COM 	 */
1897836SJohn.Forte@Sun.COM 	uint32_t		port_id;
1907836SJohn.Forte@Sun.COM 	/*
1917836SJohn.Forte@Sun.COM 	 * This field keeps track of the physical port state (fcp_port being
1927836SJohn.Forte@Sun.COM 	 * more like the FCP software port state).  The information stored here
1937836SJohn.Forte@Sun.COM 	 * is provided by fp/fctl except in two instances: in
1947836SJohn.Forte@Sun.COM 	 * fcp_handle_port_attach() and fcp_handle_port_resume(). The values
1957836SJohn.Forte@Sun.COM 	 * this field can take are defined in fctl.h.
1967836SJohn.Forte@Sun.COM 	 */
1977836SJohn.Forte@Sun.COM 	uint32_t		port_phys_state;
1987836SJohn.Forte@Sun.COM 	/*
1997836SJohn.Forte@Sun.COM 	 * This field points to the first element of a list of fcp_reset_elem
2008493SReed.Liu@Sun.COM 	 * structures.	Those structures are created when the target driver
2017836SJohn.Forte@Sun.COM 	 * calls fcp_reset_target().  The target or the LUN specified by the
2028493SReed.Liu@Sun.COM 	 * target driver is reset by sending a Task Management command.	 After
2037836SJohn.Forte@Sun.COM 	 * the response has been received, a fcp_reset_elem structure is
2047836SJohn.Forte@Sun.COM 	 * queued here and will remain queued for FCP_RESET_DELAY.  While
2057836SJohn.Forte@Sun.COM 	 * the fcp_reset_elem structure is in this queue the LUNs of
2067836SJohn.Forte@Sun.COM 	 * the target to reset or the LUN to reset is set to LUN_BUSY state.
2077836SJohn.Forte@Sun.COM 	 * In fcp_watch() the timeout is tested.  If the timout has expired,
2087836SJohn.Forte@Sun.COM 	 * the fcp_reset_elem structure is unqueued and freed, and all the
2097836SJohn.Forte@Sun.COM 	 * active commands for the target or LUNs are aborted.
2107836SJohn.Forte@Sun.COM 	 */
2117836SJohn.Forte@Sun.COM 	struct fcp_reset_elem	*port_reset_list;
2127836SJohn.Forte@Sun.COM 	/*
2137836SJohn.Forte@Sun.COM 	 * This points to the first element of a list of fcp_tgt_elem
2148493SReed.Liu@Sun.COM 	 * structures.	This list is a list of targets to offline.  The list
2157836SJohn.Forte@Sun.COM 	 * is walked in fcp_watch(). After the target is offlined the
2167836SJohn.Forte@Sun.COM 	 * structure fcp_tgt_elem is freed.
2177836SJohn.Forte@Sun.COM 	 */
2187836SJohn.Forte@Sun.COM 	struct fcp_tgt_elem	*port_offline_tgts;
2197836SJohn.Forte@Sun.COM 	/*
2207836SJohn.Forte@Sun.COM 	 * This points to the first element of a list of fcp_lun_elem
2218493SReed.Liu@Sun.COM 	 * structures.	This list is a list of LUNs to offline.	 The list
2227836SJohn.Forte@Sun.COM 	 * is walked in fcp_watch(). After the lun is offlined the
2237836SJohn.Forte@Sun.COM 	 * structure fcp_lun_elem is freed.
2247836SJohn.Forte@Sun.COM 	 */
2257836SJohn.Forte@Sun.COM 	struct fcp_lun_elem	*port_offline_luns;
2267836SJohn.Forte@Sun.COM 	/*
2277836SJohn.Forte@Sun.COM 	 * This field is a counter initialized to 1 when the port attaches.
2287836SJohn.Forte@Sun.COM 	 * It is incremented when the line goes from online to offline and
2298493SReed.Liu@Sun.COM 	 * vice versa.	It is also incremented when the port detaches.	The
2307836SJohn.Forte@Sun.COM 	 * value stored in this counter is used as a reference in time of the
2318493SReed.Liu@Sun.COM 	 * link state.	For example, when the line comes up internal requests
2327836SJohn.Forte@Sun.COM 	 * are generated (fcp_ipkt) such as PRLI and INQUIRY.  Those requests
2337836SJohn.Forte@Sun.COM 	 * are tagged with the value contained in this field at the time the
2347836SJohn.Forte@Sun.COM 	 * request is built.  When the callback for the request is called, the
2357836SJohn.Forte@Sun.COM 	 * current value of port_link_cnt is checked against the one set in
2367836SJohn.Forte@Sun.COM 	 * the internal request structure.  If they don't match, it means the
2377836SJohn.Forte@Sun.COM 	 * the request is not relevant anymore to the current line state and
2387836SJohn.Forte@Sun.COM 	 * must be discarded (in between a request is issued and the callback
2397836SJohn.Forte@Sun.COM 	 * routine is called the line may have bounced).  This is the way FCP
2407836SJohn.Forte@Sun.COM 	 * identifies the requests that were hanging out when the state of the
2417836SJohn.Forte@Sun.COM 	 * line changed.
2427836SJohn.Forte@Sun.COM 	 */
2437836SJohn.Forte@Sun.COM 	uint32_t		port_link_cnt;
2447836SJohn.Forte@Sun.COM 	/*
2457836SJohn.Forte@Sun.COM 	 * This field, as its name suggests, specifies a deadline for the
2467836SJohn.Forte@Sun.COM 	 * overall discovery process.  It is initialized in three cases:
2477836SJohn.Forte@Sun.COM 	 *
2487836SJohn.Forte@Sun.COM 	 * 1) When the line goes from the offline state to the online state.
2497836SJohn.Forte@Sun.COM 	 * 2) When the FP/FCTL called fcp_statec_callback() indicating that
2507836SJohn.Forte@Sun.COM 	 *    a notification was received from the fabric indicating that a new
2517836SJohn.Forte@Sun.COM 	 *    port showed up or that one disappeared.
2527836SJohn.Forte@Sun.COM 	 * 3) In the fcp_create_on_demand() function (called because of an
2537836SJohn.Forte@Sun.COM 	 *    ioctl).
2547836SJohn.Forte@Sun.COM 	 *
2557836SJohn.Forte@Sun.COM 	 * In all instances it is set to:
2567836SJohn.Forte@Sun.COM 	 *
2577836SJohn.Forte@Sun.COM 	 *	fcp_watchdog_time + FCP_ICMD_DEADLINE
2587836SJohn.Forte@Sun.COM 	 *
2597836SJohn.Forte@Sun.COM 	 * In all those instances a discovery process is started or extended
2608493SReed.Liu@Sun.COM 	 * (2).	 The value stored in port_deadline is only checked in one
2617836SJohn.Forte@Sun.COM 	 * function: fcp_is_retryable().  That function checks if an
2627836SJohn.Forte@Sun.COM 	 * internal command (fcp_ipkt) is retryable or not.  Usually
2637836SJohn.Forte@Sun.COM 	 * there's a counter that limits the number of times a command is
2647836SJohn.Forte@Sun.COM 	 * retried (Max value is FCP_MAX_RETRIES).  However, even if the
2657836SJohn.Forte@Sun.COM 	 * counter hasn't exceeded that value, the command will not be retried
2667836SJohn.Forte@Sun.COM 	 * past the deadline.  This means that the discovery process has to
2677836SJohn.Forte@Sun.COM 	 * be finished before port_deadline.  In other words, an internal
2687836SJohn.Forte@Sun.COM 	 * command retry capability is limited numerically and in time.
2697836SJohn.Forte@Sun.COM 	 */
2707836SJohn.Forte@Sun.COM 	int			port_deadline;
2717836SJohn.Forte@Sun.COM 	/*
2727836SJohn.Forte@Sun.COM 	 * This is the Node WWN of the local port.  It is initialized
2737836SJohn.Forte@Sun.COM 	 * during the port attachment.
2747836SJohn.Forte@Sun.COM 	 */
2757836SJohn.Forte@Sun.COM 	la_wwn_t		port_nwwn;
2767836SJohn.Forte@Sun.COM 	/*
2777836SJohn.Forte@Sun.COM 	 * This is the Port WWN of the local port.  It is initialized during
2787836SJohn.Forte@Sun.COM 	 * the port attachment.
2797836SJohn.Forte@Sun.COM 	 */
2807836SJohn.Forte@Sun.COM 	la_wwn_t		port_pwwn;
2817836SJohn.Forte@Sun.COM 	/*
2827836SJohn.Forte@Sun.COM 	 * This is the fp/fctl port handle.
2837836SJohn.Forte@Sun.COM 	 */
2847836SJohn.Forte@Sun.COM 	opaque_t		*port_fp_handle;
2857836SJohn.Forte@Sun.COM 	/*
2867836SJohn.Forte@Sun.COM 	 * The following 4 fields handle the queue of fcp_pkt outstanding for
2877836SJohn.Forte@Sun.COM 	 * this port.
2887836SJohn.Forte@Sun.COM 	 *
2897836SJohn.Forte@Sun.COM 	 *   port_pkt_mutex	Protects the access to the queue
2907836SJohn.Forte@Sun.COM 	 *   port_pkt_head	Points to the head of the queue
2917836SJohn.Forte@Sun.COM 	 *   port_pkt_tail	Points to the tail of the queue
2927836SJohn.Forte@Sun.COM 	 *   port_npkts	Number of commands outstanding (used only when
2937836SJohn.Forte@Sun.COM 	 *			DEBUG is defined).
2947836SJohn.Forte@Sun.COM 	 */
2957836SJohn.Forte@Sun.COM 	kmutex_t		port_pkt_mutex;
2967836SJohn.Forte@Sun.COM 	uint32_t		port_npkts;
2977836SJohn.Forte@Sun.COM 	struct fcp_pkt		*port_pkt_head;
2987836SJohn.Forte@Sun.COM 	struct fcp_pkt		*port_pkt_tail;
2997836SJohn.Forte@Sun.COM 	/*
3007836SJohn.Forte@Sun.COM 	 * This field is the counter of allocated and currently active
3017836SJohn.Forte@Sun.COM 	 * fcp_ipkt.
3027836SJohn.Forte@Sun.COM 	 */
3037836SJohn.Forte@Sun.COM 	int			port_ipkt_cnt;
3047836SJohn.Forte@Sun.COM 	/*
3057836SJohn.Forte@Sun.COM 	 * Port instance provided by FP/FCTL.  It is actually deduced using
3067836SJohn.Forte@Sun.COM 	 * ddi_get_instance() in fcp_port_attach().
3077836SJohn.Forte@Sun.COM 	 */
3087836SJohn.Forte@Sun.COM 	uint32_t		port_instance;
3097836SJohn.Forte@Sun.COM 	/*
3107836SJohn.Forte@Sun.COM 	 * Maximum number of exchanges the underlying physical FibreChannel
3117836SJohn.Forte@Sun.COM 	 * port can handle.  This field is initialized during the port
3127836SJohn.Forte@Sun.COM 	 * attachment but is never used.
3137836SJohn.Forte@Sun.COM 	 */
3147836SJohn.Forte@Sun.COM 	uint32_t		port_max_exch;
3157836SJohn.Forte@Sun.COM 	/*
3167836SJohn.Forte@Sun.COM 	 * This port stores the behavior expected of the underlying FCA driver
3177836SJohn.Forte@Sun.COM 	 * when a port reset occurs.  The values stored here are defined in the
3187836SJohn.Forte@Sun.COM 	 * file fc_types.h.
3197836SJohn.Forte@Sun.COM 	 */
3207836SJohn.Forte@Sun.COM 	fc_reset_action_t	port_reset_action;
3217836SJohn.Forte@Sun.COM 	/*
3227836SJohn.Forte@Sun.COM 	 * This port stores the DMA behavior of the underlying FCA driver.  It
3237836SJohn.Forte@Sun.COM 	 * is checked only once in fcp_prepare_pkt() and, as the comment
3247836SJohn.Forte@Sun.COM 	 * suggests, to work around an issue with an Intel PCI bridge.
3257836SJohn.Forte@Sun.COM 	 */
3267836SJohn.Forte@Sun.COM 	fc_dma_behavior_t	port_cmds_dma_flags;
3277836SJohn.Forte@Sun.COM 	/*
3287836SJohn.Forte@Sun.COM 	 * The value stored here indicates if the underlying FCA driver
3297836SJohn.Forte@Sun.COM 	 * supports DMA transfers with non SCSI data (Ex: PRLI request).
3307836SJohn.Forte@Sun.COM 	 */
3317836SJohn.Forte@Sun.COM 	fc_fcp_dma_t		port_fcp_dma;
3327836SJohn.Forte@Sun.COM 	/*
3337836SJohn.Forte@Sun.COM 	 * This field contains the size of the private space required by the
3347836SJohn.Forte@Sun.COM 	 * underlying FCA driver in a FibreChannel packet (fc_packet_t).
3357836SJohn.Forte@Sun.COM 	 */
3367836SJohn.Forte@Sun.COM 	uint32_t		port_priv_pkt_len;
3377836SJohn.Forte@Sun.COM 	/*
3388493SReed.Liu@Sun.COM 	 * This field contains the port's modlink info.	 It is provided by
3397836SJohn.Forte@Sun.COM 	 * FP/FCTL during the port attachment.
3407836SJohn.Forte@Sun.COM 	 */
3417836SJohn.Forte@Sun.COM 	struct modlinkage	port_fp_modlinkage;
3427836SJohn.Forte@Sun.COM 	/*
3437836SJohn.Forte@Sun.COM 	 * DMA attributes for data packets, commands and responses.
3447836SJohn.Forte@Sun.COM 	 */
3457836SJohn.Forte@Sun.COM 	ddi_dma_attr_t		port_data_dma_attr;
3467836SJohn.Forte@Sun.COM 	ddi_dma_attr_t		port_cmd_dma_attr;
3477836SJohn.Forte@Sun.COM 	ddi_dma_attr_t		port_resp_dma_attr;
3487836SJohn.Forte@Sun.COM 	ddi_device_acc_attr_t	port_dma_acc_attr;
3497836SJohn.Forte@Sun.COM 	/*
3507836SJohn.Forte@Sun.COM 	 * Field containing the hba_tran structure registered with SCSA.
3517836SJohn.Forte@Sun.COM 	 */
3528493SReed.Liu@Sun.COM 	struct scsi_hba_tran	*port_tran;
3537836SJohn.Forte@Sun.COM 	/*
3547836SJohn.Forte@Sun.COM 	 * Device info structure provided by fp/fctl when the port attaches and
3557836SJohn.Forte@Sun.COM 	 * representing the local physical fibre channel port.
3567836SJohn.Forte@Sun.COM 	 */
3577836SJohn.Forte@Sun.COM 	dev_info_t		*port_dip;
3587836SJohn.Forte@Sun.COM 	/*
3597836SJohn.Forte@Sun.COM 	 * Head of the list of callback routines to call when a bus reset
3607836SJohn.Forte@Sun.COM 	 * occurs.  This list is  populated by the targets drivers by calling
3617836SJohn.Forte@Sun.COM 	 * fcp_scsi_reset_notify() (tran_reset_notify(9E)).
3627836SJohn.Forte@Sun.COM 	 */
3637836SJohn.Forte@Sun.COM 	struct scsi_reset_notify_entry	*port_reset_notify_listf;
3647836SJohn.Forte@Sun.COM 	/*
3657836SJohn.Forte@Sun.COM 	 * for framework event management
3667836SJohn.Forte@Sun.COM 	 */
3677836SJohn.Forte@Sun.COM 	ndi_event_definition_t	*port_ndi_event_defs;
3687836SJohn.Forte@Sun.COM 	ndi_event_hdl_t		port_ndi_event_hdl;
3697836SJohn.Forte@Sun.COM 	ndi_event_set_t		port_ndi_events;
3707836SJohn.Forte@Sun.COM 	/*
3718493SReed.Liu@Sun.COM 	 * hash lists of targets attached to this port.	  The hashing is based
3727836SJohn.Forte@Sun.COM 	 * on the WWN.
3737836SJohn.Forte@Sun.COM 	 */
3747836SJohn.Forte@Sun.COM 	struct fcp_tgt		*port_tgt_hash_table[FCP_NUM_HASH];
3757836SJohn.Forte@Sun.COM 	/*
3767836SJohn.Forte@Sun.COM 	 * per-Port control flag.  By default mpxio is enabled on ports unless
3777836SJohn.Forte@Sun.COM 	 * explicitly disabled through driver.conf.
3787836SJohn.Forte@Sun.COM 	 */
3797836SJohn.Forte@Sun.COM 	int			port_mpxio;
3807836SJohn.Forte@Sun.COM 	/*
3817836SJohn.Forte@Sun.COM 	 * Value used as a flag to determine if the throttling has been
3827836SJohn.Forte@Sun.COM 	 * set/initialized in the FCA driver.
3837836SJohn.Forte@Sun.COM 	 */
3847836SJohn.Forte@Sun.COM 	int			port_notify;
3857836SJohn.Forte@Sun.COM 	/*
3867836SJohn.Forte@Sun.COM 	 * This field contains a string initialized at attachment time and used
3877836SJohn.Forte@Sun.COM 	 * when calling the function the function fc_trace_debug() (through
3887836SJohn.Forte@Sun.COM 	 * the macro FCP_TRACE and FCP_DTRACE) to identify the port that
3897836SJohn.Forte@Sun.COM 	 * logged the message.
3907836SJohn.Forte@Sun.COM 	 */
3917836SJohn.Forte@Sun.COM 	char			port_instbuf[24];
3927836SJohn.Forte@Sun.COM 	uchar_t			port_boot_wwn[FC_WWN_SIZE];
3937836SJohn.Forte@Sun.COM 
3947836SJohn.Forte@Sun.COM #ifdef	DEBUG
3957836SJohn.Forte@Sun.COM 	/*
3967836SJohn.Forte@Sun.COM 	 * Use once in fcp_finish_init() when calling getpcstack().
3977836SJohn.Forte@Sun.COM 	 */
3987836SJohn.Forte@Sun.COM 	int			port_finish_depth;
3997836SJohn.Forte@Sun.COM 	pc_t			port_finish_stack[FCP_STACK_DEPTH];
4007836SJohn.Forte@Sun.COM #endif /* DEBUG */
4017836SJohn.Forte@Sun.COM 	/*
4027836SJohn.Forte@Sun.COM 	 * Condition variable used during the bus enumeration process.
4037836SJohn.Forte@Sun.COM 	 */
4047836SJohn.Forte@Sun.COM 	kcondvar_t		port_config_cv;
4057836SJohn.Forte@Sun.COM 	/*
4067836SJohn.Forte@Sun.COM 	 * Size (in bytes) required to hold the cookies of a scatter/gather
4077836SJohn.Forte@Sun.COM 	 * list.
4087836SJohn.Forte@Sun.COM 	 */
4097836SJohn.Forte@Sun.COM 	int			port_dmacookie_sz;
410*10264SZhong.Wang@Sun.COM } fcp_port_t;
4117836SJohn.Forte@Sun.COM 
4127836SJohn.Forte@Sun.COM /*
4137836SJohn.Forte@Sun.COM  * We need to save the target change count values in a map tag so as
4147836SJohn.Forte@Sun.COM  * to uniquely identify the cause and handle it better as they change
4157836SJohn.Forte@Sun.COM  * counts are bound to change upon receiving more state changes.
4167836SJohn.Forte@Sun.COM  */
4177836SJohn.Forte@Sun.COM typedef int fcp_map_tag_t;
4187836SJohn.Forte@Sun.COM 
4197836SJohn.Forte@Sun.COM /*
4207836SJohn.Forte@Sun.COM  * fcp_state definitions.
4217836SJohn.Forte@Sun.COM  */
4227836SJohn.Forte@Sun.COM #define	FCP_STATE_INIT			0x0001
4237836SJohn.Forte@Sun.COM #define	FCP_STATE_OFFLINE		0x0002
4247836SJohn.Forte@Sun.COM #define	FCP_STATE_ONLINE		0x0004
4257836SJohn.Forte@Sun.COM #define	FCP_STATE_SUSPENDED		0x0008
4267836SJohn.Forte@Sun.COM #define	FCP_STATE_POWER_DOWN		0x0010
4277836SJohn.Forte@Sun.COM #define	FCP_STATE_ONLINING		0x0020
4287836SJohn.Forte@Sun.COM #define	FCP_STATE_DETACHING		0x0040
4297836SJohn.Forte@Sun.COM #define	FCP_STATE_IN_WATCHDOG		0x0080
4307836SJohn.Forte@Sun.COM #define	FCP_STATE_IN_MDI		0x0100	/* Not in S8/S9 */
4317836SJohn.Forte@Sun.COM #define	FCP_STATE_NS_REG_FAILED		0x0200	/* Diff value from S8/S9 */
4327836SJohn.Forte@Sun.COM /*
4337836SJohn.Forte@Sun.COM  * FCP_STATE_IN_CB_DEVC indicates that we're handling a state change
4347836SJohn.Forte@Sun.COM  * notification that will be changing the state of devices.  This is an
4357836SJohn.Forte@Sun.COM  * indication to fcp_scsi_start that the target's status might change.
4367836SJohn.Forte@Sun.COM  */
4377836SJohn.Forte@Sun.COM #define	FCP_STATE_IN_CB_DEVC		0x0400
4387836SJohn.Forte@Sun.COM 
439*10264SZhong.Wang@Sun.COM /*
440*10264SZhong.Wang@Sun.COM  * FCP_STATE_FCA_IS_NODMA indicates that FCA doesn't support DMA at all
441*10264SZhong.Wang@Sun.COM  */
442*10264SZhong.Wang@Sun.COM #define	FCP_STATE_FCA_IS_NODMA		0x80000000
443*10264SZhong.Wang@Sun.COM 
4447836SJohn.Forte@Sun.COM #define	FCP_MAX_DEVICES			127
4457836SJohn.Forte@Sun.COM 
4467836SJohn.Forte@Sun.COM /* To remember that dip was allocated for a lun on this target. */
4477836SJohn.Forte@Sun.COM 
4487836SJohn.Forte@Sun.COM #define	FCP_DEVICE_CREATED		0x1
4497836SJohn.Forte@Sun.COM 
4507836SJohn.Forte@Sun.COM #define	FCP_EVENT_TAG_INSERT		0
4517836SJohn.Forte@Sun.COM #define	FCP_EVENT_TAG_REMOVE		1
4527836SJohn.Forte@Sun.COM 
4537836SJohn.Forte@Sun.COM /*
4547836SJohn.Forte@Sun.COM  * fcp_pkt: FCP packet
4557836SJohn.Forte@Sun.COM  * ---------------------
4567836SJohn.Forte@Sun.COM  *
4577836SJohn.Forte@Sun.COM  * This structure is the one initialized/created in the tran_init_pkt(9E).  It
4587836SJohn.Forte@Sun.COM  * embeds the fc_packet structure eventually passed to fp/fctl as well as
4597836SJohn.Forte@Sun.COM  * the scsi_pkt returned by tran_init_pkt(9E) to the target driver.  There is
4607836SJohn.Forte@Sun.COM  * a 1-to-1 correlation between the scsi_pkt, the fcp_pkt and the
4617836SJohn.Forte@Sun.COM  * fc_packet.
4627836SJohn.Forte@Sun.COM  *
4637836SJohn.Forte@Sun.COM  * This is what a fcp_pkt looks like after allocation:
4647836SJohn.Forte@Sun.COM  *
4658493SReed.Liu@Sun.COM  *			+================================+
4668493SReed.Liu@Sun.COM  *		 +--->	|	 struct scsi_pkt	 |
4678493SReed.Liu@Sun.COM  *		 |	|				 |
4688493SReed.Liu@Sun.COM  *		 | +--- | pkt_ha_private		 |
4698493SReed.Liu@Sun.COM  *		 | |	|				 |
4708493SReed.Liu@Sun.COM  *		 | |	+================================+
4718493SReed.Liu@Sun.COM  *		 | |
4728493SReed.Liu@Sun.COM  *		 | |	+================================+
4738493SReed.Liu@Sun.COM  *		 | +--> |	 struct fcp_pkt		 | <---------+
4748493SReed.Liu@Sun.COM  *		 +----- | cmd_pkt			 |	     |
4758493SReed.Liu@Sun.COM  *			|		      cmd_fp_pkt | ---+	     |
4768493SReed.Liu@Sun.COM  *	     +--------->| cmd_fcp_rsp[]			 |    |	     |
4778493SReed.Liu@Sun.COM  *	     | +------->| cmd_fcp_cmd[]			 |    |	     |
4788493SReed.Liu@Sun.COM  *	     | |	|--------------------------------|    |	     |
4798493SReed.Liu@Sun.COM  *	     | |	|	 struct fc_packet	 | <--+	     |
4808493SReed.Liu@Sun.COM  *	     | |	|				 |	     |
4818493SReed.Liu@Sun.COM  *	     | |	|		 pkt_ulp_private | ----------+
4828493SReed.Liu@Sun.COM  *	     | |	|		 pkt_fca_private | -----+
4838493SReed.Liu@Sun.COM  *	     | |	|		 pkt_data_cookie | ---+ |
4848493SReed.Liu@Sun.COM  *	     | |	| pkt_cmdlen			 |    | |
4858493SReed.Liu@Sun.COM  *	     | |(a)	| pkt_rsplen			 |    | |
4868493SReed.Liu@Sun.COM  *	     | +--------| .......... pkt_cmd ........... | ---|-|-------+
4878493SReed.Liu@Sun.COM  *	     |	(a)	|		  pkt_cmd_cookie | ---|-|-----+ |
4888493SReed.Liu@Sun.COM  *	     +----------| .......... pkt_resp .......... | ---|-|---+ | |
4898493SReed.Liu@Sun.COM  *			|		 pkt_resp_cookie | ---|-|-+ | | |
4908493SReed.Liu@Sun.COM  *			| pkt_cmd_dma			 |    | | | | | |
4918493SReed.Liu@Sun.COM  *			| pkt_cmd_acc			 |    | | | | | |
4928493SReed.Liu@Sun.COM  *			+================================+    | | | | | |
4938493SReed.Liu@Sun.COM  *			|	  dma_cookies		 | <--+ | | | | |
4948493SReed.Liu@Sun.COM  *			|				 |	| | | | |
4958493SReed.Liu@Sun.COM  *			+================================+	| | | | |
4968493SReed.Liu@Sun.COM  *			|	  fca_private		 | <----+ | | | |
4978493SReed.Liu@Sun.COM  *			|				 |	  | | | |
4988493SReed.Liu@Sun.COM  *			+================================+	  | | | |
4998493SReed.Liu@Sun.COM  *								  | | | |
5008493SReed.Liu@Sun.COM  *								  | | | |
5018493SReed.Liu@Sun.COM  *			+================================+   (b)  | | | |
5028493SReed.Liu@Sun.COM  *			|	 fcp_resp cookies	 | <------+ | | |
5038493SReed.Liu@Sun.COM  *			|				 |	    | | |
5048493SReed.Liu@Sun.COM  *			+================================+	    | | |
5058493SReed.Liu@Sun.COM  *								    | | |
5068493SReed.Liu@Sun.COM  *			+================================+   (b)    | | |
5078493SReed.Liu@Sun.COM  *			|	     fcp_resp		 | <--------+ | |
5088493SReed.Liu@Sun.COM  *			|   (DMA resources associated)	 |	      | |
5098493SReed.Liu@Sun.COM  *			+================================+	      | |
5108493SReed.Liu@Sun.COM  *								      | |
5118493SReed.Liu@Sun.COM  *								      | |
5128493SReed.Liu@Sun.COM  *								      | |
5138493SReed.Liu@Sun.COM  *			+================================+   (b)      | |
5148493SReed.Liu@Sun.COM  *			|	  fcp_cmd cookies	 | <----------+ |
5158493SReed.Liu@Sun.COM  *			|				 |		|
5168493SReed.Liu@Sun.COM  *			+================================+		|
5178493SReed.Liu@Sun.COM  *									|
5188493SReed.Liu@Sun.COM  *			+================================+   (b)	|
5198493SReed.Liu@Sun.COM  *			|	     fcp_cmd		 | <------------+
5208493SReed.Liu@Sun.COM  *			|   (DMA resources associated)	 |
5218493SReed.Liu@Sun.COM  *			+================================+
5227836SJohn.Forte@Sun.COM  *
5237836SJohn.Forte@Sun.COM  *
5248493SReed.Liu@Sun.COM  * (a)	The underlying FCA does NOT support DMA for this field
5258493SReed.Liu@Sun.COM  * (b)	The underlying FCA supports DMA for this field
5267836SJohn.Forte@Sun.COM  */
527*10264SZhong.Wang@Sun.COM typedef struct fcp_pkt {
5287836SJohn.Forte@Sun.COM 	/*
5297836SJohn.Forte@Sun.COM 	 * The two following fields are used to queue fcp_pkt in the double
5307836SJohn.Forte@Sun.COM 	 * link list of the lun structure.  The packet is queued in
5317836SJohn.Forte@Sun.COM 	 * tran_init_pkt(9E) and unqueued in tran_destroy_pkt(9E).
5327836SJohn.Forte@Sun.COM 	 */
5337836SJohn.Forte@Sun.COM 	struct fcp_pkt		*cmd_forw;
5347836SJohn.Forte@Sun.COM 	struct fcp_pkt		*cmd_back;
5357836SJohn.Forte@Sun.COM 	/*
5367836SJohn.Forte@Sun.COM 	 * This field is used to queue the packet in the single link list of the
5377836SJohn.Forte@Sun.COM 	 * port structure.  The port keeps a list of all the commands issued
5387836SJohn.Forte@Sun.COM 	 * through it and scans it, for example, when all of those commands
5397836SJohn.Forte@Sun.COM 	 * have to be aborted.
5407836SJohn.Forte@Sun.COM 	 */
5417836SJohn.Forte@Sun.COM 	struct fcp_pkt		*cmd_next;
5427836SJohn.Forte@Sun.COM 	/*
5437836SJohn.Forte@Sun.COM 	 * This field points back to the scsi_pkt.
5447836SJohn.Forte@Sun.COM 	 */
5457836SJohn.Forte@Sun.COM 	struct scsi_pkt		*cmd_pkt;
5467836SJohn.Forte@Sun.COM 	/*
5477836SJohn.Forte@Sun.COM 	 * This field points to the field cmd_fc_packet defined further in this
5487836SJohn.Forte@Sun.COM 	 * same structure.
5497836SJohn.Forte@Sun.COM 	 */
5507836SJohn.Forte@Sun.COM 	struct fc_packet	*cmd_fp_pkt;
5517836SJohn.Forte@Sun.COM 	/*
5527836SJohn.Forte@Sun.COM 	 * Structure where the FCP_CMD information unit is going to be built.
5537836SJohn.Forte@Sun.COM 	 */
5547836SJohn.Forte@Sun.COM 	fcp_cmd_t		cmd_fcp_cmd;
5557836SJohn.Forte@Sun.COM 	/*
5568493SReed.Liu@Sun.COM 	 * State of the packet.	 The values for the state seem to indicate
5577836SJohn.Forte@Sun.COM 	 * that it isn't a bitmap.  However, in several instances the code
5587836SJohn.Forte@Sun.COM 	 * treats it as a bitmap doing a "&= ~FCP_PKT_ISSUED" to it
5597836SJohn.Forte@Sun.COM 	 * eventhough the value stored is always checked using "!=" and "==".
5607836SJohn.Forte@Sun.COM 	 */
5617836SJohn.Forte@Sun.COM 	uint_t			cmd_state;
5627836SJohn.Forte@Sun.COM 	/*
5637836SJohn.Forte@Sun.COM 	 * This field is a bitmap indicating if
5647836SJohn.Forte@Sun.COM 	 * the cmd is queued
5657836SJohn.Forte@Sun.COM 	 */
5667836SJohn.Forte@Sun.COM 	uint_t			cmd_flags;
5677836SJohn.Forte@Sun.COM 	/* Contains the number of bytes DMA mappped. */
5687836SJohn.Forte@Sun.COM 	uint_t			cmd_dmacount;
5697836SJohn.Forte@Sun.COM 	/*
5707836SJohn.Forte@Sun.COM 	 * Contains the timeout value for the packet.  This is not a delay or
5717836SJohn.Forte@Sun.COM 	 * a delta but an absolute value.
5727836SJohn.Forte@Sun.COM 	 */
5737836SJohn.Forte@Sun.COM 	uint_t			cmd_timeout;
5747836SJohn.Forte@Sun.COM 	/*
5757836SJohn.Forte@Sun.COM 	 * This array is used to store the FCP_RSP information unit returned by
5767836SJohn.Forte@Sun.COM 	 * the device when the underlying FCA cannot DMA it in.
5777836SJohn.Forte@Sun.COM 	 */
5787836SJohn.Forte@Sun.COM 	char			cmd_fcp_rsp[FCP_MAX_RSP_IU_SIZE];
5797836SJohn.Forte@Sun.COM 	/*
5807836SJohn.Forte@Sun.COM 	 * This is the fc_packet structure used to forward the request to
5817836SJohn.Forte@Sun.COM 	 * fp/fctl.
5827836SJohn.Forte@Sun.COM 	 */
5837836SJohn.Forte@Sun.COM 	struct fc_packet	cmd_fc_packet;
584*10264SZhong.Wang@Sun.COM } fcp_pkt_t;
5857836SJohn.Forte@Sun.COM 
5867836SJohn.Forte@Sun.COM /*
5877836SJohn.Forte@Sun.COM  * fcp_ipkt : Packet for internal commands.
5887836SJohn.Forte@Sun.COM  * ------------------------------------------
5897836SJohn.Forte@Sun.COM  *
5908493SReed.Liu@Sun.COM  *			+================================+
5918493SReed.Liu@Sun.COM  *			|	 struct fcp_ipkt	 | <---------+
5928493SReed.Liu@Sun.COM  *			|	 (kmem_zalloc())	 |	     |
5938493SReed.Liu@Sun.COM  *			|		       ipkt_fpkt | ---+	     |
5948493SReed.Liu@Sun.COM  *			|				 |    |	     |
5958493SReed.Liu@Sun.COM  *			|     ipkt_cmdlen = cmd_len	 |    |	     |
5968493SReed.Liu@Sun.COM  *			|				 |    |	     |
5978493SReed.Liu@Sun.COM  *			|				 |    |	     |
5988493SReed.Liu@Sun.COM  *			|				 |    |	     |
5998493SReed.Liu@Sun.COM  *			|--------------------------------|    |	     |
6008493SReed.Liu@Sun.COM  *			|	 struct fc_packet	 | <--+	     |
6018493SReed.Liu@Sun.COM  *			|				 |	     |
6028493SReed.Liu@Sun.COM  *			|		 pkt_ulp_private | ----------+
6038493SReed.Liu@Sun.COM  *			|		 pkt_fca_private | -----+
6048493SReed.Liu@Sun.COM  *			|		 pkt_data_cookie | ---+ |
6058493SReed.Liu@Sun.COM  *			|	    pkt_cmdlen		 |    | |
6068493SReed.Liu@Sun.COM  *			|	    pkt_rsplen		 |    | |
6078493SReed.Liu@Sun.COM  *			| pkt_cmd ...................... | ---|-|-------+
6088493SReed.Liu@Sun.COM  *			|		  pkt_cmd_cookie | ---|-|-----+ |
6098493SReed.Liu@Sun.COM  *			| pkt_resp ..................... | ---|-|---+ | |
6108493SReed.Liu@Sun.COM  *			|		 pkt_resp_cookie | ---|-|-+ | | |
6118493SReed.Liu@Sun.COM  *			|	   pkt_cmd_dma		 |    | | | | | |
6128493SReed.Liu@Sun.COM  *			|	   pkt_cmd_acc		 |    | | | | | |
6138493SReed.Liu@Sun.COM  *			+================================+    | | | | | |
6148493SReed.Liu@Sun.COM  *			|	  dma_cookies		 | <--+ | | | | |
6158493SReed.Liu@Sun.COM  *			|				 |	| | | | |
6168493SReed.Liu@Sun.COM  *			|				 |	| | | | |
6178493SReed.Liu@Sun.COM  *			|				 |	| | | | |
6188493SReed.Liu@Sun.COM  *			+================================+	| | | | |
6198493SReed.Liu@Sun.COM  *			|	  fca_private		 | <----+ | | | |
6208493SReed.Liu@Sun.COM  *			|				 |	  | | | |
6218493SReed.Liu@Sun.COM  *			|				 |	  | | | |
6228493SReed.Liu@Sun.COM  *			|				 |	  | | | |
6238493SReed.Liu@Sun.COM  *			+================================+	  | | | |
6248493SReed.Liu@Sun.COM  *								  | | | |
6258493SReed.Liu@Sun.COM  *								  | | | |
6268493SReed.Liu@Sun.COM  *			+================================+   (b)  | | | |
6278493SReed.Liu@Sun.COM  *			|	 fcp_resp cookies	 | <------+ | | |
6288493SReed.Liu@Sun.COM  *			|				 |	    | | |
6298493SReed.Liu@Sun.COM  *			+================================+	    | | |
6308493SReed.Liu@Sun.COM  *								    | | |
6318493SReed.Liu@Sun.COM  *			+================================+   (b)    | | |
6328493SReed.Liu@Sun.COM  *			|	     fcp_resp		 | <--------+ | |
6338493SReed.Liu@Sun.COM  *			|   (DMA resources associated)	 |	      | |
6348493SReed.Liu@Sun.COM  *			+================================+	      | |
6358493SReed.Liu@Sun.COM  *								      | |
6368493SReed.Liu@Sun.COM  *								      | |
6378493SReed.Liu@Sun.COM  *								      | |
6388493SReed.Liu@Sun.COM  *			+================================+   (b)      | |
6398493SReed.Liu@Sun.COM  *			|	  fcp_cmd cookies	 | <----------+ |
6408493SReed.Liu@Sun.COM  *			|				 |		|
6418493SReed.Liu@Sun.COM  *			+================================+		|
6428493SReed.Liu@Sun.COM  *									|
6438493SReed.Liu@Sun.COM  *			+================================+   (b)	|
6448493SReed.Liu@Sun.COM  *			|	     fcp_cmd		 | <------------+
6458493SReed.Liu@Sun.COM  *			|   (DMA resources associated)	 |
6468493SReed.Liu@Sun.COM  *			+================================+
6477836SJohn.Forte@Sun.COM  *
6488493SReed.Liu@Sun.COM  * (a)	The underlying FCA does NOT support DMA for this field
6498493SReed.Liu@Sun.COM  * (b)	The underlying FCA supports DMA for this field
6507836SJohn.Forte@Sun.COM  */
651*10264SZhong.Wang@Sun.COM typedef struct fcp_ipkt {
6527836SJohn.Forte@Sun.COM 	/*
6537836SJohn.Forte@Sun.COM 	 * Pointer to the port (fcp_port) in behalf of which this internal
6547836SJohn.Forte@Sun.COM 	 * packet was allocated.
6557836SJohn.Forte@Sun.COM 	 */
6567836SJohn.Forte@Sun.COM 	struct fcp_port		*ipkt_port;
6577836SJohn.Forte@Sun.COM 	/*
6587836SJohn.Forte@Sun.COM 	 * Pointer to the target (fcp_tgt) in behalf of which this internal
6597836SJohn.Forte@Sun.COM 	 * packet was allocated.
6607836SJohn.Forte@Sun.COM 	 */
6617836SJohn.Forte@Sun.COM 	struct fcp_tgt		*ipkt_tgt;
6627836SJohn.Forte@Sun.COM 	/*
6637836SJohn.Forte@Sun.COM 	 * Pointer to the lun (fcp_lun) in behalf of which this internal
6647836SJohn.Forte@Sun.COM 	 * packet was allocated.  This field is only meaningful when the
6657836SJohn.Forte@Sun.COM 	 * internal packet has been allocated for a "scsi passthru" command or
6667836SJohn.Forte@Sun.COM 	 * for an internal SCSI command such as REPORT LUNs and INQUIRY.
6677836SJohn.Forte@Sun.COM 	 */
6687836SJohn.Forte@Sun.COM 	struct fcp_lun		*ipkt_lun;
6697836SJohn.Forte@Sun.COM 	/*
6707836SJohn.Forte@Sun.COM 	 * Fields used to queue the internal packet into the double linked list
6717836SJohn.Forte@Sun.COM 	 * of the FCP port (fcp_port).
6727836SJohn.Forte@Sun.COM 	 */
6737836SJohn.Forte@Sun.COM 	struct fcp_ipkt		*ipkt_next;
6747836SJohn.Forte@Sun.COM 	struct fcp_ipkt		*ipkt_prev;
6757836SJohn.Forte@Sun.COM 	/*
6767836SJohn.Forte@Sun.COM 	 * This field points to the field ipkt_fc_packet defined farther in
6777836SJohn.Forte@Sun.COM 	 * this same structure.
6787836SJohn.Forte@Sun.COM 	 */
6797836SJohn.Forte@Sun.COM 	struct fc_packet	*ipkt_fpkt;
6807836SJohn.Forte@Sun.COM 	/*
6817836SJohn.Forte@Sun.COM 	 * This is the timeout value for the internal packet.  It seems to
6828493SReed.Liu@Sun.COM 	 * increase with the number of retries.	 It is initialized like this
6837836SJohn.Forte@Sun.COM 	 * in the code:
6847836SJohn.Forte@Sun.COM 	 *
6857836SJohn.Forte@Sun.COM 	 *   icmd->ipkt_restart = fcp_watchdog_time + icmd->ipkt_retries++
6867836SJohn.Forte@Sun.COM 	 *
6877836SJohn.Forte@Sun.COM 	 * First time ipkt_retries is zero.  As it increases, the timeout
6887836SJohn.Forte@Sun.COM 	 * value for the internal packet also increases.
6897836SJohn.Forte@Sun.COM 	 */
6907836SJohn.Forte@Sun.COM 	uint32_t		ipkt_restart;
6917836SJohn.Forte@Sun.COM 	/*
6927836SJohn.Forte@Sun.COM 	 * Link state counter when the internal packet was built.
6937836SJohn.Forte@Sun.COM 	 */
6947836SJohn.Forte@Sun.COM 	uint32_t		ipkt_link_cnt;
6957836SJohn.Forte@Sun.COM 	int			ipkt_cause;
6967836SJohn.Forte@Sun.COM 	uint32_t		ipkt_cmdlen;
6977836SJohn.Forte@Sun.COM 	uint32_t		ipkt_resplen;
6987836SJohn.Forte@Sun.COM 	uint32_t		ipkt_datalen;
6997836SJohn.Forte@Sun.COM 	/*
7007836SJohn.Forte@Sun.COM 	 * Counter of the times an internal packet has been retried.  Its
7017836SJohn.Forte@Sun.COM 	 * value is checked against FCP_MAX_RETRIES.
7027836SJohn.Forte@Sun.COM 	 */
7037836SJohn.Forte@Sun.COM 	uint32_t		ipkt_retries;
7047836SJohn.Forte@Sun.COM 	uint32_t		ipkt_change_cnt;
7057836SJohn.Forte@Sun.COM 	int			ipkt_nodma;
7067836SJohn.Forte@Sun.COM 	/*
7077836SJohn.Forte@Sun.COM 	 * Semaphore used to wait for completion on.
7087836SJohn.Forte@Sun.COM 	 */
7097836SJohn.Forte@Sun.COM 	ksema_t			ipkt_sema;
7107836SJohn.Forte@Sun.COM 	/*
7117836SJohn.Forte@Sun.COM 	 * Opcode indicating what internal command the packet contains (PLOGI,
7127836SJohn.Forte@Sun.COM 	 * PRLI, INQUIRY...).
7137836SJohn.Forte@Sun.COM 	 */
7147836SJohn.Forte@Sun.COM 	uchar_t			ipkt_opcode;
7157836SJohn.Forte@Sun.COM 	/*
7167836SJohn.Forte@Sun.COM 	 * FC packet.
7177836SJohn.Forte@Sun.COM 	 */
7187836SJohn.Forte@Sun.COM 	struct fc_packet	ipkt_fc_packet;
719*10264SZhong.Wang@Sun.COM } fcp_ipkt_t;
7207836SJohn.Forte@Sun.COM 
7217836SJohn.Forte@Sun.COM /*
7227836SJohn.Forte@Sun.COM  * cmd_state definitions
7237836SJohn.Forte@Sun.COM  */
7247836SJohn.Forte@Sun.COM #define	FCP_PKT_IDLE			0x1
7257836SJohn.Forte@Sun.COM #define	FCP_PKT_ISSUED			0x2
7267836SJohn.Forte@Sun.COM #define	FCP_PKT_ABORTING		0x3
7277836SJohn.Forte@Sun.COM 
7287836SJohn.Forte@Sun.COM /*
7297836SJohn.Forte@Sun.COM  * These are the defined cmd_flags for this structure.
7307836SJohn.Forte@Sun.COM  */
731*10264SZhong.Wang@Sun.COM #define	CFLAG_NONE		0x0000
732*10264SZhong.Wang@Sun.COM #define	CFLAG_IS_READ		0x0001
733*10264SZhong.Wang@Sun.COM #define	CFLAG_IN_QUEUE		0x0002	/* command in fcp queue */
7347836SJohn.Forte@Sun.COM 
7357836SJohn.Forte@Sun.COM /*
7367836SJohn.Forte@Sun.COM  * Target structure
7377836SJohn.Forte@Sun.COM  * ----------------
7387836SJohn.Forte@Sun.COM  *
7397836SJohn.Forte@Sun.COM  * This structure holds the information relative to a SCSI target.  This
7407836SJohn.Forte@Sun.COM  * structure doesn't represent the object registered with the OS (NDI or
7417836SJohn.Forte@Sun.COM  * MPxIO...).
7427836SJohn.Forte@Sun.COM  */
743*10264SZhong.Wang@Sun.COM typedef struct fcp_tgt {
7447836SJohn.Forte@Sun.COM 	/*
7457836SJohn.Forte@Sun.COM 	 * This field is used to queue the target structure in one of the
7467836SJohn.Forte@Sun.COM 	 * buckets of the fcp_port target hash table port_tgt_hash_table[].
7477836SJohn.Forte@Sun.COM 	 */
7487836SJohn.Forte@Sun.COM 	struct fcp_tgt		*tgt_next;
7497836SJohn.Forte@Sun.COM 	/* Points to the fcp_port the target belongs to. */
7507836SJohn.Forte@Sun.COM 	struct fcp_port		*tgt_port;
7517836SJohn.Forte@Sun.COM 	/*
7527836SJohn.Forte@Sun.COM 	 * This field is a bitmap indicating the state of the target.  Several
7537836SJohn.Forte@Sun.COM 	 * bits can be set simultaneously.
7547836SJohn.Forte@Sun.COM 	 */
7557836SJohn.Forte@Sun.COM 	uint32_t		tgt_state;
7567836SJohn.Forte@Sun.COM 	/*
7577836SJohn.Forte@Sun.COM 	 * State controlling if the LUNs attached to this target will be
7587836SJohn.Forte@Sun.COM 	 * automatically onlined or not.
7597836SJohn.Forte@Sun.COM 	 */
7607836SJohn.Forte@Sun.COM 	uint32_t		tgt_node_state;
7617836SJohn.Forte@Sun.COM 	/*
7627836SJohn.Forte@Sun.COM 	 * Mutex protecting this structure.
7637836SJohn.Forte@Sun.COM 	 */
7647836SJohn.Forte@Sun.COM 	kmutex_t		tgt_mutex;
7657836SJohn.Forte@Sun.COM 	/*
7667836SJohn.Forte@Sun.COM 	 * List of LUNs (single link list).
7677836SJohn.Forte@Sun.COM 	 */
7687836SJohn.Forte@Sun.COM 	struct fcp_lun		*tgt_lun;
7697836SJohn.Forte@Sun.COM 	opaque_t		tgt_fca_dev;
7707836SJohn.Forte@Sun.COM 	/*
7717836SJohn.Forte@Sun.COM 	 * Number of LUNs in this target.
7727836SJohn.Forte@Sun.COM 	 */
7737836SJohn.Forte@Sun.COM 	uint_t			tgt_lun_cnt;
7747836SJohn.Forte@Sun.COM 	/*
7757836SJohn.Forte@Sun.COM 	 * Counter of LUNs to probe.  It is used during the discovery
7767836SJohn.Forte@Sun.COM 	 * process.  Starts with the number of LUNs returned by REPORT_LUN
7777836SJohn.Forte@Sun.COM 	 * and is decremented until it reaches zero.
7787836SJohn.Forte@Sun.COM 	 */
7797836SJohn.Forte@Sun.COM 	uint_t			tgt_tmp_cnt;
7807836SJohn.Forte@Sun.COM 	/*
7817836SJohn.Forte@Sun.COM 	 * fp/fctl handle for the "port_device".
7827836SJohn.Forte@Sun.COM 	 */
7837836SJohn.Forte@Sun.COM 	opaque_t		tgt_pd_handle;
7847836SJohn.Forte@Sun.COM 	/*
7857836SJohn.Forte@Sun.COM 	 * Node World Wide Name.
7867836SJohn.Forte@Sun.COM 	 */
7877836SJohn.Forte@Sun.COM 	la_wwn_t		tgt_node_wwn;
7887836SJohn.Forte@Sun.COM 	/*
7897836SJohn.Forte@Sun.COM 	 * Port World Wide Name.
7907836SJohn.Forte@Sun.COM 	 */
7917836SJohn.Forte@Sun.COM 	la_wwn_t		tgt_port_wwn;
7927836SJohn.Forte@Sun.COM 	/*
7937836SJohn.Forte@Sun.COM 	 * Fibre Channel Port ID.
7947836SJohn.Forte@Sun.COM 	 */
7957836SJohn.Forte@Sun.COM 	uint32_t		tgt_d_id;
7967836SJohn.Forte@Sun.COM 	/*
7977836SJohn.Forte@Sun.COM 	 * Fibre Channel Port ID.  Uses bit fields to represent it.
7987836SJohn.Forte@Sun.COM 	 */
7997836SJohn.Forte@Sun.COM 	uint32_t		tgt_hard_addr;
8007836SJohn.Forte@Sun.COM 	/*
8017836SJohn.Forte@Sun.COM 	 * Becomes 1 when the LUNs are created.
8027836SJohn.Forte@Sun.COM 	 */
8037836SJohn.Forte@Sun.COM 	uchar_t			tgt_device_created;
8047836SJohn.Forte@Sun.COM 	/*
8057836SJohn.Forte@Sun.COM 	 * Counter of how many REPORT_LUN commands were sent.  It is used to
8067836SJohn.Forte@Sun.COM 	 * allow the REPORT_LUN command to be sent twice in case the buffer
8077836SJohn.Forte@Sun.COM 	 * allocated the first time wasn't big enough.
8087836SJohn.Forte@Sun.COM 	 */
8097836SJohn.Forte@Sun.COM 	uchar_t			tgt_report_lun_cnt;
8107836SJohn.Forte@Sun.COM 	/*
8117836SJohn.Forte@Sun.COM 	 * This field is incremented each time the field tgt_state is updated.
8127836SJohn.Forte@Sun.COM 	 * Its use is similar to the use of the field port_link_cnt in the
8138493SReed.Liu@Sun.COM 	 * fcp_port structure.	The internal packets are, for example, tagged
8147836SJohn.Forte@Sun.COM 	 * with the value stored here.
8157836SJohn.Forte@Sun.COM 	 */
8167836SJohn.Forte@Sun.COM 	uint32_t		tgt_change_cnt;
8177836SJohn.Forte@Sun.COM 	/*
8187836SJohn.Forte@Sun.COM 	 * This field contains the cause of the last change in state.
8197836SJohn.Forte@Sun.COM 	 */
8207836SJohn.Forte@Sun.COM 	int			tgt_statec_cause;
8217836SJohn.Forte@Sun.COM 	/*
8227836SJohn.Forte@Sun.COM 	 * The following two fields indicate whether the remote port is an
8237836SJohn.Forte@Sun.COM 	 * FCP initiator or an FCP target.  They are treated as booleans.
8247836SJohn.Forte@Sun.COM 	 */
8257836SJohn.Forte@Sun.COM 	uchar_t			tgt_icap;	/* Initiator */
8267836SJohn.Forte@Sun.COM 	uchar_t			tgt_tcap;	/* Target */
8277836SJohn.Forte@Sun.COM #ifdef	DEBUG
8287836SJohn.Forte@Sun.COM 	/*
8297836SJohn.Forte@Sun.COM 	 * Updated in fcp_call_finish_init_held() when DEBUG  is defined
8307836SJohn.Forte@Sun.COM 	 */
8317836SJohn.Forte@Sun.COM 	int			tgt_tmp_cnt_depth;
8327836SJohn.Forte@Sun.COM 	pc_t			tgt_tmp_cnt_stack[FCP_STACK_DEPTH];
8337836SJohn.Forte@Sun.COM #endif /* DEBUG */
8347836SJohn.Forte@Sun.COM 	/*
8357836SJohn.Forte@Sun.COM 	 * This field holds the timer id of the timer started when a LUN
8367836SJohn.Forte@Sun.COM 	 * reconfiguration is needed for the target.  The reconfiguration
8377836SJohn.Forte@Sun.COM 	 * is done in the timeout function.
8387836SJohn.Forte@Sun.COM 	 */
8397836SJohn.Forte@Sun.COM 	timeout_id_t		tgt_tid;
8407836SJohn.Forte@Sun.COM 	int			tgt_done;
8417836SJohn.Forte@Sun.COM 	/*
8427836SJohn.Forte@Sun.COM 	 * Bitmap used to trace the discovery process.
8437836SJohn.Forte@Sun.COM 	 */
8447836SJohn.Forte@Sun.COM 	uint32_t		tgt_trace;
8457836SJohn.Forte@Sun.COM 	/*
8467836SJohn.Forte@Sun.COM 	 * This field is used when the code is sorting out which devices
8477836SJohn.Forte@Sun.COM 	 * were known which ones are new and which ones went away.
8487836SJohn.Forte@Sun.COM 	 */
8497836SJohn.Forte@Sun.COM 	uint32_t		tgt_aux_state;
8507836SJohn.Forte@Sun.COM 	/*
8517836SJohn.Forte@Sun.COM 	 * Number of internal packets allocated in behalf of the target.
8527836SJohn.Forte@Sun.COM 	 */
8537836SJohn.Forte@Sun.COM 	int			tgt_ipkt_cnt;
8547836SJohn.Forte@Sun.COM 	/*
8557836SJohn.Forte@Sun.COM 	 * used to detect user unconfig when auto configuration is enabled.
8567836SJohn.Forte@Sun.COM 	 */
8577836SJohn.Forte@Sun.COM 	uint32_t		tgt_manual_config_only;
858*10264SZhong.Wang@Sun.COM } fcp_tgt_t;
8597836SJohn.Forte@Sun.COM 
8607836SJohn.Forte@Sun.COM /*
8617836SJohn.Forte@Sun.COM  * Target States
8627836SJohn.Forte@Sun.COM  */
8637836SJohn.Forte@Sun.COM #define	FCP_TGT_INIT		0x01
8647836SJohn.Forte@Sun.COM #define	FCP_TGT_BUSY		0x02
8657836SJohn.Forte@Sun.COM #define	FCP_TGT_MARK		0x04
8667836SJohn.Forte@Sun.COM #define	FCP_TGT_OFFLINE		0x08
8677836SJohn.Forte@Sun.COM #define	FCP_TGT_ORPHAN		0x80
8687836SJohn.Forte@Sun.COM #define	FCP_TGT_ILLREQ		0x10
8697836SJohn.Forte@Sun.COM 
8707836SJohn.Forte@Sun.COM /*
8717836SJohn.Forte@Sun.COM  * Target Aux Stat
8727836SJohn.Forte@Sun.COM  */
8737836SJohn.Forte@Sun.COM #define	FCP_TGT_TAGGED		0x01
8747836SJohn.Forte@Sun.COM 
8757836SJohn.Forte@Sun.COM /*
8767836SJohn.Forte@Sun.COM  * Target discovery tracing
8777836SJohn.Forte@Sun.COM  */
8787836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_1		0x00000001
8797836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_2		0x00000002
8807836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_3		0x00000004
8817836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_4		0x00000008
8827836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_5		0x00000010
8837836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_6		0x00000020
8847836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_7		0x00000040
8857836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_8		0x00000080
8867836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_9		0x00000100
8877836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_10	0x00000200
8887836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_11	0x00000400
8897836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_12	0x00000800
8907836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_13	0x00001000
8917836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_14	0x00002000
8927836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_15	0x00004000
8937836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_16	0x00008000
8947836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_17	0x00010000
8957836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_18	0x00020000
8967836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_19	0x00040000
8977836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_20	0x00080000
8987836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_21	0x00100000
8997836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_22	0x00200000
9007836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_23	0x00400000
9017836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_24	0x00800000
9027836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_25	0x01000000
9037836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_26	0x02000000
9047836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_27	0x04000000
9057836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_28	0x08000000
9067836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE_29	0x10000000
9077836SJohn.Forte@Sun.COM 
9087836SJohn.Forte@Sun.COM #ifndef	__lock_lint
9097836SJohn.Forte@Sun.COM 
9107836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE(ptgt, tcount, bit) {\
9117836SJohn.Forte@Sun.COM 	if (ptgt) {\
9127836SJohn.Forte@Sun.COM 		if (ptgt->tgt_change_cnt == tcount) {\
9137836SJohn.Forte@Sun.COM 			ptgt->tgt_trace |= bit;\
9147836SJohn.Forte@Sun.COM 		}\
9157836SJohn.Forte@Sun.COM 	}\
9167836SJohn.Forte@Sun.COM }
9177836SJohn.Forte@Sun.COM 
9187836SJohn.Forte@Sun.COM #else	/* __lock_lint */
9197836SJohn.Forte@Sun.COM 
9207836SJohn.Forte@Sun.COM #define	FCP_TGT_TRACE(ptgt, tcount, bit)
9217836SJohn.Forte@Sun.COM 
9227836SJohn.Forte@Sun.COM #endif /* __lock_lint */
9237836SJohn.Forte@Sun.COM 
9247836SJohn.Forte@Sun.COM 
9257836SJohn.Forte@Sun.COM /*
9267836SJohn.Forte@Sun.COM  * state change cause
9277836SJohn.Forte@Sun.COM  */
9287836SJohn.Forte@Sun.COM #define	FCP_CAUSE_TGT_CHANGE	0x01
9297836SJohn.Forte@Sun.COM #define	FCP_CAUSE_LINK_CHANGE	0x02
9307836SJohn.Forte@Sun.COM #define	FCP_CAUSE_LINK_DOWN	0x04
9317836SJohn.Forte@Sun.COM #define	FCP_CAUSE_USER_CREATE	0x08
9327836SJohn.Forte@Sun.COM 
9337836SJohn.Forte@Sun.COM 
9347836SJohn.Forte@Sun.COM /*
9357836SJohn.Forte@Sun.COM  * Target node states (applicable to LUNs behind the target)
9367836SJohn.Forte@Sun.COM  */
9377836SJohn.Forte@Sun.COM #define	FCP_TGT_NODE_NONE	0x00	/* No node exists */
9387836SJohn.Forte@Sun.COM #define	FCP_TGT_NODE_ON_DEMAND	0x01	/* create only upon request */
9397836SJohn.Forte@Sun.COM #define	FCP_TGT_NODE_PRESENT	0x02	/* Node exists; rediscover it */
9407836SJohn.Forte@Sun.COM 
9417836SJohn.Forte@Sun.COM 
9427836SJohn.Forte@Sun.COM #define	FCP_NO_CHANGE		0x1
9437836SJohn.Forte@Sun.COM #define	FCP_LINK_CHANGE		0x2
9447836SJohn.Forte@Sun.COM #define	FCP_DEV_CHANGE		0x3
9457836SJohn.Forte@Sun.COM 
9467836SJohn.Forte@Sun.COM 
9477836SJohn.Forte@Sun.COM /* hotplug event struct */
9487836SJohn.Forte@Sun.COM struct fcp_hp_event {
9497836SJohn.Forte@Sun.COM 	int (*callback)();
9507836SJohn.Forte@Sun.COM 	void *arg;
9517836SJohn.Forte@Sun.COM };
9527836SJohn.Forte@Sun.COM 
9537836SJohn.Forte@Sun.COM /*
9547836SJohn.Forte@Sun.COM  * We talk to both NDI and MDI framework to enumerate our child devices.
9557836SJohn.Forte@Sun.COM  * We internally define a generic child handle and assign either dev_info
9567836SJohn.Forte@Sun.COM  * or mdi_pathinfo handle depending on the device.
9577836SJohn.Forte@Sun.COM  */
9587836SJohn.Forte@Sun.COM typedef void		*child_info_t;
9597836SJohn.Forte@Sun.COM 
9607836SJohn.Forte@Sun.COM #define	CIP(child)	((child_info_t *)(child))
9617836SJohn.Forte@Sun.COM #define	DIP(child)	((dev_info_t *)(child))
9627836SJohn.Forte@Sun.COM #define	PIP(child)	((mdi_pathinfo_t *)(child))
9637836SJohn.Forte@Sun.COM 
9647836SJohn.Forte@Sun.COM /*
9657836SJohn.Forte@Sun.COM  * LUN structure
9667836SJohn.Forte@Sun.COM  * -------------
9677836SJohn.Forte@Sun.COM  *
9688493SReed.Liu@Sun.COM  * This structure holds the information relative to a SCSI LUN.	 This
9697836SJohn.Forte@Sun.COM  * structure is the one representing the object registered with the OS (NDI
9707836SJohn.Forte@Sun.COM  * or MPxIO...).
9717836SJohn.Forte@Sun.COM  */
972*10264SZhong.Wang@Sun.COM typedef struct fcp_lun {
9737836SJohn.Forte@Sun.COM 	/*
9747836SJohn.Forte@Sun.COM 	 * Mutex protecting the access to this structure.
9757836SJohn.Forte@Sun.COM 	 */
9767836SJohn.Forte@Sun.COM 	kmutex_t		lun_mutex;
9777836SJohn.Forte@Sun.COM 	/*
9788493SReed.Liu@Sun.COM 	 * Logical unit number.	 It is a SCSI3 format.
9797836SJohn.Forte@Sun.COM 	 */
9807836SJohn.Forte@Sun.COM 	fcp_ent_addr_t		lun_addr;
9817836SJohn.Forte@Sun.COM 	/*
9827836SJohn.Forte@Sun.COM 	 * The two following fields are respectively the head and tail of a
9837836SJohn.Forte@Sun.COM 	 * double link list of fcp_packets.  It is populated in
9847836SJohn.Forte@Sun.COM 	 * tran_init_pkt(9E) (fcp_scsi_init_pkt) and emptied in
9857836SJohn.Forte@Sun.COM 	 * tran_destroy_pkt(9E) (fcp_scsi_destroy_pkt).
9867836SJohn.Forte@Sun.COM 	 */
9877836SJohn.Forte@Sun.COM 	struct fcp_pkt		*lun_pkt_head;
9887836SJohn.Forte@Sun.COM 	struct fcp_pkt		*lun_pkt_tail;
9897836SJohn.Forte@Sun.COM 	/*
9908493SReed.Liu@Sun.COM 	 * This field is treated like a union.	It may contain the dev_info_t
9917836SJohn.Forte@Sun.COM 	 * or the mdi_pathinfo_t depending on how the device associated with
9927836SJohn.Forte@Sun.COM 	 * this LUN was registered.
9937836SJohn.Forte@Sun.COM 	 */
9947836SJohn.Forte@Sun.COM 	child_info_t		*lun_cip;
9957836SJohn.Forte@Sun.COM 	/*
9967836SJohn.Forte@Sun.COM 	 * Online/Offline event count.
9977836SJohn.Forte@Sun.COM 	 */
9987836SJohn.Forte@Sun.COM 	int			lun_event_count;
9997836SJohn.Forte@Sun.COM 	/*
10007836SJohn.Forte@Sun.COM 	 * Back pointer to the target the LUN belongs to.
10017836SJohn.Forte@Sun.COM 	 */
10027836SJohn.Forte@Sun.COM 	struct fcp_tgt		*lun_tgt;
10037836SJohn.Forte@Sun.COM 	/*
10047836SJohn.Forte@Sun.COM 	 * Bit map reflecting the state of the LUN.
10057836SJohn.Forte@Sun.COM 	 */
10067836SJohn.Forte@Sun.COM 	uint_t			lun_state;
10077836SJohn.Forte@Sun.COM 	/*
10087836SJohn.Forte@Sun.COM 	 * LUN type (disk, tape...).  The value stored here is taken from the
10097836SJohn.Forte@Sun.COM 	 * inquiry data.
10107836SJohn.Forte@Sun.COM 	 */
10117836SJohn.Forte@Sun.COM 	uchar_t			lun_type;
10127836SJohn.Forte@Sun.COM 	/*
10137836SJohn.Forte@Sun.COM 	 * This field is incremented each time fcp_scsi_tgt_init()
10147836SJohn.Forte@Sun.COM 	 * (tran_tgt_init(9E)) is called and decremented each time
10157836SJohn.Forte@Sun.COM 	 * fcp_scsi_tgt_free() (tran_tgt_free(9E)) is called.  The
10167836SJohn.Forte@Sun.COM 	 * incrementation and decrementation will also have an effect on
10177836SJohn.Forte@Sun.COM 	 * lun_state bit FCP_SCSI_LUN_TGT_INIT.
10187836SJohn.Forte@Sun.COM 	 */
10197836SJohn.Forte@Sun.COM 	uchar_t			lun_tgt_count;
10207836SJohn.Forte@Sun.COM 	/*
10217836SJohn.Forte@Sun.COM 	 * LUN number as it is returned by REPORT_LUNS.
10227836SJohn.Forte@Sun.COM 	 */
10237836SJohn.Forte@Sun.COM 	uint16_t		lun_num;
10247836SJohn.Forte@Sun.COM 	/*
10257836SJohn.Forte@Sun.COM 	 * Pointer to the next LUN.
10267836SJohn.Forte@Sun.COM 	 */
10277836SJohn.Forte@Sun.COM 	struct fcp_lun		*lun_next;
10287836SJohn.Forte@Sun.COM 	/*
10299028SReed.Liu@Sun.COM 	 * lun level association with scsi_device
10307836SJohn.Forte@Sun.COM 	 */
10319028SReed.Liu@Sun.COM 	struct scsi_device	*lun_sd;
10327836SJohn.Forte@Sun.COM 	/*
10337836SJohn.Forte@Sun.COM 	 * per-Lun control flag.  A value of '1' means the LUN is managed by
10347836SJohn.Forte@Sun.COM 	 * mpxio.  A value of '0' means the LUN has been physically enumerated
10357836SJohn.Forte@Sun.COM 	 * as a child of corresponding port driver node.
10367836SJohn.Forte@Sun.COM 	 */
10377836SJohn.Forte@Sun.COM 	int			lun_mpxio;
10387836SJohn.Forte@Sun.COM 	/*
10397836SJohn.Forte@Sun.COM 	 * Length of the GUID.
10407836SJohn.Forte@Sun.COM 	 */
10417836SJohn.Forte@Sun.COM 	size_t			lun_guid_size;
10427836SJohn.Forte@Sun.COM 	/*
10437836SJohn.Forte@Sun.COM 	 * Pointer to a buffer that contains the GUID.
10447836SJohn.Forte@Sun.COM 	 */
10457836SJohn.Forte@Sun.COM 	char			*lun_guid;
10467836SJohn.Forte@Sun.COM 	/*
10477836SJohn.Forte@Sun.COM 	 * Pointer to a buffer that contains the old GUID.
10487836SJohn.Forte@Sun.COM 	 */
10497836SJohn.Forte@Sun.COM 	char			*lun_old_guid;
10507836SJohn.Forte@Sun.COM 	/*
10517836SJohn.Forte@Sun.COM 	 * Length of the old GUID
10527836SJohn.Forte@Sun.COM 	 */
10537836SJohn.Forte@Sun.COM 	size_t			lun_old_guid_size;
10547836SJohn.Forte@Sun.COM 	/*
10557836SJohn.Forte@Sun.COM 	 * Bitmap used to track the LUN discovery process.
10567836SJohn.Forte@Sun.COM 	 */
10577836SJohn.Forte@Sun.COM 	uint32_t		lun_trace;
10587836SJohn.Forte@Sun.COM 	/*
10597836SJohn.Forte@Sun.COM 	 * Bitmap representing the SCSI capabilities.
10607836SJohn.Forte@Sun.COM 	 */
10617836SJohn.Forte@Sun.COM 	uchar_t			lun_cap;
10627836SJohn.Forte@Sun.COM 	/*
10637836SJohn.Forte@Sun.COM 	 * LUN inquiry data (as returned by the INQUIRY command).
10647836SJohn.Forte@Sun.COM 	 */
10657836SJohn.Forte@Sun.COM 	struct scsi_inquiry	lun_inq;
1066*10264SZhong.Wang@Sun.COM } fcp_lun_t;
10677836SJohn.Forte@Sun.COM 
10687836SJohn.Forte@Sun.COM 
10697836SJohn.Forte@Sun.COM /*
10707836SJohn.Forte@Sun.COM  * Lun discovery tracing
10717836SJohn.Forte@Sun.COM  */
10727836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_1		0x0000001
10737836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_2		0x0000002
10747836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_3		0x0000004
10757836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_4		0x0000008
10767836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_5		0x0000010
10777836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_6		0x0000020
10787836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_7		0x0000040
10797836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_8		0x0000080
10807836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_9		0x0000100
10817836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_10	0x0000200
10827836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_11	0x0000400
10837836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_12	0x0000800
10847836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_13	0x0001000
10857836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_14	0x0002000
10867836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_15	0x0004000
10877836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_16	0x0008000
10887836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_17	0x0010000
10897836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_18	0x0020000
10907836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_19	0x0040000
10917836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_20	0x0080000
10927836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_21	0x0100000
10937836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_22	0x0200000
10947836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_23	0x0400000
10957836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_24	0x0800000
10967836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_25	0x1000000
10977836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_26	0x2000000
10987836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_27	0x4000000
10997836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE_28	0x8000000
11007836SJohn.Forte@Sun.COM 
11017836SJohn.Forte@Sun.COM 
11027836SJohn.Forte@Sun.COM #define	FCP_LUN_TRACE(plun, bit) {\
11037836SJohn.Forte@Sun.COM 	if (plun && plun->lun_tgt) {\
11047836SJohn.Forte@Sun.COM 		mutex_enter(&plun->lun_tgt->tgt_mutex);\
11057836SJohn.Forte@Sun.COM 		plun->lun_trace |= bit;\
11067836SJohn.Forte@Sun.COM 		mutex_exit(&plun->lun_tgt->tgt_mutex);\
11077836SJohn.Forte@Sun.COM 	}\
11087836SJohn.Forte@Sun.COM }
11097836SJohn.Forte@Sun.COM 
11107836SJohn.Forte@Sun.COM #define	FCP_LUN_CAP_RESET	0x01
11117836SJohn.Forte@Sun.COM 
11127836SJohn.Forte@Sun.COM /*
11137836SJohn.Forte@Sun.COM  * Lun State -- these have the same values as the target states so
11147836SJohn.Forte@Sun.COM  * that they can be interchanged (in cases where the same state occurs
11157836SJohn.Forte@Sun.COM  * for both targets and luns)
11167836SJohn.Forte@Sun.COM  */
11177836SJohn.Forte@Sun.COM 
11187836SJohn.Forte@Sun.COM #define	FCP_LUN_INIT		FCP_TGT_INIT
11197836SJohn.Forte@Sun.COM #define	FCP_LUN_BUSY		FCP_TGT_BUSY
11207836SJohn.Forte@Sun.COM #define	FCP_LUN_MARK		FCP_TGT_MARK
11217836SJohn.Forte@Sun.COM #define	FCP_LUN_OFFLINE		FCP_TGT_OFFLINE
11227836SJohn.Forte@Sun.COM #define	FCP_SCSI_LUN_TGT_INIT	0x20	/* target/LUNs all inited */
11237836SJohn.Forte@Sun.COM #define	FCP_LUN_DISAPPEARED	0x40
11247836SJohn.Forte@Sun.COM /*
11257836SJohn.Forte@Sun.COM  * Use the below flag with caution as it is can cause a delay in
11267836SJohn.Forte@Sun.COM  * fcp_scsi_start() which is in the normal I/O performance path
11277836SJohn.Forte@Sun.COM  */
11287836SJohn.Forte@Sun.COM #define	FCP_LUN_ONLINING	0x80
11297836SJohn.Forte@Sun.COM /*
11307836SJohn.Forte@Sun.COM  * Set the below flag when the DTYPE or GUID of a LUN changes during discovery
11317836SJohn.Forte@Sun.COM  */
11327836SJohn.Forte@Sun.COM #define	FCP_LUN_CHANGED	0x100
11337836SJohn.Forte@Sun.COM /*
11347836SJohn.Forte@Sun.COM  * This flag is used specifically for the special lun: lun 0.
11357836SJohn.Forte@Sun.COM  */
11367836SJohn.Forte@Sun.COM #define	FCP_LUN_DEVICE_NOT_CONNECTED	0x200
11377836SJohn.Forte@Sun.COM 
11387836SJohn.Forte@Sun.COM /*
11397836SJohn.Forte@Sun.COM  * Report Lun Format
11407836SJohn.Forte@Sun.COM  */
11417836SJohn.Forte@Sun.COM struct fcp_reportlun_resp {
11427836SJohn.Forte@Sun.COM 	uint32_t	num_lun;	/* num LUNs * 8 */
11437836SJohn.Forte@Sun.COM 	uint32_t	reserved;
11447836SJohn.Forte@Sun.COM 	longlong_t	lun_string[1];
11457836SJohn.Forte@Sun.COM };
11467836SJohn.Forte@Sun.COM 
11477836SJohn.Forte@Sun.COM /*
11487836SJohn.Forte@Sun.COM  * This structure actually represents a request executed by the hot plug task.
11497836SJohn.Forte@Sun.COM  */
11507836SJohn.Forte@Sun.COM struct fcp_hp_elem {
11517836SJohn.Forte@Sun.COM 	/*
11527836SJohn.Forte@Sun.COM 	 * FCP port concerned by the request.
11537836SJohn.Forte@Sun.COM 	 */
11547836SJohn.Forte@Sun.COM 	struct fcp_port	*port;
11557836SJohn.Forte@Sun.COM 	/*
11567836SJohn.Forte@Sun.COM 	 * LUN concerned by the request.
11577836SJohn.Forte@Sun.COM 	 */
11587836SJohn.Forte@Sun.COM 	struct fcp_lun	*lun;
11597836SJohn.Forte@Sun.COM 	/*
11607836SJohn.Forte@Sun.COM 	 * dev_info_t or mdi_pathinfo_t pointer.
11617836SJohn.Forte@Sun.COM 	 */
11627836SJohn.Forte@Sun.COM 	child_info_t		*cip;
11637836SJohn.Forte@Sun.COM 	/*
11648493SReed.Liu@Sun.COM 	 * lun_mpxio when the event is submitted
11658493SReed.Liu@Sun.COM 	 */
11668493SReed.Liu@Sun.COM 	int			old_lun_mpxio;
11678493SReed.Liu@Sun.COM 	/*
11687836SJohn.Forte@Sun.COM 	 * What to do (offline, online...).
11697836SJohn.Forte@Sun.COM 	 */
11708493SReed.Liu@Sun.COM 	int			what;
11717836SJohn.Forte@Sun.COM 	/*
11727836SJohn.Forte@Sun.COM 	 * FLags used when calling NDI fucntions.
11737836SJohn.Forte@Sun.COM 	 */
11748493SReed.Liu@Sun.COM 	int			flags;
11757836SJohn.Forte@Sun.COM 	/*
11767836SJohn.Forte@Sun.COM 	 * Link state change count when the structure was created.
11777836SJohn.Forte@Sun.COM 	 */
11787836SJohn.Forte@Sun.COM 	int			link_cnt;
11797836SJohn.Forte@Sun.COM 	/*
11807836SJohn.Forte@Sun.COM 	 * Target state change count when the structure was created.
11817836SJohn.Forte@Sun.COM 	 */
11827836SJohn.Forte@Sun.COM 	int			tgt_cnt;
11837836SJohn.Forte@Sun.COM 	/*
11847836SJohn.Forte@Sun.COM 	 * Online/Offline count when this event was queued.
11857836SJohn.Forte@Sun.COM 	 */
11867836SJohn.Forte@Sun.COM 	int			event_cnt;
11877836SJohn.Forte@Sun.COM 	/*
11887836SJohn.Forte@Sun.COM 	 * This is the flag protected by the mutex and condition variable
11897836SJohn.Forte@Sun.COM 	 * defined further in this structure.  It is the flag indicating
11907836SJohn.Forte@Sun.COM 	 * that the hot plug task is done with the treatment of the structure.
11917836SJohn.Forte@Sun.COM 	 */
11927836SJohn.Forte@Sun.COM 	int			wait;
11937836SJohn.Forte@Sun.COM 	/*
11947836SJohn.Forte@Sun.COM 	 * This is where the result of the request is returned when the sender
11957836SJohn.Forte@Sun.COM 	 * waits for the completion.
11967836SJohn.Forte@Sun.COM 	 */
11977836SJohn.Forte@Sun.COM 	int			result;
11987836SJohn.Forte@Sun.COM 	/*
11997836SJohn.Forte@Sun.COM 	 * Condition variable used when wait is true.
12007836SJohn.Forte@Sun.COM 	 */
12017836SJohn.Forte@Sun.COM 	kcondvar_t		cv;
12027836SJohn.Forte@Sun.COM 	/*
12037836SJohn.Forte@Sun.COM 	 * Mutex used in conjunction with the previous condition variable.
12047836SJohn.Forte@Sun.COM 	 */
12057836SJohn.Forte@Sun.COM 	kmutex_t		mutex;
12067836SJohn.Forte@Sun.COM };
12077836SJohn.Forte@Sun.COM 
12087836SJohn.Forte@Sun.COM 
12097836SJohn.Forte@Sun.COM struct fcp_reset_elem {
12107836SJohn.Forte@Sun.COM 	struct fcp_reset_elem	*next;
12117836SJohn.Forte@Sun.COM 	struct fcp_tgt		*tgt;
12127836SJohn.Forte@Sun.COM 	struct fcp_lun		*lun;
12137836SJohn.Forte@Sun.COM 	clock_t			timeout;
12147836SJohn.Forte@Sun.COM 	uint_t			tgt_cnt;
12157836SJohn.Forte@Sun.COM };
12167836SJohn.Forte@Sun.COM 
12177836SJohn.Forte@Sun.COM /*
12187836SJohn.Forte@Sun.COM  * This structure is used to offline targets.  It is queued in the FCP port
12197836SJohn.Forte@Sun.COM  * structure single linked list port_offline_tgts and walked by the watchdog
12207836SJohn.Forte@Sun.COM  * timer.
12217836SJohn.Forte@Sun.COM  */
12227836SJohn.Forte@Sun.COM struct fcp_tgt_elem {
12237836SJohn.Forte@Sun.COM 	/*
12247836SJohn.Forte@Sun.COM 	 * Points to the next element of the list.
12257836SJohn.Forte@Sun.COM 	 */
12267836SJohn.Forte@Sun.COM 	struct fcp_tgt_elem	*next;
12277836SJohn.Forte@Sun.COM 	/*
12287836SJohn.Forte@Sun.COM 	 * Points to the target to offline.
12297836SJohn.Forte@Sun.COM 	 */
12307836SJohn.Forte@Sun.COM 	struct fcp_tgt		*ptgt;
12317836SJohn.Forte@Sun.COM 	/*
12327836SJohn.Forte@Sun.COM 	 * Absolute time after which the target must be offlined.
12337836SJohn.Forte@Sun.COM 	 */
12347836SJohn.Forte@Sun.COM 	int			time;
12357836SJohn.Forte@Sun.COM 	/*
12367836SJohn.Forte@Sun.COM 	 * Link state change count when the structure was created.
12377836SJohn.Forte@Sun.COM 	 */
12387836SJohn.Forte@Sun.COM 	int			link_cnt;
12397836SJohn.Forte@Sun.COM 	/*
12407836SJohn.Forte@Sun.COM 	 * Target state change count when the structure was created.
12417836SJohn.Forte@Sun.COM 	 */
12427836SJohn.Forte@Sun.COM 	int			tgt_cnt;
12437836SJohn.Forte@Sun.COM 	/*
12447836SJohn.Forte@Sun.COM 	 * Flags providing information for the offline (when calling mdi or
12457836SJohn.Forte@Sun.COM 	 * ndi).
12467836SJohn.Forte@Sun.COM 	 */
12477836SJohn.Forte@Sun.COM 	int			flags;
12487836SJohn.Forte@Sun.COM };
12497836SJohn.Forte@Sun.COM 
12507836SJohn.Forte@Sun.COM /*
12517836SJohn.Forte@Sun.COM  * This structure is used to offline LUNs.  It is queued in the FCP port
12527836SJohn.Forte@Sun.COM  * structure single linked list port_offline_luns and walked by the watchdog
12537836SJohn.Forte@Sun.COM  * timer.
12547836SJohn.Forte@Sun.COM  */
12557836SJohn.Forte@Sun.COM struct fcp_lun_elem {
12567836SJohn.Forte@Sun.COM 	/*
12577836SJohn.Forte@Sun.COM 	 * Points to the next element of the list.
12587836SJohn.Forte@Sun.COM 	 */
12597836SJohn.Forte@Sun.COM 	struct fcp_lun_elem	*next;
12607836SJohn.Forte@Sun.COM 	/*
12617836SJohn.Forte@Sun.COM 	 * Points to the LUN to offline.
12627836SJohn.Forte@Sun.COM 	 */
12637836SJohn.Forte@Sun.COM 	struct fcp_lun		*plun;
12647836SJohn.Forte@Sun.COM 	/*
12657836SJohn.Forte@Sun.COM 	 * Absolute time after which the LUN must be offlined.
12667836SJohn.Forte@Sun.COM 	 */
12677836SJohn.Forte@Sun.COM 	int			time;
12687836SJohn.Forte@Sun.COM 	/*
12697836SJohn.Forte@Sun.COM 	 * Link state change count when the structure was created.
12707836SJohn.Forte@Sun.COM 	 */
12717836SJohn.Forte@Sun.COM 	int			link_cnt;
12727836SJohn.Forte@Sun.COM 	/*
12737836SJohn.Forte@Sun.COM 	 * Target state change count when the structure was created.
12747836SJohn.Forte@Sun.COM 	 */
12757836SJohn.Forte@Sun.COM 	int			tgt_cnt;
12767836SJohn.Forte@Sun.COM 	/*
12777836SJohn.Forte@Sun.COM 	 * Flags providing information for the offline (when calling mdi or
12787836SJohn.Forte@Sun.COM 	 * ndi).
12797836SJohn.Forte@Sun.COM 	 */
12807836SJohn.Forte@Sun.COM 	int			flags;
12817836SJohn.Forte@Sun.COM };
12827836SJohn.Forte@Sun.COM 
12837836SJohn.Forte@Sun.COM /*
12847836SJohn.Forte@Sun.COM  * LUN masking
12857836SJohn.Forte@Sun.COM  */
12867836SJohn.Forte@Sun.COM typedef struct fcp_black_list_entry {
12877836SJohn.Forte@Sun.COM 	/*
12887836SJohn.Forte@Sun.COM 	 * Points to the next element of the list.
12897836SJohn.Forte@Sun.COM 	 */
12907836SJohn.Forte@Sun.COM 	struct fcp_black_list_entry	*next;
12917836SJohn.Forte@Sun.COM 	/*
12927836SJohn.Forte@Sun.COM 	 * Port WWN of the target.
12937836SJohn.Forte@Sun.COM 	 */
12947836SJohn.Forte@Sun.COM 	la_wwn_t			wwn;
12957836SJohn.Forte@Sun.COM 	/*
12967836SJohn.Forte@Sun.COM 	 * LUN number which need to be masked.
12977836SJohn.Forte@Sun.COM 	 */
12987836SJohn.Forte@Sun.COM 	uint32_t			lun;
12997836SJohn.Forte@Sun.COM 	/*
13007836SJohn.Forte@Sun.COM 	 * Counter of access times.
13017836SJohn.Forte@Sun.COM 	 */
13027836SJohn.Forte@Sun.COM 	int				masked;
13037836SJohn.Forte@Sun.COM } fcp_black_list_entry_t;
13047836SJohn.Forte@Sun.COM 
1305*10264SZhong.Wang@Sun.COM #define	ADDR2FCP(ap)	((struct fcp_port *)		\
1306*10264SZhong.Wang@Sun.COM 		((ap)->a_hba_tran->tran_hba_private))
1307*10264SZhong.Wang@Sun.COM #define	ADDR2LUN(ap)	((struct fcp_lun *)				\
1308*10264SZhong.Wang@Sun.COM 		scsi_device_hba_private_get(scsi_address_device(ap)))
13097836SJohn.Forte@Sun.COM #define	CMD2PKT(cmd)	((cmd)->cmd_pkt)
13108335SChris.Horne@Sun.COM #define	PKT2CMD(pkt)	((struct fcp_pkt *)((pkt)->pkt_ha_private))
13117836SJohn.Forte@Sun.COM 
13127836SJohn.Forte@Sun.COM /*
13137836SJohn.Forte@Sun.COM  * timeout values
13147836SJohn.Forte@Sun.COM  */
13158493SReed.Liu@Sun.COM #define	FCP_ELS_TIMEOUT		20	/* 20 seconds */
13167836SJohn.Forte@Sun.COM #define	FCP_SCSI_CMD_TIMEOUT	25	/* 30 seconds */
13177836SJohn.Forte@Sun.COM #define	FCP_POLL_TIMEOUT	60	/* 60 seconds */
13187836SJohn.Forte@Sun.COM #define	FCP_TIMEOUT_DELTA	2	/* 2 seconds */
13197836SJohn.Forte@Sun.COM #define	FCP_ICMD_DEADLINE	120	/* 60 seconds */
13207836SJohn.Forte@Sun.COM #define	FCP_MAX_RETRIES		4
13217836SJohn.Forte@Sun.COM 
13227836SJohn.Forte@Sun.COM 
13237836SJohn.Forte@Sun.COM #if !defined(__lint)
13247836SJohn.Forte@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(fcp_port::port_mutex,
13257836SJohn.Forte@Sun.COM     fcp_port::port_state fcp_tgt::tgt_change_cnt
13267836SJohn.Forte@Sun.COM     fcp_port::fcp_next fcp_port::port_tgt_hash_table
13277836SJohn.Forte@Sun.COM     fcp_port::port_link_cnt fcp_port::port_reset_list
13287836SJohn.Forte@Sun.COM     fcp_port::port_tmp_cnt fcp_port::port_ipkt_list
13297836SJohn.Forte@Sun.COM     fcp_tgt::tgt_next))
13307836SJohn.Forte@Sun.COM 
13317836SJohn.Forte@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(fcp_port::port_pkt_mutex,
13327836SJohn.Forte@Sun.COM     fcp_port::port_pkt_head fcp_port::port_pkt_tail
13337836SJohn.Forte@Sun.COM     fcp_port::port_npkts))
13347836SJohn.Forte@Sun.COM 
13357836SJohn.Forte@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(fcp_tgt::tgt_mutex,
13368493SReed.Liu@Sun.COM     fcp_tgt::tgt_state	fcp_tgt::tgt_device_created
13377836SJohn.Forte@Sun.COM     fcp_tgt::tgt_icap fcp_tgt::tgt_tcap
13387836SJohn.Forte@Sun.COM     fcp_tgt::tgt_tid fcp_tgt::tgt_pd_handle fcp_tgt::tgt_tmp_cnt
13397836SJohn.Forte@Sun.COM     fcp_tgt::tgt_statec_cause fcp_lun::lun_next fcp_lun::lun_state))
13407836SJohn.Forte@Sun.COM 
13417836SJohn.Forte@Sun.COM _NOTE(LOCK_ORDER(fcp_port::fcp_mutex fcp_tgt::tgt_mutex))
13427836SJohn.Forte@Sun.COM _NOTE(LOCK_ORDER(fcp_tgt::tgt_mutex fcp_lun::lun_mutex))
13437836SJohn.Forte@Sun.COM 
13447836SJohn.Forte@Sun.COM _NOTE(MUTEX_PROTECTS_DATA(fcp_lun::lun_mutex,
13457836SJohn.Forte@Sun.COM     fcp_lun::lun_pkt_head fcp_lun::lun_pkt_tail
13467836SJohn.Forte@Sun.COM     fcp_lun::lun_cip fcp_lun::lun_mpxio))
13477836SJohn.Forte@Sun.COM 
13487836SJohn.Forte@Sun.COM _NOTE(DATA_READABLE_WITHOUT_LOCK( fcp_tgt::tgt_state))
13497836SJohn.Forte@Sun.COM _NOTE(DATA_READABLE_WITHOUT_LOCK( fcp_tgt::tgt_pd_handle))
13507836SJohn.Forte@Sun.COM 
13517836SJohn.Forte@Sun.COM _NOTE(DATA_READABLE_WITHOUT_LOCK(fcp_tgt::tgt_tid))
13527836SJohn.Forte@Sun.COM 
13537836SJohn.Forte@Sun.COM 
13547836SJohn.Forte@Sun.COM _NOTE(SCHEME_PROTECTS_DATA("Safe Data",
13557836SJohn.Forte@Sun.COM     fcp_port::port_dma_acc_attr
13567836SJohn.Forte@Sun.COM     fcp_port::port_fcp_dma fcp_port::fcp_tran
13577836SJohn.Forte@Sun.COM     fcp_port::port_ndi_events fcp_port::port_ndi_event_defs
13587836SJohn.Forte@Sun.COM     fcp_port::port_pkt_cache fcp_port::port_dip fcp_port::port_phys_state
13597836SJohn.Forte@Sun.COM     fcp_port::port_reset_action fcp_port::port_cmds_dma_flags
13607836SJohn.Forte@Sun.COM     fcp_port::port_fp_handle fcp_port::port_instance
13617836SJohn.Forte@Sun.COM     fcp_port::port_fp_modlinkage fcp_port::port_max_exch
13627836SJohn.Forte@Sun.COM     fcp_port::port_priv_pkt_len fcp_port::port_id
13637836SJohn.Forte@Sun.COM     fcp_port::port_topology fcp_port::port_deadline fcp_port::port_mpxio
13647836SJohn.Forte@Sun.COM     fcp_tgt::tgt_d_id fcp_tgt::tgt_hard_addr fcp_tgt::tgt_lun_cnt
13657836SJohn.Forte@Sun.COM     fcp_tgt::tgt_port fcp_lun::lun_num fcp_lun::lun_tgt
13667836SJohn.Forte@Sun.COM     fcp_lun::lun_type
13677836SJohn.Forte@Sun.COM     fcp_lun::lun_guid_size fcp_lun::lun_guid
13687836SJohn.Forte@Sun.COM     fcp_hp_elem::lun fcp_hp_elem::flags fcp_hp_elem::cip
13697836SJohn.Forte@Sun.COM     fcp_hp_elem::what fcp_hp_elem::tgt_cnt fcp_hp_elem::tgt_cnt
13707836SJohn.Forte@Sun.COM     fcp_hp_elem::link_cnt fcp_reset_elem fcp_pkt fcp_ipkt
13717836SJohn.Forte@Sun.COM     scsi_pkt scsi_arq_status scsi_device scsi_hba_tran scsi_cdb))
13728493SReed.Liu@Sun.COM #endif	/* __lint */
13737836SJohn.Forte@Sun.COM 
1374*10264SZhong.Wang@Sun.COM /*
1375*10264SZhong.Wang@Sun.COM  * Local variable "pptr" must exist before using these
1376*10264SZhong.Wang@Sun.COM  */
1377*10264SZhong.Wang@Sun.COM #define	FCP_CP_IN(s, d, handle, len)					\
1378*10264SZhong.Wang@Sun.COM 	{								\
1379*10264SZhong.Wang@Sun.COM 		if (!((pptr)->port_state & FCP_STATE_FCA_IS_NODMA)) {	\
1380*10264SZhong.Wang@Sun.COM 			ddi_rep_get8((handle), (uint8_t *)(d),		\
1381*10264SZhong.Wang@Sun.COM 			    (uint8_t *)(s), (len), DDI_DEV_AUTOINCR);	\
1382*10264SZhong.Wang@Sun.COM 		} else {						\
1383*10264SZhong.Wang@Sun.COM 			bcopy((s), (d), (len));				\
1384*10264SZhong.Wang@Sun.COM 		}							\
1385*10264SZhong.Wang@Sun.COM 	}
13867836SJohn.Forte@Sun.COM 
1387*10264SZhong.Wang@Sun.COM #define	FCP_CP_OUT(s, d, handle, len)				\
1388*10264SZhong.Wang@Sun.COM 	{								\
1389*10264SZhong.Wang@Sun.COM 		if (!((pptr)->port_state & FCP_STATE_FCA_IS_NODMA)) {	\
1390*10264SZhong.Wang@Sun.COM 			ddi_rep_put8((handle), (uint8_t *)(s),		\
1391*10264SZhong.Wang@Sun.COM 			    (uint8_t *)(d), (len), DDI_DEV_AUTOINCR);	\
1392*10264SZhong.Wang@Sun.COM 		} else {						\
1393*10264SZhong.Wang@Sun.COM 			bcopy((s), (d), (len));				\
1394*10264SZhong.Wang@Sun.COM 		}							\
1395*10264SZhong.Wang@Sun.COM 	}
13967836SJohn.Forte@Sun.COM 
13977836SJohn.Forte@Sun.COM #define	FCP_ONLINE			0x1
13987836SJohn.Forte@Sun.COM #define	FCP_OFFLINE			0x2
13997836SJohn.Forte@Sun.COM #define	FCP_MPXIO_PATH_CLEAR_BUSY	0x3
14007836SJohn.Forte@Sun.COM #define	FCP_MPXIO_PATH_SET_BUSY		0x4
14017836SJohn.Forte@Sun.COM 
14027836SJohn.Forte@Sun.COM #define	FCP_IDLE			0x00
14037836SJohn.Forte@Sun.COM #define	FCP_OPEN			0x01
14047836SJohn.Forte@Sun.COM #define	FCP_EXCL			0x02
14057836SJohn.Forte@Sun.COM #define	FCP_BUSY			0x04
14067836SJohn.Forte@Sun.COM 
14077836SJohn.Forte@Sun.COM #define	LFA(x)				(x & 0xFFFF00)
14087836SJohn.Forte@Sun.COM #define	FCP_SET				1
14097836SJohn.Forte@Sun.COM #define	FCP_RESET			0
14107836SJohn.Forte@Sun.COM 
14117836SJohn.Forte@Sun.COM /* init() and attach() wait timeout values (in usecs) */
14127836SJohn.Forte@Sun.COM #define	FCP_INIT_WAIT_TIMEOUT		60000000	/* 60 seconds */
14137836SJohn.Forte@Sun.COM #define	FCP_ATTACH_WAIT_TIMEOUT		10000000	/* 10 seconds */
14147836SJohn.Forte@Sun.COM 
14157836SJohn.Forte@Sun.COM #ifdef	TRUE
14167836SJohn.Forte@Sun.COM #undef	TRUE
14177836SJohn.Forte@Sun.COM #endif
14187836SJohn.Forte@Sun.COM #define	TRUE			1
14197836SJohn.Forte@Sun.COM 
14207836SJohn.Forte@Sun.COM #ifdef	FALSE
14217836SJohn.Forte@Sun.COM #undef	FALSE
14227836SJohn.Forte@Sun.COM #endif
14237836SJohn.Forte@Sun.COM #define	FALSE			0
14247836SJohn.Forte@Sun.COM 
14257836SJohn.Forte@Sun.COM #define	UNDEFINED		-1
14267836SJohn.Forte@Sun.COM 
14277836SJohn.Forte@Sun.COM /* for softstate */
14287836SJohn.Forte@Sun.COM #define	FCP_INIT_ITEMS	5
14297836SJohn.Forte@Sun.COM 
14307836SJohn.Forte@Sun.COM #ifdef	__cplusplus
14317836SJohn.Forte@Sun.COM }
14327836SJohn.Forte@Sun.COM #endif
14337836SJohn.Forte@Sun.COM 
14347836SJohn.Forte@Sun.COM #endif	/* _FCPVAR_H */
1435