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