aacvar.h revision 70393
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *	$FreeBSD: head/sys/dev/aac/aacvar.h 70393 2000-12-27 13:14:56Z msmith $
28 */
29
30/********************************************************************************
31 ********************************************************************************
32                                                     Driver Parameter Definitions
33 ********************************************************************************
34 ********************************************************************************/
35
36/*
37 * The firmware interface allows for a 16-bit s/g list length.  We limit
38 * ourselves to a reasonable maximum and ensure alignment.
39 */
40#define AAC_MAXSGENTRIES	64	/* max S/G entries, limit 65535 */
41
42/*
43 * We allocate a small set of FIBs for the adapter to use to send us messages.
44 */
45#define AAC_ADAPTER_FIBS	8
46
47/*
48 * FIBs are allocated up-front, and the pool isn't grown.  We should allocate
49 * enough here to let us keep the adapter busy without wasting large amounts
50 * of kernel memory.  The current interface implementation limits us to 512
51 * FIBs queued for the adapter at any one time.
52 */
53#define AAC_FIB_COUNT		128
54
55/*
56 * The controller reports status events in AIFs.  We hang on to a number of these
57 * in order to pass them out to user-space management tools.
58 */
59#define AAC_AIFQ_LENGTH		64
60
61/*
62 * Firmware messages are passed in the printf buffer.
63 */
64#define AAC_PRINTF_BUFSIZE	256
65
66/*
67 * We wait this many seconds for the adapter to come ready if it is still booting
68 */
69#define AAC_BOOT_TIMEOUT	(3 * 60)
70
71/*
72 * Timeout for immediate commands.
73 */
74#define AAC_IMMEDIATE_TIMEOUT	30		/* seconds */
75
76/*
77 * Timeout for normal commands
78 */
79#define AAC_CMD_TIMEOUT		30		/* seconds */
80
81/*
82 * Rate at which we periodically check for timed out commands and kick the
83 * controller.
84 */
85#define AAC_PERIODIC_INTERVAL	10		/* seconds */
86
87/*
88 * Character device major numbers.
89 */
90#define AAC_DISK_MAJOR	200
91
92/********************************************************************************
93 ********************************************************************************
94                                                      Driver Variable Definitions
95 ********************************************************************************
96 ********************************************************************************/
97
98#if __FreeBSD_version >= 500005
99# include <sys/taskqueue.h>
100#endif
101
102/*
103 * Per-container data structure
104 */
105struct aac_container
106{
107    struct aac_mntobj	co_mntobj;
108    device_t		co_disk;
109};
110
111/*
112 * Per-disk structure
113 */
114struct aac_disk
115{
116    device_t			ad_dev;
117    dev_t			ad_dev_t;
118    struct aac_softc		*ad_controller;
119    struct aac_container	*ad_container;
120    struct disk			ad_disk;
121    struct devstat		ad_stats;
122    struct disklabel		ad_label;
123    int				ad_flags;
124#define AAC_DISK_OPEN	(1<<0)
125    int				ad_cylinders;
126    int				ad_heads;
127    int				ad_sectors;
128    u_int32_t			ad_size;
129};
130
131/*
132 * Per-command control structure.
133 */
134struct aac_command
135{
136    TAILQ_ENTRY(aac_command)	cm_link;	/* list linkage */
137
138    struct aac_softc		*cm_sc;		/* controller that owns us */
139
140    struct aac_fib		*cm_fib;	/* FIB associated with this command */
141    u_int32_t			cm_fibphys;	/* bus address of the FIB */
142    struct bio			*cm_data;	/* pointer to data in kernel space */
143    u_int32_t			cm_datalen;	/* data length */
144    bus_dmamap_t		cm_datamap;	/* DMA map for bio data */
145    struct aac_sg_table		*cm_sgtable;	/* pointer to s/g table in command */
146
147    int				cm_flags;
148#define AAC_CMD_MAPPED		(1<<0)		/* command has had its data mapped */
149#define AAC_CMD_DATAIN		(1<<1)		/* command involves data moving from controller to host */
150#define AAC_CMD_DATAOUT		(1<<2)		/* command involves data moving from host to controller */
151#define AAC_CMD_COMPLETED	(1<<3)		/* command has been completed */
152#define AAC_CMD_TIMEDOUT	(1<<4)		/* command taken too long */
153
154    void			(* cm_complete)(struct aac_command *cm);
155    void			*cm_private;
156    time_t			cm_timestamp;	/* command creation time */
157};
158
159/*
160 * We gather a number of adapter-visible items into a single structure.
161 *
162 * The ordering of this strucure may be important; we copy the Linux driver:
163 *
164 * Adapter FIBs
165 * Init struct
166 * Queue headers (Comm Area)
167 * Printf buffer
168 *
169 * In addition, we add:
170 * Sync Fib
171 */
172struct aac_common {
173    /* fibs for the controller to send us messages */
174    struct aac_fib		ac_fibs[AAC_ADAPTER_FIBS];
175
176    /* the init structure */
177    struct aac_adapter_init	ac_init;
178
179    /* arena within which the queue structures are kept */
180    u_int8_t			ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
181
182    /* buffer for text messages from the controller */
183    char		       	ac_printf[AAC_PRINTF_BUFSIZE];
184
185    /* fib for synchronous commands */
186    struct aac_fib		ac_sync_fib;
187};
188
189/*
190 * Interface operations
191 */
192struct aac_interface
193{
194    int		(* aif_get_fwstatus)(struct aac_softc *sc);
195    void	(* aif_qnotify)(struct aac_softc *sc, int qbit);
196    int		(* aif_get_istatus)(struct aac_softc *sc);
197    void	(* aif_set_istatus)(struct aac_softc *sc, int mask);
198    void	(* aif_set_mailbox)(struct aac_softc *sc, u_int32_t command,
199				    u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3);
200    int		(* aif_get_mailboxstatus)(struct aac_softc *sc);
201    void	(* aif_set_interrupts)(struct aac_softc *sc, int enable);
202};
203extern struct aac_interface	aac_rx_interface;
204extern struct aac_interface	aac_sa_interface;
205
206#define AAC_GET_FWSTATUS(sc)		((sc)->aac_if.aif_get_fwstatus((sc)))
207#define AAC_QNOTIFY(sc, qbit)		((sc)->aac_if.aif_qnotify((sc), (qbit)))
208#define AAC_GET_ISTATUS(sc)		((sc)->aac_if.aif_get_istatus((sc)))
209#define AAC_CLEAR_ISTATUS(sc, mask)	((sc)->aac_if.aif_set_istatus((sc), (mask)))
210#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
211	((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), (arg3)))
212#define AAC_GET_MAILBOXSTATUS(sc)	((sc)->aac_if.aif_get_mailboxstatus((sc)))
213#define	AAC_MASK_INTERRUPTS(sc)		((sc)->aac_if.aif_set_interrupts((sc), 0))
214#define AAC_UNMASK_INTERRUPTS(sc)	((sc)->aac_if.aif_set_interrupts((sc), 1))
215
216#define AAC_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag, sc->aac_bhandle, reg, val)
217#define AAC_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag, sc->aac_bhandle, reg)
218#define AAC_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag, sc->aac_bhandle, reg, val)
219#define AAC_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag, sc->aac_bhandle, reg)
220#define AAC_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag, sc->aac_bhandle, reg, val)
221#define AAC_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag, sc->aac_bhandle, reg)
222
223/*
224 * Per-controller structure.
225 */
226struct aac_softc
227{
228    /* bus connections */
229    device_t			aac_dev;
230    struct resource		*aac_regs_resource;	/* register interface window */
231    int				aac_regs_rid;		/* resource ID */
232    bus_space_handle_t		aac_bhandle;		/* bus space handle */
233    bus_space_tag_t		aac_btag;		/* bus space tag */
234    bus_dma_tag_t		aac_parent_dmat;	/* parent DMA tag */
235    bus_dma_tag_t		aac_buffer_dmat;	/* data buffer/command DMA tag */
236    struct resource		*aac_irq;		/* interrupt */
237    int				aac_irq_rid;
238    void			*aac_intr;		/* interrupt handle */
239
240    /* controller features, limits and status */
241    int				aac_state;
242#define AAC_STATE_SUSPEND	(1<<0)
243#define	AAC_STATE_OPEN		(1<<1)
244#define AAC_STATE_INTERRUPTS_ON	(1<<2)
245#define AAC_STATE_AIF_SLEEPER	(1<<3)
246    struct FsaRevision		aac_revision;
247
248    /* controller hardware interface */
249    int				aac_hwif;
250#define AAC_HWIF_I960RX		0
251#define AAC_HWIF_STRONGARM	1
252#define AAC_HWIF_UNKNOWN	-1
253    bus_dma_tag_t		aac_common_dmat;	/* common structure DMA tag */
254    bus_dmamap_t		aac_common_dmamap;	/* common structure DMA map */
255    struct aac_common		*aac_common;
256    u_int32_t			aac_common_busaddr;
257    struct aac_interface	aac_if;
258
259    /* command/fib resources */
260    bus_dma_tag_t		aac_fib_dmat;	/* DMA tag for allocating FIBs */
261    struct aac_fib		*aac_fibs;
262    bus_dmamap_t		aac_fibmap;
263    u_int32_t			aac_fibphys;
264    struct aac_command		aac_command[AAC_FIB_COUNT];
265
266    /* command management */
267    TAILQ_HEAD(,aac_command)	aac_free;	/* command structures available for reuse */
268    TAILQ_HEAD(,aac_command)	aac_ready;	/* commands on hold for controller resources */
269    TAILQ_HEAD(,aac_command)	aac_busy;
270    TAILQ_HEAD(,aac_command)	aac_complete;	/* commands which have been returned by the controller */
271    struct bio_queue_head	aac_bioq;
272    struct aac_queue_table	*aac_queues;
273    struct aac_queue_entry	*aac_qentries[AAC_QUEUE_COUNT];
274
275    struct aac_qstat		aac_qstat[AACQ_COUNT];	/* queue statistics */
276
277    /* connected containters */
278    struct aac_container	aac_container[AAC_MAX_CONTAINERS];
279
280    /* delayed activity infrastructure */
281#if __FreeBSD_version >= 500005
282    struct task			aac_task_complete;	/* deferred-completion task */
283#endif
284    struct intr_config_hook	aac_ich;
285
286    /* management interface */
287    dev_t			aac_dev_t;
288    struct aac_aif_command	aac_aifq[AAC_AIFQ_LENGTH];
289    int				aac_aifq_head;
290    int				aac_aifq_tail;
291};
292
293
294/*
295 * Public functions
296 */
297extern void		aac_free(struct aac_softc *sc);
298extern int		aac_attach(struct aac_softc *sc);
299extern int		aac_detach(device_t dev);
300extern int		aac_shutdown(device_t dev);
301extern int		aac_suspend(device_t dev);
302extern int		aac_resume(device_t dev);
303extern void		aac_intr(void *arg);
304extern devclass_t	aac_devclass;
305extern void		aac_submit_bio(struct bio *bp);
306extern void		aac_biodone(struct bio *bp);
307
308/*
309 * Debugging levels:
310 *  0 - quiet, only emit warnings
311 *  1 - noisy, emit major function points and things done
312 *  2 - extremely noisy, emit trace items in loops, etc.
313 */
314#ifdef AAC_DEBUG
315# define debug(level, fmt, args...)						\
316    do {									\
317	if (level <= AAC_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args);	\
318    } while(0)
319# define debug_called(level)						\
320    do {								\
321	if (level <= AAC_DEBUG) printf(__FUNCTION__ ": called\n");	\
322    } while(0)
323
324extern void	aac_print_queues(struct aac_softc *sc);
325extern void	aac_panic(struct aac_softc *sc, char *reason);
326extern void	aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller);
327extern void	aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif);
328
329# define AAC_PRINT_FIB(sc, fib)	aac_print_fib(sc, fib, __FUNCTION__)
330
331#else
332# define debug(level, fmt, args...)
333# define debug_called(level)
334
335# define aac_print_queues(sc)
336# define aac_panic(sc, reason)
337# define aac_print_aif(sc, aif)
338
339# define AAC_PRINT_FIB(sc, fib)
340#endif
341
342struct aac_code_lookup {
343    char	*string;
344    u_int32_t	code;
345};
346
347/********************************************************************************
348 * Queue primitives for driver queues.
349 */
350#define AACQ_ADD(sc, qname)					\
351	do {							\
352	    struct aac_qstat *qs = &(sc)->aac_qstat[qname];	\
353								\
354	    qs->q_length++;					\
355	    if (qs->q_length > qs->q_max)			\
356		qs->q_max = qs->q_length;			\
357	} while(0)
358
359#define AACQ_REMOVE(sc, qname)    (sc)->aac_qstat[qname].q_length--
360#define AACQ_INIT(sc, qname)			\
361	do {					\
362	    sc->aac_qstat[qname].q_length = 0;	\
363	    sc->aac_qstat[qname].q_max = 0;	\
364	} while(0)
365
366
367#define AACQ_COMMAND_QUEUE(name, index)					\
368static __inline void							\
369aac_initq_ ## name (struct aac_softc *sc)				\
370{									\
371    TAILQ_INIT(&sc->aac_ ## name);					\
372    AACQ_INIT(sc, index);						\
373}									\
374static __inline void							\
375aac_enqueue_ ## name (struct aac_command *cm)				\
376{									\
377    int		s;							\
378									\
379    s = splbio();							\
380    TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link);		\
381    AACQ_ADD(cm->cm_sc, index);						\
382    splx(s);								\
383}									\
384static __inline void							\
385aac_requeue_ ## name (struct aac_command *cm)				\
386{									\
387    int		s;							\
388									\
389    s = splbio();							\
390    TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link);		\
391    AACQ_ADD(cm->cm_sc, index);						\
392    splx(s);								\
393}									\
394static __inline struct aac_command *					\
395aac_dequeue_ ## name (struct aac_softc *sc)				\
396{									\
397    struct aac_command	*cm;						\
398    int			s;						\
399									\
400    s = splbio();							\
401    if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) {		\
402	TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link);			\
403	AACQ_REMOVE(sc, index);						\
404    }									\
405    splx(s);								\
406    return(cm);								\
407}									\
408static __inline void							\
409aac_remove_ ## name (struct aac_command *cm)				\
410{									\
411    int			s;						\
412									\
413    s = splbio();							\
414    TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link);		\
415    AACQ_REMOVE(cm->cm_sc, index);					\
416    splx(s);								\
417}									\
418struct hack
419
420AACQ_COMMAND_QUEUE(free, AACQ_FREE);
421AACQ_COMMAND_QUEUE(ready, AACQ_READY);
422AACQ_COMMAND_QUEUE(busy, AACQ_BUSY);
423AACQ_COMMAND_QUEUE(complete, AACQ_COMPLETE);
424
425/*
426 * outstanding bio queue
427 */
428static __inline void
429aac_initq_bio(struct aac_softc *sc)
430{
431    bioq_init(&sc->aac_bioq);
432    AACQ_INIT(sc, AACQ_BIO);
433}
434
435static __inline void
436aac_enqueue_bio(struct aac_softc *sc, struct bio *bp)
437{
438    int		s;
439
440    s = splbio();
441    bioq_insert_tail(&sc->aac_bioq, bp);
442    AACQ_ADD(sc, AACQ_BIO);
443    splx(s);
444}
445
446static __inline struct bio *
447aac_dequeue_bio(struct aac_softc *sc)
448{
449    int		s;
450    struct bio	*bp;
451
452    s = splbio();
453    if ((bp = bioq_first(&sc->aac_bioq)) != NULL) {
454	bioq_remove(&sc->aac_bioq, bp);
455	AACQ_REMOVE(sc, AACQ_BIO);
456    }
457    splx(s);
458    return(bp);
459}
460