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