xref: /onnv-gate/usr/src/uts/common/sys/scsi/adapters/pmcs/pmcs.h (revision 12120:8a783f4db0ad)
110696SDavid.Hollister@Sun.COM /*
210696SDavid.Hollister@Sun.COM  * CDDL HEADER START
310696SDavid.Hollister@Sun.COM  *
410696SDavid.Hollister@Sun.COM  * The contents of this file are subject to the terms of the
510696SDavid.Hollister@Sun.COM  * Common Development and Distribution License (the "License").
610696SDavid.Hollister@Sun.COM  * You may not use this file except in compliance with the License.
710696SDavid.Hollister@Sun.COM  *
810696SDavid.Hollister@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910696SDavid.Hollister@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1010696SDavid.Hollister@Sun.COM  * See the License for the specific language governing permissions
1110696SDavid.Hollister@Sun.COM  * and limitations under the License.
1210696SDavid.Hollister@Sun.COM  *
1310696SDavid.Hollister@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1410696SDavid.Hollister@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510696SDavid.Hollister@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1610696SDavid.Hollister@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1710696SDavid.Hollister@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1810696SDavid.Hollister@Sun.COM  *
1910696SDavid.Hollister@Sun.COM  * CDDL HEADER END
2012060SDavid.Hollister@Sun.COM  */
2112060SDavid.Hollister@Sun.COM /*
2212060SDavid.Hollister@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2310696SDavid.Hollister@Sun.COM  */
2410696SDavid.Hollister@Sun.COM /*
2510696SDavid.Hollister@Sun.COM  * This file is the principle header file for the PMCS driver
2610696SDavid.Hollister@Sun.COM  */
2710696SDavid.Hollister@Sun.COM #ifndef _PMCS_H
2810696SDavid.Hollister@Sun.COM #define	_PMCS_H
2910696SDavid.Hollister@Sun.COM #ifdef	__cplusplus
3010696SDavid.Hollister@Sun.COM extern "C" {
3110696SDavid.Hollister@Sun.COM #endif
3210696SDavid.Hollister@Sun.COM 
3310696SDavid.Hollister@Sun.COM 
3410696SDavid.Hollister@Sun.COM #include <sys/cpuvar.h>
3510696SDavid.Hollister@Sun.COM #include <sys/ddi.h>
3610696SDavid.Hollister@Sun.COM #include <sys/sunddi.h>
3710696SDavid.Hollister@Sun.COM #include <sys/modctl.h>
3810696SDavid.Hollister@Sun.COM #include <sys/pci.h>
3910696SDavid.Hollister@Sun.COM #include <sys/pcie.h>
4011694SDavid.Hollister@Sun.COM #include <sys/file.h>
4110696SDavid.Hollister@Sun.COM #include <sys/isa_defs.h>
4210696SDavid.Hollister@Sun.COM #include <sys/sunmdi.h>
4310696SDavid.Hollister@Sun.COM #include <sys/mdi_impldefs.h>
4410696SDavid.Hollister@Sun.COM #include <sys/scsi/scsi.h>
4510696SDavid.Hollister@Sun.COM #include <sys/scsi/impl/scsi_reset_notify.h>
4611052SChris.Horne@Sun.COM #include <sys/scsi/impl/scsi_sas.h>
4711052SChris.Horne@Sun.COM #include <sys/scsi/impl/smp_transport.h>
4810696SDavid.Hollister@Sun.COM #include <sys/scsi/generic/sas.h>
4911052SChris.Horne@Sun.COM #include <sys/scsi/generic/smp_frames.h>
5010696SDavid.Hollister@Sun.COM #include <sys/atomic.h>
5110696SDavid.Hollister@Sun.COM #include <sys/byteorder.h>
5211241SDavid.Hollister@Sun.COM #include <sys/sysmacros.h>
5310696SDavid.Hollister@Sun.COM #include <sys/bitmap.h>
5410696SDavid.Hollister@Sun.COM #include <sys/queue.h>
5510696SDavid.Hollister@Sun.COM #include <sys/sdt.h>
5610696SDavid.Hollister@Sun.COM #include <sys/ddifm.h>
5710696SDavid.Hollister@Sun.COM #include <sys/fm/protocol.h>
5810696SDavid.Hollister@Sun.COM #include <sys/fm/util.h>
5910696SDavid.Hollister@Sun.COM #include <sys/fm/io/ddi.h>
6010696SDavid.Hollister@Sun.COM #include <sys/scsi/impl/spc3_types.h>
6110696SDavid.Hollister@Sun.COM 
6210696SDavid.Hollister@Sun.COM typedef struct pmcs_hw pmcs_hw_t;
6310696SDavid.Hollister@Sun.COM typedef struct pmcs_iport pmcs_iport_t;
6410696SDavid.Hollister@Sun.COM typedef struct pmcs_phy pmcs_phy_t;
6510696SDavid.Hollister@Sun.COM typedef struct lsas_cmd lsas_cmd_t;
6610696SDavid.Hollister@Sun.COM typedef struct lsas_result lsas_result_t;
6710696SDavid.Hollister@Sun.COM typedef struct lsata_cmd lsata_cmd_t;
6810696SDavid.Hollister@Sun.COM typedef struct lsata_result lsata_result_t;
6910696SDavid.Hollister@Sun.COM typedef struct pmcwork pmcwork_t;
7010696SDavid.Hollister@Sun.COM typedef struct pmcs_cmd pmcs_cmd_t;
7110696SDavid.Hollister@Sun.COM typedef	struct pmcs_xscsi pmcs_xscsi_t;
7210696SDavid.Hollister@Sun.COM typedef	struct pmcs_lun pmcs_lun_t;
7310696SDavid.Hollister@Sun.COM typedef struct pmcs_chunk pmcs_chunk_t;
7410696SDavid.Hollister@Sun.COM 
7510696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_param.h>
7610696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_reg.h>
7710696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_mpi.h>
7810696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_iomb.h>
7910696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_sgl.h>
8010696SDavid.Hollister@Sun.COM 
8110696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/ata.h>
8210696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_def.h>
8310696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_proto.h>
8410696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_scsa.h>
8510696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs_smhba.h>
8610696SDavid.Hollister@Sun.COM 
8710696SDavid.Hollister@Sun.COM #define	PMCS_MAX_UA_SIZE	32
8810696SDavid.Hollister@Sun.COM 
8910696SDavid.Hollister@Sun.COM struct pmcs_xscsi {
9010696SDavid.Hollister@Sun.COM 	uint32_t
9110696SDavid.Hollister@Sun.COM 		ca		:	1,		/* SATA specific */
9210696SDavid.Hollister@Sun.COM 		ncq		:	1,		/* SATA specific */
9310696SDavid.Hollister@Sun.COM 		pio		:	1,		/* SATA specific */
9410696SDavid.Hollister@Sun.COM 		special_needed	:	1,		/* SATA specific */
9510696SDavid.Hollister@Sun.COM 		special_running	:	1,		/* SATA specific */
9610696SDavid.Hollister@Sun.COM 		reset_success	:	1,		/* last reset ok */
9710696SDavid.Hollister@Sun.COM 		reset_wait	:	1,		/* wait for reset */
9810696SDavid.Hollister@Sun.COM 		resetting	:	1,		/* now resetting */
9910696SDavid.Hollister@Sun.COM 		recover_wait	:	1,		/* wait for recovery */
10010696SDavid.Hollister@Sun.COM 		recovering	:	1,		/* now recovering */
10110696SDavid.Hollister@Sun.COM 		event_recovery	:	1,		/* event recovery */
10210696SDavid.Hollister@Sun.COM 		draining	:	1,
10310696SDavid.Hollister@Sun.COM 		new		:	1,
10410696SDavid.Hollister@Sun.COM 		assigned	:	1,
10510696SDavid.Hollister@Sun.COM 		dev_gone	:	1,
10610696SDavid.Hollister@Sun.COM 		phy_addressable	:	1,		/* Direct attach SATA */
10710696SDavid.Hollister@Sun.COM 		dev_state	:	4;
10810696SDavid.Hollister@Sun.COM 	uint16_t			maxdepth;
10910696SDavid.Hollister@Sun.COM 	uint16_t			qdepth;
11011347SRamana.Srikanth@Sun.COM 	uint16_t			actv_cnt;	/* Pkts ON CHIP */
11111347SRamana.Srikanth@Sun.COM 	uint16_t			actv_pkts;	/* Pkts in driver */
11210696SDavid.Hollister@Sun.COM 	uint16_t			target_num;
11310696SDavid.Hollister@Sun.COM 	/* statlock protects both target stats and the special queue (sq) */
11410696SDavid.Hollister@Sun.COM 	kmutex_t			statlock;
11510696SDavid.Hollister@Sun.COM 	int32_t				ref_count;
11610696SDavid.Hollister@Sun.COM 	dev_info_t 			*dip;	/* Solaris device dip */
11710696SDavid.Hollister@Sun.COM 	pmcs_phy_t			*phy;
11810696SDavid.Hollister@Sun.COM 	STAILQ_HEAD(wqh, pmcs_cmd)	wq;
11910696SDavid.Hollister@Sun.COM 	pmcs_cmd_t			*wq_recovery_tail;	/* See below */
12010696SDavid.Hollister@Sun.COM 	kmutex_t			wqlock;
12110696SDavid.Hollister@Sun.COM 	STAILQ_HEAD(aqh, pmcs_cmd)	aq;
12210696SDavid.Hollister@Sun.COM 	kmutex_t			aqlock;
12310696SDavid.Hollister@Sun.COM 	STAILQ_HEAD(sqh, pmcs_cmd)	sq;		/* SATA specific */
12410696SDavid.Hollister@Sun.COM 	uint32_t			tagmap;		/* SATA specific */
12510696SDavid.Hollister@Sun.COM 	pmcs_hw_t			*pwp;
12610696SDavid.Hollister@Sun.COM 	ddi_soft_state_bystr		*lun_sstate;
12710696SDavid.Hollister@Sun.COM 	uint64_t			capacity;	/* SATA specific */
12810696SDavid.Hollister@Sun.COM 	char				unit_address[PMCS_MAX_UA_SIZE];
12910696SDavid.Hollister@Sun.COM 	kcondvar_t			reset_cv;
13010696SDavid.Hollister@Sun.COM 	kcondvar_t			abort_cv;
13110696SDavid.Hollister@Sun.COM 	char				*ua;
13210696SDavid.Hollister@Sun.COM 	pmcs_dtype_t			dtype;
13311501SDavid.Hollister@Sun.COM 	list_t				lun_list;	/* list of LUNs */
13411307SDavid.Hollister@Sun.COM 	struct smp_device		*smpd;		/* Ptr to smp_device */
13510696SDavid.Hollister@Sun.COM };
13610696SDavid.Hollister@Sun.COM 
13710696SDavid.Hollister@Sun.COM /*
13810696SDavid.Hollister@Sun.COM  * wq_recovery_tail in the pmcs_xscsi structure is a pointer to a command in
13910696SDavid.Hollister@Sun.COM  * the wait queue (wq).  That pointer is the last command in the wait queue
14010696SDavid.Hollister@Sun.COM  * that needs to be reissued after device state recovery is complete.  Commands
14110696SDavid.Hollister@Sun.COM  * that need to be retried are reinserted into the wq after wq_recovery_tail
14210696SDavid.Hollister@Sun.COM  * to maintain the order in which the commands were originally submitted.
14310696SDavid.Hollister@Sun.COM  */
14410696SDavid.Hollister@Sun.COM 
14510696SDavid.Hollister@Sun.COM #define	PMCS_INVALID_TARGET_NUM		(uint16_t)-1
14610696SDavid.Hollister@Sun.COM 
14710696SDavid.Hollister@Sun.COM #define	PMCS_TGT_WAIT_QUEUE		0x01
14810696SDavid.Hollister@Sun.COM #define	PMCS_TGT_ACTIVE_QUEUE		0x02
14910696SDavid.Hollister@Sun.COM #define	PMCS_TGT_SPECIAL_QUEUE		0x04
15010696SDavid.Hollister@Sun.COM #define	PMCS_TGT_ALL_QUEUES		0xff
15110696SDavid.Hollister@Sun.COM 
15210696SDavid.Hollister@Sun.COM /*
15310696SDavid.Hollister@Sun.COM  * LUN representation.  Just a LUN (number) and pointer to the target
15410696SDavid.Hollister@Sun.COM  * structure (pmcs_xscsi).
15510696SDavid.Hollister@Sun.COM  */
15610696SDavid.Hollister@Sun.COM 
15710696SDavid.Hollister@Sun.COM struct pmcs_lun {
15811501SDavid.Hollister@Sun.COM 	list_node_t		lun_list_next;
15911501SDavid.Hollister@Sun.COM 	pmcs_xscsi_t		*target;
16011501SDavid.Hollister@Sun.COM 	struct scsi_device	*sd;
16111501SDavid.Hollister@Sun.COM 	uint64_t		lun_num;	/* lun64 */
16211501SDavid.Hollister@Sun.COM 	scsi_lun_t		scsi_lun;	/* Wire format */
16311501SDavid.Hollister@Sun.COM 	char			unit_address[PMCS_MAX_UA_SIZE];
16410696SDavid.Hollister@Sun.COM };
16510696SDavid.Hollister@Sun.COM 
16610696SDavid.Hollister@Sun.COM /*
16710696SDavid.Hollister@Sun.COM  * Interrupt coalescing values
16810696SDavid.Hollister@Sun.COM  */
16910696SDavid.Hollister@Sun.COM #define	PMCS_MAX_IO_COMPS_PER_INTR	12
17010696SDavid.Hollister@Sun.COM #define	PMCS_MAX_IO_COMPS_HIWAT_SHIFT	6
17110696SDavid.Hollister@Sun.COM #define	PMCS_MAX_IO_COMPS_LOWAT_SHIFT	10
17210696SDavid.Hollister@Sun.COM #define	PMCS_QUANTUM_TIME_USECS		(1000000 / 10)	/* 1/10th sec. */
17310696SDavid.Hollister@Sun.COM #define	PMCS_MAX_COAL_TIMER		0x200	/* Don't set > than this */
17410696SDavid.Hollister@Sun.COM #define	PMCS_MAX_CQ_THREADS		4
17510696SDavid.Hollister@Sun.COM #define	PMCS_COAL_TIMER_GRAN		2	/* Go up/down by 2 usecs */
17610696SDavid.Hollister@Sun.COM #define	PMCS_INTR_THRESHOLD(x)		((x) * 6 / 10)
17710696SDavid.Hollister@Sun.COM 
17810696SDavid.Hollister@Sun.COM /*
17910696SDavid.Hollister@Sun.COM  * This structure is used to maintain state with regard to I/O interrupt
18010696SDavid.Hollister@Sun.COM  * coalescing.
18110696SDavid.Hollister@Sun.COM  */
18210696SDavid.Hollister@Sun.COM 
18310696SDavid.Hollister@Sun.COM typedef struct pmcs_io_intr_coal_s {
18410696SDavid.Hollister@Sun.COM 	hrtime_t	nsecs_between_intrs;
18510696SDavid.Hollister@Sun.COM 	hrtime_t	last_io_comp;
18610696SDavid.Hollister@Sun.COM 	clock_t		quantum;
18710696SDavid.Hollister@Sun.COM 	uint32_t	num_io_completions;
18810696SDavid.Hollister@Sun.COM 	uint32_t	num_intrs;
18910696SDavid.Hollister@Sun.COM 	uint32_t	max_io_completions;
19010696SDavid.Hollister@Sun.COM 	uint32_t	intr_latency;
19110696SDavid.Hollister@Sun.COM 	uint32_t	intr_threshold;
19210696SDavid.Hollister@Sun.COM 	uint16_t	intr_coal_timer;
19310696SDavid.Hollister@Sun.COM 	boolean_t	timer_on;
19410696SDavid.Hollister@Sun.COM 	boolean_t	stop_thread;
19510696SDavid.Hollister@Sun.COM 	boolean_t	int_cleared;
19610696SDavid.Hollister@Sun.COM } pmcs_io_intr_coal_t;
19710696SDavid.Hollister@Sun.COM 
19810696SDavid.Hollister@Sun.COM typedef struct pmcs_cq_thr_info_s {
19910696SDavid.Hollister@Sun.COM 	kthread_t	*cq_thread;
20010696SDavid.Hollister@Sun.COM 	kmutex_t	cq_thr_lock;
20110696SDavid.Hollister@Sun.COM 	kcondvar_t	cq_cv;
20210696SDavid.Hollister@Sun.COM 	pmcs_hw_t	*cq_pwp;
20310696SDavid.Hollister@Sun.COM } pmcs_cq_thr_info_t;
20410696SDavid.Hollister@Sun.COM 
20510696SDavid.Hollister@Sun.COM typedef struct pmcs_cq_info_s {
20610696SDavid.Hollister@Sun.COM 	uint32_t		cq_threads;
20710696SDavid.Hollister@Sun.COM 	uint32_t		cq_next_disp_thr;
20810696SDavid.Hollister@Sun.COM 	boolean_t		cq_stop;
20910696SDavid.Hollister@Sun.COM 	pmcs_cq_thr_info_t	*cq_thr_info;
21010696SDavid.Hollister@Sun.COM } pmcs_cq_info_t;
21110696SDavid.Hollister@Sun.COM 
21210696SDavid.Hollister@Sun.COM typedef struct pmcs_iocomp_cb_s {
21310696SDavid.Hollister@Sun.COM 	pmcwork_t		*pwrk;
21410696SDavid.Hollister@Sun.COM 	char			iomb[PMCS_QENTRY_SIZE << 1];
21510696SDavid.Hollister@Sun.COM 	struct pmcs_iocomp_cb_s	*next;
21610696SDavid.Hollister@Sun.COM } pmcs_iocomp_cb_t;
21710696SDavid.Hollister@Sun.COM 
21810696SDavid.Hollister@Sun.COM typedef struct pmcs_iqp_trace_s {
21910696SDavid.Hollister@Sun.COM 	char		*head;
22010696SDavid.Hollister@Sun.COM 	char		*curpos;
22110696SDavid.Hollister@Sun.COM 	uint32_t	size_left;
22210696SDavid.Hollister@Sun.COM } pmcs_iqp_trace_t;
22310696SDavid.Hollister@Sun.COM 
22410696SDavid.Hollister@Sun.COM /*
22510696SDavid.Hollister@Sun.COM  * Used by string-based softstate as hint to possible size.
22610696SDavid.Hollister@Sun.COM  */
22710696SDavid.Hollister@Sun.COM 
22810696SDavid.Hollister@Sun.COM #define	PMCS_TGT_SSTATE_SZ		64
22910696SDavid.Hollister@Sun.COM #define	PMCS_LUN_SSTATE_SZ		4
23010696SDavid.Hollister@Sun.COM 
23110696SDavid.Hollister@Sun.COM /*
23210696SDavid.Hollister@Sun.COM  * HBA iport node softstate
23310696SDavid.Hollister@Sun.COM  */
23411347SRamana.Srikanth@Sun.COM #define	PMCS_IPORT_INVALID_PORT_ID	0xf
23510696SDavid.Hollister@Sun.COM 
23610696SDavid.Hollister@Sun.COM struct pmcs_iport {
23710696SDavid.Hollister@Sun.COM 	kmutex_t	lock;		/* iport lock */
23810696SDavid.Hollister@Sun.COM 	list_node_t	list_node;	/* list node for pwp->iports list_t */
23910696SDavid.Hollister@Sun.COM 	kmutex_t	refcnt_lock;	/* refcnt lock */
24010696SDavid.Hollister@Sun.COM 	kcondvar_t	refcnt_cv;	/* refcnt cv */
24110696SDavid.Hollister@Sun.COM 	int		refcnt;		/* refcnt for this iport */
24210696SDavid.Hollister@Sun.COM 	dev_info_t	*dip;		/* iport dip */
24310696SDavid.Hollister@Sun.COM 	pmcs_hw_t	*pwp;		/* back pointer to HBA state */
24410696SDavid.Hollister@Sun.COM 	pmcs_phy_t	*pptr;		/* pointer to this port's primary phy */
24510696SDavid.Hollister@Sun.COM 	enum {				/* unit address state in the phymap */
24610696SDavid.Hollister@Sun.COM 		UA_INACTIVE,
24710696SDavid.Hollister@Sun.COM 		UA_PEND_ACTIVATE,
24810696SDavid.Hollister@Sun.COM 		UA_ACTIVE,
24910696SDavid.Hollister@Sun.COM 		UA_PEND_DEACTIVATE
25010696SDavid.Hollister@Sun.COM 	} ua_state;
25110696SDavid.Hollister@Sun.COM 	char		*ua;		/* unit address (phy mask) */
25210696SDavid.Hollister@Sun.COM 	int		portid;		/* portid */
25310696SDavid.Hollister@Sun.COM 	int		report_skip;	/* skip or report during discovery */
25410696SDavid.Hollister@Sun.COM 	list_t		phys;		/* list of phys on this port */
25510696SDavid.Hollister@Sun.COM 	int		nphy;		/* number of phys in this port */
25610696SDavid.Hollister@Sun.COM 	scsi_hba_tgtmap_t	*iss_tgtmap;	/* tgtmap */
25710696SDavid.Hollister@Sun.COM 	ddi_soft_state_bystr	*tgt_sstate;	/* tgt softstate */
25811267SJesse.Butler@Sun.COM 	/* SMP serialization */
25911267SJesse.Butler@Sun.COM 	kmutex_t	smp_lock;
26011267SJesse.Butler@Sun.COM 	kcondvar_t	smp_cv;
26111267SJesse.Butler@Sun.COM 	boolean_t	smp_active;
26211267SJesse.Butler@Sun.COM 	kthread_t	*smp_active_thread;
26310696SDavid.Hollister@Sun.COM };
26410696SDavid.Hollister@Sun.COM 
26510696SDavid.Hollister@Sun.COM struct pmcs_chunk {
26610696SDavid.Hollister@Sun.COM 	pmcs_chunk_t		*next;
26710696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	acc_handle;
26810696SDavid.Hollister@Sun.COM 	ddi_dma_handle_t	dma_handle;
26910696SDavid.Hollister@Sun.COM 	uint8_t			*addrp;
27010696SDavid.Hollister@Sun.COM 	uint64_t		dma_addr;
27110696SDavid.Hollister@Sun.COM };
27210696SDavid.Hollister@Sun.COM 
27310696SDavid.Hollister@Sun.COM /*
27410696SDavid.Hollister@Sun.COM  * HBA node (i.e. non-iport) softstate
27510696SDavid.Hollister@Sun.COM  */
27610696SDavid.Hollister@Sun.COM struct pmcs_hw {
27710696SDavid.Hollister@Sun.COM 	/*
27810696SDavid.Hollister@Sun.COM 	 * Identity
27910696SDavid.Hollister@Sun.COM 	 */
28010696SDavid.Hollister@Sun.COM 	dev_info_t	*dip;
28110696SDavid.Hollister@Sun.COM 
28210696SDavid.Hollister@Sun.COM 	/*
28310696SDavid.Hollister@Sun.COM 	 * 16 possible initiator PHY WWNs
28410696SDavid.Hollister@Sun.COM 	 */
28510696SDavid.Hollister@Sun.COM 	uint64_t	sas_wwns[PMCS_MAX_PORTS];
28610696SDavid.Hollister@Sun.COM 
28710696SDavid.Hollister@Sun.COM 	/*
28810696SDavid.Hollister@Sun.COM 	 * Card State
28910696SDavid.Hollister@Sun.COM 	 */
29010696SDavid.Hollister@Sun.COM 	enum pwpstate {
29110696SDavid.Hollister@Sun.COM 		STATE_NIL,
29210696SDavid.Hollister@Sun.COM 		STATE_PROBING,
29310696SDavid.Hollister@Sun.COM 		STATE_RUNNING,
29410696SDavid.Hollister@Sun.COM 		STATE_UNPROBING,
29511692SJesse.Butler@Sun.COM 		STATE_IN_RESET,
29610696SDavid.Hollister@Sun.COM 		STATE_DEAD
29710696SDavid.Hollister@Sun.COM 	} state;
29810696SDavid.Hollister@Sun.COM 
29911692SJesse.Butler@Sun.COM 	/*
30011692SJesse.Butler@Sun.COM 	 * Last reason for a soft reset
30111692SJesse.Butler@Sun.COM 	 */
30211692SJesse.Butler@Sun.COM 	enum pwp_last_reset_reason {
30311692SJesse.Butler@Sun.COM 		PMCS_LAST_RST_UNINIT,
30411692SJesse.Butler@Sun.COM 		PMCS_LAST_RST_ATTACH,
30511692SJesse.Butler@Sun.COM 		PMCS_LAST_RST_FW_UPGRADE,
30611692SJesse.Butler@Sun.COM 		PMCS_LAST_RST_FATAL_ERROR,
30711692SJesse.Butler@Sun.COM 		PMCS_LAST_RST_STALL,
30811692SJesse.Butler@Sun.COM 		PMCS_LAST_RST_QUIESCE,
30911692SJesse.Butler@Sun.COM 		PMCS_LAST_RST_DETACH
31011692SJesse.Butler@Sun.COM 	} last_reset_reason;
31111692SJesse.Butler@Sun.COM 
31210696SDavid.Hollister@Sun.COM 	uint32_t
31310696SDavid.Hollister@Sun.COM 		fw_disable_update	: 1,
31410696SDavid.Hollister@Sun.COM 		fw_force_update		: 1,
31510696SDavid.Hollister@Sun.COM 		blocked			: 1,
31610696SDavid.Hollister@Sun.COM 		stuck			: 1,
31710696SDavid.Hollister@Sun.COM 		locks_initted		: 1,
31810696SDavid.Hollister@Sun.COM 		mpi_table_setup		: 1,
31910696SDavid.Hollister@Sun.COM 		hba_attached		: 1,
32010696SDavid.Hollister@Sun.COM 		iports_attached		: 1,
32110696SDavid.Hollister@Sun.COM 		suspended		: 1,
32210696SDavid.Hollister@Sun.COM 		separate_ports		: 1,
32310696SDavid.Hollister@Sun.COM 		fwlog			: 4,
32410696SDavid.Hollister@Sun.COM 		phymode			: 3,
32510696SDavid.Hollister@Sun.COM 		physpeed		: 3,
32610696SDavid.Hollister@Sun.COM 		resource_limited	: 1,
32710696SDavid.Hollister@Sun.COM 		configuring		: 1,
32811692SJesse.Butler@Sun.COM 		ds_err_recovering	: 1,
32911694SDavid.Hollister@Sun.COM 		quiesced		: 1,
33011980SDavid.Hollister@Sun.COM 		fwlog_file		: 1,
33111980SDavid.Hollister@Sun.COM 		fw_active_img		: 1;	/* 1='A', 0='B' */
33210696SDavid.Hollister@Sun.COM 
33310696SDavid.Hollister@Sun.COM 	/*
33410696SDavid.Hollister@Sun.COM 	 * This HBA instance's iportmap and list of iport states.
33510696SDavid.Hollister@Sun.COM 	 * Note: iports_lock protects iports, iports_attached, and
33610696SDavid.Hollister@Sun.COM 	 * num_iports on the HBA softstate.
33710696SDavid.Hollister@Sun.COM 	 */
33810696SDavid.Hollister@Sun.COM 	krwlock_t		iports_lock;
33910696SDavid.Hollister@Sun.COM 	scsi_hba_iportmap_t	*hss_iportmap;
34010696SDavid.Hollister@Sun.COM 	list_t			iports;
34110696SDavid.Hollister@Sun.COM 	int			num_iports;
34210696SDavid.Hollister@Sun.COM 
34310696SDavid.Hollister@Sun.COM 	sas_phymap_t		*hss_phymap;
34410696SDavid.Hollister@Sun.COM 	int			phymap_active;
34510696SDavid.Hollister@Sun.COM 
34610696SDavid.Hollister@Sun.COM 	/*
34710696SDavid.Hollister@Sun.COM 	 * Locks
34810696SDavid.Hollister@Sun.COM 	 */
34910696SDavid.Hollister@Sun.COM 	kmutex_t	lock;
35010696SDavid.Hollister@Sun.COM 	kmutex_t	dma_lock;
35110696SDavid.Hollister@Sun.COM 	kmutex_t	axil_lock;
35210696SDavid.Hollister@Sun.COM 	kcondvar_t	drain_cv;
35310696SDavid.Hollister@Sun.COM 
35410696SDavid.Hollister@Sun.COM 	/*
35510696SDavid.Hollister@Sun.COM 	 * FMA Capabilities
35610696SDavid.Hollister@Sun.COM 	 */
35710696SDavid.Hollister@Sun.COM 	int		fm_capabilities;
35810696SDavid.Hollister@Sun.COM 
35910696SDavid.Hollister@Sun.COM 	/*
36010696SDavid.Hollister@Sun.COM 	 * Register Access Handles
36110696SDavid.Hollister@Sun.COM 	 */
36210696SDavid.Hollister@Sun.COM 	ddi_device_acc_attr_t 	dev_acc_attr;
36310696SDavid.Hollister@Sun.COM 	ddi_device_acc_attr_t	reg_acc_attr;
36410696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t 	pci_acc_handle;
36510696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t 	msg_acc_handle;
36610696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t 	top_acc_handle;
36710696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	mpi_acc_handle;
36810696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	gsm_acc_handle;
36910696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	iqp_acchdls[PMCS_MAX_IQ];
37010696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	oqp_acchdls[PMCS_MAX_IQ];
37110696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	cip_acchdls;
37210696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	fwlog_acchdl;
37310696SDavid.Hollister@Sun.COM 	ddi_acc_handle_t	regdump_acchdl;
37410696SDavid.Hollister@Sun.COM 
37510696SDavid.Hollister@Sun.COM 	/*
37610696SDavid.Hollister@Sun.COM 	 * DMA Handles
37710696SDavid.Hollister@Sun.COM 	 */
37810696SDavid.Hollister@Sun.COM 	ddi_dma_attr_t		iqp_dma_attr;
37910696SDavid.Hollister@Sun.COM 	ddi_dma_attr_t		oqp_dma_attr;
38010696SDavid.Hollister@Sun.COM 	ddi_dma_attr_t		cip_dma_attr;
38110696SDavid.Hollister@Sun.COM 	ddi_dma_attr_t		fwlog_dma_attr;
38210696SDavid.Hollister@Sun.COM 	ddi_dma_attr_t		regdump_dma_attr;
38310696SDavid.Hollister@Sun.COM 	ddi_dma_handle_t 	iqp_handles[PMCS_MAX_IQ];
38410696SDavid.Hollister@Sun.COM 	ddi_dma_handle_t 	oqp_handles[PMCS_MAX_OQ];
38510696SDavid.Hollister@Sun.COM 	ddi_dma_handle_t	cip_handles;
38610696SDavid.Hollister@Sun.COM 	ddi_dma_handle_t	fwlog_hndl;
38710696SDavid.Hollister@Sun.COM 	ddi_dma_handle_t	regdump_hndl;
38810696SDavid.Hollister@Sun.COM 
38910696SDavid.Hollister@Sun.COM 	/*
39010696SDavid.Hollister@Sun.COM 	 * Register Pointers
39110696SDavid.Hollister@Sun.COM 	 */
39210696SDavid.Hollister@Sun.COM 	uint32_t	*msg_regs;	/* message unit registers */
39310696SDavid.Hollister@Sun.COM 	uint32_t	*top_regs;	/* top unit registers */
39410696SDavid.Hollister@Sun.COM 	uint32_t	*mpi_regs;	/* message passing unit registers */
39510696SDavid.Hollister@Sun.COM 	uint32_t	*gsm_regs;	/* GSM registers */
39610696SDavid.Hollister@Sun.COM 
39710696SDavid.Hollister@Sun.COM 	/*
39810696SDavid.Hollister@Sun.COM 	 * Message Passing and other offsets.
39910696SDavid.Hollister@Sun.COM 	 *
40010696SDavid.Hollister@Sun.COM 	 * mpi_offset is the offset within the fourth register set (mpi_regs)
40110696SDavid.Hollister@Sun.COM 	 * that contains the base of the MPI structures. Since this is actually
40210696SDavid.Hollister@Sun.COM 	 * set by the card firmware, it can change from startup to startup.
40310696SDavid.Hollister@Sun.COM 	 *
40410696SDavid.Hollister@Sun.COM 	 * The other offsets (gst, iqc, oqc) are for similar tables in
40510696SDavid.Hollister@Sun.COM 	 * MPI space, typically only accessed during setup.
40610696SDavid.Hollister@Sun.COM 	 */
40710696SDavid.Hollister@Sun.COM 	uint32_t	mpi_offset;
40810696SDavid.Hollister@Sun.COM 	uint32_t	mpi_gst_offset;
40910696SDavid.Hollister@Sun.COM 	uint32_t	mpi_iqc_offset;
41010696SDavid.Hollister@Sun.COM 	uint32_t	mpi_oqc_offset;
41110696SDavid.Hollister@Sun.COM 
41210696SDavid.Hollister@Sun.COM 	/*
41310696SDavid.Hollister@Sun.COM 	 * Inbound and outbound queue depth
41410696SDavid.Hollister@Sun.COM 	 */
41510696SDavid.Hollister@Sun.COM 	uint32_t	ioq_depth;
41610696SDavid.Hollister@Sun.COM 
41710696SDavid.Hollister@Sun.COM 	/*
41810696SDavid.Hollister@Sun.COM 	 * Kernel addresses and offsets for Inbound Queue Producer Indices
41910696SDavid.Hollister@Sun.COM 	 *
42010696SDavid.Hollister@Sun.COM 	 * See comments in pmcs_iomb.h about Inbound Queues. Since it
42110696SDavid.Hollister@Sun.COM 	 * is relatively expensive to go across the PCIe bus to read or
42210696SDavid.Hollister@Sun.COM 	 * write inside the card, we maintain shadow copies in kernel
42310696SDavid.Hollister@Sun.COM 	 * memory and update the card as needed.
42410696SDavid.Hollister@Sun.COM 	 */
42510696SDavid.Hollister@Sun.COM 	uint32_t	shadow_iqpi[PMCS_MAX_IQ];
42611832SJesse.Butler@Sun.COM 	uint32_t	iqpi_offset[PMCS_MAX_IQ];
42711692SJesse.Butler@Sun.COM 	uint32_t	last_iqci[PMCS_MAX_IQ];
42811832SJesse.Butler@Sun.COM 	uint32_t	last_htag[PMCS_MAX_IQ];
42910696SDavid.Hollister@Sun.COM 	uint32_t	*iqp[PMCS_MAX_IQ];
43010696SDavid.Hollister@Sun.COM 	kmutex_t	iqp_lock[PMCS_NIQ];
43110696SDavid.Hollister@Sun.COM 
43210696SDavid.Hollister@Sun.COM 	pmcs_iqp_trace_t	*iqpt;
43310696SDavid.Hollister@Sun.COM 
43410696SDavid.Hollister@Sun.COM 	/*
43510696SDavid.Hollister@Sun.COM 	 * Kernel addresses and offsets for Outbound Queue Consumer Indices
43610696SDavid.Hollister@Sun.COM 	 */
43710696SDavid.Hollister@Sun.COM 	uint32_t	*oqp[PMCS_MAX_OQ];
43810696SDavid.Hollister@Sun.COM 	uint32_t	oqci_offset[PMCS_MAX_OQ];
43910696SDavid.Hollister@Sun.COM 
44010696SDavid.Hollister@Sun.COM 	/*
44110696SDavid.Hollister@Sun.COM 	 * Driver's copy of the outbound queue indices
44210696SDavid.Hollister@Sun.COM 	 */
44310696SDavid.Hollister@Sun.COM 
44410696SDavid.Hollister@Sun.COM 	uint32_t	oqci[PMCS_NOQ];
44510696SDavid.Hollister@Sun.COM 	uint32_t	oqpi[PMCS_NOQ];
44610696SDavid.Hollister@Sun.COM 
44710696SDavid.Hollister@Sun.COM 	/*
44810696SDavid.Hollister@Sun.COM 	 * DMA addresses for both Inbound and Outbound queues.
44910696SDavid.Hollister@Sun.COM 	 */
45010696SDavid.Hollister@Sun.COM 	uint64_t	oqaddr[PMCS_MAX_OQ];
45110696SDavid.Hollister@Sun.COM 	uint64_t	iqaddr[PMCS_MAX_IQ];
45210696SDavid.Hollister@Sun.COM 
45310696SDavid.Hollister@Sun.COM 	/*
45410696SDavid.Hollister@Sun.COM 	 * Producer/Queue Host Memory Pointers and scratch areas,
45510696SDavid.Hollister@Sun.COM 	 * as well as DMA scatter/gather chunk areas.
45610696SDavid.Hollister@Sun.COM 	 *
45710696SDavid.Hollister@Sun.COM 	 * See discussion in pmcs_def.h about how this is laid out.
45810696SDavid.Hollister@Sun.COM 	 */
45910696SDavid.Hollister@Sun.COM 	uint8_t		*cip;
46010696SDavid.Hollister@Sun.COM 	uint64_t	ciaddr;
46110696SDavid.Hollister@Sun.COM 
46210696SDavid.Hollister@Sun.COM 	/*
46310696SDavid.Hollister@Sun.COM 	 * Scratch area pointer and DMA addrress for SATA and SMP operations.
46410696SDavid.Hollister@Sun.COM 	 */
46510696SDavid.Hollister@Sun.COM 	void			*scratch;
46610696SDavid.Hollister@Sun.COM 	uint64_t		scratch_dma;
46710696SDavid.Hollister@Sun.COM 	volatile uint8_t	scratch_locked;	/* Scratch area ownership */
46810696SDavid.Hollister@Sun.COM 
46910696SDavid.Hollister@Sun.COM 	/*
47011694SDavid.Hollister@Sun.COM 	 * Firmware info
47111694SDavid.Hollister@Sun.COM 	 *
47211694SDavid.Hollister@Sun.COM 	 * fwlogp: Pointer to block of memory mapped for the event logs
47311694SDavid.Hollister@Sun.COM 	 * fwlogp_aap1: Pointer to the beginning of the AAP1 event log
47411694SDavid.Hollister@Sun.COM 	 * fwlogp_iop: Pointer to the beginning of the IOP event log
47511694SDavid.Hollister@Sun.COM 	 * fwaddr: The physical address of fwlogp
47611694SDavid.Hollister@Sun.COM 	 *
47711694SDavid.Hollister@Sun.COM 	 * fwlogfile_aap1/iop: Path to the saved AAP1/IOP event logs
47811694SDavid.Hollister@Sun.COM 	 * fwlog_max_entries_aap1/iop: Max # of entries in each log
47911694SDavid.Hollister@Sun.COM 	 * fwlog_oldest_idx_aap1/iop: Index of oldest entry in each log
48011694SDavid.Hollister@Sun.COM 	 * fwlog_latest_idx_aap1/iop: Index of newest entry in each log
48111694SDavid.Hollister@Sun.COM 	 * fwlog_threshold_aap1/iop: % full at which we save the event log
48211694SDavid.Hollister@Sun.COM 	 * fwlog_findex_aap1/iop: Suffix to each event log's next filename
48311694SDavid.Hollister@Sun.COM 	 *
48411694SDavid.Hollister@Sun.COM 	 * Firmware event logs are written out to the filenames specified in
48511694SDavid.Hollister@Sun.COM 	 * fwlogp_aap1/iop when the number of entries in the in-memory copy
48611694SDavid.Hollister@Sun.COM 	 * reaches or exceeds the threshold value.  The filenames are suffixed
48711694SDavid.Hollister@Sun.COM 	 * with .X where X is an integer ranging from 0 to 4.  This allows us
48811694SDavid.Hollister@Sun.COM 	 * to save up to 5MB of event log data for each log.
48910696SDavid.Hollister@Sun.COM 	 */
49010696SDavid.Hollister@Sun.COM 	uint32_t	*fwlogp;
49111694SDavid.Hollister@Sun.COM 	pmcs_fw_event_hdr_t *fwlogp_aap1;
49211694SDavid.Hollister@Sun.COM 	pmcs_fw_event_hdr_t *fwlogp_iop;
49310696SDavid.Hollister@Sun.COM 	uint64_t	fwaddr;
49411694SDavid.Hollister@Sun.COM 	char		fwlogfile_aap1[MAXPATHLEN + 1];
49511694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_max_entries_aap1;
49611694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_oldest_idx_aap1;
49711694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_latest_idx_aap1;
49811694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_threshold_aap1;
49911694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_findex_aap1;
50011694SDavid.Hollister@Sun.COM 	char		fwlogfile_iop[MAXPATHLEN + 1];
50111694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_max_entries_iop;
50211694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_oldest_idx_iop;
50311694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_latest_idx_iop;
50411694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_threshold_iop;
50511694SDavid.Hollister@Sun.COM 	uint32_t	fwlog_findex_iop;
50610696SDavid.Hollister@Sun.COM 
50710696SDavid.Hollister@Sun.COM 	/*
50810696SDavid.Hollister@Sun.COM 	 * Internal register dump region and flash chunk DMA info
50910696SDavid.Hollister@Sun.COM 	 */
51010696SDavid.Hollister@Sun.COM 
51110696SDavid.Hollister@Sun.COM 	caddr_t		regdumpp;
51210696SDavid.Hollister@Sun.COM 	uint32_t	*flash_chunkp;
51310696SDavid.Hollister@Sun.COM 	uint64_t	flash_chunk_addr;
51410696SDavid.Hollister@Sun.COM 
51510696SDavid.Hollister@Sun.COM 	/*
51611692SJesse.Butler@Sun.COM 	 * Copies of the last read MSGU and IOP heartbeats.
51711692SJesse.Butler@Sun.COM 	 */
51811692SJesse.Butler@Sun.COM 	uint32_t	last_msgu_tick;
51911692SJesse.Butler@Sun.COM 	uint32_t	last_iop_tick;
52011692SJesse.Butler@Sun.COM 
52111692SJesse.Butler@Sun.COM 	/*
52210696SDavid.Hollister@Sun.COM 	 * Card information, some determined during MPI setup
52310696SDavid.Hollister@Sun.COM 	 */
52410696SDavid.Hollister@Sun.COM 	uint32_t	fw;		/* firmware version */
52511980SDavid.Hollister@Sun.COM 	uint32_t	ila_ver;	/* ILA version */
52610696SDavid.Hollister@Sun.COM 	uint8_t		max_iq;		/* maximum inbound queues this card */
52710696SDavid.Hollister@Sun.COM 	uint8_t 	max_oq;		/* "" outbound "" */
52810696SDavid.Hollister@Sun.COM 	uint8_t		nphy;		/* number of phys this card */
52910696SDavid.Hollister@Sun.COM 	uint8_t		chiprev;	/* chip revision */
53010696SDavid.Hollister@Sun.COM 	uint16_t	max_cmd;	/* max number of commands supported */
53110696SDavid.Hollister@Sun.COM 	uint16_t	max_dev;	/* max number of devices supported */
53210696SDavid.Hollister@Sun.COM 	uint16_t	last_wq_dev;	/* last dev whose wq was serviced */
53310696SDavid.Hollister@Sun.COM 
53411692SJesse.Butler@Sun.COM 	/*
53511692SJesse.Butler@Sun.COM 	 * Counter for the number of times watchdog fires.  We can use this
53611692SJesse.Butler@Sun.COM 	 * to throttle events which fire off of the watchdog, such as the
53711692SJesse.Butler@Sun.COM 	 * forward progress detection routine.
53811692SJesse.Butler@Sun.COM 	 */
53911692SJesse.Butler@Sun.COM 	uint8_t		watchdog_count;
54010696SDavid.Hollister@Sun.COM 
54110696SDavid.Hollister@Sun.COM 	/*
54210696SDavid.Hollister@Sun.COM 	 * Interrupt Setup stuff.
54310696SDavid.Hollister@Sun.COM 	 *
54410696SDavid.Hollister@Sun.COM 	 * int_type defines the kind of interrupt we're using with this card.
54510696SDavid.Hollister@Sun.COM 	 * oqvec defines the relationship between an Outbound Queue Number and
54610696SDavid.Hollister@Sun.COM 	 * a MSI-X vector.
54710696SDavid.Hollister@Sun.COM 	 */
54810696SDavid.Hollister@Sun.COM 	enum {
54910696SDavid.Hollister@Sun.COM 		PMCS_INT_NONE,
55010696SDavid.Hollister@Sun.COM 		PMCS_INT_TIMER,
55110696SDavid.Hollister@Sun.COM 		PMCS_INT_MSI,
55210696SDavid.Hollister@Sun.COM 		PMCS_INT_MSIX,
55310696SDavid.Hollister@Sun.COM 		PMCS_INT_FIXED
55410696SDavid.Hollister@Sun.COM 	} int_type;
55510696SDavid.Hollister@Sun.COM 	uint8_t			oqvec[PMCS_NOQ];
55610696SDavid.Hollister@Sun.COM 
55710696SDavid.Hollister@Sun.COM 	/*
55810696SDavid.Hollister@Sun.COM 	 * Interrupt handle table and size
55910696SDavid.Hollister@Sun.COM 	 */
56010696SDavid.Hollister@Sun.COM 	ddi_intr_handle_t	*ih_table;
56110696SDavid.Hollister@Sun.COM 	size_t			ih_table_size;
56210696SDavid.Hollister@Sun.COM 
56310696SDavid.Hollister@Sun.COM 	timeout_id_t		wdhandle;
56410696SDavid.Hollister@Sun.COM 	uint32_t		intr_mask;
56510696SDavid.Hollister@Sun.COM 	int			intr_cnt;
56610696SDavid.Hollister@Sun.COM 	int			intr_cap;
56710696SDavid.Hollister@Sun.COM 	uint32_t		odb_auto_clear;
56810696SDavid.Hollister@Sun.COM 
56910696SDavid.Hollister@Sun.COM 	/*
57010696SDavid.Hollister@Sun.COM 	 * DMA S/G chunk list
57110696SDavid.Hollister@Sun.COM 	 */
57210696SDavid.Hollister@Sun.COM 	int		nchunks;
57310696SDavid.Hollister@Sun.COM 	pmcs_chunk_t	*dma_chunklist;
57410696SDavid.Hollister@Sun.COM 
57510696SDavid.Hollister@Sun.COM 	/*
57610696SDavid.Hollister@Sun.COM 	 * Front of the DMA S/G chunk freelist
57710696SDavid.Hollister@Sun.COM 	 */
57810696SDavid.Hollister@Sun.COM 	pmcs_dmachunk_t	*dma_freelist;
57910696SDavid.Hollister@Sun.COM 
58010696SDavid.Hollister@Sun.COM 	/*
58110696SDavid.Hollister@Sun.COM 	 * PHY and Discovery Related Stuff
58210696SDavid.Hollister@Sun.COM 	 *
58310696SDavid.Hollister@Sun.COM 	 * The PMC chip can have up to 16 local phys. We build a level-first
58410696SDavid.Hollister@Sun.COM 	 * traversal tree of phys starting with the physical phys on the
58510696SDavid.Hollister@Sun.COM 	 * chip itself (i.e., treating the chip as if it were an expander).
58610696SDavid.Hollister@Sun.COM 	 *
58710696SDavid.Hollister@Sun.COM 	 * Our discovery process goes through a level and discovers what
58810696SDavid.Hollister@Sun.COM 	 * each entity is (and it's phy number within that expander's
58910696SDavid.Hollister@Sun.COM 	 * address space). It then configures each non-empty item (SAS,
59010696SDavid.Hollister@Sun.COM 	 * SATA/STP, EXPANDER). For expanders, it then performs
59110696SDavid.Hollister@Sun.COM 	 * discover on that expander itself via REPORT GENERAL and
59210696SDavid.Hollister@Sun.COM 	 * DISCOVERY SMP commands, attaching the discovered entities
59310696SDavid.Hollister@Sun.COM 	 * to the next level. Then we step down a level and continue
59410696SDavid.Hollister@Sun.COM 	 * (and so on).
59510696SDavid.Hollister@Sun.COM 	 *
59610696SDavid.Hollister@Sun.COM 	 * The PMC chip maintains an I_T_NEXUS notion based upon our
59710696SDavid.Hollister@Sun.COM 	 * registering each new device found (getting back a device handle).
59810696SDavid.Hollister@Sun.COM 	 *
59910696SDavid.Hollister@Sun.COM 	 * Like with the number of physical PHYS being a maximum of 16,
60010696SDavid.Hollister@Sun.COM 	 * there are a maximum number of PORTS also being 16. Some
60110696SDavid.Hollister@Sun.COM 	 * events apply to PORTS entirely, so we track PORTS as well.
60210696SDavid.Hollister@Sun.COM 	 */
60310696SDavid.Hollister@Sun.COM 	pmcs_phy_t		*root_phys;	/* HBA PHYs (level 0) */
60410696SDavid.Hollister@Sun.COM 	pmcs_phy_t		*ports[PMCS_MAX_PORTS];
60510696SDavid.Hollister@Sun.COM 	kmutex_t		dead_phylist_lock;	/* Protects dead_phys */
60610696SDavid.Hollister@Sun.COM 	pmcs_phy_t		*dead_phys;	/* PHYs waiting to be freed */
60710696SDavid.Hollister@Sun.COM 
60810696SDavid.Hollister@Sun.COM 	kmem_cache_t		*phy_cache;
60910696SDavid.Hollister@Sun.COM 
61010696SDavid.Hollister@Sun.COM 	/*
61110696SDavid.Hollister@Sun.COM 	 * Discovery-related items.
61210696SDavid.Hollister@Sun.COM 	 * config_lock: Protects config_changed and should never be held
61312078SJesse.Butler@Sun.COM 	 * outside of getting or setting the value of config_changed or
61412078SJesse.Butler@Sun.COM 	 * configuring.
61510696SDavid.Hollister@Sun.COM 	 * config_changed: Boolean indicating whether discovery needs to
61610696SDavid.Hollister@Sun.COM 	 * be restarted.
61710696SDavid.Hollister@Sun.COM 	 * configuring: 1 = discovery is running, 0 = discovery not running.
61810696SDavid.Hollister@Sun.COM 	 * NOTE: configuring is now in the bitfield above.
61911601SDavid.Hollister@Sun.COM 	 * config_restart_time is set by the tgtmap_[de]activate callbacks each
62011601SDavid.Hollister@Sun.COM 	 * time we decide we want SCSA to retry enumeration on some device.
62111601SDavid.Hollister@Sun.COM 	 * The watchdog timer will not fire discovery unless it has reached
62211601SDavid.Hollister@Sun.COM 	 * config_restart_time and config_restart is TRUE.  This ensures that
62311601SDavid.Hollister@Sun.COM 	 * we don't ask SCSA to retry enumerating devices while it is still
62411601SDavid.Hollister@Sun.COM 	 * running.
62512078SJesse.Butler@Sun.COM 	 * config_cv can be used by any thread waiting on the configuring
62612078SJesse.Butler@Sun.COM 	 * bit to clear.
62710696SDavid.Hollister@Sun.COM 	 */
62810696SDavid.Hollister@Sun.COM 	kmutex_t		config_lock;
62910696SDavid.Hollister@Sun.COM 	volatile boolean_t	config_changed;
63011601SDavid.Hollister@Sun.COM 	boolean_t		config_restart;
63111601SDavid.Hollister@Sun.COM 	clock_t			config_restart_time;
63212078SJesse.Butler@Sun.COM 	kcondvar_t		config_cv;
63310696SDavid.Hollister@Sun.COM 
63410696SDavid.Hollister@Sun.COM 	/*
63510696SDavid.Hollister@Sun.COM 	 * Work Related Stuff
63610696SDavid.Hollister@Sun.COM 	 *
63710696SDavid.Hollister@Sun.COM 	 * Each command given to the PMC chip has an associated work structure.
63810696SDavid.Hollister@Sun.COM 	 * See the discussion in pmcs_def.h about work structures.
63910696SDavid.Hollister@Sun.COM 	 */
64010696SDavid.Hollister@Sun.COM 	pmcwork_t	*work;		/* pool of work structures */
64110696SDavid.Hollister@Sun.COM 	STAILQ_HEAD(wfh, pmcwork) wf;	/* current freelist */
64210696SDavid.Hollister@Sun.COM 	STAILQ_HEAD(pfh, pmcwork) pf;	/* current pending freelist */
64310696SDavid.Hollister@Sun.COM 	uint16_t	wserno;		/* rolling serial number */
64410696SDavid.Hollister@Sun.COM 	kmutex_t	wfree_lock;	/* freelist/actvlist/wserno lock */
64510696SDavid.Hollister@Sun.COM 	kmutex_t	pfree_lock;	/* freelist/actvlist/wserno lock */
64610696SDavid.Hollister@Sun.COM 
64710696SDavid.Hollister@Sun.COM 	/*
64810696SDavid.Hollister@Sun.COM 	 * Solaris/SCSA items.
64910696SDavid.Hollister@Sun.COM 	 */
65010696SDavid.Hollister@Sun.COM 	scsi_hba_tran_t		*tran;
65111052SChris.Horne@Sun.COM 	smp_hba_tran_t		*smp_tran;
65210696SDavid.Hollister@Sun.COM 	struct scsi_reset_notify_entry	*reset_notify_listf;
65310696SDavid.Hollister@Sun.COM 
65410696SDavid.Hollister@Sun.COM 	/*
65510696SDavid.Hollister@Sun.COM 	 * Thread Level stuff.
65610696SDavid.Hollister@Sun.COM 	 *
65710696SDavid.Hollister@Sun.COM 	 * A number of tasks are done off worker thread taskq.
65810696SDavid.Hollister@Sun.COM 	 */
65910696SDavid.Hollister@Sun.COM 	ddi_taskq_t 		*tq;		/* For the worker thread */
66010696SDavid.Hollister@Sun.COM 	volatile ulong_t	work_flags;
66110696SDavid.Hollister@Sun.COM 
66210696SDavid.Hollister@Sun.COM 	/*
66310696SDavid.Hollister@Sun.COM 	 * Solaris target representation.
66410696SDavid.Hollister@Sun.COM 	 * targets = array of pointers to xscsi structures
66510696SDavid.Hollister@Sun.COM 	 * allocated by ssoftstate.
66610696SDavid.Hollister@Sun.COM 	 */
66710696SDavid.Hollister@Sun.COM 	pmcs_xscsi_t			**targets;
66810696SDavid.Hollister@Sun.COM 
66910696SDavid.Hollister@Sun.COM 	STAILQ_HEAD(dqh, pmcs_cmd)	dq;	/* dead commands */
67010696SDavid.Hollister@Sun.COM 	STAILQ_HEAD(cqh, pmcs_cmd)	cq;	/* completed commands */
67110696SDavid.Hollister@Sun.COM 	kmutex_t			cq_lock;
67210696SDavid.Hollister@Sun.COM 	kmem_cache_t			*iocomp_cb_cache;
67310696SDavid.Hollister@Sun.COM 	pmcs_iocomp_cb_t		*iocomp_cb_head;
67410696SDavid.Hollister@Sun.COM 	pmcs_iocomp_cb_t		*iocomp_cb_tail;
67510696SDavid.Hollister@Sun.COM 
67610696SDavid.Hollister@Sun.COM 	uint16_t			debug_mask;
67710696SDavid.Hollister@Sun.COM 	uint16_t			phyid_block_mask;
67810696SDavid.Hollister@Sun.COM 	uint16_t			phys_started;
67912060SDavid.Hollister@Sun.COM 	uint16_t			open_retry_interval;
68010696SDavid.Hollister@Sun.COM 	uint32_t			hipri_queue;
68110696SDavid.Hollister@Sun.COM 	uint32_t			mpibar;
68210696SDavid.Hollister@Sun.COM 	uint32_t			intr_pri;
68310696SDavid.Hollister@Sun.COM 
68410696SDavid.Hollister@Sun.COM 	pmcs_io_intr_coal_t		io_intr_coal;
68510696SDavid.Hollister@Sun.COM 	pmcs_cq_info_t			cq_info;
68610696SDavid.Hollister@Sun.COM 	kmutex_t			ict_lock;
68710696SDavid.Hollister@Sun.COM 	kcondvar_t			ict_cv;
68810696SDavid.Hollister@Sun.COM 	kthread_t			*ict_thread;
68910696SDavid.Hollister@Sun.COM 
69012060SDavid.Hollister@Sun.COM 	/*
69112060SDavid.Hollister@Sun.COM 	 * Receptacle information - FMA
69212060SDavid.Hollister@Sun.COM 	 */
69312060SDavid.Hollister@Sun.COM 	char				*recept_labels[PMCS_NUM_RECEPTACLES];
694*12120SDavid.Hollister@Sun.COM 	char				*recept_pm[PMCS_NUM_RECEPTACLES];
695*12120SDavid.Hollister@Sun.COM 
696*12120SDavid.Hollister@Sun.COM 	/*
697*12120SDavid.Hollister@Sun.COM 	 * fw_timestamp: Firmware timestamp taken after PHYs are started
698*12120SDavid.Hollister@Sun.COM 	 * sys_timestamp: System timestamp taken at roughly the same time
699*12120SDavid.Hollister@Sun.COM 	 * hrtimestamp is the hrtime at roughly the same time
700*12120SDavid.Hollister@Sun.COM 	 * All of these are protected by the global pmcs_trace_lock.
701*12120SDavid.Hollister@Sun.COM 	 */
702*12120SDavid.Hollister@Sun.COM 	uint64_t	fw_timestamp;
703*12120SDavid.Hollister@Sun.COM 	timespec_t	sys_timestamp;
704*12120SDavid.Hollister@Sun.COM 	hrtime_t	hrtimestamp;
70512060SDavid.Hollister@Sun.COM 
70610696SDavid.Hollister@Sun.COM #ifdef	DEBUG
70710696SDavid.Hollister@Sun.COM 	kmutex_t	dbglock;
70810696SDavid.Hollister@Sun.COM 	uint32_t	ltags[256];
70910696SDavid.Hollister@Sun.COM 	uint32_t	ftags[256];
71010696SDavid.Hollister@Sun.COM 	hrtime_t	ltime[256];
71110696SDavid.Hollister@Sun.COM 	hrtime_t	ftime[256];
71210696SDavid.Hollister@Sun.COM 	uint16_t	ftag_lines[256];
71310696SDavid.Hollister@Sun.COM 	uint8_t		lti;			/* last tag index */
71410696SDavid.Hollister@Sun.COM 	uint8_t		fti;			/* first tag index */
71510696SDavid.Hollister@Sun.COM #endif
71610696SDavid.Hollister@Sun.COM };
71710696SDavid.Hollister@Sun.COM 
71810696SDavid.Hollister@Sun.COM extern void 		*pmcs_softc_state;
71910696SDavid.Hollister@Sun.COM extern void 		*pmcs_iport_softstate;
72010696SDavid.Hollister@Sun.COM 
72110696SDavid.Hollister@Sun.COM /*
72210696SDavid.Hollister@Sun.COM  * Some miscellaneous, oft used strings
72310696SDavid.Hollister@Sun.COM  */
72410696SDavid.Hollister@Sun.COM extern const char pmcs_nowrk[];
72510696SDavid.Hollister@Sun.COM extern const char pmcs_nomsg[];
72610696SDavid.Hollister@Sun.COM extern const char pmcs_timeo[];
72710696SDavid.Hollister@Sun.COM 
72811926SDavid.Hollister@Sun.COM /*
72911926SDavid.Hollister@Sun.COM  * Other externs
73011926SDavid.Hollister@Sun.COM  */
73111926SDavid.Hollister@Sun.COM extern int modrootloaded;
73211926SDavid.Hollister@Sun.COM 
73310696SDavid.Hollister@Sun.COM #ifdef	__cplusplus
73410696SDavid.Hollister@Sun.COM }
73510696SDavid.Hollister@Sun.COM #endif
73610696SDavid.Hollister@Sun.COM #endif	/* _PMCS_H */
737