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