xref: /openbsd-src/sys/dev/ic/aacvar.h (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: aacvar.h,v 1.1 2000/11/10 09:39:36 niklas Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 Michael Smith
5  * Copyright (c) 2000 BSDi
6  * Copyright (c) 2000 Niklas Hallqvist
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *	$FreeBSD: /c/ncvs/src/sys/dev/aac/aacvar.h,v 1.1 2000/09/13 03:20:34 msmith Exp $
31  */
32 
33 /*
34  * This driver would not have rewritten for OpenBSD if it was not for the
35  * hardware dontion from Nocom.  I want to thank them for their support.
36  * Of course, credit should go to Mike Smith for the original work he did
37  * in the FreeBSD driver where I found lots of inspiration.
38  * - Niklas Hallqvist
39  */
40 
41 /* Debugging */
42 #ifdef AAC_DEBUG
43 #define AAC_DPRINTF(mask, args) if (aac_debug & (mask)) printf args
44 #define AAC_D_INTR	0x01
45 #define AAC_D_MISC	0x02
46 #define AAC_D_CMD	0x04
47 #define AAC_D_QUEUE	0x08
48 #define AAC_D_IO	0x10
49 extern int aac_debug;
50 
51 #define AAC_PRINT_FIB(sc, fib)	aac_print_fib((sc), (fib), __FUNCTION__)
52 #else
53 #define AAC_DPRINTF(mask, args)
54 #define AAC_PRINT_FIB(sc, fib)
55 #endif
56 
57 struct aac_code_lookup {
58 	char	*string;
59 	u_int32_t code;
60 };
61 
62 struct aac_softc;
63 
64 /*
65  * We allocate a small set of FIBs for the adapter to use to send us messages.
66  */
67 #define AAC_ADAPTER_FIBS	8
68 
69 /*
70  * Firmware messages are passed in the printf buffer.
71  */
72 #define AAC_PRINTF_BUFSIZE	256
73 
74 /*
75  * We wait this many seconds for the adapter to come ready if it is still
76  * booting.
77  */
78 #define AAC_BOOT_TIMEOUT	(3 * 60)
79 
80 /*
81  * Wait this long for a lost interrupt to get detected.
82  */
83 #define AAC_WATCH_TIMEOUT	10000		/* 10000 * 1ms = 10s */
84 
85 /*
86  * Timeout for immediate commands.
87  */
88 #define AAC_IMMEDIATE_TIMEOUT	30
89 
90 /*
91  * Delay 20ms after the qnotify in sync operations.  Experimentally deduced.
92  */
93 #define AAC_SYNC_DELAY 20000
94 
95 /*
96  * The firmware interface allows for a 16-bit s/g list length.  We limit
97  * ourselves to a reasonable maximum and ensure alignment.
98  */
99 #define AAC_MAXSGENTRIES	64	/* max S/G entries, limit 65535 */
100 /*
101  * We gather a number of adapter-visible items into a single structure.
102  *
103  * The ordering of this strucure may be important; we copy the Linux driver:
104  *
105  * Adapter FIBs
106  * Init struct
107  * Queue headers (Comm Area)
108  * Printf buffer
109  *
110  * In addition, we add:
111  * Sync Fib
112  */
113 struct aac_common {
114 	/* fibs for the controller to send us messages */
115 	struct aac_fib ac_fibs[AAC_ADAPTER_FIBS];
116 
117 	/* the init structure */
118 	struct aac_adapter_init	ac_init;
119 
120 	/* arena within which the queue structures are kept */
121 	u_int8_t ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
122 
123 	/* buffer for text messages from the controller */
124 	char	ac_printf[AAC_PRINTF_BUFSIZE];
125 
126 	/* fib for synchronous commands */
127 	struct aac_fib ac_sync_fib;
128 };
129 
130 /*
131  * Interface operations
132  */
133 struct aac_interface {
134 	int	(*aif_get_fwstatus) __P((struct aac_softc *));
135 	void	(*aif_qnotify) __P((struct aac_softc *, int));
136 	int	(*aif_get_istatus) __P((struct aac_softc *));
137 	void	(*aif_set_istatus) __P((struct aac_softc *, int));
138 	void	(*aif_set_mailbox) __P((struct aac_softc *, u_int32_t,
139 	    u_int32_t, u_int32_t, u_int32_t, u_int32_t));
140 	int	(*aif_get_mailboxstatus) __P((struct aac_softc *));
141 	void	(*aif_set_interrupts) __P((struct aac_softc *, int));
142 };
143 extern struct aac_interface aac_rx_interface;
144 extern struct aac_interface aac_sa_interface;
145 
146 #define AAC_GET_FWSTATUS(sc)		((sc)->sc_if.aif_get_fwstatus(sc))
147 #define AAC_QNOTIFY(sc, qbit) \
148 	((sc)->sc_if.aif_qnotify((sc), (qbit)))
149 #define AAC_GET_ISTATUS(sc)		((sc)->sc_if.aif_get_istatus(sc))
150 #define AAC_CLEAR_ISTATUS(sc, mask) \
151 	((sc)->sc_if.aif_set_istatus((sc), (mask)))
152 #define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
153 	do {								\
154 		((sc)->sc_if.aif_set_mailbox((sc), (command), (arg0),	\
155 		    (arg1), (arg2), (arg3)));				\
156 	} while(0)
157 #define AAC_GET_MAILBOXSTATUS(sc) \
158 	((sc)->sc_if.aif_get_mailboxstatus(sc))
159 #define	AAC_MASK_INTERRUPTS(sc)	\
160 	((sc)->sc_if.aif_set_interrupts((sc), 0))
161 #define AAC_UNMASK_INTERRUPTS(sc) \
162 	((sc)->sc_if.aif_set_interrupts((sc), 1))
163 
164 #define AAC_SETREG4(sc, reg, val) \
165 	bus_space_write_4((sc)->sc_memt, (sc)->sc_memh, (reg), (val))
166 #define AAC_GETREG4(sc, reg) \
167 	bus_space_read_4((sc)->sc_memt, (sc)->sc_memh, (reg))
168 #define AAC_SETREG2(sc, reg, val) \
169 	bus_space_write_2((sc)->sc_memt, (sc)->sc_memh, (reg), (val))
170 #define AAC_GETREG2(sc, reg) \
171 	bus_space_read_2((sc)->sc_memt, (sc)->sc_memh, (reg))
172 #define AAC_SETREG1(sc, reg, val) \
173 	bus_space_write_1((sc)->sc_memt, (sc)->sc_memh, (reg), (val))
174 #define AAC_GETREG1(sc, reg) \
175 	bus_space_read_1((sc)->sc_memt, (sc)->sc_memh, (reg))
176 
177 /*
178  * Per-container data structure
179  */
180 struct aac_container
181 {
182 	struct aac_mntobj co_mntobj;
183 	struct device co_disk;
184 };
185 
186 /*
187  * A command contol block, one for each corresponding command index of the
188  * controller.
189  */
190 struct aac_ccb {
191 	TAILQ_ENTRY(aac_ccb) ac_chain;
192 	struct scsi_xfer *ac_xs;
193 	struct aac_fib *ac_fib;		/* FIB associated with this command */
194 	bus_addr_t ac_fibphys;		/* bus address of the FIB */
195 	bus_dmamap_t ac_dmamap_xfer;
196 	struct aac_sg_table *ac_sgtable;/* pointer to s/g table in command */
197 	int ac_timeout;
198 	u_int32_t ac_blockno;
199 	u_int32_t ac_blockcnt;
200 	u_int8_t ac_flags;
201 #define AAC_ACF_WATCHDOG 	0x1
202 #define AAC_ACF_COMPLETED 	0x2
203 };
204 
205 /*
206  * Per-controller structure.
207  */
208 struct aac_softc {
209 	struct device sc_dev;
210 	void   *sc_ih;
211 	struct	scsi_link sc_link;	/* Virtual SCSI bus for cache devs */
212 
213 	bus_space_tag_t sc_memt;
214 	bus_space_handle_t sc_memh;
215 	bus_dma_tag_t sc_dmat;		/* parent DMA tag */
216 
217 	/* controller features, limits and status */
218 	int	sc_state;
219 #define AAC_STATE_SUSPEND	(1<<0)
220 #define	AAC_STATE_OPEN		(1<<1)
221 #define AAC_STATE_INTERRUPTS_ON	(1<<2)
222 #define AAC_STATE_AIF_SLEEPER	(1<<3)
223 	struct FsaRevision sc_revision;
224 
225 	int	sc_hwif;	/* controller hardware interface */
226 #define AAC_HWIF_I960RX		0
227 #define AAC_HWIF_STRONGARM	1
228 
229 	struct aac_common *sc_common;
230 	u_int32_t sc_common_busaddr;
231 	struct aac_interface sc_if;
232 
233 	/* XXX This should really be dynamic.  It is very wasteful now. */
234 	struct aac_ccb sc_ccbs[AAC_ADAP_NORM_CMD_ENTRIES];
235 	TAILQ_HEAD(, aac_ccb) sc_free_ccb, sc_ccbq;
236 	/* commands on hold for controller resources */
237 	TAILQ_HEAD(, aac_ccb) sc_ready;
238 	/* commands which have been returned by the controller */
239 	TAILQ_HEAD(, aac_ccb) sc_completed;
240 	LIST_HEAD(, scsi_xfer) sc_queue;
241 	struct scsi_xfer *sc_queuelast;
242 
243 	/* command management */
244 	struct aac_queue_table *sc_queues;
245 	struct aac_queue_entry *sc_qentries[AAC_QUEUE_COUNT];
246 
247 	struct {
248 		u_int8_t hd_present;
249 		u_int8_t hd_is_logdrv;
250 		u_int8_t hd_is_arraydrv;
251 		u_int8_t hd_is_master;
252 		u_int8_t hd_is_parity;
253 		u_int8_t hd_is_hotfix;
254 		u_int8_t hd_master_no;
255 		u_int8_t hd_lock;
256 		u_int8_t hd_heads;
257 		u_int8_t hd_secs;
258 		u_int16_t hd_devtype;
259 		u_int32_t hd_size;
260 		u_int8_t hd_ldr_no;
261 		u_int8_t hd_rw_attribs;
262 		u_int32_t hd_start_sec;
263 	} sc_hdr[AAC_MAX_CONTAINERS];
264 };
265 
266 /* XXX These have to become spinlocks in case of SMP */
267 #define AAC_LOCK(sc) splbio()
268 #define AAC_UNLOCK(sc, lock) splx(lock)
269 typedef int aac_lock_t;
270 
271 void	aacminphys __P((struct buf *));
272 int	aac_attach __P((struct aac_softc *));
273 int	aac_intr __P((void *));
274 
275 #ifdef __GNUC__
276 /* These all require correctly aligned buffers */
277 static __inline__ void aac_enc16 __P((u_int8_t *, u_int16_t));
278 static __inline__ void aac_enc32 __P((u_int8_t *, u_int32_t));
279 static __inline__ u_int16_t aac_dec16 __P((u_int8_t *));
280 static __inline__ u_int32_t aac_dec32 __P((u_int8_t *));
281 
282 static __inline__ void
283 aac_enc16(addr, value)
284 	u_int8_t *addr;
285 	u_int16_t value;
286 {
287 	*(u_int16_t *)addr = htole16(value);
288 }
289 
290 static __inline__ void
291 aac_enc32(addr, value)
292 	u_int8_t *addr;
293 	u_int32_t value;
294 {
295 	*(u_int32_t *)addr = htole32(value);
296 }
297 
298 static __inline__ u_int16_t
299 aac_dec16(addr)
300 	u_int8_t *addr;
301 {
302 	return letoh16(*(u_int16_t *)addr);
303 }
304 
305 static __inline__ u_int32_t
306 aac_dec32(addr)
307 	u_int8_t *addr;
308 {
309 	return letoh32(*(u_int32_t *)addr);
310 }
311 
312 /*
313  * Queue primitives
314  *
315  * These are broken out individually to make statistics gathering easier.
316  */
317 
318 static __inline__ void
319 aac_enqueue_completed(struct aac_ccb *ccb)
320 {
321 	struct aac_softc *sc = ccb->ac_xs->sc_link->adapter_softc;
322 	aac_lock_t lock;
323 
324 	lock = AAC_LOCK(sc);
325 	TAILQ_INSERT_TAIL(&sc->sc_completed, ccb, ac_chain);
326 	AAC_UNLOCK(sc, lock);
327 }
328 
329 static __inline__ struct aac_ccb *
330 aac_dequeue_completed(struct aac_softc *sc)
331 {
332 	struct aac_ccb *ccb;
333 	aac_lock_t lock;
334 
335 	lock = AAC_LOCK(sc);
336 	if ((ccb = TAILQ_FIRST(&sc->sc_completed)) != NULL)
337 		TAILQ_REMOVE(&sc->sc_completed, ccb, ac_chain);
338 	AAC_UNLOCK(sc, lock);
339 	return (ccb);
340 }
341 #endif
342