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