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