xref: /netbsd-src/sys/dev/ic/aacvar.h (revision aaf4ece63a859a04e37cf3a7229b5fab0157cc06)
1 /*	$NetBSD: aacvar.h,v 1.8 2005/12/11 12:21:25 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Andrew Doran.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*-
40  * Copyright (c) 2000 Michael Smith
41  * Copyright (c) 2000 BSDi
42  * Copyright (c) 2000 Niklas Hallqvist
43  * All rights reserved.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  * 1. Redistributions of source code must retain the above copyright
49  *    notice, this list of conditions and the following disclaimer.
50  * 2. Redistributions in binary form must reproduce the above copyright
51  *    notice, this list of conditions and the following disclaimer in the
52  *    documentation and/or other materials provided with the distribution.
53  *
54  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
55  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
58  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64  * SUCH DAMAGE.
65  *
66  *	from FreeBSD: aacvar.h,v 1.1 2000/09/13 03:20:34 msmith Exp
67  *	via OpenBSD: aacvar.h,v 1.2 2002/03/14 01:26:53 millert Exp
68  */
69 
70 #ifndef _PCI_AACVAR_H_
71 #define	_PCI_AACVAR_H_
72 
73 /* Debugging */
74 #ifdef AAC_DEBUG
75 #define AAC_DPRINTF(mask, args) if ((aac_debug & (mask)) != 0) printf args
76 #define AAC_D_INTR	0x01
77 #define AAC_D_MISC	0x02
78 #define AAC_D_CMD	0x04
79 #define AAC_D_QUEUE	0x08
80 #define AAC_D_IO	0x10
81 extern int aac_debug;
82 
83 #define AAC_PRINT_FIB(sc, fib)	aac_print_fib((sc), (fib), __FUNCTION__)
84 #else
85 #define AAC_DPRINTF(mask, args)
86 #define AAC_PRINT_FIB(sc, fib)
87 #endif
88 
89 struct aac_code_lookup {
90 	const char	*string;
91 	u_int32_t code;
92 };
93 
94 extern const struct	 aac_code_lookup aac_command_status_table[];
95 extern const struct	 aac_code_lookup aac_container_types[];
96 
97 struct aac_softc;
98 
99 /*
100  * We allocate a small set of FIBs for the adapter to use to send us messages.
101  */
102 #define AAC_ADAPTER_FIBS	8
103 
104 /*
105  * Firmware messages are passed in the printf buffer.
106  */
107 #define AAC_PRINTF_BUFSIZE	256
108 
109 /*
110  * We wait this many seconds for the adapter to come ready if it is still
111  * booting.
112  */
113 #define AAC_BOOT_TIMEOUT	(3 * 60)
114 
115 /*
116  * Wait this long for a lost interrupt to get detected.
117  */
118 #define AAC_WATCH_TIMEOUT	10000		/* 10000 * 1ms = 10s */
119 
120 /*
121  * Timeout for immediate commands.
122  */
123 #define AAC_IMMEDIATE_TIMEOUT	30
124 
125 /*
126  * Delay 20ms after the qnotify in sync operations.  Experimentally deduced.
127  */
128 #define AAC_SYNC_DELAY		20000
129 
130 /*
131  * The firmware interface allows for a 16-bit s/g list length.  We limit
132  * ourselves to a reasonable maximum and ensure alignment.
133  */
134 #define AAC_MAX_SGENTRIES	17	/* max S/G entries, limit 65535 */
135 #define	AAC_MAX_XFER		((AAC_MAX_SGENTRIES - 1) * PAGE_SIZE)
136 
137 /*
138  * Fixed sector size.
139  */
140 #define	AAC_SECTOR_SIZE		512
141 
142 /*
143  * Number of CCBs to allocate, and to reserve for control operations.
144  */
145 #define	AAC_NCCBS		256
146 #define	AAC_NCCBS_RESERVE	4
147 
148 /*
149  * Quirk listings.
150  */
151 #define AAC_QUIRK_PERC2QC	(1 << 0)	/* Dell PERC 2QC */
152 #define AAC_QUIRK_SG_64BIT	(1 << 4)	/* Use 64-bit S/G addresses */
153 #define AAC_QUIRK_4GB_WINDOW	(1 << 5)	/* Device can access host mem
154 						 * in 2GB-4GB range */
155 #define AAC_QUIRK_NO4GB		(1 << 6)	/* Can't access host mem >2GB */
156 #define AAC_QUIRK_256FIBS	(1 << 7)	/* Can only handle 256 cmds */
157 #define AAC_QUIRK_BROKEN_MMAP	(1 << 8)	/* Broken HostPhysMemPages */
158 
159 
160 /*
161  * We gather a number of adapter-visible items into a single structure.
162  *
163  * The ordering of this structure may be important; we copy the Linux driver:
164  *
165  * Adapter FIBs
166  * Init struct
167  * Queue headers (Comm Area)
168  * Printf buffer
169  *
170  * In addition, we add:
171  * Sync Fib
172  */
173 struct aac_common {
174 	/* fibs for the controller to send us messages */
175 	struct aac_fib ac_fibs[AAC_ADAPTER_FIBS];
176 
177 	/* the init structure */
178 	struct aac_adapter_init	ac_init;
179 
180 	/* arena within which the queue structures are kept */
181 	u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
182 
183 	/* buffer for text messages from the controller */
184 	char	ac_printf[AAC_PRINTF_BUFSIZE];
185 
186 	/* fib for synchronous commands */
187 	struct aac_fib ac_sync_fib;
188 };
189 
190 /*
191  * Interface operations
192  */
193 struct aac_interface {
194 	int	(*aif_get_fwstatus)(struct aac_softc *);
195 	void	(*aif_qnotify)(struct aac_softc *, int);
196 	int	(*aif_get_istatus)(struct aac_softc *);
197 	void	(*aif_set_istatus)(struct aac_softc *, int);
198 	void	(*aif_set_mailbox)(struct aac_softc *, u_int32_t,
199 				   u_int32_t, u_int32_t, u_int32_t, u_int32_t);
200 	uint32_t (*aif_get_mailbox)(struct aac_softc *, int);
201 	void	(*aif_set_interrupts)(struct aac_softc *, int);
202 };
203 
204 #define AAC_GET_FWSTATUS(sc)		((sc)->sc_if.aif_get_fwstatus(sc))
205 #define AAC_QNOTIFY(sc, qbit) \
206 	((sc)->sc_if.aif_qnotify((sc), (qbit)))
207 #define AAC_GET_ISTATUS(sc)		((sc)->sc_if.aif_get_istatus(sc))
208 #define AAC_CLEAR_ISTATUS(sc, mask) \
209 	((sc)->sc_if.aif_set_istatus((sc), (mask)))
210 #define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
211 	do {								\
212 		((sc)->sc_if.aif_set_mailbox((sc), (command), (arg0),	\
213 		    (arg1), (arg2), (arg3)));				\
214 	} while(0)
215 #define AAC_GET_MAILBOX(sc, mb)		((sc)->sc_if.aif_get_mailbox(sc, mb))
216 #define AAC_GET_MAILBOXSTATUS(sc)	(AAC_GET_MAILBOX(sc, 0))
217 #define	AAC_MASK_INTERRUPTS(sc)	\
218 	((sc)->sc_if.aif_set_interrupts((sc), 0))
219 #define AAC_UNMASK_INTERRUPTS(sc) \
220 	((sc)->sc_if.aif_set_interrupts((sc), 1))
221 
222 #define AAC_SETREG4(sc, reg, val) \
223 	bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (reg), (val))
224 #define AAC_GETREG4(sc, reg) \
225 	bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (reg))
226 #define AAC_SETREG2(sc, reg, val) \
227 	bus_space_write_2((sc)->sc_memt, (sc)->sc_memh, (reg), (val))
228 #define AAC_GETREG2(sc, reg) \
229 	bus_space_read_2((sc)->sc_memt, (sc)->sc_memh, (reg))
230 #define AAC_SETREG1(sc, reg, val) \
231 	bus_space_write_1((sc)->sc_memt, (sc)->sc_memh, (reg), (val))
232 #define AAC_GETREG1(sc, reg) \
233 	bus_space_read_1((sc)->sc_memt, (sc)->sc_memh, (reg))
234 
235 
236 /*
237  * A command contol block, one for each corresponding command index of the
238  * controller.
239  */
240 struct aac_ccb {
241 	SIMPLEQ_ENTRY(aac_ccb)	ac_chain;
242 
243 	struct aac_fib		*ac_fib;
244 	bus_addr_t		ac_fibphys;
245 	bus_dmamap_t		ac_dmamap_xfer;
246 
247 	void			*ac_data;
248 	size_t			ac_datalen;
249 	u_int			ac_flags;
250 
251 	void			(*ac_intr)(struct aac_ccb *);
252 	struct device		*ac_device;
253 	void			*ac_context;
254 };
255 #define AAC_CCB_MAPPED	 	0x01
256 #define AAC_CCB_COMPLETED 	0x02
257 #define AAC_CCB_DATA_IN		0x04
258 #define AAC_CCB_DATA_OUT	0x08
259 
260 struct aac_drive {
261 	u_int	hd_present;
262 	u_int	hd_devtype;
263 	u_int	hd_size;
264 };
265 
266 /*
267  * Per-controller structure.
268  */
269 struct aac_softc {
270 	struct device		sc_dv;
271 	void			*sc_ih;
272 	bus_space_tag_t		sc_memt;
273 	bus_space_handle_t	sc_memh;
274 	bus_dma_tag_t		sc_dmat;
275 
276 	struct FsaRevision	sc_revision;
277 	int			sc_hwif;
278 	int			sc_quirks;
279 	struct aac_interface	sc_if;
280 
281 	struct aac_common	*sc_common;
282 	bus_dma_segment_t	sc_common_seg;
283 	bus_dmamap_t		sc_common_dmamap;
284 	struct aac_fib		*sc_fibs;
285 	bus_dma_segment_t	sc_fibs_seg;
286 	bus_dmamap_t		sc_fibs_dmamap;
287 
288 	struct aac_ccb		*sc_ccbs;
289 	SIMPLEQ_HEAD(, aac_ccb)	sc_ccb_free;
290 	SIMPLEQ_HEAD(, aac_ccb)	sc_ccb_queue;
291 	SIMPLEQ_HEAD(, aac_ccb)	sc_ccb_complete;
292 
293 	struct aac_queue_table	*sc_queues;
294 	struct aac_queue_entry	*sc_qentries[AAC_QUEUE_COUNT];
295 	struct aac_drive	sc_hdr[AAC_MAX_CONTAINERS];
296 	int			sc_nunits;
297 	int			sc_flags;
298 	uint32_t		sc_supported_options;
299 };
300 #define AAC_HWIF_I960RX		0
301 #define AAC_HWIF_STRONGARM	1
302 
303 #define	AAC_ONLINE		2
304 
305 struct aac_attach_args {
306 	int		aaca_unit;
307 };
308 
309 int	aac_attach(struct aac_softc *);
310 void	aac_ccb_enqueue(struct aac_softc *, struct aac_ccb *);
311 void	aac_ccb_free(struct aac_softc *, struct aac_ccb *);
312 struct aac_ccb *aac_ccb_alloc(struct aac_softc *, int);
313 int	aac_ccb_map(struct aac_softc *, struct aac_ccb *);
314 int	aac_ccb_poll(struct aac_softc *, struct aac_ccb *, int);
315 int	aac_ccb_submit(struct aac_softc *, struct aac_ccb *);
316 void	aac_ccb_unmap(struct aac_softc *, struct aac_ccb *);
317 const char	*aac_describe_code(const struct aac_code_lookup *, u_int32_t);
318 int	aac_intr(void *);
319 
320 #endif	/* !_PCI_AACVAR_H_ */
321