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