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