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