aac.c revision 68920
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/aac.c 68920 2000-11-19 23:46:21Z scottl $
28 */
29
30/*
31 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h>
38
39#include <dev/aac/aac_compat.h>
40
41#include <sys/bus.h>
42#include <sys/conf.h>
43#include <sys/devicestat.h>
44#include <sys/disk.h>
45#include <sys/file.h>
46#include <sys/signalvar.h>
47
48#include <machine/bus_memio.h>
49#include <machine/bus.h>
50#include <machine/resource.h>
51
52#include <dev/aac/aacreg.h>
53#include <dev/aac/aacvar.h>
54#include <dev/aac/aac_tables.h>
55#include <dev/aac/aac_ioctl.h>
56
57devclass_t	aac_devclass;
58
59static void	aac_startup(void *arg);
60
61/* Command Processing */
62static void	aac_startio(struct aac_softc *sc);
63static void	aac_timeout(struct aac_command *cm);
64static int	aac_start(struct aac_command *cm);
65static void	aac_complete(void *context, int pending);
66static int	aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
67static void	aac_bio_complete(struct aac_command *cm);
68static int	aac_wait_command(struct aac_command *cm, int timeout);
69static void	aac_host_command(struct aac_softc *sc);
70static void	aac_host_response(struct aac_softc *sc);
71
72/* Command Buffer Management */
73static int	aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp);
74static void	aac_release_command(struct aac_command *cm);
75static void	aac_map_command_cluster(void *arg, bus_dma_segment_t *segs, int nseg, int error);
76static void	aac_alloc_command_cluster(struct aac_softc *sc);
77static void	aac_free_command_cluster(struct aac_command_cluster *cmc);
78static void	aac_map_command(struct aac_command *cm);
79static void	aac_unmap_command(struct aac_command *cm);
80
81/* Hardware Interface */
82static void	aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error);
83static int	aac_init(struct aac_softc *sc);
84static int	aac_sync_command(struct aac_softc *sc, u_int32_t command,
85				 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
86				 u_int32_t *sp);
87static int	aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
88			     void *data, u_int16_t datasize,
89			     void *result, u_int16_t *resultsize);
90static int	aac_enqueue_fib(struct aac_softc *sc, int queue, u_int32_t fib_size, u_int32_t fib_addr);
91static int	aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, struct aac_fib **fib_addr);
92
93/* StrongARM interface */
94static int	aac_sa_get_fwstatus(struct aac_softc *sc);
95static void	aac_sa_qnotify(struct aac_softc *sc, int qbit);
96static int	aac_sa_get_istatus(struct aac_softc *sc);
97static void	aac_sa_clear_istatus(struct aac_softc *sc, int mask);
98static void	aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
99				   u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3);
100static int	aac_sa_get_mailboxstatus(struct aac_softc *sc);
101static void	aac_sa_set_interrupts(struct aac_softc *sc, int enable);
102
103struct aac_interface aac_sa_interface = {
104    aac_sa_get_fwstatus,
105    aac_sa_qnotify,
106    aac_sa_get_istatus,
107    aac_sa_clear_istatus,
108    aac_sa_set_mailbox,
109    aac_sa_get_mailboxstatus,
110    aac_sa_set_interrupts
111};
112
113/* i960Rx interface */
114static int	aac_rx_get_fwstatus(struct aac_softc *sc);
115static void	aac_rx_qnotify(struct aac_softc *sc, int qbit);
116static int	aac_rx_get_istatus(struct aac_softc *sc);
117static void	aac_rx_clear_istatus(struct aac_softc *sc, int mask);
118static void	aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
119				   u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3);
120static int	aac_rx_get_mailboxstatus(struct aac_softc *sc);
121static void	aac_rx_set_interrupts(struct aac_softc *sc, int enable);
122
123struct aac_interface aac_rx_interface = {
124    aac_rx_get_fwstatus,
125    aac_rx_qnotify,
126    aac_rx_get_istatus,
127    aac_rx_clear_istatus,
128    aac_rx_set_mailbox,
129    aac_rx_get_mailboxstatus,
130    aac_rx_set_interrupts
131};
132
133/* Debugging and Diagnostics */
134static void	aac_describe_controller(struct aac_softc *sc);
135static char	*aac_describe_code(struct aac_code_lookup *table, u_int32_t code);
136
137/* Management Interface */
138static d_open_t		aac_open;
139static d_close_t	aac_close;
140static d_ioctl_t	aac_ioctl;
141static int		aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
142static void		aac_handle_aif(struct aac_softc *sc, struct aac_aif_command *aif);
143static int		aac_return_aif(struct aac_softc *sc, caddr_t uptr);
144#ifdef AAC_COMPAT_LINUX
145static int		aac_linux_rev_check(struct aac_softc *sc, caddr_t udata);
146static int		aac_linux_getnext_aif(struct aac_softc *sc, caddr_t arg);
147#endif
148
149#define AAC_CDEV_MAJOR	150
150
151static struct cdevsw aac_cdevsw = {
152    aac_open,		/* open */
153    aac_close,		/* close */
154    noread,		/* read */
155    nowrite,		/* write */
156    aac_ioctl,		/* ioctl */
157    nopoll,		/* poll */
158    nommap,		/* mmap */
159    nostrategy,		/* strategy */
160    "aac",		/* name */
161    AAC_CDEV_MAJOR,	/* major */
162    nodump,		/* dump */
163    nopsize,		/* psize */
164    0,			/* flags */
165    -1,			/* bmaj */
166};
167
168/* Timeout for giving up on a command sent to the controller */
169#ifndef AAC_CMD_TIMEOUT
170#define AAC_CMD_TIMEOUT 15
171#endif
172
173/********************************************************************************
174 ********************************************************************************
175                                                                 Device Interface
176 ********************************************************************************
177 ********************************************************************************/
178
179/********************************************************************************
180 * Initialise the controller and softc
181 */
182int
183aac_attach(struct aac_softc *sc)
184{
185    int		error, unit;
186
187    debug_called(1);
188
189    /*
190     * Initialise per-controller queues.
191     */
192    TAILQ_INIT(&sc->aac_freecmds);
193    TAILQ_INIT(&sc->aac_ready);
194    TAILQ_INIT(&sc->aac_completed);
195    TAILQ_INIT(&sc->aac_clusters);
196    bioq_init(&sc->aac_bioq);
197
198#if __FreeBSD_version >= 500005
199    /*
200     * Initialise command-completion task.
201     */
202    TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
203#endif
204
205    /* disable interrupts before we enable anything */
206    AAC_MASK_INTERRUPTS(sc);
207
208    /* mark controller as suspended until we get ourselves organised */
209    sc->aac_state |= AAC_STATE_SUSPEND;
210
211    /*
212     * Initialise the adapter.
213     */
214    if ((error = aac_init(sc)))
215	return(error);
216
217    /*
218     * Print a little information about the controller.
219     */
220    aac_describe_controller(sc);
221
222    /*
223     * Register to probe our containers later.
224     */
225    bzero(&sc->aac_ich, sizeof(struct intr_config_hook));
226    sc->aac_ich.ich_func = aac_startup;
227    sc->aac_ich.ich_arg = sc;
228    if (config_intrhook_establish(&sc->aac_ich) != 0) {
229        device_printf(sc->aac_dev, "can't establish configuration hook\n");
230        return(ENXIO);
231    }
232
233    /*
234     * Make the control device.
235     */
236    unit = device_get_unit(sc->aac_dev);
237    sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_WHEEL, 0644, "aac%d", unit);
238    sc->aac_dev_t->si_drv1 = sc;
239
240    return(0);
241}
242
243/********************************************************************************
244 * Probe for containers, create disks.
245 */
246static void
247aac_startup(void *arg)
248{
249    struct aac_softc		*sc = (struct aac_softc *)arg;
250    struct aac_mntinfo		mi;
251    struct aac_mntinforesponse	mir;
252    device_t			child;
253    u_int16_t			rsize;
254    int				i;
255
256    debug_called(1);
257
258    /* disconnect ourselves from the intrhook chain */
259    config_intrhook_disestablish(&sc->aac_ich);
260
261    /* loop over possible containers */
262    mi.Command = VM_NameServe;
263    mi.MntType = FT_FILESYS;
264    for (i = 0; i < AAC_MAX_CONTAINERS; i++) {
265	/* request information on this container */
266	mi.MntCount = i;
267	if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(struct aac_mntinfo), &mir, &rsize)) {
268	    debug(2, "error probing container %d", i);
269	    continue;
270	}
271	/* check response size */
272	if (rsize != sizeof(mir)) {
273	    debug(2, "container info response wrong size (%d should be %d)", rsize, sizeof(mir));
274	    continue;
275	}
276	/*
277	 * Check container volume type for validity.  Note that many of the possible types
278	 * may never show up.
279	 */
280	if ((mir.Status == ST_OK) && (mir.MntTable[0].VolType != CT_NONE)) {
281	    debug(1, "%d: id %x  name '%.16s'  size %u  type %d",
282		  i, mir.MntTable[0].ObjectId,
283		  mir.MntTable[0].FileSystemName, mir.MntTable[0].Capacity,
284		  mir.MntTable[0].VolType);
285
286	    if ((child = device_add_child(sc->aac_dev, NULL, -1)) == NULL) {
287		device_printf(sc->aac_dev, "device_add_child failed\n");
288	    } else {
289		device_set_ivars(child, &sc->aac_container[i]);
290	    }
291	    device_set_desc(child, aac_describe_code(aac_container_types, mir.MntTable[0].VolType));
292	    sc->aac_container[i].co_disk = child;
293	    sc->aac_container[i].co_mntobj = mir.MntTable[0];
294	}
295    }
296
297    /* poke the bus to actually attach the child devices */
298    if (bus_generic_attach(sc->aac_dev))
299	device_printf(sc->aac_dev, "bus_generic_attach failed\n");
300
301    /* mark the controller up */
302    sc->aac_state &= ~AAC_STATE_SUSPEND;
303
304    /* enable interrupts now */
305    AAC_UNMASK_INTERRUPTS(sc);
306}
307
308/********************************************************************************
309 * Free all of the resources associated with (sc)
310 *
311 * Should not be called if the controller is active.
312 *
313 * XXX verify that we are freeing all our resources here...
314 */
315void
316aac_free(struct aac_softc *sc)
317{
318    struct aac_command_cluster	*cmc;
319
320    debug_called(1);
321
322    /* remove the control device */
323    if (sc->aac_dev_t != NULL)
324	destroy_dev(sc->aac_dev_t);
325
326    /* throw away any command buffers */
327    while ((cmc = aac_dequeue_cluster(sc)) != NULL)
328	aac_free_command_cluster(cmc);
329
330    /* destroy the common area */
331    if (sc->aac_common) {
332	bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
333	bus_dmamem_free(sc->aac_common_dmat, sc->aac_common, sc->aac_common_dmamap);
334	bus_dma_tag_destroy(sc->aac_common_dmat);
335    }
336
337    /* disconnect the interrupt handler */
338    if (sc->aac_intr)
339	bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
340    if (sc->aac_irq != NULL)
341	bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid, sc->aac_irq);
342
343    /* destroy data-transfer DMA tag */
344    if (sc->aac_buffer_dmat)
345	bus_dma_tag_destroy(sc->aac_buffer_dmat);
346
347    /* destroy FIB DMA tag */
348    if (sc->aac_buffer_dmat)
349	bus_dma_tag_destroy(sc->aac_fib_dmat);
350
351    /* destroy the parent DMA tag */
352    if (sc->aac_parent_dmat)
353	bus_dma_tag_destroy(sc->aac_parent_dmat);
354
355    /* release the register window mapping */
356    if (sc->aac_regs_resource != NULL)
357	bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, sc->aac_regs_rid, sc->aac_regs_resource);
358}
359
360/********************************************************************************
361 * Disconnect from the controller completely, in preparation for unload.
362 */
363int
364aac_detach(device_t dev)
365{
366    struct aac_softc	*sc = device_get_softc(dev);
367    int			error;
368
369    debug_called(1);
370
371    if (sc->aac_state & AAC_STATE_OPEN)
372	return(EBUSY);
373
374    if ((error = aac_shutdown(dev)))
375	return(error);
376
377    aac_free(sc);
378
379    return(0);
380}
381
382/********************************************************************************
383 * Bring the controller down to a dormant state and detach all child devices.
384 *
385 * This function is called before detach or system shutdown.
386 *
387 * Note that we can assume that the camq on the controller is empty, as we won't
388 * allow shutdown if any device is open.
389 */
390int
391aac_shutdown(device_t dev)
392{
393    struct aac_softc		*sc = device_get_softc(dev);
394    struct aac_close_command	cc;
395    int				s, i;
396
397    debug_called(1);
398
399    s = splbio();
400
401    sc->aac_state |= AAC_STATE_SUSPEND;
402
403    /*
404     * Send a Container shutdown followed by a HostShutdown FIB to the
405     * controller to convince it that we don't want to talk to it anymore.
406     * We've been closed and all I/O completed already
407     */
408    device_printf(sc->aac_dev, "shutting down controller...");
409
410    cc.Command = VM_CloseAll;
411    cc.ContainerId = 0xffffffff;
412    if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), NULL, NULL)) {
413	printf("FAILED.\n");
414    } else {
415	i = 0;
416	if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, &i, sizeof(i), NULL, NULL)) {
417	    printf("FAILED.\n");
418	} else {
419	    printf("done.\n");
420	}
421    }
422
423    AAC_MASK_INTERRUPTS(sc);
424
425    splx(s);
426    return(0);
427}
428
429/********************************************************************************
430 * Bring the controller to a quiescent state, ready for system suspend.
431 */
432int
433aac_suspend(device_t dev)
434{
435    struct aac_softc	*sc = device_get_softc(dev);
436    int			s;
437
438    debug_called(1);
439    s = splbio();
440
441    sc->aac_state |= AAC_STATE_SUSPEND;
442
443    AAC_MASK_INTERRUPTS(sc);
444    splx(s);
445    return(0);
446}
447
448/********************************************************************************
449 * Bring the controller back to a state ready for operation.
450 */
451int
452aac_resume(device_t dev)
453{
454    struct aac_softc	*sc = device_get_softc(dev);
455
456    debug_called(1);
457    sc->aac_state &= ~AAC_STATE_SUSPEND;
458    AAC_UNMASK_INTERRUPTS(sc);
459    return(0);
460}
461
462/*******************************************************************************
463 * Take an interrupt.
464 */
465void
466aac_intr(void *arg)
467{
468    struct aac_softc	*sc = (struct aac_softc *)arg;
469    u_int16_t		reason;
470
471    debug_called(2);
472
473    reason = AAC_GET_ISTATUS(sc);
474
475    /* controller wants to talk to the log?  XXX should we defer this? */
476    if (reason & AAC_DB_PRINTF) {
477	if (sc->aac_common->ac_printf[0]) {
478	    device_printf(sc->aac_dev, "** %.*s", AAC_PRINTF_BUFSIZE, sc->aac_common->ac_printf);
479	    sc->aac_common->ac_printf[0] = 0;
480	}
481	AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
482	AAC_QNOTIFY(sc, AAC_DB_PRINTF);
483    }
484
485    /* controller has a message for us? */
486    if (reason & AAC_DB_COMMAND_READY) {
487	aac_host_command(sc);
488	AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
489    }
490
491    /* controller has a response for us? */
492    if (reason & AAC_DB_RESPONSE_READY) {
493	aac_host_response(sc);
494	AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
495    }
496
497    /* spurious interrupts that we don't use - reset the mask and clear the interrupts */
498    if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) {
499	AAC_UNMASK_INTERRUPTS(sc);
500	AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
501    }
502};
503
504/********************************************************************************
505 ********************************************************************************
506                                                               Command Processing
507 ********************************************************************************
508 ********************************************************************************/
509
510/********************************************************************************
511 * Start as much queued I/O as possible on the controller
512 */
513static void
514aac_startio(struct aac_softc *sc)
515{
516    struct aac_command	*cm;
517
518    debug_called(2);
519
520    for(;;) {
521	/* try to get a command that's been put off for lack of resources */
522	cm = aac_dequeue_ready(sc);
523
524	/* try to build a command off the bio queue (ignore error return) */
525	aac_bio_command(sc, &cm);
526
527	/* nothing to do? */
528	if (cm == NULL)
529	    break;
530
531	/* Set a timeout for this command to be completed by the controller */
532	/* Disable this for now until the timeout queue is fixed or the driver
533	 * can watch timeouts itself
534	 * cm->timeout_handle = timeout((timeout_t*)aac_timeout, cm, AAC_CMD_TIMEOUT * hz);
535	 */
536
537	/* try to give the command to the controller */
538	if (aac_start(cm) == EBUSY) {
539	    /* put it on the ready queue for later */
540	    aac_requeue_ready(cm);
541	    break;
542	}
543    }
544}
545
546static void
547aac_timeout(struct aac_command *cm)
548{
549	struct aac_softc *sc;
550	struct bio *bp;
551	struct aac_disk  *ad;
552
553	sc = cm->cm_sc;
554	bp = (struct bio*)cm->cm_private;
555	ad = (struct aac_disk *)bp->bio_dev->si_drv1;
556
557	device_printf(sc->aac_dev, "Timeout waiting for controller to respond to command\n");
558
559	/* Should try to requeue the command... is it possible?  Bail for now */
560	bp->bio_error = EIO;
561	bp->bio_flags |= BIO_ERROR;
562	devstat_end_transaction_bio(&ad->ad_stats, bp);
563	biodone(bp);
564	aac_release_command(cm);
565}
566
567/********************************************************************************
568 * Deliver a command to the controller; allocate controller resources at the
569 * last moment when possible.
570 */
571static int
572aac_start(struct aac_command *cm)
573{
574    struct aac_softc	*sc = cm->cm_sc;
575
576    debug_called(2);
577
578    /* get the command mapped */
579    aac_map_command(cm);
580
581    /* fix up the address values */
582    cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
583    cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
584
585    /* save a pointer to the command for speedy reverse-lookup */
586    cm->cm_fib->Header.SenderData = (u_int32_t)cm;		/* XXX ack, sizing */
587
588    /* put the FIB on the outbound queue */
589    if (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, cm->cm_fib->Header.Size,
590			cm->cm_fib->Header.ReceiverFibAddress))
591	return(EBUSY);
592
593    return(0);
594}
595
596/********************************************************************************
597 * Handle notification of one or more FIBs coming from the controller.
598 */
599static void
600aac_host_command(struct aac_softc *sc)
601{
602    struct aac_fib	*fib;
603    u_int32_t		fib_size;
604
605    debug_called(1);
606
607    for (;;) {
608	if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size, &fib))
609	    break;	/* nothing to do */
610
611	switch(fib->Header.Command) {
612	case AifRequest:
613	    aac_handle_aif(sc, (struct aac_aif_command *)&fib->data[0]);
614	    break;
615	default:
616	    device_printf(sc->aac_dev, "unknown command from controller\n");
617	    AAC_PRINT_FIB(sc, fib);
618	    break;
619	}
620
621	/* XXX reply to FIBs requesting responses ?? */
622	/* XXX how do we return these FIBs to the controller? */
623    }
624}
625
626/********************************************************************************
627 * Handle notification of one or more FIBs completed by the controller
628 */
629static void
630aac_host_response(struct aac_softc *sc)
631{
632    struct aac_command	*cm;
633    struct aac_fib	*fib;
634    u_int32_t		fib_size;
635
636    debug_called(2);
637
638    for (;;) {
639	/* look for completed FIBs on our queue */
640	if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size, &fib))
641	    break;	/* nothing to do */
642
643	/* get the command, unmap and queue for later processing */
644	cm = (struct aac_command *)fib->Header.SenderData;
645	if (cm == NULL) {
646	    AAC_PRINT_FIB(sc, fib);
647	} else {
648	    aac_unmap_command(cm);		/* XXX defer? */
649	    aac_enqueue_completed(cm);
650	}
651    }
652
653    /* handle completion processing */
654#if __FreeBSD_version >= 500005
655    taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
656#else
657    aac_complete(sc, 0);
658#endif
659}
660
661/********************************************************************************
662 * Process completed commands.
663 */
664static void
665aac_complete(void *context, int pending)
666{
667    struct aac_softc	*sc = (struct aac_softc *)context;
668    struct aac_command	*cm;
669
670    debug_called(2);
671
672    /* pull completed commands off the queue */
673    for (;;) {
674	cm = aac_dequeue_completed(sc);
675	if (cm == NULL)
676	    return;
677	cm->cm_flags |= AAC_CMD_COMPLETED;
678
679	/* is there a completion handler? */
680	if (cm->cm_complete != NULL) {
681	    cm->cm_complete(cm);
682	} else {
683	    /* assume that someone is sleeping on this command */
684	    wakeup(cm);
685	}
686    }
687}
688
689/********************************************************************************
690 * Handle a bio submitted from a disk device.
691 */
692void
693aac_submit_bio(struct bio *bp)
694{
695    struct aac_disk	*ad = (struct aac_disk *)bp->bio_dev->si_drv1;
696    struct aac_softc	*sc = ad->ad_controller;
697
698    debug_called(2);
699
700    /* queue the BIO and try to get some work done */
701    bioq_insert_tail(&sc->aac_bioq, bp);
702    aac_startio(sc);
703}
704
705/********************************************************************************
706 * Get a bio and build a command to go with it.
707 */
708static int
709aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
710{
711    struct aac_command		*cm;
712    struct aac_fib		*fib;
713    struct aac_blockread	*br;
714    struct aac_blockwrite	*bw;
715    struct aac_disk		*ad;
716    struct bio			*bp;
717    int				s;
718
719    debug_called(2);
720
721    /* get the resources we will need */
722    cm = NULL;
723    s = splbio();
724    if ((bp = bioq_first(&sc->aac_bioq)))
725	bioq_remove(&sc->aac_bioq, bp);
726    splx(s);
727    if (bp == NULL)			/* no work? */
728	goto fail;
729    if (aac_alloc_command(sc, &cm))	/* get a command */
730	goto fail;
731
732    /* fill out the command */
733    cm->cm_private = bp;
734
735    /* build the FIB */
736    fib = cm->cm_fib;
737    fib->Header.XferState =
738	AAC_FIBSTATE_HOSTOWNED   |
739	AAC_FIBSTATE_INITIALISED |
740	AAC_FIBSTATE_FROMHOST    |
741	AAC_FIBSTATE_REXPECTED   |
742	AAC_FIBSTATE_NORM;
743    fib->Header.Command = ContainerCommand;
744    fib->Header.Size = sizeof(struct aac_fib_header);
745
746    /* build the read/write request */
747    ad = (struct aac_disk *)bp->bio_dev->si_drv1;
748    cm->cm_data = (void *)bp->bio_data;
749    cm->cm_datalen = bp->bio_bcount;
750    cm->cm_complete = aac_bio_complete;
751    if (BIO_IS_READ(bp)) {
752	br = (struct aac_blockread *)&fib->data[0];
753	br->Command = VM_CtBlockRead;
754	br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
755	br->BlockNumber = bp->bio_pblkno;
756	br->ByteCount = bp->bio_bcount;
757	fib->Header.Size += sizeof(struct aac_blockread);
758	cm->cm_sgtable = &br->SgMap;
759	cm->cm_flags |= AAC_CMD_DATAIN;
760    } else {
761	bw = (struct aac_blockwrite *)&fib->data[0];
762	bw->Command = VM_CtBlockWrite;
763	bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
764	bw->BlockNumber = bp->bio_pblkno;
765	bw->ByteCount = bp->bio_bcount;
766	bw->Stable = CUNSTABLE;		/* XXX what's appropriate here? */
767	fib->Header.Size += sizeof(struct aac_blockwrite);
768	cm->cm_flags |= AAC_CMD_DATAOUT;
769	cm->cm_sgtable = &bw->SgMap;
770    }
771
772    *cmp = cm;
773    return(0);
774
775fail:
776    if (bp != NULL)
777	bioq_insert_tail(&sc->aac_bioq, bp);
778    if (cm != NULL)
779	aac_release_command(cm);
780    return(ENOMEM);
781}
782
783/********************************************************************************
784 * Handle a bio-instigated command that has been completed.
785 */
786static void
787aac_bio_complete(struct aac_command *cm)
788{
789    struct aac_softc			*sc = cm->cm_sc;
790    struct aac_blockread_response	*brr;
791    struct aac_blockwrite_response	*bwr;
792    struct bio				*bp;
793    AAC_FSAStatus			status;
794
795    /* kill the timeout timer */
796    /* Disable this for now until the timeout queue is fixed or the driver
797     * can watch timeouts itself
798     * untimeout((timeout_t *)aac_timeout, cm, cm->timeout_handle);
799     */
800
801    /* fetch relevant status and then release the command */
802    bp = (struct bio *)cm->cm_private;
803    if (BIO_IS_READ(bp)) {
804	brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
805	status = brr->Status;
806    } else {
807	bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
808	status = bwr->Status;
809    }
810    aac_release_command(cm);
811
812    /* fix up the bio based on status */
813    if (status == ST_OK) {
814	bp->bio_resid = 0;
815    } else {
816	bp->bio_error = EIO;
817	bp->bio_flags |= BIO_ERROR;
818
819	/* XXX be more verbose? */
820	device_printf(sc->aac_dev, "I/O error %d (%s)\n", status, AAC_COMMAND_STATUS(status));
821    }
822    aac_complete_bio(bp);	/* XXX rename one of these functions! */
823}
824
825/********************************************************************************
826 * Submit a command to the controller, return when it completes.
827 */
828static int
829aac_wait_command(struct aac_command *cm, int timeout)
830{
831    int s, error = 0;
832
833    debug_called(2);
834
835    /* Put the command on the ready queue and get things going */
836    aac_enqueue_ready(cm);
837    aac_startio(cm->cm_sc);
838    s = splbio();
839    while(!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
840        error = tsleep(cm, PRIBIO, "aacwait", timeout * hz);
841    }
842    splx(s);
843    return(error);
844}
845
846/********************************************************************************
847 ********************************************************************************
848                                                        Command Buffer Management
849 ********************************************************************************
850 ********************************************************************************/
851
852/********************************************************************************
853 * Allocate a command.
854 */
855static int
856aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
857{
858    struct aac_command	*cm;
859
860    debug_called(3);
861
862    cm = aac_dequeue_free(sc);
863    if (cm == NULL) {
864	aac_alloc_command_cluster(sc);
865	cm = aac_dequeue_free(sc);
866    }
867    if (cm == NULL)
868	return(ENOMEM);
869
870    /* initialise the command/FIB */
871    cm->cm_sgtable = NULL;
872    cm->cm_flags = 0;
873    cm->cm_complete = NULL;
874    cm->cm_private = NULL;
875    cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
876    cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
877    cm->cm_fib->Header.Flags = 0;
878    cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
879
880    /*
881     * These are duplicated in aac_start to cover the case where an
882     * intermediate stage may have destroyed them.  They're left
883     * initialised here for debugging purposes only.
884     */
885    cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
886    cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
887
888    *cmp = cm;
889    return(0);
890}
891
892/********************************************************************************
893 * Release a command back to the freelist.
894 */
895static void
896aac_release_command(struct aac_command *cm)
897{
898    debug_called(3);
899
900    aac_enqueue_free(cm);
901}
902
903/********************************************************************************
904 * Map helper for command cluster allocation. Tell each of the FIBs what its
905 * address in the adapter's space is, fill in a few other fields.
906 */
907static void
908aac_map_command_cluster(void *arg, bus_dma_segment_t *segs, int nseg, int error)
909{
910    struct aac_command_cluster	*cmc = (struct aac_command_cluster *)arg;
911
912    debug_called(3);
913
914    cmc->cmc_fibphys = segs[0].ds_addr;
915}
916
917/********************************************************************************
918 * Allocate and initialise a cluster of commands.
919 */
920static void
921aac_alloc_command_cluster(struct aac_softc *sc)
922{
923    struct aac_command_cluster	*cmc;
924    struct aac_command		*cm;
925    int				i;
926
927    debug_called(1);
928
929    cmc = malloc(sizeof(struct aac_command_cluster), M_DEVBUF,
930	M_NOWAIT | M_ZERO);
931    if (cmc != NULL) {
932	/* allocate the FIB cluster in DMAable memory and load it */
933	if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&cmc->cmc_fibs, BUS_DMA_NOWAIT, &cmc->cmc_fibmap)) {
934	    free(cmc, M_DEVBUF);
935	    return;
936	}
937	bus_dmamap_load(sc->aac_fib_dmat, cmc->cmc_fibmap, cmc->cmc_fibs,
938			AAC_CLUSTER_COUNT * sizeof(struct aac_fib), aac_map_command_cluster, cmc, 0);
939
940	aac_enqueue_cluster(sc, cmc);
941	for (i = 0; i < AAC_CLUSTER_COUNT; i++) {
942	    cm = &cmc->cmc_command[i];
943	    cm->cm_sc = sc;
944	    cm->cm_fib = cmc->cmc_fibs + i;
945	    cm->cm_fibphys = cmc->cmc_fibphys + (i * sizeof(struct aac_fib));
946
947	    if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap))
948		aac_release_command(cm);
949	}
950    } else {
951	debug(2, "can't allocate memeory for command cluster");
952    }
953}
954
955/********************************************************************************
956 * Free a command cluster.
957 */
958static void
959aac_free_command_cluster(struct aac_command_cluster *cmc)
960{
961    struct aac_softc	*sc = cmc->cmc_command[0].cm_sc;
962    int			i;
963
964    debug_called(1);
965
966    for (i = 0; i < AAC_CLUSTER_COUNT; i++)
967	bus_dmamap_destroy(sc->aac_buffer_dmat, cmc->cmc_command[i].cm_datamap);
968    bus_dmamap_unload(sc->aac_fib_dmat, cmc->cmc_fibmap);
969    bus_dmamem_free(sc->aac_fib_dmat, cmc->cmc_fibs, cmc->cmc_fibmap);
970
971    free(cmc, M_DEVBUF);
972}
973
974/********************************************************************************
975 * Command-mapping helper function - populate this command's s/g table.
976 */
977static void
978aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
979{
980    struct aac_command		*cm = (struct aac_command *)arg;
981    struct aac_fib		*fib = cm->cm_fib;
982    struct aac_sg_table		*sg;
983    int				i;
984
985    debug_called(3);
986
987    /* find the s/g table */
988    sg = cm->cm_sgtable;
989
990    /* copy into the FIB */
991    if (sg != NULL) {
992	sg->SgCount = nseg;
993	for (i = 0; i < nseg; i++) {
994	    sg->SgEntry[i].SgAddress = segs[i].ds_addr;
995	    sg->SgEntry[i].SgByteCount = segs[i].ds_len;
996	}
997	/* update the FIB size for the s/g count */
998	fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
999    }
1000
1001}
1002
1003/********************************************************************************
1004 * Map a command into controller-visible space.
1005 */
1006static void
1007aac_map_command(struct aac_command *cm)
1008{
1009    struct aac_softc	*sc = cm->cm_sc;
1010
1011    debug_called(2);
1012
1013    /* don't map more than once */
1014    if (cm->cm_flags & AAC_CMD_MAPPED)
1015	return;
1016
1017    if (cm->cm_datalen != 0) {
1018	bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap, cm->cm_data,
1019			cm->cm_datalen, aac_map_command_sg, cm, 0);
1020
1021	if (cm->cm_flags & AAC_CMD_DATAIN)
1022	    bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_PREREAD);
1023	if (cm->cm_flags & AAC_CMD_DATAOUT)
1024	    bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_PREWRITE);
1025    }
1026    cm->cm_flags |= AAC_CMD_MAPPED;
1027}
1028
1029/********************************************************************************
1030 * Unmap a command from controller-visible space.
1031 */
1032static void
1033aac_unmap_command(struct aac_command *cm)
1034{
1035    struct aac_softc	*sc = cm->cm_sc;
1036
1037    debug_called(2);
1038
1039    if (!(cm->cm_flags & AAC_CMD_MAPPED))
1040	return;
1041
1042    if (cm->cm_datalen != 0) {
1043	if (cm->cm_flags & AAC_CMD_DATAIN)
1044	    bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_POSTREAD);
1045	if (cm->cm_flags & AAC_CMD_DATAOUT)
1046	    bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap, BUS_DMASYNC_POSTWRITE);
1047
1048	bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1049    }
1050    cm->cm_flags &= ~AAC_CMD_MAPPED;
1051}
1052
1053/********************************************************************************
1054 ********************************************************************************
1055                                                               Hardware Interface
1056 ********************************************************************************
1057 ********************************************************************************/
1058
1059/********************************************************************************
1060 * Initialise the adapter.
1061 */
1062static void
1063aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1064{
1065    struct aac_softc	*sc = (struct aac_softc *)arg;
1066
1067    debug_called(1);
1068
1069    sc->aac_common_busaddr = segs[0].ds_addr;
1070}
1071
1072static int
1073aac_init(struct aac_softc *sc)
1074{
1075    struct aac_adapter_init	*ip;
1076    time_t			then;
1077    u_int32_t			code;
1078    u_int8_t			*qaddr;
1079
1080    debug_called(1);
1081
1082    /*
1083     * First wait for the adapter to come ready.
1084     */
1085    then = time_second;
1086    do {
1087	code = AAC_GET_FWSTATUS(sc);
1088	if (code & AAC_SELF_TEST_FAILED) {
1089	    device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1090	    return(ENXIO);
1091	}
1092	if (code & AAC_KERNEL_PANIC) {
1093	    device_printf(sc->aac_dev, "FATAL: controller kernel panic\n");
1094	    return(ENXIO);
1095	}
1096	if (time_second > (then + AAC_BOOT_TIMEOUT)) {
1097	    device_printf(sc->aac_dev, "FATAL: controller not coming ready, status %x\n", code);
1098	    return(ENXIO);
1099	}
1100    } while (!(code & AAC_UP_AND_RUNNING));
1101
1102    /*
1103     * Create DMA tag for the common structure and allocate it.
1104     */
1105    if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
1106			   1, 0, 			/* alignment, boundary */
1107			   BUS_SPACE_MAXADDR,		/* lowaddr */
1108			   BUS_SPACE_MAXADDR, 		/* highaddr */
1109			   NULL, NULL, 			/* filter, filterarg */
1110			   sizeof(struct aac_common), 1,/* maxsize, nsegments */
1111			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
1112			   0,				/* flags */
1113			   &sc->aac_common_dmat)) {
1114	device_printf(sc->aac_dev, "can't allocate common structure DMA tag\n");
1115	return(ENOMEM);
1116    }
1117    if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common, BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1118	device_printf(sc->aac_dev, "can't allocate common structure\n");
1119	return(ENOMEM);
1120    }
1121    bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap, sc->aac_common, sizeof(*sc->aac_common),
1122		    aac_common_map, sc, 0);
1123    bzero(sc->aac_common, sizeof(*sc->aac_common));
1124
1125    /*
1126     * Fill in the init structure.  This tells the adapter about the physical location
1127     * of various important shared data structures.
1128     */
1129    ip = &sc->aac_common->ac_init;
1130    ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1131
1132    ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr + offsetof(struct aac_common, ac_fibs);
1133    ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0];
1134    ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1135    ip->AdapterFibAlign = sizeof(struct aac_fib);
1136
1137    ip->PrintfBufferAddress = sc->aac_common_busaddr + offsetof(struct aac_common, ac_printf);
1138    ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1139
1140    ip->HostPhysMemPages = 0;			/* not used? */
1141    ip->HostElapsedSeconds = time_second;	/* reset later if invalid */
1142
1143    /*
1144     * Initialise FIB queues.  Note that it appears that the layout of the indexes
1145     * and the segmentation of the entries is mandated by the adapter, which is
1146     * only told about the base of the queue index fields.
1147     *
1148     * The initial values of the indices are assumed to inform the adapter
1149     * of the sizes of the respective queues.
1150     *
1151     * The Linux driver uses a much more complex scheme whereby several header
1152     * records are kept for each queue.  We use a couple of generic list manipulation
1153     * functions which 'know' the size of each list by virtue of a table.
1154     */
1155    qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1156    qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1157    sc->aac_queues = (struct aac_queue_table *)qaddr;
1158    ip->CommHeaderAddress = sc->aac_common_busaddr + ((u_int32_t)sc->aac_queues - (u_int32_t)sc->aac_common);
1159    bzero(sc->aac_queues, sizeof(struct aac_queue_table));
1160
1161    sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX]  = AAC_HOST_NORM_CMD_ENTRIES;
1162    sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX]  = AAC_HOST_NORM_CMD_ENTRIES;
1163    sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX]  = AAC_HOST_HIGH_CMD_ENTRIES;
1164    sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX]  = AAC_HOST_HIGH_CMD_ENTRIES;
1165    sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX]  = AAC_ADAP_NORM_CMD_ENTRIES;
1166    sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX]  = AAC_ADAP_NORM_CMD_ENTRIES;
1167    sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX]  = AAC_ADAP_HIGH_CMD_ENTRIES;
1168    sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX]  = AAC_ADAP_HIGH_CMD_ENTRIES;
1169    sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_HOST_NORM_RESP_ENTRIES;
1170    sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_HOST_NORM_RESP_ENTRIES;
1171    sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_HOST_HIGH_RESP_ENTRIES;
1172    sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_HOST_HIGH_RESP_ENTRIES;
1173    sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_ADAP_NORM_RESP_ENTRIES;
1174    sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_ADAP_NORM_RESP_ENTRIES;
1175    sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = AAC_ADAP_HIGH_RESP_ENTRIES;
1176    sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = AAC_ADAP_HIGH_RESP_ENTRIES;
1177    sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] = &sc->aac_queues->qt_HostNormCmdQueue[0];
1178    sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] = &sc->aac_queues->qt_HostHighCmdQueue[0];
1179    sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] = &sc->aac_queues->qt_AdapNormCmdQueue[0];
1180    sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] = &sc->aac_queues->qt_AdapHighCmdQueue[0];
1181    sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] = &sc->aac_queues->qt_HostNormRespQueue[0];
1182    sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] = &sc->aac_queues->qt_HostHighRespQueue[0];
1183    sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] = &sc->aac_queues->qt_AdapNormRespQueue[0];
1184    sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] = &sc->aac_queues->qt_AdapHighRespQueue[0];
1185
1186    /*
1187     * Do controller-type-specific initialisation
1188     */
1189    switch (sc->aac_hwif) {
1190    case AAC_HWIF_I960RX:
1191	AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1192	break;
1193    }
1194
1195    /*
1196     * Give the init structure to the controller.
1197     */
1198    if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1199			  sc->aac_common_busaddr + offsetof(struct aac_common, ac_init),
1200			  0, 0, 0, NULL)) {
1201	device_printf(sc->aac_dev, "error establishing init structure\n");
1202	return(EIO);
1203    }
1204
1205    return(0);
1206}
1207
1208/********************************************************************************
1209 * Send a synchronous command to the controller and wait for a result.
1210 */
1211static int
1212aac_sync_command(struct aac_softc *sc, u_int32_t command,
1213		       u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1214		       u_int32_t *sp)
1215{
1216    time_t	then;
1217    u_int32_t	status;
1218
1219    debug_called(3);
1220
1221    /* populate the mailbox */
1222    AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1223
1224    /* ensure the sync command doorbell flag is cleared */
1225    AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1226
1227    /* then set it to signal the adapter */
1228    AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1229
1230    /* spin waiting for the command to complete */
1231    then = time_second;
1232    do {
1233	if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) {
1234	    debug(2, "timed out");
1235	    return(EIO);
1236	}
1237    } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1238
1239    /* clear the completion flag */
1240    AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1241
1242    /* get the command status */
1243    status = AAC_GET_MAILBOXSTATUS(sc);
1244    if (sp != NULL)
1245	*sp = status;
1246    return(0);	/* check command return status? */
1247}
1248
1249/********************************************************************************
1250 * Send a synchronous FIB to the controller and wait for a result.
1251 */
1252static int
1253aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1254	     void *data, u_int16_t datasize,
1255	     void *result, u_int16_t *resultsize)
1256{
1257    struct aac_fib	*fib = &sc->aac_common->ac_sync_fib;
1258
1259    debug_called(3);
1260
1261    if (datasize > AAC_FIB_DATASIZE)
1262	return(EINVAL);
1263
1264    /*
1265     * Set up the sync FIB
1266     */
1267    fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED | AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY;
1268    fib->Header.XferState |= xferstate;
1269    fib->Header.Command = command;
1270    fib->Header.StructType = AAC_FIBTYPE_TFIB;
1271    fib->Header.Size = sizeof(struct aac_fib) + datasize;
1272    fib->Header.SenderSize = sizeof(struct aac_fib);
1273    fib->Header.SenderFibAddress = (u_int32_t)fib;
1274    fib->Header.ReceiverFibAddress = sc->aac_common_busaddr + offsetof(struct aac_common, ac_sync_fib);
1275
1276    /*
1277     * Copy in data.
1278     */
1279    if (data != NULL) {
1280	bcopy(data, fib->data, datasize);
1281	fib->Header.XferState |= AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM;
1282    }
1283
1284    /*
1285     * Give the FIB to the controller, wait for a response.
1286     */
1287    if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fib->Header.ReceiverFibAddress,
1288			  0, 0, 0, NULL)) {
1289	debug(2, "IO error");
1290	return(EIO);
1291    }
1292
1293    /*
1294     * Copy out the result
1295     */
1296    if (result != NULL) {
1297	*resultsize = fib->Header.Size - sizeof(struct aac_fib_header);
1298	bcopy(fib->data, result, *resultsize);
1299    }
1300    return(0);
1301}
1302
1303/********************************************************************************
1304 * Adapter-space FIB queue manipulation
1305 *
1306 * Note that the queue implementation here is a little funky; neither the PI or
1307 * CI will ever be zero.  This behaviour is a controller feature.
1308 */
1309static struct {
1310    int		size;
1311    int		notify;
1312} aac_qinfo[] = {
1313    {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
1314    {AAC_HOST_HIGH_CMD_ENTRIES, 0},
1315    {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
1316    {AAC_ADAP_HIGH_CMD_ENTRIES, 0},
1317    {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
1318    {AAC_HOST_HIGH_RESP_ENTRIES, 0},
1319    {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
1320    {AAC_ADAP_HIGH_RESP_ENTRIES, 0}
1321};
1322
1323/*
1324 * Atomically insert an entry into the nominated queue, returns 0 on success or EBUSY
1325 * if the queue is full.
1326 *
1327 * XXX note that it would be more efficient to defer notifying the controller in
1328 * the case where we may be inserting several entries in rapid succession, but
1329 * implementing this usefully is difficult.
1330 */
1331static int
1332aac_enqueue_fib(struct aac_softc *sc, int queue, u_int32_t fib_size, u_int32_t fib_addr)
1333{
1334    u_int32_t	pi, ci;
1335    int		s, error;
1336
1337    debug_called(3);
1338
1339    s = splbio();
1340
1341    /* get the producer/consumer indices */
1342    pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1343    ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1344
1345    /* wrap the queue? */
1346    if (pi >= aac_qinfo[queue].size)
1347	pi = 0;
1348
1349    /* check for queue full */
1350    if ((pi + 1) == ci) {
1351	error = EBUSY;
1352	goto out;
1353    }
1354
1355    /* populate queue entry */
1356    (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1357    (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1358
1359    /* update producer index */
1360    sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1361
1362    /* notify the adapter if we know how */
1363    if (aac_qinfo[queue].notify != 0)
1364	AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1365
1366    error = 0;
1367
1368out:
1369    splx(s);
1370    return(error);
1371}
1372
1373/*
1374 * Atomically remove one entry from the nominated queue, returns 0 on success or ENOENT
1375 * if the queue is empty.
1376 */
1377static int
1378aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size, struct aac_fib **fib_addr)
1379{
1380    u_int32_t	pi, ci;
1381    int		s, error;
1382
1383    debug_called(3);
1384
1385    s = splbio();
1386
1387    /* get the producer/consumer indices */
1388    pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1389    ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1390
1391    /* check for queue empty */
1392    if (ci == pi) {
1393	error = ENOENT;
1394	goto out;
1395    }
1396
1397    /* wrap the queue? */
1398    if (ci >= aac_qinfo[queue].size)
1399	ci = 0;
1400
1401    /* fetch the entry */
1402    *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1403    *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] + ci)->aq_fib_addr;
1404
1405    /* update consumer index */
1406    sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1407
1408    /* if we have made the queue un-full, notify the adapter */
1409    if (((pi + 1) == ci) && (aac_qinfo[queue].notify != 0))
1410	AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1411    error = 0;
1412
1413out:
1414    splx(s);
1415    return(error);
1416}
1417
1418/********************************************************************************
1419 ********************************************************************************
1420                                                       Interface Function Vectors
1421 ********************************************************************************
1422 ********************************************************************************/
1423
1424/********************************************************************************
1425 * Read the current firmware status word.
1426 */
1427static int
1428aac_sa_get_fwstatus(struct aac_softc *sc)
1429{
1430    debug_called(3);
1431
1432    return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1433}
1434
1435static int
1436aac_rx_get_fwstatus(struct aac_softc *sc)
1437{
1438    debug_called(3);
1439
1440    return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1441}
1442
1443/********************************************************************************
1444 * Notify the controller of a change in a given queue
1445 */
1446
1447static void
1448aac_sa_qnotify(struct aac_softc *sc, int qbit)
1449{
1450    debug_called(3);
1451
1452    AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1453}
1454
1455static void
1456aac_rx_qnotify(struct aac_softc *sc, int qbit)
1457{
1458    debug_called(3);
1459
1460    AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1461}
1462
1463/********************************************************************************
1464 * Get the interrupt reason bits
1465 */
1466static int
1467aac_sa_get_istatus(struct aac_softc *sc)
1468{
1469    debug_called(3);
1470
1471    return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1472}
1473
1474static int
1475aac_rx_get_istatus(struct aac_softc *sc)
1476{
1477    debug_called(3);
1478
1479    return(AAC_GETREG4(sc, AAC_RX_ODBR));
1480}
1481
1482/********************************************************************************
1483 * Clear some interrupt reason bits
1484 */
1485static void
1486aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1487{
1488    debug_called(3);
1489
1490    AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1491}
1492
1493static void
1494aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1495{
1496    debug_called(3);
1497
1498    AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1499}
1500
1501/********************************************************************************
1502 * Populate the mailbox and set the command word
1503 */
1504static void
1505aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
1506		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1507{
1508    debug_called(4);
1509
1510    AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1511    AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1512    AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1513    AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1514    AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1515}
1516
1517static void
1518aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
1519		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1520{
1521    debug_called(4);
1522
1523    AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1524    AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1525    AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1526    AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1527    AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1528}
1529
1530/********************************************************************************
1531 * Fetch the immediate command status word
1532 */
1533static int
1534aac_sa_get_mailboxstatus(struct aac_softc *sc)
1535{
1536    debug_called(4);
1537
1538    return(AAC_GETREG4(sc, AAC_SA_MAILBOX));
1539}
1540
1541static int
1542aac_rx_get_mailboxstatus(struct aac_softc *sc)
1543{
1544    debug_called(4);
1545
1546    return(AAC_GETREG4(sc, AAC_RX_MAILBOX));
1547}
1548
1549/********************************************************************************
1550 * Set/clear interrupt masks
1551 */
1552static void
1553aac_sa_set_interrupts(struct aac_softc *sc, int enable)
1554{
1555    debug(2, "%sable interrupts", enable ? "en" : "dis");
1556
1557    if (enable) {
1558	AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
1559    } else {
1560	AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
1561    }
1562}
1563
1564static void
1565aac_rx_set_interrupts(struct aac_softc *sc, int enable)
1566{
1567    debug(2, "%sable interrupts", enable ? "en" : "dis");
1568
1569    if (enable) {
1570	AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
1571    } else {
1572	AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
1573    }
1574}
1575
1576/********************************************************************************
1577 ********************************************************************************
1578                                                        Debugging and Diagnostics
1579 ********************************************************************************
1580 ********************************************************************************/
1581
1582/********************************************************************************
1583 * Print some information about the controller.
1584 */
1585static void
1586aac_describe_controller(struct aac_softc *sc)
1587{
1588    u_int8_t			buf[AAC_FIB_DATASIZE];	/* XXX really a bit big for the stack */
1589    u_int16_t			bufsize;
1590    struct aac_adapter_info	*info;
1591    u_int8_t			arg;
1592
1593    debug_called(2);
1594
1595    arg = 0;
1596    if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &buf, &bufsize)) {
1597	device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
1598	return;
1599    }
1600    if (bufsize != sizeof(*info)) {
1601	device_printf(sc->aac_dev, "RequestAdapterInfo returned wrong data size (%d != %d)\n",
1602		      bufsize, sizeof(*info));
1603	return;
1604    }
1605    info = (struct aac_adapter_info *)&buf[0];
1606
1607    device_printf(sc->aac_dev, "%s %dMHz, %dMB total memory, %s (%d)\n",
1608		  aac_describe_code(aac_cpu_variant, info->CpuVariant), info->ClockSpeed,
1609		  info->TotalMem / (1024 * 1024),
1610		  aac_describe_code(aac_battery_platform, info->batteryPlatform), info->batteryPlatform);
1611
1612    /* save the kernel revision structure for later use */
1613    sc->aac_revision = info->KernelRevision;
1614    device_printf(sc->aac_dev, "Kernel %d.%d-%d, S/N %llx\n",
1615		  info->KernelRevision.external.comp.major,
1616		  info->KernelRevision.external.comp.minor,
1617		  info->KernelRevision.external.comp.dash,
1618		  info->SerialNumber);	/* XXX how is this meant to be formatted? */
1619}
1620
1621/********************************************************************************
1622 * Look up a text description of a numeric error code and return a pointer to
1623 * same.
1624 */
1625static char *
1626aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
1627{
1628    int		i;
1629
1630    for (i = 0; table[i].string != NULL; i++)
1631	if (table[i].code == code)
1632	    return(table[i].string);
1633    return(table[i+1].string);
1634}
1635
1636/*****************************************************************************
1637 *****************************************************************************
1638                                                    Management Interface
1639 *****************************************************************************
1640 *****************************************************************************/
1641
1642static int
1643aac_open(dev_t dev, int flags, int fmt, struct proc *p)
1644{
1645    struct aac_softc	*sc = dev->si_drv1;
1646
1647    debug_called(2);
1648
1649    /* Check to make sure the device isn't already open */
1650    if (sc->aac_state & AAC_STATE_OPEN) {
1651        return EBUSY;
1652    }
1653    sc->aac_state |= AAC_STATE_OPEN;
1654
1655    return 0;
1656}
1657
1658static int
1659aac_close(dev_t dev, int flags, int fmt, struct proc *p)
1660{
1661    struct aac_softc	*sc = dev->si_drv1;
1662
1663    debug_called(2);
1664
1665    /* Mark this unit as no longer open  */
1666    sc->aac_state &= ~AAC_STATE_OPEN;
1667
1668    return 0;
1669}
1670
1671static int
1672aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
1673{
1674    struct aac_softc	*sc = dev->si_drv1;
1675    int			error = 0, i;
1676
1677    debug_called(2);
1678
1679    switch (cmd) {
1680#ifdef AAC_COMPAT_LINUX
1681    case FSACTL_SENDFIB:
1682	debug(0, "FSACTL_SENDFIB");
1683	error = aac_ioctl_sendfib(sc, arg);
1684	break;
1685    case FSACTL_AIF_THREAD:
1686	debug(0, "FSACTL_AIF_THREAD");
1687	error = EINVAL;
1688	break;
1689    case FSACTL_OPEN_GET_ADAPTER_FIB:
1690	debug(0, "FSACTL_OPEN_GET_ADAPTER_FIB");
1691	/*
1692	 * Pass the caller out an AdapterFibContext.
1693	 *
1694	 * Note that because we only support one opener, we
1695	 * basically ignore this.  Set the caller's context to a magic
1696	 * number just in case.
1697	 */
1698	i = AAC_AIF_SILLYMAGIC;
1699	error = copyout(&i, arg, sizeof(i));
1700	break;
1701    case FSACTL_GET_NEXT_ADAPTER_FIB:
1702	debug(0, "FSACTL_GET_NEXT_ADAPTER_FIB");
1703	error = aac_linux_getnext_aif(sc, arg);
1704	break;
1705    case FSACTL_CLOSE_GET_ADAPTER_FIB:
1706	debug(0, "FSACTL_CLOSE_GET_ADAPTER_FIB");
1707	/* don't do anything here */
1708	break;
1709    case FSACTL_MINIPORT_REV_CHECK:
1710	debug(0, "FSACTL_MINIPORT_REV_CHECK");
1711	error = aac_linux_rev_check(sc, arg);
1712	break;
1713#endif
1714    default:
1715	device_printf(sc->aac_dev, "unsupported cmd 0x%lx\n", cmd);
1716	error = EINVAL;
1717	break;
1718    }
1719    return(error);
1720}
1721
1722/********************************************************************************
1723 * Send a FIB supplied from userspace
1724 */
1725static int
1726aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
1727{
1728    struct aac_command 	*cm;
1729    int			size, error;
1730
1731    debug_called(2);
1732
1733    cm = NULL;
1734
1735    /*
1736     * Get a command
1737     */
1738    if (aac_alloc_command(sc, &cm)) {
1739	error = EBUSY;
1740	goto out;
1741    }
1742
1743    /*
1744     * Fetch the FIB header, then re-copy to get data as well.
1745     */
1746    if ((error = copyin(ufib, cm->cm_fib, sizeof(struct aac_fib_header))) != 0)
1747	goto out;
1748    size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
1749    if (size > sizeof(struct aac_fib)) {
1750	device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n", size, sizeof(struct aac_fib));
1751	size = sizeof(struct aac_fib);
1752    }
1753    if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
1754	goto out;
1755    cm->cm_fib->Header.Size = size;
1756
1757    /*
1758     * Pass the FIB to the controller, wait for it to complete.
1759     */
1760    if ((error = aac_wait_command(cm, 30)) != 0)	/* XXX user timeout? */
1761	goto out;
1762
1763    /*
1764     * Copy the FIB and data back out to the caller.
1765     */
1766    size = cm->cm_fib->Header.Size;
1767    if (size > sizeof(struct aac_fib)) {
1768	device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n", size, sizeof(struct aac_fib));
1769	size = sizeof(struct aac_fib);
1770    }
1771    error = copyout(cm->cm_fib, ufib, size);
1772
1773out:
1774    if (cm != NULL)
1775	aac_release_command(cm);
1776    return(error);
1777}
1778
1779/********************************************************************************
1780 * Handle an AIF sent to us by the controller; queue it for later reference.
1781 *
1782 * XXX what's the right thing to do here when the queue is full?  Drop the older
1783 * or newer entries?
1784 */
1785static void
1786aac_handle_aif(struct aac_softc *sc, struct aac_aif_command *aif)
1787{
1788    int		next, s;
1789
1790    debug_called(2);
1791
1792    s = splbio();
1793    next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
1794    if (next != sc->aac_aifq_tail) {
1795	bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
1796	sc->aac_aifq_head = next;
1797	if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
1798	    wakeup(sc->aac_aifq);
1799    }
1800    splx(s);
1801    aac_print_aif(sc, aif);
1802}
1803
1804/********************************************************************************
1805 * Hand the next AIF off the top of the queue out to userspace.
1806 */
1807static int
1808aac_return_aif(struct aac_softc *sc, caddr_t uptr)
1809{
1810    int		error, s;
1811
1812    debug_called(2);
1813
1814    s = splbio();
1815    if (sc->aac_aifq_tail == sc->aac_aifq_head) {
1816	error = EAGAIN;
1817    } else {
1818	error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr, sizeof(struct aac_aif_command));
1819	if (!error)
1820	    sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) % AAC_AIFQ_LENGTH;
1821    }
1822    splx(s);
1823    return(error);
1824}
1825
1826/********************************************************************************
1827 ********************************************************************************
1828                                                       Linux Management Interface
1829 ********************************************************************************
1830 ********************************************************************************/
1831
1832#ifdef AAC_COMPAT_LINUX
1833
1834#include <sys/proc.h>
1835#include <machine/../linux/linux.h>
1836#include <machine/../linux/linux_proto.h>
1837#include <compat/linux/linux_ioctl.h>
1838
1839#define AAC_LINUX_IOCTL_MIN  0x2000
1840#define AAC_LINUX_IOCTL_MAX  0x21ff
1841
1842static linux_ioctl_function_t aac_linux_ioctl;
1843static struct linux_ioctl_handler aac_handler = {aac_linux_ioctl, AAC_LINUX_IOCTL_MIN, AAC_LINUX_IOCTL_MAX};
1844
1845SYSINIT  (aac_register,   SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_register_handler, &aac_handler);
1846SYSUNINIT(aac_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE, linux_ioctl_unregister_handler, &aac_handler);
1847
1848MODULE_DEPEND(aac, linux, 1, 1, 1);
1849
1850static int
1851aac_linux_ioctl(struct proc *p, struct linux_ioctl_args *args)
1852{
1853    struct file		*fp = p->p_fd->fd_ofiles[args->fd];
1854    u_long		cmd = args->cmd;
1855
1856    /*
1857     * Pass the ioctl off to our standard handler.
1858     */
1859    return(fo_ioctl(fp, cmd, (caddr_t)args->arg, p));
1860}
1861
1862/********************************************************************************
1863 * Return the Revision of the driver to the userspace and check to see if the
1864 * userspace app is possibly compatible.  This is extremely bogus right now
1865 * because I have no idea how to handle the versioning of this driver.  It is
1866 * needed, though, to get aaccli working.
1867 */
1868static int
1869aac_linux_rev_check(struct aac_softc *sc, caddr_t udata)
1870{
1871    struct aac_rev_check	rev_check;
1872    struct aac_rev_check_resp	rev_check_resp;
1873    int				error = 0;
1874
1875    debug_called(2);
1876
1877    /*
1878     * Copyin the revision struct from userspace
1879     */
1880    if ((error = copyin(udata, (caddr_t)&rev_check, sizeof(struct aac_rev_check))) != 0) {
1881	return error;
1882    }
1883
1884    debug(2, "Userland revision= %d\n", rev_check.callingRevision.buildNumber);
1885
1886    /*
1887     * Doctor up the response struct.
1888     */
1889    rev_check_resp.possiblyCompatible = 1;
1890    rev_check_resp.adapterSWRevision.external.ul = sc->aac_revision.external.ul;
1891    rev_check_resp.adapterSWRevision.buildNumber = sc->aac_revision.buildNumber;
1892
1893    return(copyout((caddr_t)&rev_check_resp, udata, sizeof(struct aac_rev_check_resp)));
1894}
1895
1896/********************************************************************************
1897 * Pass the caller the next AIF in their queue
1898 */
1899static int
1900aac_linux_getnext_aif(struct aac_softc *sc, caddr_t arg)
1901{
1902    struct get_adapter_fib_ioctl	agf;
1903    int					error, s;
1904
1905    debug_called(2);
1906
1907    if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
1908
1909	/*
1910	 * Check the magic number that we gave the caller.
1911	 */
1912	if (agf.AdapterFibContext != AAC_AIF_SILLYMAGIC) {
1913	    error = EFAULT;
1914	} else {
1915
1916	    s = splbio();
1917	    error = aac_return_aif(sc, agf.AifFib);
1918
1919	    if ((error == EAGAIN) && (agf.Wait)) {
1920		sc->aac_state |= AAC_STATE_AIF_SLEEPER;
1921		while (error == EAGAIN) {
1922		    error = tsleep(sc->aac_aifq, PRIBIO | PCATCH, "aacaif", 0);
1923		    if (error == 0)
1924			error = aac_return_aif(sc, agf.AifFib);
1925		}
1926		sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
1927	    }
1928	    splx(s);
1929	}
1930    }
1931    return(error);
1932}
1933
1934#endif /* AAC_COMPAT_LINUX */
1935