aac.c revision 177463
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
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/aac/aac.c 177463 2008-03-20 20:33:48Z emaste $");
32
33/*
34 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
35 */
36#define AAC_DRIVER_VERSION		0x02000000
37#define AAC_DRIVERNAME			"aac"
38
39#include "opt_aac.h"
40
41/* #include <stddef.h> */
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/malloc.h>
45#include <sys/kernel.h>
46#include <sys/kthread.h>
47#include <sys/sysctl.h>
48#include <sys/poll.h>
49#include <sys/ioccom.h>
50
51#include <sys/bus.h>
52#include <sys/conf.h>
53#include <sys/signalvar.h>
54#include <sys/time.h>
55#include <sys/eventhandler.h>
56#include <sys/rman.h>
57
58#include <machine/bus.h>
59#include <sys/bus_dma.h>
60#include <machine/resource.h>
61
62#include <dev/pci/pcireg.h>
63#include <dev/pci/pcivar.h>
64
65#include <dev/aac/aacreg.h>
66#include <sys/aac_ioctl.h>
67#include <dev/aac/aacvar.h>
68#include <dev/aac/aac_tables.h>
69
70static void	aac_startup(void *arg);
71static void	aac_add_container(struct aac_softc *sc,
72				  struct aac_mntinforesp *mir, int f);
73static void	aac_get_bus_info(struct aac_softc *sc);
74
75/* Command Processing */
76static void	aac_timeout(struct aac_softc *sc);
77static void	aac_complete(void *context, int pending);
78static int	aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
79static void	aac_bio_complete(struct aac_command *cm);
80static int	aac_wait_command(struct aac_command *cm);
81static void	aac_command_thread(struct aac_softc *sc);
82
83/* Command Buffer Management */
84static void	aac_map_command_sg(void *arg, bus_dma_segment_t *segs,
85				   int nseg, int error);
86static void	aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
87				       int nseg, int error);
88static int	aac_alloc_commands(struct aac_softc *sc);
89static void	aac_free_commands(struct aac_softc *sc);
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_check_firmware(struct aac_softc *sc);
96static int	aac_init(struct aac_softc *sc);
97static int	aac_sync_command(struct aac_softc *sc, u_int32_t command,
98				 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
99				 u_int32_t arg3, u_int32_t *sp);
100static int	aac_enqueue_fib(struct aac_softc *sc, int queue,
101				struct aac_command *cm);
102static int	aac_dequeue_fib(struct aac_softc *sc, int queue,
103				u_int32_t *fib_size, struct aac_fib **fib_addr);
104static int	aac_enqueue_response(struct aac_softc *sc, int queue,
105				     struct aac_fib *fib);
106
107/* Falcon/PPC interface */
108static int	aac_fa_get_fwstatus(struct aac_softc *sc);
109static void	aac_fa_qnotify(struct aac_softc *sc, int qbit);
110static int	aac_fa_get_istatus(struct aac_softc *sc);
111static void	aac_fa_clear_istatus(struct aac_softc *sc, int mask);
112static void	aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
113				   u_int32_t arg0, u_int32_t arg1,
114				   u_int32_t arg2, u_int32_t arg3);
115static int	aac_fa_get_mailbox(struct aac_softc *sc, int mb);
116static void	aac_fa_set_interrupts(struct aac_softc *sc, int enable);
117
118struct aac_interface aac_fa_interface = {
119	aac_fa_get_fwstatus,
120	aac_fa_qnotify,
121	aac_fa_get_istatus,
122	aac_fa_clear_istatus,
123	aac_fa_set_mailbox,
124	aac_fa_get_mailbox,
125	aac_fa_set_interrupts,
126	NULL, NULL, NULL
127};
128
129/* StrongARM interface */
130static int	aac_sa_get_fwstatus(struct aac_softc *sc);
131static void	aac_sa_qnotify(struct aac_softc *sc, int qbit);
132static int	aac_sa_get_istatus(struct aac_softc *sc);
133static void	aac_sa_clear_istatus(struct aac_softc *sc, int mask);
134static void	aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
135				   u_int32_t arg0, u_int32_t arg1,
136				   u_int32_t arg2, u_int32_t arg3);
137static int	aac_sa_get_mailbox(struct aac_softc *sc, int mb);
138static void	aac_sa_set_interrupts(struct aac_softc *sc, int enable);
139
140struct aac_interface aac_sa_interface = {
141	aac_sa_get_fwstatus,
142	aac_sa_qnotify,
143	aac_sa_get_istatus,
144	aac_sa_clear_istatus,
145	aac_sa_set_mailbox,
146	aac_sa_get_mailbox,
147	aac_sa_set_interrupts,
148	NULL, NULL, NULL
149};
150
151/* i960Rx interface */
152static int	aac_rx_get_fwstatus(struct aac_softc *sc);
153static void	aac_rx_qnotify(struct aac_softc *sc, int qbit);
154static int	aac_rx_get_istatus(struct aac_softc *sc);
155static void	aac_rx_clear_istatus(struct aac_softc *sc, int mask);
156static void	aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
157				   u_int32_t arg0, u_int32_t arg1,
158				   u_int32_t arg2, u_int32_t arg3);
159static int	aac_rx_get_mailbox(struct aac_softc *sc, int mb);
160static void	aac_rx_set_interrupts(struct aac_softc *sc, int enable);
161static int aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm);
162static int aac_rx_get_outb_queue(struct aac_softc *sc);
163static void aac_rx_set_outb_queue(struct aac_softc *sc, int index);
164
165struct aac_interface aac_rx_interface = {
166	aac_rx_get_fwstatus,
167	aac_rx_qnotify,
168	aac_rx_get_istatus,
169	aac_rx_clear_istatus,
170	aac_rx_set_mailbox,
171	aac_rx_get_mailbox,
172	aac_rx_set_interrupts,
173	aac_rx_send_command,
174	aac_rx_get_outb_queue,
175	aac_rx_set_outb_queue
176};
177
178/* Rocket/MIPS interface */
179static int	aac_rkt_get_fwstatus(struct aac_softc *sc);
180static void	aac_rkt_qnotify(struct aac_softc *sc, int qbit);
181static int	aac_rkt_get_istatus(struct aac_softc *sc);
182static void	aac_rkt_clear_istatus(struct aac_softc *sc, int mask);
183static void	aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command,
184				    u_int32_t arg0, u_int32_t arg1,
185				    u_int32_t arg2, u_int32_t arg3);
186static int	aac_rkt_get_mailbox(struct aac_softc *sc, int mb);
187static void	aac_rkt_set_interrupts(struct aac_softc *sc, int enable);
188static int aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm);
189static int aac_rkt_get_outb_queue(struct aac_softc *sc);
190static void aac_rkt_set_outb_queue(struct aac_softc *sc, int index);
191
192struct aac_interface aac_rkt_interface = {
193	aac_rkt_get_fwstatus,
194	aac_rkt_qnotify,
195	aac_rkt_get_istatus,
196	aac_rkt_clear_istatus,
197	aac_rkt_set_mailbox,
198	aac_rkt_get_mailbox,
199	aac_rkt_set_interrupts,
200	aac_rkt_send_command,
201	aac_rkt_get_outb_queue,
202	aac_rkt_set_outb_queue
203};
204
205/* Debugging and Diagnostics */
206static void	aac_describe_controller(struct aac_softc *sc);
207static char	*aac_describe_code(struct aac_code_lookup *table,
208				   u_int32_t code);
209
210/* Management Interface */
211static d_open_t		aac_open;
212static d_close_t	aac_close;
213static d_ioctl_t	aac_ioctl;
214static d_poll_t		aac_poll;
215static int		aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
216static int		aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
217static void		aac_handle_aif(struct aac_softc *sc,
218					   struct aac_fib *fib);
219static int		aac_rev_check(struct aac_softc *sc, caddr_t udata);
220static int		aac_open_aif(struct aac_softc *sc, caddr_t arg);
221static int		aac_close_aif(struct aac_softc *sc, caddr_t arg);
222static int		aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
223static int		aac_return_aif(struct aac_softc *sc,
224					struct aac_fib_context *ctx, caddr_t uptr);
225static int		aac_query_disk(struct aac_softc *sc, caddr_t uptr);
226static int		aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
227static void		aac_ioctl_event(struct aac_softc *sc,
228				        struct aac_event *event, void *arg);
229
230static struct cdevsw aac_cdevsw = {
231	.d_version =	D_VERSION,
232	.d_flags =	D_NEEDGIANT,
233	.d_open =	aac_open,
234	.d_close =	aac_close,
235	.d_ioctl =	aac_ioctl,
236	.d_poll =	aac_poll,
237	.d_name =	"aac",
238};
239
240MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
241
242/* sysctl node */
243SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
244
245/*
246 * Device Interface
247 */
248
249/*
250 * Initialize the controller and softc
251 */
252int
253aac_attach(struct aac_softc *sc)
254{
255	int error, unit;
256
257	debug_called(1);
258
259	/*
260	 * Initialize per-controller queues.
261	 */
262	aac_initq_free(sc);
263	aac_initq_ready(sc);
264	aac_initq_busy(sc);
265	aac_initq_bio(sc);
266
267	/*
268	 * Initialize command-completion task.
269	 */
270	TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
271
272	/* mark controller as suspended until we get ourselves organised */
273	sc->aac_state |= AAC_STATE_SUSPEND;
274
275	/*
276	 * Check that the firmware on the card is supported.
277	 */
278	if ((error = aac_check_firmware(sc)) != 0)
279		return(error);
280
281	/*
282	 * Initialize locks
283	 */
284	mtx_init(&sc->aac_aifq_lock, "AAC AIF lock", NULL, MTX_DEF);
285	mtx_init(&sc->aac_io_lock, "AAC I/O lock", NULL, MTX_DEF);
286	mtx_init(&sc->aac_container_lock, "AAC container lock", NULL, MTX_DEF);
287	TAILQ_INIT(&sc->aac_container_tqh);
288	TAILQ_INIT(&sc->aac_ev_cmfree);
289
290	/*
291	 * Initialize the adapter.
292	 */
293	if ((error = aac_init(sc)) != 0)
294		return(error);
295
296	/*
297	 * Allocate and connect our interrupt.
298	 */
299	sc->aac_irq_rid = 0;
300	if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
301			   			  &sc->aac_irq_rid,
302			   			  RF_SHAREABLE |
303						  RF_ACTIVE)) == NULL) {
304		device_printf(sc->aac_dev, "can't allocate interrupt\n");
305		return (EINVAL);
306	}
307	if (sc->flags & AAC_FLAGS_NEW_COMM) {
308		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
309				   INTR_MPSAFE|INTR_TYPE_BIO, NULL,
310				   aac_new_intr, sc, &sc->aac_intr)) {
311			device_printf(sc->aac_dev, "can't set up interrupt\n");
312			return (EINVAL);
313		}
314	} else {
315		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
316				   INTR_TYPE_BIO, aac_fast_intr, NULL,
317				   sc, &sc->aac_intr)) {
318			device_printf(sc->aac_dev,
319				      "can't set up FAST interrupt\n");
320			if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
321					   INTR_MPSAFE|INTR_TYPE_BIO,
322					   NULL, (driver_intr_t *)aac_fast_intr,
323					   sc, &sc->aac_intr)) {
324				device_printf(sc->aac_dev,
325					     "can't set up MPSAFE interrupt\n");
326				return (EINVAL);
327			}
328		}
329	}
330
331	/*
332	 * Print a little information about the controller.
333	 */
334	aac_describe_controller(sc);
335
336	/*
337	 * Register to probe our containers later.
338	 */
339	sc->aac_ich.ich_func = aac_startup;
340	sc->aac_ich.ich_arg = sc;
341	if (config_intrhook_establish(&sc->aac_ich) != 0) {
342		device_printf(sc->aac_dev,
343			      "can't establish configuration hook\n");
344		return(ENXIO);
345	}
346
347	/*
348	 * Make the control device.
349	 */
350	unit = device_get_unit(sc->aac_dev);
351	sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_OPERATOR,
352				 0640, "aac%d", unit);
353	(void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
354	(void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
355	sc->aac_dev_t->si_drv1 = sc;
356
357	/* Create the AIF thread */
358	if (kproc_create((void(*)(void *))aac_command_thread, sc,
359		   &sc->aifthread, 0, 0, "aac%daif", unit))
360		panic("Could not create AIF thread\n");
361
362	/* Register the shutdown method to only be called post-dump */
363	if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
364	    sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
365		device_printf(sc->aac_dev,
366			      "shutdown event registration failed\n");
367
368	/* Register with CAM for the non-DASD devices */
369	if ((sc->flags & AAC_FLAGS_ENABLE_CAM) != 0) {
370		TAILQ_INIT(&sc->aac_sim_tqh);
371		aac_get_bus_info(sc);
372	}
373
374	return(0);
375}
376
377void
378aac_add_event(struct aac_softc *sc, struct aac_event *event)
379{
380
381	switch (event->ev_type & AAC_EVENT_MASK) {
382	case AAC_EVENT_CMFREE:
383		TAILQ_INSERT_TAIL(&sc->aac_ev_cmfree, event, ev_links);
384		break;
385	default:
386		device_printf(sc->aac_dev, "aac_add event: unknown event %d\n",
387		    event->ev_type);
388		break;
389	}
390
391	return;
392}
393
394/*
395 * Probe for containers, create disks.
396 */
397static void
398aac_startup(void *arg)
399{
400	struct aac_softc *sc;
401	struct aac_fib *fib;
402	struct aac_mntinfo *mi;
403	struct aac_mntinforesp *mir = NULL;
404	int count = 0, i = 0;
405
406	debug_called(1);
407
408	sc = (struct aac_softc *)arg;
409
410	/* disconnect ourselves from the intrhook chain */
411	config_intrhook_disestablish(&sc->aac_ich);
412
413	mtx_lock(&sc->aac_io_lock);
414	aac_alloc_sync_fib(sc, &fib);
415	mi = (struct aac_mntinfo *)&fib->data[0];
416
417	/* loop over possible containers */
418	do {
419		/* request information on this container */
420		bzero(mi, sizeof(struct aac_mntinfo));
421		mi->Command = VM_NameServe;
422		mi->MntType = FT_FILESYS;
423		mi->MntCount = i;
424		if (aac_sync_fib(sc, ContainerCommand, 0, fib,
425				 sizeof(struct aac_mntinfo))) {
426			printf("error probing container %d", i);
427			continue;
428		}
429
430		mir = (struct aac_mntinforesp *)&fib->data[0];
431		/* XXX Need to check if count changed */
432		count = mir->MntRespCount;
433		aac_add_container(sc, mir, 0);
434		i++;
435	} while ((i < count) && (i < AAC_MAX_CONTAINERS));
436
437	aac_release_sync_fib(sc);
438	mtx_unlock(&sc->aac_io_lock);
439
440	/* poke the bus to actually attach the child devices */
441	if (bus_generic_attach(sc->aac_dev))
442		device_printf(sc->aac_dev, "bus_generic_attach failed\n");
443
444	/* mark the controller up */
445	sc->aac_state &= ~AAC_STATE_SUSPEND;
446
447	/* enable interrupts now */
448	AAC_UNMASK_INTERRUPTS(sc);
449}
450
451/*
452 * Create a device to represent a new container
453 */
454static void
455aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
456{
457	struct aac_container *co;
458	device_t child;
459
460	/*
461	 * Check container volume type for validity.  Note that many of
462	 * the possible types may never show up.
463	 */
464	if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
465		co = (struct aac_container *)malloc(sizeof *co, M_AACBUF,
466		       M_NOWAIT | M_ZERO);
467		if (co == NULL)
468			panic("Out of memory?!\n");
469		debug(1, "id %x  name '%.16s'  size %u  type %d",
470		      mir->MntTable[0].ObjectId,
471		      mir->MntTable[0].FileSystemName,
472		      mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
473
474		if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
475			device_printf(sc->aac_dev, "device_add_child failed\n");
476		else
477			device_set_ivars(child, co);
478		device_set_desc(child, aac_describe_code(aac_container_types,
479				mir->MntTable[0].VolType));
480		co->co_disk = child;
481		co->co_found = f;
482		bcopy(&mir->MntTable[0], &co->co_mntobj,
483		      sizeof(struct aac_mntobj));
484		mtx_lock(&sc->aac_container_lock);
485		TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
486		mtx_unlock(&sc->aac_container_lock);
487	}
488}
489
490/*
491 * Free all of the resources associated with (sc)
492 *
493 * Should not be called if the controller is active.
494 */
495void
496aac_free(struct aac_softc *sc)
497{
498
499	debug_called(1);
500
501	/* remove the control device */
502	if (sc->aac_dev_t != NULL)
503		destroy_dev(sc->aac_dev_t);
504
505	/* throw away any FIB buffers, discard the FIB DMA tag */
506	aac_free_commands(sc);
507	if (sc->aac_fib_dmat)
508		bus_dma_tag_destroy(sc->aac_fib_dmat);
509
510	free(sc->aac_commands, M_AACBUF);
511
512	/* destroy the common area */
513	if (sc->aac_common) {
514		bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
515		bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
516				sc->aac_common_dmamap);
517	}
518	if (sc->aac_common_dmat)
519		bus_dma_tag_destroy(sc->aac_common_dmat);
520
521	/* disconnect the interrupt handler */
522	if (sc->aac_intr)
523		bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
524	if (sc->aac_irq != NULL)
525		bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
526				     sc->aac_irq);
527
528	/* destroy data-transfer DMA tag */
529	if (sc->aac_buffer_dmat)
530		bus_dma_tag_destroy(sc->aac_buffer_dmat);
531
532	/* destroy the parent DMA tag */
533	if (sc->aac_parent_dmat)
534		bus_dma_tag_destroy(sc->aac_parent_dmat);
535
536	/* release the register window mapping */
537	if (sc->aac_regs_resource != NULL)
538		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
539				     sc->aac_regs_rid, sc->aac_regs_resource);
540}
541
542/*
543 * Disconnect from the controller completely, in preparation for unload.
544 */
545int
546aac_detach(device_t dev)
547{
548	struct aac_softc *sc;
549	struct aac_container *co;
550	struct aac_sim	*sim;
551	int error;
552
553	debug_called(1);
554
555	sc = device_get_softc(dev);
556
557	if (sc->aac_state & AAC_STATE_OPEN)
558		return(EBUSY);
559
560	/* Remove the child containers */
561	while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
562		error = device_delete_child(dev, co->co_disk);
563		if (error)
564			return (error);
565		TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
566		free(co, M_AACBUF);
567	}
568
569	/* Remove the CAM SIMs */
570	while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
571		TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
572		error = device_delete_child(dev, sim->sim_dev);
573		if (error)
574			return (error);
575		free(sim, M_AACBUF);
576	}
577
578	if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
579		sc->aifflags |= AAC_AIFFLAGS_EXIT;
580		wakeup(sc->aifthread);
581		tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
582	}
583
584	if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
585		panic("Cannot shutdown AIF thread\n");
586
587	if ((error = aac_shutdown(dev)))
588		return(error);
589
590	EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
591
592	aac_free(sc);
593
594	mtx_destroy(&sc->aac_aifq_lock);
595	mtx_destroy(&sc->aac_io_lock);
596	mtx_destroy(&sc->aac_container_lock);
597
598	return(0);
599}
600
601/*
602 * Bring the controller down to a dormant state and detach all child devices.
603 *
604 * This function is called before detach or system shutdown.
605 *
606 * Note that we can assume that the bioq on the controller is empty, as we won't
607 * allow shutdown if any device is open.
608 */
609int
610aac_shutdown(device_t dev)
611{
612	struct aac_softc *sc;
613	struct aac_fib *fib;
614	struct aac_close_command *cc;
615
616	debug_called(1);
617
618	sc = device_get_softc(dev);
619
620	sc->aac_state |= AAC_STATE_SUSPEND;
621
622	/*
623	 * Send a Container shutdown followed by a HostShutdown FIB to the
624	 * controller to convince it that we don't want to talk to it anymore.
625	 * We've been closed and all I/O completed already
626	 */
627	device_printf(sc->aac_dev, "shutting down controller...");
628
629	mtx_lock(&sc->aac_io_lock);
630	aac_alloc_sync_fib(sc, &fib);
631	cc = (struct aac_close_command *)&fib->data[0];
632
633	bzero(cc, sizeof(struct aac_close_command));
634	cc->Command = VM_CloseAll;
635	cc->ContainerId = 0xffffffff;
636	if (aac_sync_fib(sc, ContainerCommand, 0, fib,
637	    sizeof(struct aac_close_command)))
638		printf("FAILED.\n");
639	else
640		printf("done\n");
641#if 0
642	else {
643		fib->data[0] = 0;
644		/*
645		 * XXX Issuing this command to the controller makes it shut down
646		 * but also keeps it from coming back up without a reset of the
647		 * PCI bus.  This is not desirable if you are just unloading the
648		 * driver module with the intent to reload it later.
649		 */
650		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
651		    fib, 1)) {
652			printf("FAILED.\n");
653		} else {
654			printf("done.\n");
655		}
656	}
657#endif
658
659	AAC_MASK_INTERRUPTS(sc);
660	aac_release_sync_fib(sc);
661	mtx_unlock(&sc->aac_io_lock);
662
663	return(0);
664}
665
666/*
667 * Bring the controller to a quiescent state, ready for system suspend.
668 */
669int
670aac_suspend(device_t dev)
671{
672	struct aac_softc *sc;
673
674	debug_called(1);
675
676	sc = device_get_softc(dev);
677
678	sc->aac_state |= AAC_STATE_SUSPEND;
679
680	AAC_MASK_INTERRUPTS(sc);
681	return(0);
682}
683
684/*
685 * Bring the controller back to a state ready for operation.
686 */
687int
688aac_resume(device_t dev)
689{
690	struct aac_softc *sc;
691
692	debug_called(1);
693
694	sc = device_get_softc(dev);
695
696	sc->aac_state &= ~AAC_STATE_SUSPEND;
697	AAC_UNMASK_INTERRUPTS(sc);
698	return(0);
699}
700
701/*
702 * Interrupt handler for NEW_COMM interface.
703 */
704void
705aac_new_intr(void *arg)
706{
707	struct aac_softc *sc;
708	u_int32_t index, fast;
709	struct aac_command *cm;
710	struct aac_fib *fib;
711	int i;
712
713	debug_called(2);
714
715	sc = (struct aac_softc *)arg;
716
717	mtx_lock(&sc->aac_io_lock);
718	while (1) {
719		index = AAC_GET_OUTB_QUEUE(sc);
720		if (index == 0xffffffff)
721			index = AAC_GET_OUTB_QUEUE(sc);
722		if (index == 0xffffffff)
723			break;
724		if (index & 2) {
725			if (index == 0xfffffffe) {
726				/* XXX This means that the controller wants
727				 * more work.  Ignore it for now.
728				 */
729				continue;
730			}
731			/* AIF */
732			fib = (struct aac_fib *)malloc(sizeof *fib, M_AACBUF,
733				   M_NOWAIT | M_ZERO);
734			if (fib == NULL) {
735				/* If we're really this short on memory,
736				 * hopefully breaking out of the handler will
737				 * allow something to get freed.  This
738				 * actually sucks a whole lot.
739				 */
740				break;
741			}
742			index &= ~2;
743			for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
744				((u_int32_t *)fib)[i] = AAC_GETREG4(sc, index + i*4);
745			aac_handle_aif(sc, fib);
746			free(fib, M_AACBUF);
747
748			/*
749			 * AIF memory is owned by the adapter, so let it
750			 * know that we are done with it.
751			 */
752			AAC_SET_OUTB_QUEUE(sc, index);
753			AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
754		} else {
755			fast = index & 1;
756			cm = sc->aac_commands + (index >> 2);
757			fib = cm->cm_fib;
758			if (fast) {
759				fib->Header.XferState |= AAC_FIBSTATE_DONEADAP;
760				*((u_int32_t *)(fib->data)) = AAC_ERROR_NORMAL;
761			}
762			aac_remove_busy(cm);
763 			aac_unmap_command(cm);
764			cm->cm_flags |= AAC_CMD_COMPLETED;
765
766			/* is there a completion handler? */
767			if (cm->cm_complete != NULL) {
768				cm->cm_complete(cm);
769			} else {
770				/* assume that someone is sleeping on this
771				 * command
772				 */
773				wakeup(cm);
774			}
775			sc->flags &= ~AAC_QUEUE_FRZN;
776		}
777	}
778	/* see if we can start some more I/O */
779	if ((sc->flags & AAC_QUEUE_FRZN) == 0)
780		aac_startio(sc);
781
782	mtx_unlock(&sc->aac_io_lock);
783}
784
785int
786aac_fast_intr(void *arg)
787{
788	struct aac_softc *sc;
789	u_int16_t reason;
790
791	debug_called(2);
792
793	sc = (struct aac_softc *)arg;
794
795	/*
796	 * Read the status register directly.  This is faster than taking the
797	 * driver lock and reading the queues directly.  It also saves having
798	 * to turn parts of the driver lock into a spin mutex, which would be
799	 * ugly.
800	 */
801	reason = AAC_GET_ISTATUS(sc);
802	AAC_CLEAR_ISTATUS(sc, reason);
803
804	/* handle completion processing */
805	if (reason & AAC_DB_RESPONSE_READY)
806		taskqueue_enqueue_fast(taskqueue_fast, &sc->aac_task_complete);
807
808	/* controller wants to talk to us */
809	if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY)) {
810		/*
811		 * XXX Make sure that we don't get fooled by strange messages
812		 * that start with a NULL.
813		 */
814		if ((reason & AAC_DB_PRINTF) &&
815			(sc->aac_common->ac_printf[0] == 0))
816			sc->aac_common->ac_printf[0] = 32;
817
818		/*
819		 * This might miss doing the actual wakeup.  However, the
820		 * msleep that this is waking up has a timeout, so it will
821		 * wake up eventually.  AIFs and printfs are low enough
822		 * priority that they can handle hanging out for a few seconds
823		 * if needed.
824		 */
825		wakeup(sc->aifthread);
826	}
827	return (FILTER_HANDLED);
828}
829
830/*
831 * Command Processing
832 */
833
834/*
835 * Start as much queued I/O as possible on the controller
836 */
837void
838aac_startio(struct aac_softc *sc)
839{
840	struct aac_command *cm;
841	int error;
842
843	debug_called(2);
844
845	for (;;) {
846		/*
847		 * This flag might be set if the card is out of resources.
848		 * Checking it here prevents an infinite loop of deferrals.
849		 */
850		if (sc->flags & AAC_QUEUE_FRZN)
851			break;
852
853		/*
854		 * Try to get a command that's been put off for lack of
855		 * resources
856		 */
857		cm = aac_dequeue_ready(sc);
858
859		/*
860		 * Try to build a command off the bio queue (ignore error
861		 * return)
862		 */
863		if (cm == NULL)
864			aac_bio_command(sc, &cm);
865
866		/* nothing to do? */
867		if (cm == NULL)
868			break;
869
870		/* don't map more than once */
871		if (cm->cm_flags & AAC_CMD_MAPPED)
872			panic("aac: command %p already mapped", cm);
873
874		/*
875		 * Set up the command to go to the controller.  If there are no
876		 * data buffers associated with the command then it can bypass
877		 * busdma.
878		 */
879		if (cm->cm_datalen != 0) {
880			error = bus_dmamap_load(sc->aac_buffer_dmat,
881						cm->cm_datamap, cm->cm_data,
882						cm->cm_datalen,
883						aac_map_command_sg, cm, 0);
884			if (error == EINPROGRESS) {
885				debug(1, "freezing queue\n");
886				sc->flags |= AAC_QUEUE_FRZN;
887				error = 0;
888			} else if (error != 0)
889				panic("aac_startio: unexpected error %d from "
890				      "busdma\n", error);
891		} else
892			aac_map_command_sg(cm, NULL, 0, 0);
893	}
894}
895
896/*
897 * Handle notification of one or more FIBs coming from the controller.
898 */
899static void
900aac_command_thread(struct aac_softc *sc)
901{
902	struct aac_fib *fib;
903	u_int32_t fib_size;
904	int size, retval;
905
906	debug_called(2);
907
908	mtx_lock(&sc->aac_io_lock);
909	sc->aifflags = AAC_AIFFLAGS_RUNNING;
910
911	while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
912
913		retval = 0;
914		if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
915			retval = msleep(sc->aifthread, &sc->aac_io_lock, PRIBIO,
916					"aifthd", AAC_PERIODIC_INTERVAL * hz);
917
918		/*
919		 * First see if any FIBs need to be allocated.  This needs
920		 * to be called without the driver lock because contigmalloc
921		 * will grab Giant, and would result in an LOR.
922		 */
923		if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
924			mtx_unlock(&sc->aac_io_lock);
925			aac_alloc_commands(sc);
926			mtx_lock(&sc->aac_io_lock);
927			sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
928			aac_startio(sc);
929		}
930
931		/*
932		 * While we're here, check to see if any commands are stuck.
933		 * This is pretty low-priority, so it's ok if it doesn't
934		 * always fire.
935		 */
936		if (retval == EWOULDBLOCK)
937			aac_timeout(sc);
938
939		/* Check the hardware printf message buffer */
940		if (sc->aac_common->ac_printf[0] != 0)
941			aac_print_printf(sc);
942
943		/* Also check to see if the adapter has a command for us. */
944		if (sc->flags & AAC_FLAGS_NEW_COMM)
945			continue;
946		for (;;) {
947			if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
948					   &fib_size, &fib))
949				break;
950
951			AAC_PRINT_FIB(sc, fib);
952
953			switch (fib->Header.Command) {
954			case AifRequest:
955				aac_handle_aif(sc, fib);
956				break;
957			default:
958				device_printf(sc->aac_dev, "unknown command "
959					      "from controller\n");
960				break;
961			}
962
963			if ((fib->Header.XferState == 0) ||
964			    (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
965				break;
966			}
967
968			/* Return the AIF to the controller. */
969			if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
970				fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
971				*(AAC_FSAStatus*)fib->data = ST_OK;
972
973				/* XXX Compute the Size field? */
974				size = fib->Header.Size;
975				if (size > sizeof(struct aac_fib)) {
976					size = sizeof(struct aac_fib);
977					fib->Header.Size = size;
978				}
979				/*
980				 * Since we did not generate this command, it
981				 * cannot go through the normal
982				 * enqueue->startio chain.
983				 */
984				aac_enqueue_response(sc,
985						 AAC_ADAP_NORM_RESP_QUEUE,
986						 fib);
987			}
988		}
989	}
990	sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
991	mtx_unlock(&sc->aac_io_lock);
992	wakeup(sc->aac_dev);
993
994	kproc_exit(0);
995}
996
997/*
998 * Process completed commands.
999 */
1000static void
1001aac_complete(void *context, int pending)
1002{
1003	struct aac_softc *sc;
1004	struct aac_command *cm;
1005	struct aac_fib *fib;
1006	u_int32_t fib_size;
1007
1008	debug_called(2);
1009
1010	sc = (struct aac_softc *)context;
1011
1012	mtx_lock(&sc->aac_io_lock);
1013
1014	/* pull completed commands off the queue */
1015	for (;;) {
1016		/* look for completed FIBs on our queue */
1017		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1018							&fib))
1019			break;	/* nothing to do */
1020
1021		/* get the command, unmap and hand off for processing */
1022		cm = sc->aac_commands + fib->Header.SenderData;
1023		if (cm == NULL) {
1024			AAC_PRINT_FIB(sc, fib);
1025			break;
1026		}
1027		aac_remove_busy(cm);
1028
1029 		aac_unmap_command(cm);
1030		cm->cm_flags |= AAC_CMD_COMPLETED;
1031
1032		/* is there a completion handler? */
1033		if (cm->cm_complete != NULL) {
1034			cm->cm_complete(cm);
1035		} else {
1036			/* assume that someone is sleeping on this command */
1037			wakeup(cm);
1038		}
1039	}
1040
1041	/* see if we can start some more I/O */
1042	sc->flags &= ~AAC_QUEUE_FRZN;
1043	aac_startio(sc);
1044
1045	mtx_unlock(&sc->aac_io_lock);
1046}
1047
1048/*
1049 * Handle a bio submitted from a disk device.
1050 */
1051void
1052aac_submit_bio(struct bio *bp)
1053{
1054	struct aac_disk *ad;
1055	struct aac_softc *sc;
1056
1057	debug_called(2);
1058
1059	ad = (struct aac_disk *)bp->bio_disk->d_drv1;
1060	sc = ad->ad_controller;
1061
1062	/* queue the BIO and try to get some work done */
1063	aac_enqueue_bio(sc, bp);
1064	aac_startio(sc);
1065}
1066
1067/*
1068 * Get a bio and build a command to go with it.
1069 */
1070static int
1071aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
1072{
1073	struct aac_command *cm;
1074	struct aac_fib *fib;
1075	struct aac_disk *ad;
1076	struct bio *bp;
1077
1078	debug_called(2);
1079
1080	/* get the resources we will need */
1081	cm = NULL;
1082	bp = NULL;
1083	if (aac_alloc_command(sc, &cm))	/* get a command */
1084		goto fail;
1085	if ((bp = aac_dequeue_bio(sc)) == NULL)
1086		goto fail;
1087
1088	/* fill out the command */
1089	cm->cm_data = (void *)bp->bio_data;
1090	cm->cm_datalen = bp->bio_bcount;
1091	cm->cm_complete = aac_bio_complete;
1092	cm->cm_private = bp;
1093	cm->cm_timestamp = time_uptime;
1094	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1095
1096	/* build the FIB */
1097	fib = cm->cm_fib;
1098	fib->Header.Size = sizeof(struct aac_fib_header);
1099	fib->Header.XferState =
1100		AAC_FIBSTATE_HOSTOWNED   |
1101		AAC_FIBSTATE_INITIALISED |
1102		AAC_FIBSTATE_EMPTY	 |
1103		AAC_FIBSTATE_FROMHOST	 |
1104		AAC_FIBSTATE_REXPECTED   |
1105		AAC_FIBSTATE_NORM	 |
1106		AAC_FIBSTATE_ASYNC	 |
1107		AAC_FIBSTATE_FAST_RESPONSE;
1108
1109	/* build the read/write request */
1110	ad = (struct aac_disk *)bp->bio_disk->d_drv1;
1111
1112	if (sc->flags & AAC_FLAGS_RAW_IO) {
1113		struct aac_raw_io *raw;
1114		raw = (struct aac_raw_io *)&fib->data[0];
1115		fib->Header.Command = RawIo;
1116		raw->BlockNumber = (u_int64_t)bp->bio_pblkno;
1117		raw->ByteCount = bp->bio_bcount;
1118		raw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1119		raw->BpTotal = 0;
1120		raw->BpComplete = 0;
1121		fib->Header.Size += sizeof(struct aac_raw_io);
1122		cm->cm_sgtable = (struct aac_sg_table *)&raw->SgMapRaw;
1123		if (bp->bio_cmd == BIO_READ) {
1124			raw->Flags = 1;
1125			cm->cm_flags |= AAC_CMD_DATAIN;
1126		} else {
1127			raw->Flags = 0;
1128			cm->cm_flags |= AAC_CMD_DATAOUT;
1129		}
1130	} else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1131		fib->Header.Command = ContainerCommand;
1132		if (bp->bio_cmd == BIO_READ) {
1133			struct aac_blockread *br;
1134			br = (struct aac_blockread *)&fib->data[0];
1135			br->Command = VM_CtBlockRead;
1136			br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1137			br->BlockNumber = bp->bio_pblkno;
1138			br->ByteCount = bp->bio_bcount;
1139			fib->Header.Size += sizeof(struct aac_blockread);
1140			cm->cm_sgtable = &br->SgMap;
1141			cm->cm_flags |= AAC_CMD_DATAIN;
1142		} else {
1143			struct aac_blockwrite *bw;
1144			bw = (struct aac_blockwrite *)&fib->data[0];
1145			bw->Command = VM_CtBlockWrite;
1146			bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1147			bw->BlockNumber = bp->bio_pblkno;
1148			bw->ByteCount = bp->bio_bcount;
1149			bw->Stable = CUNSTABLE;
1150			fib->Header.Size += sizeof(struct aac_blockwrite);
1151			cm->cm_flags |= AAC_CMD_DATAOUT;
1152			cm->cm_sgtable = &bw->SgMap;
1153		}
1154	} else {
1155		fib->Header.Command = ContainerCommand64;
1156		if (bp->bio_cmd == BIO_READ) {
1157			struct aac_blockread64 *br;
1158			br = (struct aac_blockread64 *)&fib->data[0];
1159			br->Command = VM_CtHostRead64;
1160			br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1161			br->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE;
1162			br->BlockNumber = bp->bio_pblkno;
1163			br->Pad = 0;
1164			br->Flags = 0;
1165			fib->Header.Size += sizeof(struct aac_blockread64);
1166			cm->cm_flags |= AAC_CMD_DATAOUT;
1167			cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
1168		} else {
1169			struct aac_blockwrite64 *bw;
1170			bw = (struct aac_blockwrite64 *)&fib->data[0];
1171			bw->Command = VM_CtHostWrite64;
1172			bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1173			bw->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE;
1174			bw->BlockNumber = bp->bio_pblkno;
1175			bw->Pad = 0;
1176			bw->Flags = 0;
1177			fib->Header.Size += sizeof(struct aac_blockwrite64);
1178			cm->cm_flags |= AAC_CMD_DATAIN;
1179			cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
1180		}
1181	}
1182
1183	*cmp = cm;
1184	return(0);
1185
1186fail:
1187	if (bp != NULL)
1188		aac_enqueue_bio(sc, bp);
1189	if (cm != NULL)
1190		aac_release_command(cm);
1191	return(ENOMEM);
1192}
1193
1194/*
1195 * Handle a bio-instigated command that has been completed.
1196 */
1197static void
1198aac_bio_complete(struct aac_command *cm)
1199{
1200	struct aac_blockread_response *brr;
1201	struct aac_blockwrite_response *bwr;
1202	struct bio *bp;
1203	AAC_FSAStatus status;
1204
1205	/* fetch relevant status and then release the command */
1206	bp = (struct bio *)cm->cm_private;
1207	if (bp->bio_cmd == BIO_READ) {
1208		brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
1209		status = brr->Status;
1210	} else {
1211		bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
1212		status = bwr->Status;
1213	}
1214	aac_release_command(cm);
1215
1216	/* fix up the bio based on status */
1217	if (status == ST_OK) {
1218		bp->bio_resid = 0;
1219	} else {
1220		bp->bio_error = EIO;
1221		bp->bio_flags |= BIO_ERROR;
1222		/* pass an error string out to the disk layer */
1223		bp->bio_driver1 = aac_describe_code(aac_command_status_table,
1224						    status);
1225	}
1226	aac_biodone(bp);
1227}
1228
1229/*
1230 * Submit a command to the controller, return when it completes.
1231 * XXX This is very dangerous!  If the card has gone out to lunch, we could
1232 *     be stuck here forever.  At the same time, signals are not caught
1233 *     because there is a risk that a signal could wakeup the sleep before
1234 *     the card has a chance to complete the command.  Since there is no way
1235 *     to cancel a command that is in progress, we can't protect against the
1236 *     card completing a command late and spamming the command and data
1237 *     memory.  So, we are held hostage until the command completes.
1238 */
1239static int
1240aac_wait_command(struct aac_command *cm)
1241{
1242	struct aac_softc *sc;
1243	int error;
1244
1245	debug_called(2);
1246
1247	sc = cm->cm_sc;
1248
1249	/* Put the command on the ready queue and get things going */
1250	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1251	aac_enqueue_ready(cm);
1252	aac_startio(sc);
1253	error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
1254	return(error);
1255}
1256
1257/*
1258 *Command Buffer Management
1259 */
1260
1261/*
1262 * Allocate a command.
1263 */
1264int
1265aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1266{
1267	struct aac_command *cm;
1268
1269	debug_called(3);
1270
1271	if ((cm = aac_dequeue_free(sc)) == NULL) {
1272		if (sc->total_fibs < sc->aac_max_fibs) {
1273			sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1274			wakeup(sc->aifthread);
1275		}
1276		return (EBUSY);
1277	}
1278
1279	*cmp = cm;
1280	return(0);
1281}
1282
1283/*
1284 * Release a command back to the freelist.
1285 */
1286void
1287aac_release_command(struct aac_command *cm)
1288{
1289	struct aac_event *event;
1290	struct aac_softc *sc;
1291
1292	debug_called(3);
1293
1294	/* (re)initialize the command/FIB */
1295	cm->cm_sgtable = NULL;
1296	cm->cm_flags = 0;
1297	cm->cm_complete = NULL;
1298	cm->cm_private = NULL;
1299	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1300	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1301	cm->cm_fib->Header.Flags = 0;
1302	cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
1303
1304	/*
1305	 * These are duplicated in aac_start to cover the case where an
1306	 * intermediate stage may have destroyed them.  They're left
1307	 * initialized here for debugging purposes only.
1308	 */
1309	cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1310	cm->cm_fib->Header.SenderData = 0;
1311
1312	aac_enqueue_free(cm);
1313
1314	/*
1315	 * Dequeue all events so that there's no risk of events getting
1316	 * stranded.
1317	 */
1318	sc = cm->cm_sc;
1319	while ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
1320		TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
1321		event->ev_callback(sc, event, event->ev_arg);
1322	}
1323}
1324
1325/*
1326 * Map helper for command/FIB allocation.
1327 */
1328static void
1329aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1330{
1331	uint64_t	*fibphys;
1332
1333	fibphys = (uint64_t *)arg;
1334
1335	debug_called(3);
1336
1337	*fibphys = segs[0].ds_addr;
1338}
1339
1340/*
1341 * Allocate and initialize commands/FIBs for this adapter.
1342 */
1343static int
1344aac_alloc_commands(struct aac_softc *sc)
1345{
1346	struct aac_command *cm;
1347	struct aac_fibmap *fm;
1348	uint64_t fibphys;
1349	int i, error;
1350
1351	debug_called(2);
1352
1353	if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
1354		return (ENOMEM);
1355
1356	fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
1357	if (fm == NULL)
1358		return (ENOMEM);
1359
1360	/* allocate the FIBs in DMAable memory and load them */
1361	if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1362			     BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1363		device_printf(sc->aac_dev,
1364			      "Not enough contiguous memory available.\n");
1365		free(fm, M_AACBUF);
1366		return (ENOMEM);
1367	}
1368
1369	/* Ignore errors since this doesn't bounce */
1370	(void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1371			      sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
1372			      aac_map_command_helper, &fibphys, 0);
1373
1374	/* initialize constant fields in the command structure */
1375	bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
1376	for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
1377		cm = sc->aac_commands + sc->total_fibs;
1378		fm->aac_commands = cm;
1379		cm->cm_sc = sc;
1380		cm->cm_fib = (struct aac_fib *)
1381			((u_int8_t *)fm->aac_fibs + i*sc->aac_max_fib_size);
1382		cm->cm_fibphys = fibphys + i*sc->aac_max_fib_size;
1383		cm->cm_index = sc->total_fibs;
1384
1385		if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1386					       &cm->cm_datamap)) != 0)
1387			break;
1388		mtx_lock(&sc->aac_io_lock);
1389		aac_release_command(cm);
1390		sc->total_fibs++;
1391		mtx_unlock(&sc->aac_io_lock);
1392	}
1393
1394	if (i > 0) {
1395		mtx_lock(&sc->aac_io_lock);
1396		TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1397		debug(1, "total_fibs= %d\n", sc->total_fibs);
1398		mtx_unlock(&sc->aac_io_lock);
1399		return (0);
1400	}
1401
1402	bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1403	bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1404	free(fm, M_AACBUF);
1405	return (ENOMEM);
1406}
1407
1408/*
1409 * Free FIBs owned by this adapter.
1410 */
1411static void
1412aac_free_commands(struct aac_softc *sc)
1413{
1414	struct aac_fibmap *fm;
1415	struct aac_command *cm;
1416	int i;
1417
1418	debug_called(1);
1419
1420	while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1421
1422		TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1423		/*
1424		 * We check against total_fibs to handle partially
1425		 * allocated blocks.
1426		 */
1427		for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) {
1428			cm = fm->aac_commands + i;
1429			bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1430		}
1431		bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1432		bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1433		free(fm, M_AACBUF);
1434	}
1435}
1436
1437/*
1438 * Command-mapping helper function - populate this command's s/g table.
1439 */
1440static void
1441aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1442{
1443	struct aac_softc *sc;
1444	struct aac_command *cm;
1445	struct aac_fib *fib;
1446	int i;
1447
1448	debug_called(3);
1449
1450	cm = (struct aac_command *)arg;
1451	sc = cm->cm_sc;
1452	fib = cm->cm_fib;
1453
1454	/* copy into the FIB */
1455	if (cm->cm_sgtable != NULL) {
1456		if (fib->Header.Command == RawIo) {
1457			struct aac_sg_tableraw *sg;
1458			sg = (struct aac_sg_tableraw *)cm->cm_sgtable;
1459			sg->SgCount = nseg;
1460			for (i = 0; i < nseg; i++) {
1461				sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr;
1462				sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len;
1463				sg->SgEntryRaw[i].Next = 0;
1464				sg->SgEntryRaw[i].Prev = 0;
1465				sg->SgEntryRaw[i].Flags = 0;
1466			}
1467			/* update the FIB size for the s/g count */
1468			fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw);
1469		} else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1470			struct aac_sg_table *sg;
1471			sg = cm->cm_sgtable;
1472			sg->SgCount = nseg;
1473			for (i = 0; i < nseg; i++) {
1474				sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1475				sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1476			}
1477			/* update the FIB size for the s/g count */
1478			fib->Header.Size += nseg*sizeof(struct aac_sg_entry);
1479		} else {
1480			struct aac_sg_table64 *sg;
1481			sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1482			sg->SgCount = nseg;
1483			for (i = 0; i < nseg; i++) {
1484				sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1485				sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1486			}
1487			/* update the FIB size for the s/g count */
1488			fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1489		}
1490	}
1491
1492	/* Fix up the address values in the FIB.  Use the command array index
1493	 * instead of a pointer since these fields are only 32 bits.  Shift
1494	 * the SenderFibAddress over to make room for the fast response bit
1495	 * and for the AIF bit
1496	 */
1497	cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2);
1498	cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1499
1500	/* save a pointer to the command for speedy reverse-lookup */
1501	cm->cm_fib->Header.SenderData = cm->cm_index;
1502
1503	if (cm->cm_flags & AAC_CMD_DATAIN)
1504		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1505				BUS_DMASYNC_PREREAD);
1506	if (cm->cm_flags & AAC_CMD_DATAOUT)
1507		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1508				BUS_DMASYNC_PREWRITE);
1509	cm->cm_flags |= AAC_CMD_MAPPED;
1510
1511	if (sc->flags & AAC_FLAGS_NEW_COMM) {
1512		int count = 10000000L;
1513		while (AAC_SEND_COMMAND(sc, cm) != 0) {
1514			if (--count == 0) {
1515				aac_unmap_command(cm);
1516				sc->flags |= AAC_QUEUE_FRZN;
1517				aac_requeue_ready(cm);
1518			}
1519			DELAY(5);			/* wait 5 usec. */
1520		}
1521	} else {
1522		/* Put the FIB on the outbound queue */
1523		if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1524			aac_unmap_command(cm);
1525			sc->flags |= AAC_QUEUE_FRZN;
1526			aac_requeue_ready(cm);
1527		}
1528	}
1529
1530	return;
1531}
1532
1533/*
1534 * Unmap a command from controller-visible space.
1535 */
1536static void
1537aac_unmap_command(struct aac_command *cm)
1538{
1539	struct aac_softc *sc;
1540
1541	debug_called(2);
1542
1543	sc = cm->cm_sc;
1544
1545	if (!(cm->cm_flags & AAC_CMD_MAPPED))
1546		return;
1547
1548	if (cm->cm_datalen != 0) {
1549		if (cm->cm_flags & AAC_CMD_DATAIN)
1550			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1551					BUS_DMASYNC_POSTREAD);
1552		if (cm->cm_flags & AAC_CMD_DATAOUT)
1553			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1554					BUS_DMASYNC_POSTWRITE);
1555
1556		bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1557	}
1558	cm->cm_flags &= ~AAC_CMD_MAPPED;
1559}
1560
1561/*
1562 * Hardware Interface
1563 */
1564
1565/*
1566 * Initialize the adapter.
1567 */
1568static void
1569aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1570{
1571	struct aac_softc *sc;
1572
1573	debug_called(1);
1574
1575	sc = (struct aac_softc *)arg;
1576
1577	sc->aac_common_busaddr = segs[0].ds_addr;
1578}
1579
1580static int
1581aac_check_firmware(struct aac_softc *sc)
1582{
1583	u_int32_t major, minor, options = 0, atu_size = 0;
1584	int status;
1585
1586	debug_called(1);
1587
1588	/*
1589	 * Retrieve the firmware version numbers.  Dell PERC2/QC cards with
1590	 * firmware version 1.x are not compatible with this driver.
1591	 */
1592	if (sc->flags & AAC_FLAGS_PERC2QC) {
1593		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1594				     NULL)) {
1595			device_printf(sc->aac_dev,
1596				      "Error reading firmware version\n");
1597			return (EIO);
1598		}
1599
1600		/* These numbers are stored as ASCII! */
1601		major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1602		minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1603		if (major == 1) {
1604			device_printf(sc->aac_dev,
1605			    "Firmware version %d.%d is not supported.\n",
1606			    major, minor);
1607			return (EINVAL);
1608		}
1609	}
1610
1611	/*
1612	 * Retrieve the capabilities/supported options word so we know what
1613	 * work-arounds to enable.  Some firmware revs don't support this
1614	 * command.
1615	 */
1616	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
1617		if (status != AAC_SRB_STS_INVALID_REQUEST) {
1618			device_printf(sc->aac_dev,
1619			     "RequestAdapterInfo failed\n");
1620			return (EIO);
1621		}
1622	} else {
1623		options = AAC_GET_MAILBOX(sc, 1);
1624		atu_size = AAC_GET_MAILBOX(sc, 2);
1625		sc->supported_options = options;
1626
1627		if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1628		    (sc->flags & AAC_FLAGS_NO4GB) == 0)
1629			sc->flags |= AAC_FLAGS_4GB_WINDOW;
1630		if (options & AAC_SUPPORTED_NONDASD)
1631			sc->flags |= AAC_FLAGS_ENABLE_CAM;
1632		if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1633		     && (sizeof(bus_addr_t) > 4)) {
1634			device_printf(sc->aac_dev,
1635			    "Enabling 64-bit address support\n");
1636			sc->flags |= AAC_FLAGS_SG_64BIT;
1637		}
1638		if ((options & AAC_SUPPORTED_NEW_COMM)
1639		 && sc->aac_if.aif_send_command)
1640			sc->flags |= AAC_FLAGS_NEW_COMM;
1641		if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
1642			sc->flags |= AAC_FLAGS_ARRAY_64BIT;
1643	}
1644
1645	/* Check for broken hardware that does a lower number of commands */
1646	sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512);
1647
1648	/* Remap mem. resource, if required */
1649	if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
1650		atu_size > rman_get_size(sc->aac_regs_resource)) {
1651		bus_release_resource(
1652			sc->aac_dev, SYS_RES_MEMORY,
1653			sc->aac_regs_rid, sc->aac_regs_resource);
1654		sc->aac_regs_resource = bus_alloc_resource(
1655			sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid,
1656			0ul, ~0ul, atu_size, RF_ACTIVE);
1657		if (sc->aac_regs_resource == NULL) {
1658			sc->aac_regs_resource = bus_alloc_resource_any(
1659				sc->aac_dev, SYS_RES_MEMORY,
1660				&sc->aac_regs_rid, RF_ACTIVE);
1661			if (sc->aac_regs_resource == NULL) {
1662				device_printf(sc->aac_dev,
1663				    "couldn't allocate register window\n");
1664				return (ENXIO);
1665			}
1666			sc->flags &= ~AAC_FLAGS_NEW_COMM;
1667		}
1668		sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
1669		sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
1670	}
1671
1672	/* Read preferred settings */
1673	sc->aac_max_fib_size = sizeof(struct aac_fib);
1674	sc->aac_max_sectors = 128;				/* 64KB */
1675	if (sc->flags & AAC_FLAGS_SG_64BIT)
1676		sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1677		 - sizeof(struct aac_blockwrite64))
1678		 / sizeof(struct aac_sg_entry64);
1679	else
1680		sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1681		 - sizeof(struct aac_blockwrite))
1682		 / sizeof(struct aac_sg_entry);
1683
1684	if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
1685		options = AAC_GET_MAILBOX(sc, 1);
1686		sc->aac_max_fib_size = (options & 0xFFFF);
1687		sc->aac_max_sectors = (options >> 16) << 1;
1688		options = AAC_GET_MAILBOX(sc, 2);
1689		sc->aac_sg_tablesize = (options >> 16);
1690		options = AAC_GET_MAILBOX(sc, 3);
1691		sc->aac_max_fibs = (options & 0xFFFF);
1692	}
1693	if (sc->aac_max_fib_size > PAGE_SIZE)
1694		sc->aac_max_fib_size = PAGE_SIZE;
1695	sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size;
1696
1697	if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1698		sc->flags |= AAC_FLAGS_RAW_IO;
1699		device_printf(sc->aac_dev, "Enable Raw I/O\n");
1700	}
1701
1702	return (0);
1703}
1704
1705static int
1706aac_init(struct aac_softc *sc)
1707{
1708	struct aac_adapter_init	*ip;
1709	time_t then;
1710	u_int32_t code, qoffset;
1711	int error;
1712
1713	debug_called(1);
1714
1715	/*
1716	 * First wait for the adapter to come ready.
1717	 */
1718	then = time_uptime;
1719	do {
1720		code = AAC_GET_FWSTATUS(sc);
1721		if (code & AAC_SELF_TEST_FAILED) {
1722			device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1723			return(ENXIO);
1724		}
1725		if (code & AAC_KERNEL_PANIC) {
1726			device_printf(sc->aac_dev,
1727				      "FATAL: controller kernel panic\n");
1728			return(ENXIO);
1729		}
1730		if (time_uptime > (then + AAC_BOOT_TIMEOUT)) {
1731			device_printf(sc->aac_dev,
1732				      "FATAL: controller not coming ready, "
1733					   "status %x\n", code);
1734			return(ENXIO);
1735		}
1736	} while (!(code & AAC_UP_AND_RUNNING));
1737
1738	error = ENOMEM;
1739	/*
1740	 * Create DMA tag for mapping buffers into controller-addressable space.
1741	 */
1742	if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
1743			       1, 0, 			/* algnmnt, boundary */
1744			       (sc->flags & AAC_FLAGS_SG_64BIT) ?
1745			       BUS_SPACE_MAXADDR :
1746			       BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
1747			       BUS_SPACE_MAXADDR, 	/* highaddr */
1748			       NULL, NULL, 		/* filter, filterarg */
1749			       MAXBSIZE,		/* maxsize */
1750			       sc->aac_sg_tablesize,	/* nsegments */
1751			       MAXBSIZE,		/* maxsegsize */
1752			       BUS_DMA_ALLOCNOW,	/* flags */
1753			       busdma_lock_mutex,	/* lockfunc */
1754			       &sc->aac_io_lock,	/* lockfuncarg */
1755			       &sc->aac_buffer_dmat)) {
1756		device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
1757		goto out;
1758	}
1759
1760	/*
1761	 * Create DMA tag for mapping FIBs into controller-addressable space..
1762	 */
1763	if (bus_dma_tag_create(sc->aac_parent_dmat,	/* parent */
1764			       1, 0, 			/* algnmnt, boundary */
1765			       (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
1766			       BUS_SPACE_MAXADDR_32BIT :
1767			       0x7fffffff,		/* lowaddr */
1768			       BUS_SPACE_MAXADDR, 	/* highaddr */
1769			       NULL, NULL, 		/* filter, filterarg */
1770			       sc->aac_max_fibs_alloc *
1771			       sc->aac_max_fib_size,  /* maxsize */
1772			       1,			/* nsegments */
1773			       sc->aac_max_fibs_alloc *
1774			       sc->aac_max_fib_size,	/* maxsegsize */
1775			       0,			/* flags */
1776			       NULL, NULL,		/* No locking needed */
1777			       &sc->aac_fib_dmat)) {
1778		device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");;
1779		goto out;
1780	}
1781
1782	/*
1783	 * Create DMA tag for the common structure and allocate it.
1784	 */
1785	if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
1786			       1, 0,			/* algnmnt, boundary */
1787			       (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
1788			       BUS_SPACE_MAXADDR_32BIT :
1789			       0x7fffffff,		/* lowaddr */
1790			       BUS_SPACE_MAXADDR, 	/* highaddr */
1791			       NULL, NULL, 		/* filter, filterarg */
1792			       8192 + sizeof(struct aac_common), /* maxsize */
1793			       1,			/* nsegments */
1794			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
1795			       0,			/* flags */
1796			       NULL, NULL,		/* No locking needed */
1797			       &sc->aac_common_dmat)) {
1798		device_printf(sc->aac_dev,
1799			      "can't allocate common structure DMA tag\n");
1800		goto out;
1801	}
1802	if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1803			     BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1804		device_printf(sc->aac_dev, "can't allocate common structure\n");
1805		goto out;
1806	}
1807
1808	/*
1809	 * Work around a bug in the 2120 and 2200 that cannot DMA commands
1810	 * below address 8192 in physical memory.
1811	 * XXX If the padding is not needed, can it be put to use instead
1812	 * of ignored?
1813	 */
1814	(void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1815			sc->aac_common, 8192 + sizeof(*sc->aac_common),
1816			aac_common_map, sc, 0);
1817
1818	if (sc->aac_common_busaddr < 8192) {
1819		sc->aac_common = (struct aac_common *)
1820		    ((uint8_t *)sc->aac_common + 8192);
1821		sc->aac_common_busaddr += 8192;
1822	}
1823	bzero(sc->aac_common, sizeof(*sc->aac_common));
1824
1825	/* Allocate some FIBs and associated command structs */
1826	TAILQ_INIT(&sc->aac_fibmap_tqh);
1827	sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
1828				  M_AACBUF, M_WAITOK|M_ZERO);
1829	while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
1830		if (aac_alloc_commands(sc) != 0)
1831			break;
1832	}
1833	if (sc->total_fibs == 0)
1834		goto out;
1835
1836	/*
1837	 * Fill in the init structure.  This tells the adapter about the
1838	 * physical location of various important shared data structures.
1839	 */
1840	ip = &sc->aac_common->ac_init;
1841	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1842	if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1843		ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_4;
1844		sc->flags |= AAC_FLAGS_RAW_IO;
1845	}
1846	ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1847
1848	ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1849					 offsetof(struct aac_common, ac_fibs);
1850	ip->AdapterFibsVirtualAddress = 0;
1851	ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1852	ip->AdapterFibAlign = sizeof(struct aac_fib);
1853
1854	ip->PrintfBufferAddress = sc->aac_common_busaddr +
1855				  offsetof(struct aac_common, ac_printf);
1856	ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1857
1858	/*
1859	 * The adapter assumes that pages are 4K in size, except on some
1860 	 * broken firmware versions that do the page->byte conversion twice,
1861	 * therefore 'assuming' that this value is in 16MB units (2^24).
1862	 * Round up since the granularity is so high.
1863	 */
1864	ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1865	if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1866		ip->HostPhysMemPages =
1867		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1868	}
1869	ip->HostElapsedSeconds = time_uptime;	/* reset later if invalid */
1870
1871	ip->InitFlags = 0;
1872	if (sc->flags & AAC_FLAGS_NEW_COMM) {
1873		ip->InitFlags = INITFLAGS_NEW_COMM_SUPPORTED;
1874		device_printf(sc->aac_dev, "New comm. interface enabled\n");
1875	}
1876
1877	ip->MaxIoCommands = sc->aac_max_fibs;
1878	ip->MaxIoSize = sc->aac_max_sectors << 9;
1879	ip->MaxFibSize = sc->aac_max_fib_size;
1880
1881	/*
1882	 * Initialize FIB queues.  Note that it appears that the layout of the
1883	 * indexes and the segmentation of the entries may be mandated by the
1884	 * adapter, which is only told about the base of the queue index fields.
1885	 *
1886	 * The initial values of the indices are assumed to inform the adapter
1887	 * of the sizes of the respective queues, and theoretically it could
1888	 * work out the entire layout of the queue structures from this.  We
1889	 * take the easy route and just lay this area out like everyone else
1890	 * does.
1891	 *
1892	 * The Linux driver uses a much more complex scheme whereby several
1893	 * header records are kept for each queue.  We use a couple of generic
1894	 * list manipulation functions which 'know' the size of each list by
1895	 * virtue of a table.
1896	 */
1897	qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1898	qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1899	sc->aac_queues =
1900	    (struct aac_queue_table *)((uintptr_t)sc->aac_common + qoffset);
1901	ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1902
1903	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1904		AAC_HOST_NORM_CMD_ENTRIES;
1905	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1906		AAC_HOST_NORM_CMD_ENTRIES;
1907	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1908		AAC_HOST_HIGH_CMD_ENTRIES;
1909	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1910		AAC_HOST_HIGH_CMD_ENTRIES;
1911	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1912		AAC_ADAP_NORM_CMD_ENTRIES;
1913	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1914		AAC_ADAP_NORM_CMD_ENTRIES;
1915	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1916		AAC_ADAP_HIGH_CMD_ENTRIES;
1917	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1918		AAC_ADAP_HIGH_CMD_ENTRIES;
1919	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1920		AAC_HOST_NORM_RESP_ENTRIES;
1921	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1922		AAC_HOST_NORM_RESP_ENTRIES;
1923	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1924		AAC_HOST_HIGH_RESP_ENTRIES;
1925	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1926		AAC_HOST_HIGH_RESP_ENTRIES;
1927	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1928		AAC_ADAP_NORM_RESP_ENTRIES;
1929	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1930		AAC_ADAP_NORM_RESP_ENTRIES;
1931	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1932		AAC_ADAP_HIGH_RESP_ENTRIES;
1933	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1934		AAC_ADAP_HIGH_RESP_ENTRIES;
1935	sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1936		&sc->aac_queues->qt_HostNormCmdQueue[0];
1937	sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1938		&sc->aac_queues->qt_HostHighCmdQueue[0];
1939	sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1940		&sc->aac_queues->qt_AdapNormCmdQueue[0];
1941	sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1942		&sc->aac_queues->qt_AdapHighCmdQueue[0];
1943	sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1944		&sc->aac_queues->qt_HostNormRespQueue[0];
1945	sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1946		&sc->aac_queues->qt_HostHighRespQueue[0];
1947	sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1948		&sc->aac_queues->qt_AdapNormRespQueue[0];
1949	sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1950		&sc->aac_queues->qt_AdapHighRespQueue[0];
1951
1952	/*
1953	 * Do controller-type-specific initialisation
1954	 */
1955	switch (sc->aac_hwif) {
1956	case AAC_HWIF_I960RX:
1957		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1958		break;
1959	case AAC_HWIF_RKT:
1960		AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
1961		break;
1962	default:
1963		break;
1964	}
1965
1966	/*
1967	 * Give the init structure to the controller.
1968	 */
1969	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1970			     sc->aac_common_busaddr +
1971			     offsetof(struct aac_common, ac_init), 0, 0, 0,
1972			     NULL)) {
1973		device_printf(sc->aac_dev,
1974			      "error establishing init structure\n");
1975		error = EIO;
1976		goto out;
1977	}
1978
1979	error = 0;
1980out:
1981	return(error);
1982}
1983
1984/*
1985 * Send a synchronous command to the controller and wait for a result.
1986 * Indicate if the controller completed the command with an error status.
1987 */
1988static int
1989aac_sync_command(struct aac_softc *sc, u_int32_t command,
1990		 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1991		 u_int32_t *sp)
1992{
1993	time_t then;
1994	u_int32_t status;
1995
1996	debug_called(3);
1997
1998	/* populate the mailbox */
1999	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
2000
2001	/* ensure the sync command doorbell flag is cleared */
2002	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2003
2004	/* then set it to signal the adapter */
2005	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
2006
2007	/* spin waiting for the command to complete */
2008	then = time_uptime;
2009	do {
2010		if (time_uptime > (then + AAC_IMMEDIATE_TIMEOUT)) {
2011			debug(1, "timed out");
2012			return(EIO);
2013		}
2014	} while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
2015
2016	/* clear the completion flag */
2017	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2018
2019	/* get the command status */
2020	status = AAC_GET_MAILBOX(sc, 0);
2021	if (sp != NULL)
2022		*sp = status;
2023
2024	if (status != AAC_SRB_STS_SUCCESS)
2025		return (-1);
2026	return(0);
2027}
2028
2029int
2030aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
2031		 struct aac_fib *fib, u_int16_t datasize)
2032{
2033	debug_called(3);
2034	mtx_assert(&sc->aac_io_lock, MA_OWNED);
2035
2036	if (datasize > AAC_FIB_DATASIZE)
2037		return(EINVAL);
2038
2039	/*
2040	 * Set up the sync FIB
2041	 */
2042	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
2043				AAC_FIBSTATE_INITIALISED |
2044				AAC_FIBSTATE_EMPTY;
2045	fib->Header.XferState |= xferstate;
2046	fib->Header.Command = command;
2047	fib->Header.StructType = AAC_FIBTYPE_TFIB;
2048	fib->Header.Size = sizeof(struct aac_fib_header) + datasize;
2049	fib->Header.SenderSize = sizeof(struct aac_fib);
2050	fib->Header.SenderFibAddress = 0;	/* Not needed */
2051	fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
2052					 offsetof(struct aac_common,
2053						  ac_sync_fib);
2054
2055	/*
2056	 * Give the FIB to the controller, wait for a response.
2057	 */
2058	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
2059			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
2060		debug(2, "IO error");
2061		return(EIO);
2062	}
2063
2064	return (0);
2065}
2066
2067/*
2068 * Adapter-space FIB queue manipulation
2069 *
2070 * Note that the queue implementation here is a little funky; neither the PI or
2071 * CI will ever be zero.  This behaviour is a controller feature.
2072 */
2073static struct {
2074	int		size;
2075	int		notify;
2076} aac_qinfo[] = {
2077	{AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
2078	{AAC_HOST_HIGH_CMD_ENTRIES, 0},
2079	{AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
2080	{AAC_ADAP_HIGH_CMD_ENTRIES, 0},
2081	{AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
2082	{AAC_HOST_HIGH_RESP_ENTRIES, 0},
2083	{AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
2084	{AAC_ADAP_HIGH_RESP_ENTRIES, 0}
2085};
2086
2087/*
2088 * Atomically insert an entry into the nominated queue, returns 0 on success or
2089 * EBUSY if the queue is full.
2090 *
2091 * Note: it would be more efficient to defer notifying the controller in
2092 *	 the case where we may be inserting several entries in rapid succession,
2093 *	 but implementing this usefully may be difficult (it would involve a
2094 *	 separate queue/notify interface).
2095 */
2096static int
2097aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
2098{
2099	u_int32_t pi, ci;
2100	int error;
2101	u_int32_t fib_size;
2102	u_int32_t fib_addr;
2103
2104	debug_called(3);
2105
2106	fib_size = cm->cm_fib->Header.Size;
2107	fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
2108
2109	/* get the producer/consumer indices */
2110	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2111	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2112
2113	/* wrap the queue? */
2114	if (pi >= aac_qinfo[queue].size)
2115		pi = 0;
2116
2117	/* check for queue full */
2118	if ((pi + 1) == ci) {
2119		error = EBUSY;
2120		goto out;
2121	}
2122
2123	/*
2124	 * To avoid a race with its completion interrupt, place this command on
2125	 * the busy queue prior to advertising it to the controller.
2126	 */
2127	aac_enqueue_busy(cm);
2128
2129	/* populate queue entry */
2130	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2131	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2132
2133	/* update producer index */
2134	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2135
2136	/* notify the adapter if we know how */
2137	if (aac_qinfo[queue].notify != 0)
2138		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2139
2140	error = 0;
2141
2142out:
2143	return(error);
2144}
2145
2146/*
2147 * Atomically remove one entry from the nominated queue, returns 0 on
2148 * success or ENOENT if the queue is empty.
2149 */
2150static int
2151aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
2152		struct aac_fib **fib_addr)
2153{
2154	u_int32_t pi, ci;
2155	u_int32_t fib_index;
2156	int error;
2157	int notify;
2158
2159	debug_called(3);
2160
2161	/* get the producer/consumer indices */
2162	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2163	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2164
2165	/* check for queue empty */
2166	if (ci == pi) {
2167		error = ENOENT;
2168		goto out;
2169	}
2170
2171	/* wrap the pi so the following test works */
2172	if (pi >= aac_qinfo[queue].size)
2173		pi = 0;
2174
2175	notify = 0;
2176	if (ci == pi + 1)
2177		notify++;
2178
2179	/* wrap the queue? */
2180	if (ci >= aac_qinfo[queue].size)
2181		ci = 0;
2182
2183	/* fetch the entry */
2184	*fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
2185
2186	switch (queue) {
2187	case AAC_HOST_NORM_CMD_QUEUE:
2188	case AAC_HOST_HIGH_CMD_QUEUE:
2189		/*
2190		 * The aq_fib_addr is only 32 bits wide so it can't be counted
2191		 * on to hold an address.  For AIF's, the adapter assumes
2192		 * that it's giving us an address into the array of AIF fibs.
2193		 * Therefore, we have to convert it to an index.
2194		 */
2195		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
2196			sizeof(struct aac_fib);
2197		*fib_addr = &sc->aac_common->ac_fibs[fib_index];
2198		break;
2199
2200	case AAC_HOST_NORM_RESP_QUEUE:
2201	case AAC_HOST_HIGH_RESP_QUEUE:
2202	{
2203		struct aac_command *cm;
2204
2205		/*
2206		 * As above, an index is used instead of an actual address.
2207		 * Gotta shift the index to account for the fast response
2208		 * bit.  No other correction is needed since this value was
2209		 * originally provided by the driver via the SenderFibAddress
2210		 * field.
2211		 */
2212		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
2213		cm = sc->aac_commands + (fib_index >> 2);
2214		*fib_addr = cm->cm_fib;
2215
2216		/*
2217		 * Is this a fast response? If it is, update the fib fields in
2218		 * local memory since the whole fib isn't DMA'd back up.
2219		 */
2220		if (fib_index & 0x01) {
2221			(*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
2222			*((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
2223		}
2224		break;
2225	}
2226	default:
2227		panic("Invalid queue in aac_dequeue_fib()");
2228		break;
2229	}
2230
2231	/* update consumer index */
2232	sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
2233
2234	/* if we have made the queue un-full, notify the adapter */
2235	if (notify && (aac_qinfo[queue].notify != 0))
2236		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2237	error = 0;
2238
2239out:
2240	return(error);
2241}
2242
2243/*
2244 * Put our response to an Adapter Initialed Fib on the response queue
2245 */
2246static int
2247aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
2248{
2249	u_int32_t pi, ci;
2250	int error;
2251	u_int32_t fib_size;
2252	u_int32_t fib_addr;
2253
2254	debug_called(1);
2255
2256	/* Tell the adapter where the FIB is */
2257	fib_size = fib->Header.Size;
2258	fib_addr = fib->Header.SenderFibAddress;
2259	fib->Header.ReceiverFibAddress = fib_addr;
2260
2261	/* get the producer/consumer indices */
2262	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2263	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2264
2265	/* wrap the queue? */
2266	if (pi >= aac_qinfo[queue].size)
2267		pi = 0;
2268
2269	/* check for queue full */
2270	if ((pi + 1) == ci) {
2271		error = EBUSY;
2272		goto out;
2273	}
2274
2275	/* populate queue entry */
2276	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2277	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2278
2279	/* update producer index */
2280	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2281
2282	/* notify the adapter if we know how */
2283	if (aac_qinfo[queue].notify != 0)
2284		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2285
2286	error = 0;
2287
2288out:
2289	return(error);
2290}
2291
2292/*
2293 * Check for commands that have been outstanding for a suspiciously long time,
2294 * and complain about them.
2295 */
2296static void
2297aac_timeout(struct aac_softc *sc)
2298{
2299	struct aac_command *cm;
2300	time_t deadline;
2301	int timedout, code;
2302
2303	/*
2304	 * Traverse the busy command list, bitch about late commands once
2305	 * only.
2306	 */
2307	timedout = 0;
2308	deadline = time_uptime - AAC_CMD_TIMEOUT;
2309	TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
2310		if ((cm->cm_timestamp  < deadline)
2311			/* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
2312			cm->cm_flags |= AAC_CMD_TIMEDOUT;
2313			device_printf(sc->aac_dev,
2314				      "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
2315				      cm, (int)(time_uptime-cm->cm_timestamp));
2316			AAC_PRINT_FIB(sc, cm->cm_fib);
2317			timedout++;
2318		}
2319	}
2320
2321	if (timedout) {
2322		code = AAC_GET_FWSTATUS(sc);
2323		if (code != AAC_UP_AND_RUNNING) {
2324			device_printf(sc->aac_dev, "WARNING! Controller is no "
2325				      "longer running! code= 0x%x\n", code);
2326		}
2327	}
2328	return;
2329}
2330
2331/*
2332 * Interface Function Vectors
2333 */
2334
2335/*
2336 * Read the current firmware status word.
2337 */
2338static int
2339aac_sa_get_fwstatus(struct aac_softc *sc)
2340{
2341	debug_called(3);
2342
2343	return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
2344}
2345
2346static int
2347aac_rx_get_fwstatus(struct aac_softc *sc)
2348{
2349	debug_called(3);
2350
2351	return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
2352}
2353
2354static int
2355aac_fa_get_fwstatus(struct aac_softc *sc)
2356{
2357	int val;
2358
2359	debug_called(3);
2360
2361	val = AAC_GETREG4(sc, AAC_FA_FWSTATUS);
2362	return (val);
2363}
2364
2365static int
2366aac_rkt_get_fwstatus(struct aac_softc *sc)
2367{
2368	debug_called(3);
2369
2370	return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
2371}
2372
2373/*
2374 * Notify the controller of a change in a given queue
2375 */
2376
2377static void
2378aac_sa_qnotify(struct aac_softc *sc, int qbit)
2379{
2380	debug_called(3);
2381
2382	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
2383}
2384
2385static void
2386aac_rx_qnotify(struct aac_softc *sc, int qbit)
2387{
2388	debug_called(3);
2389
2390	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
2391}
2392
2393static void
2394aac_fa_qnotify(struct aac_softc *sc, int qbit)
2395{
2396	debug_called(3);
2397
2398	AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
2399	AAC_FA_HACK(sc);
2400}
2401
2402static void
2403aac_rkt_qnotify(struct aac_softc *sc, int qbit)
2404{
2405	debug_called(3);
2406
2407	AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
2408}
2409
2410/*
2411 * Get the interrupt reason bits
2412 */
2413static int
2414aac_sa_get_istatus(struct aac_softc *sc)
2415{
2416	debug_called(3);
2417
2418	return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
2419}
2420
2421static int
2422aac_rx_get_istatus(struct aac_softc *sc)
2423{
2424	debug_called(3);
2425
2426	return(AAC_GETREG4(sc, AAC_RX_ODBR));
2427}
2428
2429static int
2430aac_fa_get_istatus(struct aac_softc *sc)
2431{
2432	int val;
2433
2434	debug_called(3);
2435
2436	val = AAC_GETREG2(sc, AAC_FA_DOORBELL0);
2437	return (val);
2438}
2439
2440static int
2441aac_rkt_get_istatus(struct aac_softc *sc)
2442{
2443	debug_called(3);
2444
2445	return(AAC_GETREG4(sc, AAC_RKT_ODBR));
2446}
2447
2448/*
2449 * Clear some interrupt reason bits
2450 */
2451static void
2452aac_sa_clear_istatus(struct aac_softc *sc, int mask)
2453{
2454	debug_called(3);
2455
2456	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
2457}
2458
2459static void
2460aac_rx_clear_istatus(struct aac_softc *sc, int mask)
2461{
2462	debug_called(3);
2463
2464	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
2465}
2466
2467static void
2468aac_fa_clear_istatus(struct aac_softc *sc, int mask)
2469{
2470	debug_called(3);
2471
2472	AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
2473	AAC_FA_HACK(sc);
2474}
2475
2476static void
2477aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
2478{
2479	debug_called(3);
2480
2481	AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
2482}
2483
2484/*
2485 * Populate the mailbox and set the command word
2486 */
2487static void
2488aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2489		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2490{
2491	debug_called(4);
2492
2493	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
2494	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
2495	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
2496	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
2497	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
2498}
2499
2500static void
2501aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
2502		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2503{
2504	debug_called(4);
2505
2506	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
2507	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2508	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2509	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2510	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2511}
2512
2513static void
2514aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2515		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2516{
2517	debug_called(4);
2518
2519	AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
2520	AAC_FA_HACK(sc);
2521	AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
2522	AAC_FA_HACK(sc);
2523	AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
2524	AAC_FA_HACK(sc);
2525	AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
2526	AAC_FA_HACK(sc);
2527	AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
2528	AAC_FA_HACK(sc);
2529}
2530
2531static void
2532aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2533		    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2534{
2535	debug_called(4);
2536
2537	AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
2538	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
2539	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
2540	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
2541	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
2542}
2543
2544/*
2545 * Fetch the immediate command status word
2546 */
2547static int
2548aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2549{
2550	debug_called(4);
2551
2552	return(AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2553}
2554
2555static int
2556aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2557{
2558	debug_called(4);
2559
2560	return(AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2561}
2562
2563static int
2564aac_fa_get_mailbox(struct aac_softc *sc, int mb)
2565{
2566	int val;
2567
2568	debug_called(4);
2569
2570	val = AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
2571	return (val);
2572}
2573
2574static int
2575aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2576{
2577	debug_called(4);
2578
2579	return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2580}
2581
2582/*
2583 * Set/clear interrupt masks
2584 */
2585static void
2586aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2587{
2588	debug(2, "%sable interrupts", enable ? "en" : "dis");
2589
2590	if (enable) {
2591		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2592	} else {
2593		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2594	}
2595}
2596
2597static void
2598aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2599{
2600	debug(2, "%sable interrupts", enable ? "en" : "dis");
2601
2602	if (enable) {
2603		if (sc->flags & AAC_FLAGS_NEW_COMM)
2604			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
2605		else
2606			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2607	} else {
2608		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
2609	}
2610}
2611
2612static void
2613aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2614{
2615	debug(2, "%sable interrupts", enable ? "en" : "dis");
2616
2617	if (enable) {
2618		AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2619		AAC_FA_HACK(sc);
2620	} else {
2621		AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
2622		AAC_FA_HACK(sc);
2623	}
2624}
2625
2626static void
2627aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2628{
2629	debug(2, "%sable interrupts", enable ? "en" : "dis");
2630
2631	if (enable) {
2632		if (sc->flags & AAC_FLAGS_NEW_COMM)
2633			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
2634		else
2635			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2636	} else {
2637		AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
2638	}
2639}
2640
2641/*
2642 * New comm. interface: Send command functions
2643 */
2644static int
2645aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm)
2646{
2647	u_int32_t index, device;
2648
2649	debug(2, "send command (new comm.)");
2650
2651	index = AAC_GETREG4(sc, AAC_RX_IQUE);
2652	if (index == 0xffffffffL)
2653		index = AAC_GETREG4(sc, AAC_RX_IQUE);
2654	if (index == 0xffffffffL)
2655		return index;
2656	aac_enqueue_busy(cm);
2657	device = index;
2658	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2659	device += 4;
2660	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2661	device += 4;
2662	AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
2663	AAC_SETREG4(sc, AAC_RX_IQUE, index);
2664	return 0;
2665}
2666
2667static int
2668aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
2669{
2670	u_int32_t index, device;
2671
2672	debug(2, "send command (new comm.)");
2673
2674	index = AAC_GETREG4(sc, AAC_RKT_IQUE);
2675	if (index == 0xffffffffL)
2676		index = AAC_GETREG4(sc, AAC_RKT_IQUE);
2677	if (index == 0xffffffffL)
2678		return index;
2679	aac_enqueue_busy(cm);
2680	device = index;
2681	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2682	device += 4;
2683	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2684	device += 4;
2685	AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
2686	AAC_SETREG4(sc, AAC_RKT_IQUE, index);
2687	return 0;
2688}
2689
2690/*
2691 * New comm. interface: get, set outbound queue index
2692 */
2693static int
2694aac_rx_get_outb_queue(struct aac_softc *sc)
2695{
2696	debug_called(3);
2697
2698	return(AAC_GETREG4(sc, AAC_RX_OQUE));
2699}
2700
2701static int
2702aac_rkt_get_outb_queue(struct aac_softc *sc)
2703{
2704	debug_called(3);
2705
2706	return(AAC_GETREG4(sc, AAC_RKT_OQUE));
2707}
2708
2709static void
2710aac_rx_set_outb_queue(struct aac_softc *sc, int index)
2711{
2712	debug_called(3);
2713
2714	AAC_SETREG4(sc, AAC_RX_OQUE, index);
2715}
2716
2717static void
2718aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
2719{
2720	debug_called(3);
2721
2722	AAC_SETREG4(sc, AAC_RKT_OQUE, index);
2723}
2724
2725/*
2726 * Debugging and Diagnostics
2727 */
2728
2729/*
2730 * Print some information about the controller.
2731 */
2732static void
2733aac_describe_controller(struct aac_softc *sc)
2734{
2735	struct aac_fib *fib;
2736	struct aac_adapter_info	*info;
2737	char *adapter_type = "Adaptec RAID controller";
2738
2739	debug_called(2);
2740
2741	mtx_lock(&sc->aac_io_lock);
2742	aac_alloc_sync_fib(sc, &fib);
2743
2744	if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
2745		fib->data[0] = 0;
2746		if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
2747			device_printf(sc->aac_dev,
2748			    "RequestSupplementAdapterInfo failed\n");
2749		else
2750			adapter_type = ((struct aac_supplement_adapter_info *)
2751			    &fib->data[0])->AdapterTypeText;
2752	}
2753	device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
2754		adapter_type,
2755		AAC_DRIVER_VERSION >> 24,
2756		(AAC_DRIVER_VERSION >> 16) & 0xFF,
2757		AAC_DRIVER_VERSION & 0xFF,
2758		AAC_DRIVER_BUILD);
2759
2760	fib->data[0] = 0;
2761	if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2762		device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2763		aac_release_sync_fib(sc);
2764		mtx_unlock(&sc->aac_io_lock);
2765		return;
2766	}
2767
2768	/* save the kernel revision structure for later use */
2769	info = (struct aac_adapter_info *)&fib->data[0];
2770	sc->aac_revision = info->KernelRevision;
2771
2772
2773	if (bootverbose) {
2774		device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
2775		    "(%dMB cache, %dMB execution), %s\n",
2776		    aac_describe_code(aac_cpu_variant, info->CpuVariant),
2777		    info->ClockSpeed, info->TotalMem / (1024 * 1024),
2778		    info->BufferMem / (1024 * 1024),
2779		    info->ExecutionMem / (1024 * 1024),
2780		    aac_describe_code(aac_battery_platform,
2781		    info->batteryPlatform));
2782
2783		device_printf(sc->aac_dev,
2784		    "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2785		    info->KernelRevision.external.comp.major,
2786		    info->KernelRevision.external.comp.minor,
2787		    info->KernelRevision.external.comp.dash,
2788		    info->KernelRevision.buildNumber,
2789		    (u_int32_t)(info->SerialNumber & 0xffffff));
2790
2791		device_printf(sc->aac_dev, "Supported Options=%b\n",
2792			      sc->supported_options,
2793			      "\20"
2794			      "\1SNAPSHOT"
2795			      "\2CLUSTERS"
2796			      "\3WCACHE"
2797			      "\4DATA64"
2798			      "\5HOSTTIME"
2799			      "\6RAID50"
2800			      "\7WINDOW4GB"
2801			      "\10SCSIUPGD"
2802			      "\11SOFTERR"
2803			      "\12NORECOND"
2804			      "\13SGMAP64"
2805			      "\14ALARM"
2806			      "\15NONDASD"
2807			      "\16SCSIMGT"
2808			      "\17RAIDSCSI"
2809			      "\21ADPTINFO"
2810			      "\22NEWCOMM"
2811			      "\23ARRAY64BIT"
2812			      "\24HEATSENSOR");
2813	}
2814	aac_release_sync_fib(sc);
2815	mtx_unlock(&sc->aac_io_lock);
2816}
2817
2818/*
2819 * Look up a text description of a numeric error code and return a pointer to
2820 * same.
2821 */
2822static char *
2823aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2824{
2825	int i;
2826
2827	for (i = 0; table[i].string != NULL; i++)
2828		if (table[i].code == code)
2829			return(table[i].string);
2830	return(table[i + 1].string);
2831}
2832
2833/*
2834 * Management Interface
2835 */
2836
2837static int
2838aac_open(struct cdev *dev, int flags, int fmt, d_thread_t *td)
2839{
2840	struct aac_softc *sc;
2841
2842	debug_called(2);
2843
2844	sc = dev->si_drv1;
2845	sc->aac_open_cnt++;
2846	sc->aac_state |= AAC_STATE_OPEN;
2847
2848	return 0;
2849}
2850
2851static int
2852aac_close(struct cdev *dev, int flags, int fmt, d_thread_t *td)
2853{
2854	struct aac_softc *sc;
2855
2856	debug_called(2);
2857
2858	sc = dev->si_drv1;
2859	sc->aac_open_cnt--;
2860	/* Mark this unit as no longer open  */
2861	if (sc->aac_open_cnt == 0)
2862		sc->aac_state &= ~AAC_STATE_OPEN;
2863
2864	return 0;
2865}
2866
2867static int
2868aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
2869{
2870	union aac_statrequest *as;
2871	struct aac_softc *sc;
2872	int error = 0;
2873
2874	debug_called(2);
2875
2876	as = (union aac_statrequest *)arg;
2877	sc = dev->si_drv1;
2878
2879	switch (cmd) {
2880	case AACIO_STATS:
2881		switch (as->as_item) {
2882		case AACQ_FREE:
2883		case AACQ_BIO:
2884		case AACQ_READY:
2885		case AACQ_BUSY:
2886			bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2887			      sizeof(struct aac_qstat));
2888			break;
2889		default:
2890			error = ENOENT;
2891			break;
2892		}
2893	break;
2894
2895	case FSACTL_SENDFIB:
2896	case FSACTL_SEND_LARGE_FIB:
2897		arg = *(caddr_t*)arg;
2898	case FSACTL_LNX_SENDFIB:
2899	case FSACTL_LNX_SEND_LARGE_FIB:
2900		debug(1, "FSACTL_SENDFIB");
2901		error = aac_ioctl_sendfib(sc, arg);
2902		break;
2903	case FSACTL_SEND_RAW_SRB:
2904		arg = *(caddr_t*)arg;
2905	case FSACTL_LNX_SEND_RAW_SRB:
2906		debug(1, "FSACTL_SEND_RAW_SRB");
2907		error = aac_ioctl_send_raw_srb(sc, arg);
2908		break;
2909	case FSACTL_AIF_THREAD:
2910	case FSACTL_LNX_AIF_THREAD:
2911		debug(1, "FSACTL_AIF_THREAD");
2912		error = EINVAL;
2913		break;
2914	case FSACTL_OPEN_GET_ADAPTER_FIB:
2915		arg = *(caddr_t*)arg;
2916	case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2917		debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
2918		error = aac_open_aif(sc, arg);
2919		break;
2920	case FSACTL_GET_NEXT_ADAPTER_FIB:
2921		arg = *(caddr_t*)arg;
2922	case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2923		debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB");
2924		error = aac_getnext_aif(sc, arg);
2925		break;
2926	case FSACTL_CLOSE_GET_ADAPTER_FIB:
2927		arg = *(caddr_t*)arg;
2928	case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2929		debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2930		error = aac_close_aif(sc, arg);
2931		break;
2932	case FSACTL_MINIPORT_REV_CHECK:
2933		arg = *(caddr_t*)arg;
2934	case FSACTL_LNX_MINIPORT_REV_CHECK:
2935		debug(1, "FSACTL_MINIPORT_REV_CHECK");
2936		error = aac_rev_check(sc, arg);
2937		break;
2938	case FSACTL_QUERY_DISK:
2939		arg = *(caddr_t*)arg;
2940	case FSACTL_LNX_QUERY_DISK:
2941		debug(1, "FSACTL_QUERY_DISK");
2942		error = aac_query_disk(sc, arg);
2943		break;
2944	case FSACTL_DELETE_DISK:
2945	case FSACTL_LNX_DELETE_DISK:
2946		/*
2947		 * We don't trust the underland to tell us when to delete a
2948		 * container, rather we rely on an AIF coming from the
2949		 * controller
2950		 */
2951		error = 0;
2952		break;
2953	case FSACTL_GET_PCI_INFO:
2954		arg = *(caddr_t*)arg;
2955	case FSACTL_LNX_GET_PCI_INFO:
2956		debug(1, "FSACTL_GET_PCI_INFO");
2957		error = aac_get_pci_info(sc, arg);
2958		break;
2959	default:
2960		debug(1, "unsupported cmd 0x%lx\n", cmd);
2961		error = EINVAL;
2962		break;
2963	}
2964	return(error);
2965}
2966
2967static int
2968aac_poll(struct cdev *dev, int poll_events, d_thread_t *td)
2969{
2970	struct aac_softc *sc;
2971	int revents;
2972
2973	sc = dev->si_drv1;
2974	revents = 0;
2975
2976	mtx_lock(&sc->aac_aifq_lock);
2977	if ((poll_events & (POLLRDNORM | POLLIN)) != 0) {
2978		if (sc->aifq_idx != 0 || sc->aifq_filled)
2979			revents |= poll_events & (POLLIN | POLLRDNORM);
2980	}
2981	mtx_unlock(&sc->aac_aifq_lock);
2982
2983	if (revents == 0) {
2984		if (poll_events & (POLLIN | POLLRDNORM))
2985			selrecord(td, &sc->rcv_select);
2986	}
2987
2988	return (revents);
2989}
2990
2991static void
2992aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
2993{
2994
2995	switch (event->ev_type) {
2996	case AAC_EVENT_CMFREE:
2997		mtx_assert(&sc->aac_io_lock, MA_OWNED);
2998		if (aac_alloc_command(sc, (struct aac_command **)arg)) {
2999			aac_add_event(sc, event);
3000			return;
3001		}
3002		free(event, M_AACBUF);
3003		wakeup(arg);
3004		break;
3005	default:
3006		break;
3007	}
3008}
3009
3010/*
3011 * Send a FIB supplied from userspace
3012 */
3013static int
3014aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
3015{
3016	struct aac_command *cm;
3017	int size, error;
3018
3019	debug_called(2);
3020
3021	cm = NULL;
3022
3023	/*
3024	 * Get a command
3025	 */
3026	mtx_lock(&sc->aac_io_lock);
3027	if (aac_alloc_command(sc, &cm)) {
3028		struct aac_event *event;
3029
3030		event = malloc(sizeof(struct aac_event), M_AACBUF,
3031		    M_NOWAIT | M_ZERO);
3032		if (event == NULL) {
3033			error = EBUSY;
3034			mtx_unlock(&sc->aac_io_lock);
3035			goto out;
3036		}
3037		event->ev_type = AAC_EVENT_CMFREE;
3038		event->ev_callback = aac_ioctl_event;
3039		event->ev_arg = &cm;
3040		aac_add_event(sc, event);
3041		msleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
3042	}
3043	mtx_unlock(&sc->aac_io_lock);
3044
3045	/*
3046	 * Fetch the FIB header, then re-copy to get data as well.
3047	 */
3048	if ((error = copyin(ufib, cm->cm_fib,
3049			    sizeof(struct aac_fib_header))) != 0)
3050		goto out;
3051	size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
3052	if (size > sc->aac_max_fib_size) {
3053		device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
3054			      size, sc->aac_max_fib_size);
3055		size = sc->aac_max_fib_size;
3056	}
3057	if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
3058		goto out;
3059	cm->cm_fib->Header.Size = size;
3060	cm->cm_timestamp = time_uptime;
3061
3062	/*
3063	 * Pass the FIB to the controller, wait for it to complete.
3064	 */
3065	mtx_lock(&sc->aac_io_lock);
3066	error = aac_wait_command(cm);
3067	mtx_unlock(&sc->aac_io_lock);
3068	if (error != 0) {
3069		device_printf(sc->aac_dev,
3070			      "aac_wait_command return %d\n", error);
3071		goto out;
3072	}
3073
3074	/*
3075	 * Copy the FIB and data back out to the caller.
3076	 */
3077	size = cm->cm_fib->Header.Size;
3078	if (size > sc->aac_max_fib_size) {
3079		device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
3080			      size, sc->aac_max_fib_size);
3081		size = sc->aac_max_fib_size;
3082	}
3083	error = copyout(cm->cm_fib, ufib, size);
3084
3085out:
3086	if (cm != NULL) {
3087		mtx_lock(&sc->aac_io_lock);
3088		aac_release_command(cm);
3089		mtx_unlock(&sc->aac_io_lock);
3090	}
3091	return(error);
3092}
3093
3094/*
3095 * Send a passthrough FIB supplied from userspace
3096 */
3097static int
3098aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
3099{
3100	return (EINVAL);
3101}
3102
3103/*
3104 * Handle an AIF sent to us by the controller; queue it for later reference.
3105 * If the queue fills up, then drop the older entries.
3106 */
3107static void
3108aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
3109{
3110	struct aac_aif_command *aif;
3111	struct aac_container *co, *co_next;
3112	struct aac_fib_context *ctx;
3113	struct aac_mntinfo *mi;
3114	struct aac_mntinforesp *mir = NULL;
3115	u_int16_t rsize;
3116	int next, current, found;
3117	int count = 0, added = 0, i = 0;
3118
3119	debug_called(2);
3120
3121	aif = (struct aac_aif_command*)&fib->data[0];
3122	aac_print_aif(sc, aif);
3123
3124	/* Is it an event that we should care about? */
3125	switch (aif->command) {
3126	case AifCmdEventNotify:
3127		switch (aif->data.EN.type) {
3128		case AifEnAddContainer:
3129		case AifEnDeleteContainer:
3130			/*
3131			 * A container was added or deleted, but the message
3132			 * doesn't tell us anything else!  Re-enumerate the
3133			 * containers and sort things out.
3134			 */
3135			aac_alloc_sync_fib(sc, &fib);
3136			mi = (struct aac_mntinfo *)&fib->data[0];
3137			do {
3138				/*
3139				 * Ask the controller for its containers one at
3140				 * a time.
3141				 * XXX What if the controller's list changes
3142				 * midway through this enumaration?
3143				 * XXX This should be done async.
3144				 */
3145				bzero(mi, sizeof(struct aac_mntinfo));
3146				mi->Command = VM_NameServe;
3147				mi->MntType = FT_FILESYS;
3148				mi->MntCount = i;
3149				rsize = sizeof(mir);
3150				if (aac_sync_fib(sc, ContainerCommand, 0, fib,
3151						 sizeof(struct aac_mntinfo))) {
3152					printf("Error probing container %d\n",
3153					      i);
3154					continue;
3155				}
3156				mir = (struct aac_mntinforesp *)&fib->data[0];
3157				/* XXX Need to check if count changed */
3158				count = mir->MntRespCount;
3159				/*
3160				 * Check the container against our list.
3161				 * co->co_found was already set to 0 in a
3162				 * previous run.
3163				 */
3164				if ((mir->Status == ST_OK) &&
3165				    (mir->MntTable[0].VolType != CT_NONE)) {
3166					found = 0;
3167					TAILQ_FOREACH(co,
3168						      &sc->aac_container_tqh,
3169						      co_link) {
3170						if (co->co_mntobj.ObjectId ==
3171						    mir->MntTable[0].ObjectId) {
3172							co->co_found = 1;
3173							found = 1;
3174							break;
3175						}
3176					}
3177					/*
3178					 * If the container matched, continue
3179					 * in the list.
3180					 */
3181					if (found) {
3182						i++;
3183						continue;
3184					}
3185
3186					/*
3187					 * This is a new container.  Do all the
3188					 * appropriate things to set it up.
3189					 */
3190					aac_add_container(sc, mir, 1);
3191					added = 1;
3192				}
3193				i++;
3194			} while ((i < count) && (i < AAC_MAX_CONTAINERS));
3195			aac_release_sync_fib(sc);
3196
3197			/*
3198			 * Go through our list of containers and see which ones
3199			 * were not marked 'found'.  Since the controller didn't
3200			 * list them they must have been deleted.  Do the
3201			 * appropriate steps to destroy the device.  Also reset
3202			 * the co->co_found field.
3203			 */
3204			co = TAILQ_FIRST(&sc->aac_container_tqh);
3205			while (co != NULL) {
3206				if (co->co_found == 0) {
3207					mtx_unlock(&sc->aac_io_lock);
3208					mtx_lock(&Giant);
3209					device_delete_child(sc->aac_dev,
3210							    co->co_disk);
3211					mtx_unlock(&Giant);
3212					mtx_lock(&sc->aac_io_lock);
3213					co_next = TAILQ_NEXT(co, co_link);
3214					mtx_lock(&sc->aac_container_lock);
3215					TAILQ_REMOVE(&sc->aac_container_tqh, co,
3216						     co_link);
3217					mtx_unlock(&sc->aac_container_lock);
3218					free(co, M_AACBUF);
3219					co = co_next;
3220				} else {
3221					co->co_found = 0;
3222					co = TAILQ_NEXT(co, co_link);
3223				}
3224			}
3225
3226			/* Attach the newly created containers */
3227			if (added) {
3228				mtx_unlock(&sc->aac_io_lock);
3229				mtx_lock(&Giant);
3230				bus_generic_attach(sc->aac_dev);
3231				mtx_unlock(&Giant);
3232				mtx_lock(&sc->aac_io_lock);
3233			}
3234
3235			break;
3236
3237		default:
3238			break;
3239		}
3240
3241	default:
3242		break;
3243	}
3244
3245	/* Copy the AIF data to the AIF queue for ioctl retrieval */
3246	mtx_lock(&sc->aac_aifq_lock);
3247	current = sc->aifq_idx;
3248	next = (current + 1) % AAC_AIFQ_LENGTH;
3249	if (next == 0)
3250		sc->aifq_filled = 1;
3251	bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib));
3252	/* modify AIF contexts */
3253	if (sc->aifq_filled) {
3254		for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3255			if (next == ctx->ctx_idx)
3256				ctx->ctx_wrap = 1;
3257			else if (current == ctx->ctx_idx && ctx->ctx_wrap)
3258				ctx->ctx_idx = next;
3259		}
3260	}
3261	sc->aifq_idx = next;
3262	/* On the off chance that someone is sleeping for an aif... */
3263	if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
3264		wakeup(sc->aac_aifq);
3265	/* Wakeup any poll()ers */
3266	selwakeuppri(&sc->rcv_select, PRIBIO);
3267	mtx_unlock(&sc->aac_aifq_lock);
3268
3269	return;
3270}
3271
3272/*
3273 * Return the Revision of the driver to userspace and check to see if the
3274 * userspace app is possibly compatible.  This is extremely bogus since
3275 * our driver doesn't follow Adaptec's versioning system.  Cheat by just
3276 * returning what the card reported.
3277 */
3278static int
3279aac_rev_check(struct aac_softc *sc, caddr_t udata)
3280{
3281	struct aac_rev_check rev_check;
3282	struct aac_rev_check_resp rev_check_resp;
3283	int error = 0;
3284
3285	debug_called(2);
3286
3287	/*
3288	 * Copyin the revision struct from userspace
3289	 */
3290	if ((error = copyin(udata, (caddr_t)&rev_check,
3291			sizeof(struct aac_rev_check))) != 0) {
3292		return error;
3293	}
3294
3295	debug(2, "Userland revision= %d\n",
3296	      rev_check.callingRevision.buildNumber);
3297
3298	/*
3299	 * Doctor up the response struct.
3300	 */
3301	rev_check_resp.possiblyCompatible = 1;
3302	rev_check_resp.adapterSWRevision.external.ul =
3303	    sc->aac_revision.external.ul;
3304	rev_check_resp.adapterSWRevision.buildNumber =
3305	    sc->aac_revision.buildNumber;
3306
3307	return(copyout((caddr_t)&rev_check_resp, udata,
3308			sizeof(struct aac_rev_check_resp)));
3309}
3310
3311/*
3312 * Pass the fib context to the caller
3313 */
3314static int
3315aac_open_aif(struct aac_softc *sc, caddr_t arg)
3316{
3317	struct aac_fib_context *fibctx, *ctx;
3318	int error = 0;
3319
3320	debug_called(2);
3321
3322	fibctx = malloc(sizeof(struct aac_fib_context), M_AACBUF, M_NOWAIT|M_ZERO);
3323	if (fibctx == NULL)
3324		return (ENOMEM);
3325
3326	mtx_lock(&sc->aac_aifq_lock);
3327	/* all elements are already 0, add to queue */
3328	if (sc->fibctx == NULL)
3329		sc->fibctx = fibctx;
3330	else {
3331		for (ctx = sc->fibctx; ctx->next; ctx = ctx->next)
3332			;
3333		ctx->next = fibctx;
3334		fibctx->prev = ctx;
3335	}
3336
3337	/* evaluate unique value */
3338	fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
3339	ctx = sc->fibctx;
3340	while (ctx != fibctx) {
3341		if (ctx->unique == fibctx->unique) {
3342			fibctx->unique++;
3343			ctx = sc->fibctx;
3344		} else {
3345			ctx = ctx->next;
3346		}
3347	}
3348	mtx_unlock(&sc->aac_aifq_lock);
3349
3350	error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t));
3351	if (error)
3352		aac_close_aif(sc, (caddr_t)ctx);
3353	return error;
3354}
3355
3356/*
3357 * Close the caller's fib context
3358 */
3359static int
3360aac_close_aif(struct aac_softc *sc, caddr_t arg)
3361{
3362	struct aac_fib_context *ctx;
3363
3364	debug_called(2);
3365
3366	mtx_lock(&sc->aac_aifq_lock);
3367	for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3368		if (ctx->unique == *(uint32_t *)&arg) {
3369			if (ctx == sc->fibctx)
3370				sc->fibctx = NULL;
3371			else {
3372				ctx->prev->next = ctx->next;
3373				if (ctx->next)
3374					ctx->next->prev = ctx->prev;
3375			}
3376			break;
3377		}
3378	}
3379	mtx_unlock(&sc->aac_aifq_lock);
3380	if (ctx)
3381		free(ctx, M_AACBUF);
3382
3383	return 0;
3384}
3385
3386/*
3387 * Pass the caller the next AIF in their queue
3388 */
3389static int
3390aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
3391{
3392	struct get_adapter_fib_ioctl agf;
3393	struct aac_fib_context *ctx;
3394	int error;
3395
3396	debug_called(2);
3397
3398	if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
3399		for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3400			if (agf.AdapterFibContext == ctx->unique)
3401				break;
3402		}
3403		if (!ctx)
3404			return (EFAULT);
3405
3406		error = aac_return_aif(sc, ctx, agf.AifFib);
3407		if (error == EAGAIN && agf.Wait) {
3408			debug(2, "aac_getnext_aif(): waiting for AIF");
3409			sc->aac_state |= AAC_STATE_AIF_SLEEPER;
3410			while (error == EAGAIN) {
3411				error = tsleep(sc->aac_aifq, PRIBIO |
3412					       PCATCH, "aacaif", 0);
3413				if (error == 0)
3414					error = aac_return_aif(sc, ctx, agf.AifFib);
3415			}
3416			sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
3417		}
3418	}
3419	return(error);
3420}
3421
3422/*
3423 * Hand the next AIF off the top of the queue out to userspace.
3424 */
3425static int
3426aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
3427{
3428	int current, error;
3429
3430	debug_called(2);
3431
3432	mtx_lock(&sc->aac_aifq_lock);
3433	current = ctx->ctx_idx;
3434	if (current == sc->aifq_idx && !ctx->ctx_wrap) {
3435		/* empty */
3436		mtx_unlock(&sc->aac_aifq_lock);
3437		return (EAGAIN);
3438	}
3439	error =
3440		copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
3441	if (error)
3442		device_printf(sc->aac_dev,
3443		    "aac_return_aif: copyout returned %d\n", error);
3444	else {
3445		ctx->ctx_wrap = 0;
3446		ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
3447	}
3448	mtx_unlock(&sc->aac_aifq_lock);
3449	return(error);
3450}
3451
3452static int
3453aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
3454{
3455	struct aac_pci_info {
3456		u_int32_t bus;
3457		u_int32_t slot;
3458	} pciinf;
3459	int error;
3460
3461	debug_called(2);
3462
3463	pciinf.bus = pci_get_bus(sc->aac_dev);
3464	pciinf.slot = pci_get_slot(sc->aac_dev);
3465
3466	error = copyout((caddr_t)&pciinf, uptr,
3467			sizeof(struct aac_pci_info));
3468
3469	return (error);
3470}
3471
3472/*
3473 * Give the userland some information about the container.  The AAC arch
3474 * expects the driver to be a SCSI passthrough type driver, so it expects
3475 * the containers to have b:t:l numbers.  Fake it.
3476 */
3477static int
3478aac_query_disk(struct aac_softc *sc, caddr_t uptr)
3479{
3480	struct aac_query_disk query_disk;
3481	struct aac_container *co;
3482	struct aac_disk	*disk;
3483	int error, id;
3484
3485	debug_called(2);
3486
3487	disk = NULL;
3488
3489	error = copyin(uptr, (caddr_t)&query_disk,
3490		       sizeof(struct aac_query_disk));
3491	if (error)
3492		return (error);
3493
3494	id = query_disk.ContainerNumber;
3495	if (id == -1)
3496		return (EINVAL);
3497
3498	mtx_lock(&sc->aac_container_lock);
3499	TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
3500		if (co->co_mntobj.ObjectId == id)
3501			break;
3502		}
3503
3504	if (co == NULL) {
3505			query_disk.Valid = 0;
3506			query_disk.Locked = 0;
3507			query_disk.Deleted = 1;		/* XXX is this right? */
3508	} else {
3509		disk = device_get_softc(co->co_disk);
3510		query_disk.Valid = 1;
3511		query_disk.Locked =
3512		    (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
3513		query_disk.Deleted = 0;
3514		query_disk.Bus = device_get_unit(sc->aac_dev);
3515		query_disk.Target = disk->unit;
3516		query_disk.Lun = 0;
3517		query_disk.UnMapped = 0;
3518		sprintf(&query_disk.diskDeviceName[0], "%s%d",
3519		        disk->ad_disk->d_name, disk->ad_disk->d_unit);
3520	}
3521	mtx_unlock(&sc->aac_container_lock);
3522
3523	error = copyout((caddr_t)&query_disk, uptr,
3524			sizeof(struct aac_query_disk));
3525
3526	return (error);
3527}
3528
3529static void
3530aac_get_bus_info(struct aac_softc *sc)
3531{
3532	struct aac_fib *fib;
3533	struct aac_ctcfg *c_cmd;
3534	struct aac_ctcfg_resp *c_resp;
3535	struct aac_vmioctl *vmi;
3536	struct aac_vmi_businf_resp *vmi_resp;
3537	struct aac_getbusinf businfo;
3538	struct aac_sim *caminf;
3539	device_t child;
3540	int i, found, error;
3541
3542	mtx_lock(&sc->aac_io_lock);
3543	aac_alloc_sync_fib(sc, &fib);
3544	c_cmd = (struct aac_ctcfg *)&fib->data[0];
3545	bzero(c_cmd, sizeof(struct aac_ctcfg));
3546
3547	c_cmd->Command = VM_ContainerConfig;
3548	c_cmd->cmd = CT_GET_SCSI_METHOD;
3549	c_cmd->param = 0;
3550
3551	error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3552	    sizeof(struct aac_ctcfg));
3553	if (error) {
3554		device_printf(sc->aac_dev, "Error %d sending "
3555		    "VM_ContainerConfig command\n", error);
3556		aac_release_sync_fib(sc);
3557		mtx_unlock(&sc->aac_io_lock);
3558		return;
3559	}
3560
3561	c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
3562	if (c_resp->Status != ST_OK) {
3563		device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
3564		    c_resp->Status);
3565		aac_release_sync_fib(sc);
3566		mtx_unlock(&sc->aac_io_lock);
3567		return;
3568	}
3569
3570	sc->scsi_method_id = c_resp->param;
3571
3572	vmi = (struct aac_vmioctl *)&fib->data[0];
3573	bzero(vmi, sizeof(struct aac_vmioctl));
3574
3575	vmi->Command = VM_Ioctl;
3576	vmi->ObjType = FT_DRIVE;
3577	vmi->MethId = sc->scsi_method_id;
3578	vmi->ObjId = 0;
3579	vmi->IoctlCmd = GetBusInfo;
3580
3581	error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3582	    sizeof(struct aac_vmi_businf_resp));
3583	if (error) {
3584		device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
3585		    error);
3586		aac_release_sync_fib(sc);
3587		mtx_unlock(&sc->aac_io_lock);
3588		return;
3589	}
3590
3591	vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
3592	if (vmi_resp->Status != ST_OK) {
3593		device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
3594		    vmi_resp->Status);
3595		aac_release_sync_fib(sc);
3596		mtx_unlock(&sc->aac_io_lock);
3597		return;
3598	}
3599
3600	bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
3601	aac_release_sync_fib(sc);
3602	mtx_unlock(&sc->aac_io_lock);
3603
3604	found = 0;
3605	for (i = 0; i < businfo.BusCount; i++) {
3606		if (businfo.BusValid[i] != AAC_BUS_VALID)
3607			continue;
3608
3609		caminf = (struct aac_sim *)malloc( sizeof(struct aac_sim),
3610		    M_AACBUF, M_NOWAIT | M_ZERO);
3611		if (caminf == NULL) {
3612			device_printf(sc->aac_dev,
3613			    "No memory to add passthrough bus %d\n", i);
3614			break;
3615		};
3616
3617		child = device_add_child(sc->aac_dev, "aacp", -1);
3618		if (child == NULL) {
3619			device_printf(sc->aac_dev,
3620			    "device_add_child failed for passthrough bus %d\n",
3621			    i);
3622			free(caminf, M_AACBUF);
3623			break;
3624		}
3625
3626		caminf->TargetsPerBus = businfo.TargetsPerBus;
3627		caminf->BusNumber = i;
3628		caminf->InitiatorBusId = businfo.InitiatorBusId[i];
3629		caminf->aac_sc = sc;
3630		caminf->sim_dev = child;
3631
3632		device_set_ivars(child, caminf);
3633		device_set_desc(child, "SCSI Passthrough Bus");
3634		TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
3635
3636		found = 1;
3637	}
3638
3639	if (found)
3640		bus_generic_attach(sc->aac_dev);
3641
3642	return;
3643}
3644