aacvar.h revision 67708
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 67708 2000-10-27 11:45:49Z phk $
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 in clusters as we need them; each cluster must be physically
49 * contiguous.  Set the number of FIBs to try to allocate in a cluster.
50 * Setting this value too high may result in FIBs not being available in conditions
51 * of high load with fragmented physical memory.  The value must be a multiple of
52 * (PAGE_SIZE / 512).
53 */
54#define AAC_CLUSTER_COUNT	64
55
56/*
57 * The controller reports status events in AIFs.  We hang on to a number of these
58 * in order to pass them out to user-space management tools.
59 */
60#define AAC_AIFQ_LENGTH		64
61
62/*
63 * Firmware messages are passed in the printf buffer.
64 */
65#define AAC_PRINTF_BUFSIZE	256
66
67/*
68 * We wait this many seconds for the adapter to come ready if it is still booting
69 */
70#define AAC_BOOT_TIMEOUT	(3 * 60)
71
72/*
73 * Timeout for immediate commands.
74 */
75#define AAC_IMMEDIATE_TIMEOUT	30
76
77/*
78 * Character device major numbers.
79 */
80#define AAC_DISK_MAJOR	200
81
82/********************************************************************************
83 ********************************************************************************
84                                                      Driver Variable Definitions
85 ********************************************************************************
86 ********************************************************************************/
87
88#if __FreeBSD_version >= 500005
89# include <sys/taskqueue.h>
90#endif
91
92/*
93 * Per-container data structure
94 */
95struct aac_container
96{
97    struct aac_mntobj	co_mntobj;
98    device_t		co_disk;
99};
100
101/*
102 * Per-disk structure
103 */
104struct aac_disk
105{
106    device_t			ad_dev;
107    dev_t			ad_dev_t;
108    struct aac_softc		*ad_controller;
109    struct aac_container	*ad_container;
110    struct disk			ad_disk;
111    struct devstat		ad_stats;
112    struct disklabel		ad_label;
113    int				ad_flags;
114#define AAC_DISK_OPEN	(1<<0)
115    int				ad_cylinders;
116    int				ad_heads;
117    int				ad_sectors;
118    u_int32_t			ad_size;
119};
120
121/*
122 * Per-command control structure.
123 */
124struct aac_command
125{
126    TAILQ_ENTRY(aac_command)	cm_link;	/* list linkage */
127
128    struct aac_softc		*cm_sc;		/* controller that owns us */
129
130    struct aac_fib		*cm_fib;	/* FIB associated with this command */
131    u_int32_t			cm_fibphys;	/* bus address of the FIB */
132    struct bio			*cm_data;	/* pointer to data in kernel space */
133    u_int32_t			cm_datalen;	/* data length */
134    bus_dmamap_t		cm_datamap;	/* DMA map for bio data */
135    struct aac_sg_table		*cm_sgtable;	/* pointer to s/g table in command */
136
137    int				cm_flags;
138#define AAC_CMD_MAPPED		(1<<0)		/* command has had its data mapped */
139#define AAC_CMD_DATAIN		(1<<1)		/* command involves data moving from controller to host */
140#define AAC_CMD_DATAOUT		(1<<2)		/* command involves data moving from host to controller */
141#define AAC_CMD_COMPLETED	(1<<3)		/* command has been completed */
142
143    void			(* cm_complete)(struct aac_command *cm);
144    void			*cm_private;
145    struct callout_handle	timeout_handle;	/* timeout handle */
146};
147
148/*
149 * Command/command packet cluster.
150 *
151 * Due to the difficulty of using the zone allocator to create a new
152 * zone from within a module, we use our own clustering to reduce
153 * memory wastage due to allocating lots of these small structures.
154 */
155struct aac_command_cluster
156{
157    TAILQ_ENTRY(aac_command_cluster)	cmc_link;
158    struct aac_fib			*cmc_fibs;
159    bus_dmamap_t			cmc_fibmap;
160    u_int32_t				cmc_fibphys;
161    struct aac_command			cmc_command[AAC_CLUSTER_COUNT];
162};
163
164/*
165 * We gather a number of adapter-visible items into a single structure.
166 *
167 * The ordering of this strucure may be important; we copy the Linux driver:
168 *
169 * Adapter FIBs
170 * Init struct
171 * Queue headers (Comm Area)
172 * Printf buffer
173 *
174 * In addition, we add:
175 * Sync Fib
176 */
177struct aac_common {
178    /* fibs for the controller to send us messages */
179    struct aac_fib		ac_fibs[AAC_ADAPTER_FIBS];
180
181    /* the init structure */
182    struct aac_adapter_init	ac_init;
183
184    /* arena within which the queue structures are kept */
185    u_int8_t			ac_qbuf[sizeof(struct aac_queue_table) + AAC_QUEUE_ALIGN];
186
187    /* buffer for text messages from the controller */
188    char		       	ac_printf[AAC_PRINTF_BUFSIZE];
189
190    /* fib for synchronous commands */
191    struct aac_fib		ac_sync_fib;
192};
193
194/*
195 * Interface operations
196 */
197struct aac_interface
198{
199    int		(* aif_get_fwstatus)(struct aac_softc *sc);
200    void	(* aif_qnotify)(struct aac_softc *sc, int qbit);
201    int		(* aif_get_istatus)(struct aac_softc *sc);
202    void	(* aif_set_istatus)(struct aac_softc *sc, int mask);
203    void	(* aif_set_mailbox)(struct aac_softc *sc, u_int32_t command,
204				    u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3);
205    int		(* aif_get_mailboxstatus)(struct aac_softc *sc);
206    void	(* aif_set_interrupts)(struct aac_softc *sc, int enable);
207};
208extern struct aac_interface	aac_rx_interface;
209extern struct aac_interface	aac_sa_interface;
210
211#define AAC_GET_FWSTATUS(sc)		((sc)->aac_if.aif_get_fwstatus((sc)))
212#define AAC_QNOTIFY(sc, qbit)		((sc)->aac_if.aif_qnotify((sc), (qbit)))
213#define AAC_GET_ISTATUS(sc)		((sc)->aac_if.aif_get_istatus((sc)))
214#define AAC_CLEAR_ISTATUS(sc, mask)	((sc)->aac_if.aif_set_istatus((sc), (mask)))
215#define AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3) \
216	((sc)->aac_if.aif_set_mailbox((sc), (command), (arg0), (arg1), (arg2), (arg3)))
217#define AAC_GET_MAILBOXSTATUS(sc)	((sc)->aac_if.aif_get_mailboxstatus((sc)))
218#define	AAC_MASK_INTERRUPTS(sc)		((sc)->aac_if.aif_set_interrupts((sc), 0))
219#define AAC_UNMASK_INTERRUPTS(sc)	((sc)->aac_if.aif_set_interrupts((sc), 1))
220
221#define AAC_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag, sc->aac_bhandle, reg, val)
222#define AAC_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag, sc->aac_bhandle, reg)
223#define AAC_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag, sc->aac_bhandle, reg, val)
224#define AAC_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag, sc->aac_bhandle, reg)
225#define AAC_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag, sc->aac_bhandle, reg, val)
226#define AAC_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag, sc->aac_bhandle, reg)
227
228/*
229 * Per-controller structure.
230 */
231struct aac_softc
232{
233    /* bus connections */
234    device_t		aac_dev;
235    struct resource	*aac_regs_resource;	/* register interface window */
236    int			aac_regs_rid;		/* resource ID */
237    bus_space_handle_t	aac_bhandle;		/* bus space handle */
238    bus_space_tag_t	aac_btag;		/* bus space tag */
239    bus_dma_tag_t	aac_parent_dmat;	/* parent DMA tag */
240    bus_dma_tag_t	aac_buffer_dmat;	/* data buffer/command DMA tag */
241    struct resource	*aac_irq;		/* interrupt */
242    int			aac_irq_rid;
243    void		*aac_intr;		/* interrupt handle */
244
245    /* controller features, limits and status */
246    int			aac_state;
247#define AAC_STATE_SUSPEND	(1<<0)
248#define	AAC_STATE_OPEN		(1<<1)
249#define AAC_STATE_INTERRUPTS_ON	(1<<2)
250#define AAC_STATE_AIF_SLEEPER	(1<<3)
251    struct FsaRevision	aac_revision;
252
253    /* controller hardware interface */
254    int				aac_hwif;
255#define AAC_HWIF_I960RX		0
256#define AAC_HWIF_STRONGARM	1
257    bus_dma_tag_t		aac_common_dmat;	/* common structure DMA tag */
258    bus_dmamap_t		aac_common_dmamap;	/* common structure DMA map */
259    struct aac_common		*aac_common;
260    u_int32_t			aac_common_busaddr;
261    struct aac_interface	aac_if;
262
263    /* command/fib resources */
264    TAILQ_HEAD(,aac_command_cluster)	aac_clusters;	/* command memory blocks */
265    bus_dma_tag_t			aac_fib_dmat;	/* DMA tag for allocating FIBs */
266
267    /* command management */
268    TAILQ_HEAD(,aac_command)	aac_freecmds;	/* command structures available for reuse */
269    TAILQ_HEAD(,aac_command)	aac_ready;	/* commands on hold for controller resources */
270    TAILQ_HEAD(,aac_command)	aac_completed;	/* 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    /* connected containters */
276    struct aac_container	aac_container[AAC_MAX_CONTAINERS];
277
278    /* delayed activity infrastructure */
279#if __FreeBSD_version >= 500005
280    struct task			aac_task_complete;	/* deferred-completion task */
281#endif
282    struct intr_config_hook	aac_ich;
283
284    /* management interface */
285    dev_t			aac_dev_t;
286    struct aac_aif_command	aac_aifq[AAC_AIFQ_LENGTH];
287    int				aac_aifq_head;
288    int				aac_aifq_tail;
289};
290
291
292/*
293 * Public functions
294 */
295extern void		aac_free(struct aac_softc *sc);
296extern int		aac_attach(struct aac_softc *sc);
297extern int		aac_detach(device_t dev);
298extern int		aac_shutdown(device_t dev);
299extern int		aac_suspend(device_t dev);
300extern int		aac_resume(device_t dev);
301extern void		aac_intr(void *arg);
302extern devclass_t	aac_devclass;
303extern void		aac_submit_bio(struct bio *bp);
304extern void		aac_complete_bio(struct bio *bp);
305
306/*
307 * Debugging levels:
308 *  0 - quiet, only emit warnings
309 *  1 - noisy, emit major function points and things done
310 *  2 - extremely noisy, emit trace items in loops, etc.
311 */
312#ifdef AAC_DEBUG
313#define debug(level, fmt, args...)	do { if (level <= AAC_DEBUG) printf("%s: " fmt "\n", __FUNCTION__ , ##args); } while(0)
314#define debug_called(level)		do { if (level <= AAC_DEBUG) printf(__FUNCTION__ ": called\n"); } while(0)
315
316extern void	aac_print_queues(struct aac_softc *sc);
317extern void	aac_panic(struct aac_softc *sc, char *reason);
318extern void	aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller);
319extern void	aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif);
320
321#define AAC_PRINT_FIB(sc, fib)	aac_print_fib(sc, fib, __FUNCTION__)
322
323#else
324#define debug(level, fmt, args...)
325#define debug_called(level)
326
327#define aac_print_queues(sc)
328#define aac_panic(sc, reason)
329#define aac_print_aif(sc, aif)
330
331#define AAC_PRINT_FIB(sc, fib)
332#endif
333
334struct aac_code_lookup {
335    char	*string;
336    u_int32_t	code;
337};
338
339/********************************************************************************
340 * Queue primitives
341 *
342 * These are broken out individually to make statistics gathering easier.
343 */
344
345static __inline void
346aac_enqueue_ready(struct aac_command *cm)
347{
348    int		s;
349
350    s = splbio();
351    TAILQ_INSERT_TAIL(&cm->cm_sc->aac_ready, cm, cm_link);
352    splx(s);
353}
354
355static __inline void
356aac_requeue_ready(struct aac_command *cm)
357{
358    int		s;
359
360    s = splbio();
361    TAILQ_INSERT_HEAD(&cm->cm_sc->aac_ready, cm, cm_link);
362    splx(s);
363}
364
365static __inline struct aac_command *
366aac_dequeue_ready(struct aac_softc *sc)
367{
368    struct aac_command	*cm;
369    int			s;
370
371    s = splbio();
372    if ((cm = TAILQ_FIRST(&sc->aac_ready)) != NULL)
373	TAILQ_REMOVE(&sc->aac_ready, cm, cm_link);
374    splx(s);
375    return(cm);
376}
377
378static __inline void
379aac_enqueue_completed(struct aac_command *cm)
380{
381    int		s;
382
383    s = splbio();
384    TAILQ_INSERT_TAIL(&cm->cm_sc->aac_completed, cm, cm_link);
385    splx(s);
386}
387
388static __inline struct aac_command *
389aac_dequeue_completed(struct aac_softc *sc)
390{
391    struct aac_command	*cm;
392    int			s;
393
394    s = splbio();
395    if ((cm = TAILQ_FIRST(&sc->aac_completed)) != NULL)
396	TAILQ_REMOVE(&sc->aac_completed, cm, cm_link);
397    splx(s);
398    return(cm);
399}
400
401static __inline void
402aac_enqueue_free(struct aac_command *cm)
403{
404    int		s;
405
406    s = splbio();
407    TAILQ_INSERT_HEAD(&cm->cm_sc->aac_freecmds, cm, cm_link);
408    splx(s);
409}
410
411static __inline struct aac_command *
412aac_dequeue_free(struct aac_softc *sc)
413{
414    struct aac_command	*cm;
415    int			s;
416
417    s = splbio();
418    if ((cm = TAILQ_FIRST(&sc->aac_freecmds)) != NULL)
419	TAILQ_REMOVE(&sc->aac_freecmds, cm, cm_link);
420    splx(s);
421    return(cm);
422}
423
424static __inline void
425aac_enqueue_cluster(struct aac_softc *sc, struct aac_command_cluster *cmc)
426{
427    int		s;
428
429    s = splbio();
430    TAILQ_INSERT_HEAD(&sc->aac_clusters, cmc, cmc_link);
431    splx(s);
432}
433
434static __inline struct aac_command_cluster *
435aac_dequeue_cluster(struct aac_softc *sc)
436{
437    struct aac_command_cluster	*cmc;
438    int				s;
439
440    s = splbio();
441    if ((cmc = TAILQ_FIRST(&sc->aac_clusters)) != NULL)
442	TAILQ_REMOVE(&sc->aac_clusters, cmc, cmc_link);
443    splx(s);
444    return(cmc);
445}
446