si3124var.h revision 1258:9961d7d3ec8c
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef _SI3124VAR_H
28#define	_SI3124VAR_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#ifdef	__cplusplus
33extern "C" {
34#endif
35
36#define	SI3124_MAX_PORTS		4
37#define	SI3132_MAX_PORTS		2
38#define	SI_MAX_PORTS			SI3124_MAX_PORTS
39
40#define	SI_SUCCESS			(0)	/* successful return */
41#define	SI_TIMEOUT			(1)	/* timed out */
42#define	SI_FAILURE			(-1)	/* unsuccessful return */
43
44#define	SI_MAX_SGT_TABLES_PER_PRB	10
45
46/*
47 * While the si_sge_t and si_sgt_t correspond to the actual SGE and SGT
48 * definitions as per the datasheet, the si_sgblock_t (i.e scatter gather
49 * block) is a logical data structure which holds multiple SGT tables.
50 * The idea is to use multiple chained SGT tables per each PRB request.
51 */
52
53typedef struct si_sgblock {
54	si_sgt_t sgb_sgt[SI_MAX_SGT_TABLES_PER_PRB];
55} si_sgblock_t;
56
57/*
58 * Each SGT (Scatter Gather Table) has 4 SGEs (Scatter Gather Entries).
59 * But each SGT effectively can host only 3 SGEs since the last SGE entry
60 * is used to hold a link to the next SGT in the chain. However the last
61 * SGT in the chain can host all the 4 entries since it does not need to
62 * link any more.
63 */
64#define	SI_MAX_SGL_LENGTH	(3*SI_MAX_SGT_TABLES_PER_PRB)+1
65
66typedef struct si_portmult_state {
67	int sipm_num_ports;
68	uint8_t sipm_port_type[15];
69	/* one of PORT_TYPE_[NODEV | MULTIPLIER | ATAPI | DISK | UNKNOWN] */
70
71	/*
72	 * sipm_port_type[] is good enough to capture the state of ports
73	 * behind the multiplier. Since any of the port behind a multiplier
74	 * is accessed through the same main controller port, we don't need
75	 * additional si_port_state_t here.
76	 */
77
78} si_portmult_state_t;
79
80
81/* The following are for port types */
82#define	PORT_TYPE_NODEV		0x0
83#define	PORT_TYPE_MULTIPLIER	0x1
84#define	PORT_TYPE_ATAPI		0x2
85#define	PORT_TYPE_DISK		0x3
86#define	PORT_TYPE_UNKNOWN	0x4
87
88/* The following are for active state */
89#define	PORT_INACTIVE		0x0
90#define	PORT_ACTIVE		0x1
91
92typedef struct si_port_state {
93	uint8_t siport_port_type;
94	/* one of PORT_TYPE_[NODEV | MULTIPLIER | ATAPI | DISK | UNKNOWN] */
95
96	uint8_t siport_active;		/* one of ACTIVE or INACTIVE */
97
98	si_portmult_state_t siport_portmult_state;
99
100	si_prb_t *siport_prbpool; 	/* These are 31 incore PRBs */
101	uint64_t siport_prbpool_physaddr;
102	ddi_dma_handle_t siport_prbpool_dma_handle;
103	ddi_acc_handle_t siport_prbpool_acc_handle;
104
105
106	si_sgblock_t *siport_sgbpool; 	/* These are 31 incore sg blocks */
107	uint64_t siport_sgbpool_physaddr;
108	ddi_dma_handle_t siport_sgbpool_dma_handle;
109	ddi_acc_handle_t siport_sgbpool_acc_handle;
110
111	kmutex_t siport_mutex; 		/* main per port mutex */
112	uint32_t siport_pending_tags;	/* remembers the pending tags */
113	sata_pkt_t *siport_slot_pkts[SI_NUM_SLOTS];
114
115	/*
116	 * While the reset is in progress, we don't accept any more commands
117	 * until we receive the command with SATA_CLEAR_DEV_RESET_STATE flag.
118	 * However any commands with SATA_IGNORE_DEV_RESET_STATE are allowed in
119	 * during such blockage.
120	 */
121	int siport_reset_in_progress;
122
123	/*
124	 * We mop the commands for either abort, reset, timeout or
125	 * error handling cases. Only one such mopping thread is allowed
126	 * at a time.
127	 */
128	int mopping_in_progress;
129	kmutex_t siport_mop_mutex; 	/* limits one mop at a time */
130
131	/* error recovery related info */
132	uint32_t siport_err_tags_SDBERROR;
133	uint32_t siport_err_tags_nonSDBERROR;
134	int siport_pending_ncq_count;
135
136} si_port_state_t;
137
138/* Warlock annotation */
139_NOTE(MUTEX_PROTECTS_DATA(si_port_state_t::siport_mutex, si_port_state_t))
140_NOTE(READ_ONLY_DATA(si_port_state_t::siport_prbpool_dma_handle))
141_NOTE(READ_ONLY_DATA(si_port_state_t::siport_sgbpool_dma_handle))
142
143
144typedef struct si_ctl_state {
145
146	dev_info_t *sictl_devinfop;
147
148	int sictl_num_ports;	/* number of controller ports */
149	si_port_state_t *sictl_ports[SI_MAX_PORTS];
150
151	int sictl_devid; /* whether it is 3124 or 3132 */
152	int sictl_flags; /* some important state of controller */
153	int sictl_power_level;
154
155	/* pci config space handle */
156	ddi_acc_handle_t sictl_pci_conf_handle;
157
158	/* mapping into bar 0 */
159	ddi_acc_handle_t sictl_global_acc_handle;
160	uintptr_t sictl_global_addr;
161
162	/* mapping into bar 1 */
163	ddi_acc_handle_t sictl_port_acc_handle;
164	uintptr_t sictl_port_addr;
165
166	struct sata_hba_tran *sictl_sata_hba_tran;
167	timeout_id_t sictl_timeout_id;
168
169	kmutex_t sictl_mutex; 			/* per controller mutex */
170
171	ddi_intr_handle_t *sictl_htable;	/* For array of interrupts */
172	int sictl_intr_type;			/* What type of interrupt */
173	int sictl_intr_cnt;			/* # of intrs count returned */
174	size_t sictl_intr_size;			/* Size of intr array */
175	uint_t sictl_intr_pri;			/* Interrupt priority */
176	int sictl_intr_cap;			/* Interrupt capabilities */
177
178} si_ctl_state_t;
179
180/* Warlock annotation */
181_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex,
182					si_ctl_state_t::sictl_ports))
183_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex,
184					si_ctl_state_t::sictl_power_level))
185_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex,
186					si_ctl_state_t::sictl_flags))
187_NOTE(MUTEX_PROTECTS_DATA(si_ctl_state_t::sictl_mutex,
188					si_ctl_state_t::sictl_timeout_id))
189/*
190 * flags for si_flags
191 */
192#define	SI_PM			0x01
193#define	SI_ATTACH		0x02
194#define	SI_DETACH		0x04
195#define	SI_NO_TIMEOUTS		0x08
196#define	SI_FRAMEWORK_ATTACHED	0x10	/* are we attached to framework ? */
197
198/* progress values for si_attach */
199#define	ATTACH_PROGRESS_NONE			(1<<0)
200#define	ATTACH_PROGRESS_STATEP_ALLOC		(1<<1)
201#define	ATTACH_PROGRESS_CONF_HANDLE		(1<<2)
202#define	ATTACH_PROGRESS_BAR0_MAP		(1<<3)
203#define	ATTACH_PROGRESS_BAR1_MAP		(1<<4)
204#define	ATTACH_PROGRESS_INTR_ADDED		(1<<5)
205#define	ATTACH_PROGRESS_MUTEX_INIT		(1<<6)
206#define	ATTACH_PROGRESS_HW_INIT			(1<<7)
207
208#define	SI_10MS_TICKS	(drv_usectohz(10000))	/* ticks in 10 millisec */
209#define	SI_1MS_TICKS	(drv_usectohz(1000))	/* ticks in 1 millisec */
210#define	SI_1MS_USECS	(1000)			/* usecs in 1 millisec */
211#define	SI_POLLRATE_SOFT_RESET		1000
212#define	SI_POLLRATE_SSTATUS		10
213#define	SI_POLLRATE_PORTREADY		50
214#define	SI_POLLRATE_SLOTSTATUS		50
215#define	SI_POLLRATE_RECOVERPORTMULT	1000
216
217#define	PORTMULT_CONTROL_PORT		0xf
218
219/* clearing & setting the n'th bit in a given tag */
220#define	CLEAR_BIT(tag, bit)	(tag &= ~(0x1<<bit))
221#define	SET_BIT(tag, bit)	(tag |= (0x1<<bit))
222
223#if DEBUG
224
225#define	SI_DBUG		1
226
227#define	SIDBG_TEST	0x0001
228#define	SIDBG_INIT	0x0002
229#define	SIDBG_ENTRY	0x0004
230#define	SIDBG_DUMP_PRB	0x0008
231#define	SIDBG_EVENT	0x0010
232#define	SIDBG_POLL_LOOP	0x0020
233#define	SIDBG_PKTCOMP	0x0040
234#define	SIDBG_TIMEOUT	0x0080
235#define	SIDBG_INFO	0x0100
236#define	SIDBG_VERBOSE	0x0200
237#define	SIDBG_INTR	0x0400
238#define	SIDBG_ERRS	0x0800
239#define	SIDBG_COOKIES	0x1000
240#define	SIDBG_POWER	0x2000
241
242extern int si_debug_flag;
243
244#define	SIDBG0(flag, softp, format) \
245	if (si_debug_flags & (flag)) { \
246		si_log(softp, CE_WARN, format); \
247	}
248
249#define	SIDBG1(flag, softp, format, arg1) \
250	if (si_debug_flags & (flag)) { \
251		si_log(softp, CE_WARN, format, arg1); \
252	}
253
254#define	SIDBG2(flag, softp, format, arg1, arg2) \
255	if (si_debug_flags & (flag)) { \
256		si_log(softp, CE_WARN, format, arg1, arg2); \
257	}
258
259#define	SIDBG3(flag, softp, format, arg1, arg2, arg3) \
260	if (si_debug_flags & (flag)) { \
261		si_log(softp, CE_WARN, format, arg1, arg2, arg3); \
262	}
263
264#define	SIDBG4(flag, softp, format, arg1, arg2, arg3, arg4) \
265	if (si_debug_flags & (flag)) { \
266		si_log(softp, CE_WARN, format, arg1, arg2, arg3, arg4); \
267	}
268#else
269
270#define	SIDBG0(flag, dip, frmt)
271#define	SIDBG1(flag, dip, frmt, arg1)
272#define	SIDBG2(flag, dip, frmt, arg1, arg2)
273#define	SIDBG3(flag, dip, frmt, arg1, arg2, arg3)
274#define	SIDBG4(flag, dip, frmt, arg1, arg2, arg3, arg4)
275
276#endif /* DEBUG */
277
278/* Flags controlling the reset behavior */
279#define	SI_PORT_RESET		0x1	/* Reset the port */
280#define	SI_DEVICE_RESET		0x2	/* Reset the device, not the port */
281#define	SI_RESET_NO_EVENTS_UP	0x4	/* Don't send reset events up */
282
283#ifdef	__cplusplus
284}
285#endif
286
287#endif /* _SI3124VAR_H */
288