aacvar.h revision 74374
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 74374 2001-03-17 00:12:15Z gibbs $
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#include "opt_aac.h"
99
100#if __FreeBSD_version >= 500005
101# include <sys/taskqueue.h>
102#endif
103
104/*
105 * Per-container data structure
106 */
107struct aac_container
108{
109    struct aac_mntobj	co_mntobj;
110    device_t		co_disk;
111};
112
113/*
114 * Per-disk structure
115 */
116struct aac_disk
117{
118    device_t			ad_dev;
119    dev_t			ad_dev_t;
120    struct aac_softc		*ad_controller;
121    struct aac_container	*ad_container;
122    struct disk			ad_disk;
123    struct devstat		ad_stats;
124    struct disklabel		ad_label;
125    int				ad_flags;
126#define AAC_DISK_OPEN	(1<<0)
127    int				ad_cylinders;
128    int				ad_heads;
129    int				ad_sectors;
130    u_int32_t			ad_size;
131};
132
133/*
134 * Per-command control structure.
135 */
136struct aac_command
137{
138    TAILQ_ENTRY(aac_command)	cm_link;	/* list linkage */
139
140    struct aac_softc		*cm_sc;		/* controller that owns us */
141
142    struct aac_fib		*cm_fib;	/* FIB associated with this command */
143    u_int32_t			cm_fibphys;	/* bus address of the FIB */
144    struct bio			*cm_data;	/* pointer to data in kernel space */
145    u_int32_t			cm_datalen;	/* data length */
146    bus_dmamap_t		cm_datamap;	/* DMA map for bio data */
147    struct aac_sg_table		*cm_sgtable;	/* pointer to s/g table in command */
148
149    int				cm_flags;
150#define AAC_CMD_MAPPED		(1<<0)		/* command has had its data mapped */
151#define AAC_CMD_DATAIN		(1<<1)		/* command involves data moving from controller to host */
152#define AAC_CMD_DATAOUT		(1<<2)		/* command involves data moving from host to controller */
153#define AAC_CMD_COMPLETED	(1<<3)		/* command has been completed */
154#define AAC_CMD_TIMEDOUT	(1<<4)		/* command taken too long */
155
156    void			(* cm_complete)(struct aac_command *cm);
157    void			*cm_private;
158    time_t			cm_timestamp;	/* command creation time */
159};
160
161/*
162 * We gather a number of adapter-visible items into a single structure.
163 *
164 * The ordering of this strucure may be important; we copy the Linux driver:
165 *
166 * Adapter FIBs
167 * Init struct
168 * Queue headers (Comm Area)
169 * Printf buffer
170 *
171 * In addition, we add:
172 * Sync Fib
173 */
174struct aac_common {
175    /* fibs for the controller to send us messages */
176    struct aac_fib		ac_fibs[AAC_ADAPTER_FIBS];
177
178    /* the init structure */
179    struct aac_adapter_init	ac_init;
180
181    /* arena within which the queue structures are kept */
182    u_int8_t			ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
183
184    /* buffer for text messages from the controller */
185    char		       	ac_printf[AAC_PRINTF_BUFSIZE];
186
187    /* fib for synchronous commands */
188    struct aac_fib		ac_sync_fib;
189};
190
191/*
192 * Interface operations
193 */
194struct aac_interface
195{
196    int		(* aif_get_fwstatus)(struct aac_softc *sc);
197    void	(* aif_qnotify)(struct aac_softc *sc, int qbit);
198    int		(* aif_get_istatus)(struct aac_softc *sc);
199    void	(* aif_set_istatus)(struct aac_softc *sc, int mask);
200    void	(* aif_set_mailbox)(struct aac_softc *sc, u_int32_t command,
201				    u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3);
202    int		(* aif_get_mailboxstatus)(struct aac_softc *sc);
203    void	(* aif_set_interrupts)(struct aac_softc *sc, int enable);
204};
205extern struct aac_interface	aac_rx_interface;
206extern struct aac_interface	aac_sa_interface;
207
208#define AAC_GET_FWSTATUS(sc)		((sc)->aac_if.aif_get_fwstatus((sc)))
209#define AAC_QNOTIFY(sc, qbit)		((sc)->aac_if.aif_qnotify((sc), (qbit)))
210#define AAC_GET_ISTATUS(sc)		((sc)->aac_if.aif_get_istatus((sc)))
211#define AAC_CLEAR_ISTATUS(sc, mask)	((sc)->aac_if.aif_set_istatus((sc), (mask)))
212#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
213	((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), (arg3)))
214#define AAC_GET_MAILBOXSTATUS(sc)	((sc)->aac_if.aif_get_mailboxstatus((sc)))
215#define	AAC_MASK_INTERRUPTS(sc)		((sc)->aac_if.aif_set_interrupts((sc), 0))
216#define AAC_UNMASK_INTERRUPTS(sc)	((sc)->aac_if.aif_set_interrupts((sc), 1))
217
218#define AAC_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag, sc->aac_bhandle, reg, val)
219#define AAC_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag, sc->aac_bhandle, reg)
220#define AAC_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag, sc->aac_bhandle, reg, val)
221#define AAC_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag, sc->aac_bhandle, reg)
222#define AAC_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag, sc->aac_bhandle, reg, val)
223#define AAC_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag, sc->aac_bhandle, reg)
224
225/*
226 * Per-controller structure.
227 */
228struct aac_softc
229{
230    /* bus connections */
231    device_t			aac_dev;
232    struct resource		*aac_regs_resource;	/* register interface window */
233    int				aac_regs_rid;		/* resource ID */
234    bus_space_handle_t		aac_bhandle;		/* bus space handle */
235    bus_space_tag_t		aac_btag;		/* bus space tag */
236    bus_dma_tag_t		aac_parent_dmat;	/* parent DMA tag */
237    bus_dma_tag_t		aac_buffer_dmat;	/* data buffer/command DMA tag */
238    struct resource		*aac_irq;		/* interrupt */
239    int				aac_irq_rid;
240    void			*aac_intr;		/* interrupt handle */
241
242    /* controller features, limits and status */
243    int				aac_state;
244#define AAC_STATE_SUSPEND	(1<<0)
245#define	AAC_STATE_OPEN		(1<<1)
246#define AAC_STATE_INTERRUPTS_ON	(1<<2)
247#define AAC_STATE_AIF_SLEEPER	(1<<3)
248    struct FsaRevision		aac_revision;
249
250    /* controller hardware interface */
251    int				aac_hwif;
252#define AAC_HWIF_I960RX		0
253#define AAC_HWIF_STRONGARM	1
254#define AAC_HWIF_UNKNOWN	-1
255    bus_dma_tag_t		aac_common_dmat;	/* common structure DMA tag */
256    bus_dmamap_t		aac_common_dmamap;	/* common structure DMA map */
257    struct aac_common		*aac_common;
258    u_int32_t			aac_common_busaddr;
259    struct aac_interface	aac_if;
260
261    /* command/fib resources */
262    bus_dma_tag_t		aac_fib_dmat;	/* DMA tag for allocating FIBs */
263    struct aac_fib		*aac_fibs;
264    bus_dmamap_t		aac_fibmap;
265    u_int32_t			aac_fibphys;
266    struct aac_command		aac_command[AAC_FIB_COUNT];
267
268    /* command management */
269    TAILQ_HEAD(,aac_command)	aac_free;	/* command structures available for reuse */
270    TAILQ_HEAD(,aac_command)	aac_ready;	/* commands on hold for controller resources */
271    TAILQ_HEAD(,aac_command)	aac_busy;
272    TAILQ_HEAD(,aac_command)	aac_complete;	/* commands which have been returned by the controller */
273    struct bio_queue_head	aac_bioq;
274    struct aac_queue_table	*aac_queues;
275    struct aac_queue_entry	*aac_qentries[AAC_QUEUE_COUNT];
276
277    struct aac_qstat		aac_qstat[AACQ_COUNT];	/* queue statistics */
278
279    /* connected containters */
280    struct aac_container	aac_container[AAC_MAX_CONTAINERS];
281
282    /* delayed activity infrastructure */
283#if __FreeBSD_version >= 500005
284    struct task			aac_task_complete;	/* deferred-completion task */
285#endif
286    struct intr_config_hook	aac_ich;
287
288    /* management interface */
289    dev_t			aac_dev_t;
290    struct aac_aif_command	aac_aifq[AAC_AIFQ_LENGTH];
291    int				aac_aifq_head;
292    int				aac_aifq_tail;
293};
294
295
296/*
297 * Public functions
298 */
299extern void		aac_free(struct aac_softc *sc);
300extern int		aac_attach(struct aac_softc *sc);
301extern int		aac_detach(device_t dev);
302extern int		aac_shutdown(device_t dev);
303extern int		aac_suspend(device_t dev);
304extern int		aac_resume(device_t dev);
305extern void		aac_intr(void *arg);
306extern devclass_t	aac_devclass;
307extern void		aac_submit_bio(struct bio *bp);
308extern void		aac_biodone(struct bio *bp);
309
310/*
311 * Debugging levels:
312 *  0 - quiet, only emit warnings
313 *  1 - noisy, emit major function points and things done
314 *  2 - extremely noisy, emit trace items in loops, etc.
315 */
316#ifdef AAC_DEBUG
317# define debug(level, fmt, args...)						\
318    do {									\
319	if (level <= AAC_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args);	\
320    } while(0)
321# define debug_called(level)						\
322    do {								\
323	if (level <= AAC_DEBUG) printf(__FUNCTION__ ": called\n");	\
324    } while(0)
325
326extern void	aac_print_queues(struct aac_softc *sc);
327extern void	aac_panic(struct aac_softc *sc, char *reason);
328extern void	aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller);
329extern void	aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif);
330
331# define AAC_PRINT_FIB(sc, fib)	aac_print_fib(sc, fib, __FUNCTION__)
332
333#else
334# define debug(level, fmt, args...)
335# define debug_called(level)
336
337# define aac_print_queues(sc)
338# define aac_panic(sc, reason)
339# define aac_print_aif(sc, aif)
340
341# define AAC_PRINT_FIB(sc, fib)
342#endif
343
344struct aac_code_lookup {
345    char	*string;
346    u_int32_t	code;
347};
348
349/********************************************************************************
350 * Queue primitives for driver queues.
351 */
352#define AACQ_ADD(sc, qname)					\
353	do {							\
354	    struct aac_qstat *qs = &(sc)->aac_qstat[qname];	\
355								\
356	    qs->q_length++;					\
357	    if (qs->q_length > qs->q_max)			\
358		qs->q_max = qs->q_length;			\
359	} while(0)
360
361#define AACQ_REMOVE(sc, qname)    (sc)->aac_qstat[qname].q_length--
362#define AACQ_INIT(sc, qname)			\
363	do {					\
364	    sc->aac_qstat[qname].q_length = 0;	\
365	    sc->aac_qstat[qname].q_max = 0;	\
366	} while(0)
367
368
369#define AACQ_COMMAND_QUEUE(name, index)					\
370static __inline void							\
371aac_initq_ ## name (struct aac_softc *sc)				\
372{									\
373    TAILQ_INIT(&sc->aac_ ## name);					\
374    AACQ_INIT(sc, index);						\
375}									\
376static __inline void							\
377aac_enqueue_ ## name (struct aac_command *cm)				\
378{									\
379    int		s;							\
380									\
381    s = splbio();							\
382    TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ ## name, cm, cm_link);		\
383    AACQ_ADD(cm->cm_sc, index);						\
384    splx(s);								\
385}									\
386static __inline void							\
387aac_requeue_ ## name (struct aac_command *cm)				\
388{									\
389    int		s;							\
390									\
391    s = splbio();							\
392    TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ ## name, cm, cm_link);		\
393    AACQ_ADD(cm->cm_sc, index);						\
394    splx(s);								\
395}									\
396static __inline struct aac_command *					\
397aac_dequeue_ ## name (struct aac_softc *sc)				\
398{									\
399    struct aac_command	*cm;						\
400    int			s;						\
401									\
402    s = splbio();							\
403    if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) {		\
404	TAILQ_REMOVE(&sc->aac_ ## name, cm, cm_link);			\
405	AACQ_REMOVE(sc, index);						\
406    }									\
407    splx(s);								\
408    return(cm);								\
409}									\
410static __inline void							\
411aac_remove_ ## name (struct aac_command *cm)				\
412{									\
413    int			s;						\
414									\
415    s = splbio();							\
416    TAILQ_REMOVE(&cm->cm_sc->aac_ ## name, cm, cm_link);		\
417    AACQ_REMOVE(cm->cm_sc, index);					\
418    splx(s);								\
419}									\
420struct hack
421
422AACQ_COMMAND_QUEUE(free, AACQ_FREE);
423AACQ_COMMAND_QUEUE(ready, AACQ_READY);
424AACQ_COMMAND_QUEUE(busy, AACQ_BUSY);
425AACQ_COMMAND_QUEUE(complete, AACQ_COMPLETE);
426
427/*
428 * outstanding bio queue
429 */
430static __inline void
431aac_initq_bio(struct aac_softc *sc)
432{
433    bioq_init(&sc->aac_bioq);
434    AACQ_INIT(sc, AACQ_BIO);
435}
436
437static __inline void
438aac_enqueue_bio(struct aac_softc *sc, struct bio *bp)
439{
440    int		s;
441
442    s = splbio();
443    bioq_insert_tail(&sc->aac_bioq, bp);
444    AACQ_ADD(sc, AACQ_BIO);
445    splx(s);
446}
447
448static __inline struct bio *
449aac_dequeue_bio(struct aac_softc *sc)
450{
451    int		s;
452    struct bio	*bp;
453
454    s = splbio();
455    if ((bp = bioq_first(&sc->aac_bioq)) != NULL) {
456	bioq_remove(&sc->aac_bioq, bp);
457	AACQ_REMOVE(sc, AACQ_BIO);
458    }
459    splx(s);
460    return(bp);
461}
462