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