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