]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/aac/aac.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.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
384 /*
385  * Request information of container #cid
386  */
387 static struct aac_mntinforesp *
388 aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid)
389 {
390         struct aac_mntinfo *mi;
391
392         mi = (struct aac_mntinfo *)&fib->data[0];
393         /* use 64-bit LBA if enabled */
394         mi->Command = (sc->flags & AAC_FLAGS_LBA_64BIT) ?
395             VM_NameServe64 : VM_NameServe;
396         mi->MntType = FT_FILESYS;
397         mi->MntCount = cid;
398
399         if (aac_sync_fib(sc, ContainerCommand, 0, fib,
400                          sizeof(struct aac_mntinfo))) {
401                 device_printf(sc->aac_dev, "Error probing container %d\n", cid);
402                 return (NULL);
403         }
404
405         return ((struct aac_mntinforesp *)&fib->data[0]);
406 }
407
408 /*
409  * Probe for containers, create disks.
410  */
411 static void
412 aac_startup(void *arg)
413 {
414         struct aac_softc *sc;
415         struct aac_fib *fib;
416         struct aac_mntinforesp *mir;
417         int count = 0, i = 0;
418
419         sc = (struct aac_softc *)arg;
420         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
421
422         /* disconnect ourselves from the intrhook chain */
423         config_intrhook_disestablish(&sc->aac_ich);
424
425         mtx_lock(&sc->aac_io_lock);
426         aac_alloc_sync_fib(sc, &fib);
427
428         /* loop over possible containers */
429         do {
430                 if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
431                         continue;
432                 if (i == 0)
433                         count = mir->MntRespCount;
434                 aac_add_container(sc, mir, 0);
435                 i++;
436         } while ((i < count) && (i < AAC_MAX_CONTAINERS));
437
438         aac_release_sync_fib(sc);
439         mtx_unlock(&sc->aac_io_lock);
440
441         /* poke the bus to actually attach the child devices */
442         if (bus_generic_attach(sc->aac_dev))
443                 device_printf(sc->aac_dev, "bus_generic_attach failed\n");
444
445         /* mark the controller up */
446         sc->aac_state &= ~AAC_STATE_SUSPEND;
447
448         /* enable interrupts now */
449         AAC_UNMASK_INTERRUPTS(sc);
450 }
451
452 /*
453  * Create a device to represent a new container
454  */
455 static void
456 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
457 {
458         struct aac_container *co;
459         device_t child;
460
461         /*
462          * Check container volume type for validity.  Note that many of
463          * the possible types may never show up.
464          */
465         if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
466                 co = (struct aac_container *)malloc(sizeof *co, M_AACBUF,
467                        M_NOWAIT | M_ZERO);
468                 if (co == NULL)
469                         panic("Out of memory?!");
470                 fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "id %x  name '%.16s'  size %u  type %d",
471                       mir->MntTable[0].ObjectId,
472                       mir->MntTable[0].FileSystemName,
473                       mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
474
475                 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
476                         device_printf(sc->aac_dev, "device_add_child failed\n");
477                 else
478                         device_set_ivars(child, co);
479                 device_set_desc(child, aac_describe_code(aac_container_types,
480                                 mir->MntTable[0].VolType));
481                 co->co_disk = child;
482                 co->co_found = f;
483                 bcopy(&mir->MntTable[0], &co->co_mntobj,
484                       sizeof(struct aac_mntobj));
485                 mtx_lock(&sc->aac_container_lock);
486                 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
487                 mtx_unlock(&sc->aac_container_lock);
488         }
489 }
490
491 /*
492  * Allocate resources associated with (sc)
493  */
494 static int
495 aac_alloc(struct aac_softc *sc)
496 {
497
498         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
499
500         /*
501          * Create DMA tag for mapping buffers into controller-addressable space.
502          */
503         if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
504                                1, 0,                    /* algnmnt, boundary */
505                                (sc->flags & AAC_FLAGS_SG_64BIT) ?
506                                BUS_SPACE_MAXADDR :
507                                BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
508                                BUS_SPACE_MAXADDR,       /* highaddr */
509                                NULL, NULL,              /* filter, filterarg */
510                                MAXBSIZE,                /* maxsize */
511                                sc->aac_sg_tablesize,    /* nsegments */
512                                MAXBSIZE,                /* maxsegsize */
513                                BUS_DMA_ALLOCNOW,        /* flags */
514                                busdma_lock_mutex,       /* lockfunc */
515                                &sc->aac_io_lock,        /* lockfuncarg */
516                                &sc->aac_buffer_dmat)) {
517                 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
518                 return (ENOMEM);
519         }
520
521         /*
522          * Create DMA tag for mapping FIBs into controller-addressable space..
523          */
524         if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
525                                1, 0,                    /* algnmnt, boundary */
526                                (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
527                                BUS_SPACE_MAXADDR_32BIT :
528                                0x7fffffff,              /* lowaddr */
529                                BUS_SPACE_MAXADDR,       /* highaddr */
530                                NULL, NULL,              /* filter, filterarg */
531                                sc->aac_max_fibs_alloc *
532                                sc->aac_max_fib_size,  /* maxsize */
533                                1,                       /* nsegments */
534                                sc->aac_max_fibs_alloc *
535                                sc->aac_max_fib_size,    /* maxsize */
536                                0,                       /* flags */
537                                NULL, NULL,              /* No locking needed */
538                                &sc->aac_fib_dmat)) {
539                 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
540                 return (ENOMEM);
541         }
542
543         /*
544          * Create DMA tag for the common structure and allocate it.
545          */
546         if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
547                                1, 0,                    /* algnmnt, boundary */
548                                (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
549                                BUS_SPACE_MAXADDR_32BIT :
550                                0x7fffffff,              /* lowaddr */
551                                BUS_SPACE_MAXADDR,       /* highaddr */
552                                NULL, NULL,              /* filter, filterarg */
553                                8192 + sizeof(struct aac_common), /* maxsize */
554                                1,                       /* nsegments */
555                                BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
556                                0,                       /* flags */
557                                NULL, NULL,              /* No locking needed */
558                                &sc->aac_common_dmat)) {
559                 device_printf(sc->aac_dev,
560                               "can't allocate common structure DMA tag\n");
561                 return (ENOMEM);
562         }
563         if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
564                              BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
565                 device_printf(sc->aac_dev, "can't allocate common structure\n");
566                 return (ENOMEM);
567         }
568
569         /*
570          * Work around a bug in the 2120 and 2200 that cannot DMA commands
571          * below address 8192 in physical memory.
572          * XXX If the padding is not needed, can it be put to use instead
573          * of ignored?
574          */
575         (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
576                         sc->aac_common, 8192 + sizeof(*sc->aac_common),
577                         aac_common_map, sc, 0);
578
579         if (sc->aac_common_busaddr < 8192) {
580                 sc->aac_common = (struct aac_common *)
581                     ((uint8_t *)sc->aac_common + 8192);
582                 sc->aac_common_busaddr += 8192;
583         }
584         bzero(sc->aac_common, sizeof(*sc->aac_common));
585
586         /* Allocate some FIBs and associated command structs */
587         TAILQ_INIT(&sc->aac_fibmap_tqh);
588         sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
589                                   M_AACBUF, M_WAITOK|M_ZERO);
590         while (sc->total_fibs < sc->aac_max_fibs) {
591                 if (aac_alloc_commands(sc) != 0)
592                         break;
593         }
594         if (sc->total_fibs == 0)
595                 return (ENOMEM);
596
597         return (0);
598 }
599
600 /*
601  * Free all of the resources associated with (sc)
602  *
603  * Should not be called if the controller is active.
604  */
605 void
606 aac_free(struct aac_softc *sc)
607 {
608
609         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
610
611         /* remove the control device */
612         if (sc->aac_dev_t != NULL)
613                 destroy_dev(sc->aac_dev_t);
614
615         /* throw away any FIB buffers, discard the FIB DMA tag */
616         aac_free_commands(sc);
617         if (sc->aac_fib_dmat)
618                 bus_dma_tag_destroy(sc->aac_fib_dmat);
619
620         free(sc->aac_commands, M_AACBUF);
621
622         /* destroy the common area */
623         if (sc->aac_common) {
624                 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
625                 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
626                                 sc->aac_common_dmamap);
627         }
628         if (sc->aac_common_dmat)
629                 bus_dma_tag_destroy(sc->aac_common_dmat);
630
631         /* disconnect the interrupt handler */
632         if (sc->aac_intr)
633                 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
634         if (sc->aac_irq != NULL)
635                 bus_release_resource(sc->aac_dev, SYS_RES_IRQ,
636                     rman_get_rid(sc->aac_irq), sc->aac_irq);
637
638         /* destroy data-transfer DMA tag */
639         if (sc->aac_buffer_dmat)
640                 bus_dma_tag_destroy(sc->aac_buffer_dmat);
641
642         /* destroy the parent DMA tag */
643         if (sc->aac_parent_dmat)
644                 bus_dma_tag_destroy(sc->aac_parent_dmat);
645
646         /* release the register window mapping */
647         if (sc->aac_regs_res0 != NULL)
648                 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
649                     rman_get_rid(sc->aac_regs_res0), sc->aac_regs_res0);
650         if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL)
651                 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
652                     rman_get_rid(sc->aac_regs_res1), sc->aac_regs_res1);
653 }
654
655 /*
656  * Disconnect from the controller completely, in preparation for unload.
657  */
658 int
659 aac_detach(device_t dev)
660 {
661         struct aac_softc *sc;
662         struct aac_container *co;
663         struct aac_sim  *sim;
664         int error;
665
666         sc = device_get_softc(dev);
667         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
668
669         callout_drain(&sc->aac_daemontime);
670
671         mtx_lock(&sc->aac_io_lock);
672         while (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
673                 sc->aifflags |= AAC_AIFFLAGS_EXIT;
674                 wakeup(sc->aifthread);
675                 msleep(sc->aac_dev, &sc->aac_io_lock, PUSER, "aacdch", 0);
676         }
677         mtx_unlock(&sc->aac_io_lock);
678         KASSERT((sc->aifflags & AAC_AIFFLAGS_RUNNING) == 0,
679             ("%s: invalid detach state", __func__));
680
681         /* Remove the child containers */
682         while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
683                 error = device_delete_child(dev, co->co_disk);
684                 if (error)
685                         return (error);
686                 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
687                 free(co, M_AACBUF);
688         }
689
690         /* Remove the CAM SIMs */
691         while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
692                 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
693                 error = device_delete_child(dev, sim->sim_dev);
694                 if (error)
695                         return (error);
696                 free(sim, M_AACBUF);
697         }
698
699         if ((error = aac_shutdown(dev)))
700                 return(error);
701
702         EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
703
704         aac_free(sc);
705
706         mtx_destroy(&sc->aac_aifq_lock);
707         mtx_destroy(&sc->aac_io_lock);
708         mtx_destroy(&sc->aac_container_lock);
709
710         return(0);
711 }
712
713 /*
714  * Bring the controller down to a dormant state and detach all child devices.
715  *
716  * This function is called before detach or system shutdown.
717  *
718  * Note that we can assume that the bioq on the controller is empty, as we won't
719  * allow shutdown if any device is open.
720  */
721 int
722 aac_shutdown(device_t dev)
723 {
724         struct aac_softc *sc;
725         struct aac_fib *fib;
726         struct aac_close_command *cc;
727
728         sc = device_get_softc(dev);
729         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
730
731         sc->aac_state |= AAC_STATE_SUSPEND;
732
733         /*
734          * Send a Container shutdown followed by a HostShutdown FIB to the
735          * controller to convince it that we don't want to talk to it anymore.
736          * We've been closed and all I/O completed already
737          */
738         device_printf(sc->aac_dev, "shutting down controller...");
739
740         mtx_lock(&sc->aac_io_lock);
741         aac_alloc_sync_fib(sc, &fib);
742         cc = (struct aac_close_command *)&fib->data[0];
743
744         bzero(cc, sizeof(struct aac_close_command));
745         cc->Command = VM_CloseAll;
746         cc->ContainerId = 0xffffffff;
747         if (aac_sync_fib(sc, ContainerCommand, 0, fib,
748             sizeof(struct aac_close_command)))
749                 printf("FAILED.\n");
750         else
751                 printf("done\n");
752 #if 0
753         else {
754                 fib->data[0] = 0;
755                 /*
756                  * XXX Issuing this command to the controller makes it shut down
757                  * but also keeps it from coming back up without a reset of the
758                  * PCI bus.  This is not desirable if you are just unloading the
759                  * driver module with the intent to reload it later.
760                  */
761                 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
762                     fib, 1)) {
763                         printf("FAILED.\n");
764                 } else {
765                         printf("done.\n");
766                 }
767         }
768 #endif
769
770         AAC_MASK_INTERRUPTS(sc);
771         aac_release_sync_fib(sc);
772         mtx_unlock(&sc->aac_io_lock);
773
774         return(0);
775 }
776
777 /*
778  * Bring the controller to a quiescent state, ready for system suspend.
779  */
780 int
781 aac_suspend(device_t dev)
782 {
783         struct aac_softc *sc;
784
785         sc = device_get_softc(dev);
786
787         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
788         sc->aac_state |= AAC_STATE_SUSPEND;
789
790         AAC_MASK_INTERRUPTS(sc);
791         return(0);
792 }
793
794 /*
795  * Bring the controller back to a state ready for operation.
796  */
797 int
798 aac_resume(device_t dev)
799 {
800         struct aac_softc *sc;
801
802         sc = device_get_softc(dev);
803
804         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
805         sc->aac_state &= ~AAC_STATE_SUSPEND;
806         AAC_UNMASK_INTERRUPTS(sc);
807         return(0);
808 }
809
810 /*
811  * Interrupt handler for NEW_COMM interface.
812  */
813 void
814 aac_new_intr(void *arg)
815 {
816         struct aac_softc *sc;
817         u_int32_t index, fast;
818         struct aac_command *cm;
819         struct aac_fib *fib;
820         int i;
821
822         sc = (struct aac_softc *)arg;
823
824         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
825         mtx_lock(&sc->aac_io_lock);
826         while (1) {
827                 index = AAC_GET_OUTB_QUEUE(sc);
828                 if (index == 0xffffffff)
829                         index = AAC_GET_OUTB_QUEUE(sc);
830                 if (index == 0xffffffff)
831                         break;
832                 if (index & 2) {
833                         if (index == 0xfffffffe) {
834                                 /* XXX This means that the controller wants
835                                  * more work.  Ignore it for now.
836                                  */
837                                 continue;
838                         }
839                         /* AIF */
840                         fib = (struct aac_fib *)malloc(sizeof *fib, M_AACBUF,
841                                    M_NOWAIT | M_ZERO);
842                         if (fib == NULL) {
843                                 /* If we're really this short on memory,
844                                  * hopefully breaking out of the handler will
845                                  * allow something to get freed.  This
846                                  * actually sucks a whole lot.
847                                  */
848                                 break;
849                         }
850                         index &= ~2;
851                         for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
852                                 ((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
853                         aac_handle_aif(sc, fib);
854                         free(fib, M_AACBUF);
855
856                         /*
857                          * AIF memory is owned by the adapter, so let it
858                          * know that we are done with it.
859                          */
860                         AAC_SET_OUTB_QUEUE(sc, index);
861                         AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
862                 } else {
863                         fast = index & 1;
864                         cm = sc->aac_commands + (index >> 2);
865                         fib = cm->cm_fib;
866                         if (fast) {
867                                 fib->Header.XferState |= AAC_FIBSTATE_DONEADAP;
868                                 *((u_int32_t *)(fib->data)) = AAC_ERROR_NORMAL;
869                         }
870                         aac_remove_busy(cm);
871                         aac_unmap_command(cm);
872                         cm->cm_flags |= AAC_CMD_COMPLETED;
873
874                         /* is there a completion handler? */
875                         if (cm->cm_complete != NULL) {
876                                 cm->cm_complete(cm);
877                         } else {
878                                 /* assume that someone is sleeping on this
879                                  * command
880                                  */
881                                 wakeup(cm);
882                         }
883                         sc->flags &= ~AAC_QUEUE_FRZN;
884                 }
885         }
886         /* see if we can start some more I/O */
887         if ((sc->flags & AAC_QUEUE_FRZN) == 0)
888                 aac_startio(sc);
889
890         mtx_unlock(&sc->aac_io_lock);
891 }
892
893 /*
894  * Interrupt filter for !NEW_COMM interface.
895  */
896 int
897 aac_filter(void *arg)
898 {
899         struct aac_softc *sc;
900         u_int16_t reason;
901
902         sc = (struct aac_softc *)arg;
903
904         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
905         /*
906          * Read the status register directly.  This is faster than taking the
907          * driver lock and reading the queues directly.  It also saves having
908          * to turn parts of the driver lock into a spin mutex, which would be
909          * ugly.
910          */
911         reason = AAC_GET_ISTATUS(sc);
912         AAC_CLEAR_ISTATUS(sc, reason);
913
914         /* handle completion processing */
915         if (reason & AAC_DB_RESPONSE_READY)
916                 taskqueue_enqueue_fast(taskqueue_fast, &sc->aac_task_complete);
917
918         /* controller wants to talk to us */
919         if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY)) {
920                 /*
921                  * XXX Make sure that we don't get fooled by strange messages
922                  * that start with a NULL.
923                  */
924                 if ((reason & AAC_DB_PRINTF) &&
925                         (sc->aac_common->ac_printf[0] == 0))
926                         sc->aac_common->ac_printf[0] = 32;
927
928                 /*
929                  * This might miss doing the actual wakeup.  However, the
930                  * msleep that this is waking up has a timeout, so it will
931                  * wake up eventually.  AIFs and printfs are low enough
932                  * priority that they can handle hanging out for a few seconds
933                  * if needed.
934                  */
935                 wakeup(sc->aifthread);
936         }
937         return (FILTER_HANDLED);
938 }
939
940 /*
941  * Command Processing
942  */
943
944 /*
945  * Start as much queued I/O as possible on the controller
946  */
947 void
948 aac_startio(struct aac_softc *sc)
949 {
950         struct aac_command *cm;
951         int error;
952
953         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
954
955         for (;;) {
956                 /*
957                  * This flag might be set if the card is out of resources.
958                  * Checking it here prevents an infinite loop of deferrals.
959                  */
960                 if (sc->flags & AAC_QUEUE_FRZN)
961                         break;
962
963                 /*
964                  * Try to get a command that's been put off for lack of
965                  * resources
966                  */
967                 cm = aac_dequeue_ready(sc);
968
969                 /*
970                  * Try to build a command off the bio queue (ignore error
971                  * return)
972                  */
973                 if (cm == NULL)
974                         aac_bio_command(sc, &cm);
975
976                 /* nothing to do? */
977                 if (cm == NULL)
978                         break;
979
980                 /* don't map more than once */
981                 if (cm->cm_flags & AAC_CMD_MAPPED)
982                         panic("aac: command %p already mapped", cm);
983
984                 /*
985                  * Set up the command to go to the controller.  If there are no
986                  * data buffers associated with the command then it can bypass
987                  * busdma.
988                  */
989                 if (cm->cm_datalen != 0) {
990                         if (cm->cm_flags & AAC_REQ_BIO)
991                                 error = bus_dmamap_load_bio(
992                                     sc->aac_buffer_dmat, cm->cm_datamap,
993                                     (struct bio *)cm->cm_private,
994                                     aac_map_command_sg, cm, 0);
995                         else
996                                 error = bus_dmamap_load(sc->aac_buffer_dmat,
997                                     cm->cm_datamap, cm->cm_data,
998                                     cm->cm_datalen, aac_map_command_sg, cm, 0);
999                         if (error == EINPROGRESS) {
1000                                 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "freezing queue\n");
1001                                 sc->flags |= AAC_QUEUE_FRZN;
1002                         } else if (error != 0)
1003                                 panic("aac_startio: unexpected error %d from "
1004                                       "busdma", error);
1005                 } else
1006                         aac_map_command_sg(cm, NULL, 0, 0);
1007         }
1008 }
1009
1010 /*
1011  * Handle notification of one or more FIBs coming from the controller.
1012  */
1013 static void
1014 aac_command_thread(struct aac_softc *sc)
1015 {
1016         struct aac_fib *fib;
1017         u_int32_t fib_size;
1018         int size, retval;
1019
1020         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1021
1022         mtx_lock(&sc->aac_io_lock);
1023         sc->aifflags = AAC_AIFFLAGS_RUNNING;
1024
1025         while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
1026
1027                 retval = 0;
1028                 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
1029                         retval = msleep(sc->aifthread, &sc->aac_io_lock, PRIBIO,
1030                                         "aifthd", AAC_PERIODIC_INTERVAL * hz);
1031
1032                 /*
1033                  * First see if any FIBs need to be allocated.  This needs
1034                  * to be called without the driver lock because contigmalloc
1035                  * can sleep.
1036                  */
1037                 if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
1038                         mtx_unlock(&sc->aac_io_lock);
1039                         aac_alloc_commands(sc);
1040                         mtx_lock(&sc->aac_io_lock);
1041                         sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
1042                         aac_startio(sc);
1043                 }
1044
1045                 /*
1046                  * While we're here, check to see if any commands are stuck.
1047                  * This is pretty low-priority, so it's ok if it doesn't
1048                  * always fire.
1049                  */
1050                 if (retval == EWOULDBLOCK)
1051                         aac_timeout(sc);
1052
1053                 /* Check the hardware printf message buffer */
1054                 if (sc->aac_common->ac_printf[0] != 0)
1055                         aac_print_printf(sc);
1056
1057                 /* Also check to see if the adapter has a command for us. */
1058                 if (sc->flags & AAC_FLAGS_NEW_COMM)
1059                         continue;
1060                 for (;;) {
1061                         if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
1062                                            &fib_size, &fib))
1063                                 break;
1064
1065                         AAC_PRINT_FIB(sc, fib);
1066
1067                         switch (fib->Header.Command) {
1068                         case AifRequest:
1069                                 aac_handle_aif(sc, fib);
1070                                 break;
1071                         default:
1072                                 device_printf(sc->aac_dev, "unknown command "
1073                                               "from controller\n");
1074                                 break;
1075                         }
1076
1077                         if ((fib->Header.XferState == 0) ||
1078                             (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
1079                                 break;
1080                         }
1081
1082                         /* Return the AIF to the controller. */
1083                         if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
1084                                 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
1085                                 *(AAC_FSAStatus*)fib->data = ST_OK;
1086
1087                                 /* XXX Compute the Size field? */
1088                                 size = fib->Header.Size;
1089                                 if (size > sizeof(struct aac_fib)) {
1090                                         size = sizeof(struct aac_fib);
1091                                         fib->Header.Size = size;
1092                                 }
1093                                 /*
1094                                  * Since we did not generate this command, it
1095                                  * cannot go through the normal
1096                                  * enqueue->startio chain.
1097                                  */
1098                                 aac_enqueue_response(sc,
1099                                                  AAC_ADAP_NORM_RESP_QUEUE,
1100                                                  fib);
1101                         }
1102                 }
1103         }
1104         sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
1105         mtx_unlock(&sc->aac_io_lock);
1106         wakeup(sc->aac_dev);
1107
1108         kproc_exit(0);
1109 }
1110
1111 /*
1112  * Process completed commands.
1113  */
1114 static void
1115 aac_complete(void *context, int pending)
1116 {
1117         struct aac_softc *sc;
1118         struct aac_command *cm;
1119         struct aac_fib *fib;
1120         u_int32_t fib_size;
1121
1122         sc = (struct aac_softc *)context;
1123         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1124
1125         mtx_lock(&sc->aac_io_lock);
1126
1127         /* pull completed commands off the queue */
1128         for (;;) {
1129                 /* look for completed FIBs on our queue */
1130                 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1131                                                         &fib))
1132                         break;  /* nothing to do */
1133
1134                 /* get the command, unmap and hand off for processing */
1135                 cm = sc->aac_commands + fib->Header.SenderData;
1136                 if (cm == NULL) {
1137                         AAC_PRINT_FIB(sc, fib);
1138                         break;
1139                 }
1140                 if ((cm->cm_flags & AAC_CMD_TIMEDOUT) != 0)
1141                         device_printf(sc->aac_dev,
1142                             "COMMAND %p COMPLETED AFTER %d SECONDS\n",
1143                             cm, (int)(time_uptime-cm->cm_timestamp));
1144
1145                 aac_remove_busy(cm);
1146
1147                 aac_unmap_command(cm);
1148                 cm->cm_flags |= AAC_CMD_COMPLETED;
1149
1150                 /* is there a completion handler? */
1151                 if (cm->cm_complete != NULL) {
1152                         cm->cm_complete(cm);
1153                 } else {
1154                         /* assume that someone is sleeping on this command */
1155                         wakeup(cm);
1156                 }
1157         }
1158
1159         /* see if we can start some more I/O */
1160         sc->flags &= ~AAC_QUEUE_FRZN;
1161         aac_startio(sc);
1162
1163         mtx_unlock(&sc->aac_io_lock);
1164 }
1165
1166 /*
1167  * Handle a bio submitted from a disk device.
1168  */
1169 void
1170 aac_submit_bio(struct bio *bp)
1171 {
1172         struct aac_disk *ad;
1173         struct aac_softc *sc;
1174
1175         ad = (struct aac_disk *)bp->bio_disk->d_drv1;
1176         sc = ad->ad_controller;
1177         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1178
1179         /* queue the BIO and try to get some work done */
1180         aac_enqueue_bio(sc, bp);
1181         aac_startio(sc);
1182 }
1183
1184 /*
1185  * Get a bio and build a command to go with it.
1186  */
1187 static int
1188 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
1189 {
1190         struct aac_command *cm;
1191         struct aac_fib *fib;
1192         struct aac_disk *ad;
1193         struct bio *bp;
1194
1195         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1196
1197         /* get the resources we will need */
1198         cm = NULL;
1199         bp = NULL;
1200         if (aac_alloc_command(sc, &cm)) /* get a command */
1201                 goto fail;
1202         if ((bp = aac_dequeue_bio(sc)) == NULL)
1203                 goto fail;
1204
1205         /* fill out the command */
1206         cm->cm_datalen = bp->bio_bcount;
1207         cm->cm_complete = aac_bio_complete;
1208         cm->cm_flags = AAC_REQ_BIO;
1209         cm->cm_private = bp;
1210         cm->cm_timestamp = time_uptime;
1211
1212         /* build the FIB */
1213         fib = cm->cm_fib;
1214         fib->Header.Size = sizeof(struct aac_fib_header);
1215         fib->Header.XferState =
1216                 AAC_FIBSTATE_HOSTOWNED   |
1217                 AAC_FIBSTATE_INITIALISED |
1218                 AAC_FIBSTATE_EMPTY       |
1219                 AAC_FIBSTATE_FROMHOST    |
1220                 AAC_FIBSTATE_REXPECTED   |
1221                 AAC_FIBSTATE_NORM        |
1222                 AAC_FIBSTATE_ASYNC       |
1223                 AAC_FIBSTATE_FAST_RESPONSE;
1224
1225         /* build the read/write request */
1226         ad = (struct aac_disk *)bp->bio_disk->d_drv1;
1227
1228         if (sc->flags & AAC_FLAGS_RAW_IO) {
1229                 struct aac_raw_io *raw;
1230                 raw = (struct aac_raw_io *)&fib->data[0];
1231                 fib->Header.Command = RawIo;
1232                 raw->BlockNumber = (u_int64_t)bp->bio_pblkno;
1233                 raw->ByteCount = bp->bio_bcount;
1234                 raw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1235                 raw->BpTotal = 0;
1236                 raw->BpComplete = 0;
1237                 fib->Header.Size += sizeof(struct aac_raw_io);
1238                 cm->cm_sgtable = (struct aac_sg_table *)&raw->SgMapRaw;
1239                 if (bp->bio_cmd == BIO_READ) {
1240                         raw->Flags = 1;
1241                         cm->cm_flags |= AAC_CMD_DATAIN;
1242                 } else {
1243                         raw->Flags = 0;
1244                         cm->cm_flags |= AAC_CMD_DATAOUT;
1245                 }
1246         } else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1247                 fib->Header.Command = ContainerCommand;
1248                 if (bp->bio_cmd == BIO_READ) {
1249                         struct aac_blockread *br;
1250                         br = (struct aac_blockread *)&fib->data[0];
1251                         br->Command = VM_CtBlockRead;
1252                         br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1253                         br->BlockNumber = bp->bio_pblkno;
1254                         br->ByteCount = bp->bio_bcount;
1255                         fib->Header.Size += sizeof(struct aac_blockread);
1256                         cm->cm_sgtable = &br->SgMap;
1257                         cm->cm_flags |= AAC_CMD_DATAIN;
1258                 } else {
1259                         struct aac_blockwrite *bw;
1260                         bw = (struct aac_blockwrite *)&fib->data[0];
1261                         bw->Command = VM_CtBlockWrite;
1262                         bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1263                         bw->BlockNumber = bp->bio_pblkno;
1264                         bw->ByteCount = bp->bio_bcount;
1265                         bw->Stable = CUNSTABLE;
1266                         fib->Header.Size += sizeof(struct aac_blockwrite);
1267                         cm->cm_flags |= AAC_CMD_DATAOUT;
1268                         cm->cm_sgtable = &bw->SgMap;
1269                 }
1270         } else {
1271                 fib->Header.Command = ContainerCommand64;
1272                 if (bp->bio_cmd == BIO_READ) {
1273                         struct aac_blockread64 *br;
1274                         br = (struct aac_blockread64 *)&fib->data[0];
1275                         br->Command = VM_CtHostRead64;
1276                         br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1277                         br->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE;
1278                         br->BlockNumber = bp->bio_pblkno;
1279                         br->Pad = 0;
1280                         br->Flags = 0;
1281                         fib->Header.Size += sizeof(struct aac_blockread64);
1282                         cm->cm_flags |= AAC_CMD_DATAIN;
1283                         cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
1284                 } else {
1285                         struct aac_blockwrite64 *bw;
1286                         bw = (struct aac_blockwrite64 *)&fib->data[0];
1287                         bw->Command = VM_CtHostWrite64;
1288                         bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1289                         bw->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE;
1290                         bw->BlockNumber = bp->bio_pblkno;
1291                         bw->Pad = 0;
1292                         bw->Flags = 0;
1293                         fib->Header.Size += sizeof(struct aac_blockwrite64);
1294                         cm->cm_flags |= AAC_CMD_DATAOUT;
1295                         cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
1296                 }
1297         }
1298
1299         *cmp = cm;
1300         return(0);
1301
1302 fail:
1303         if (bp != NULL)
1304                 aac_enqueue_bio(sc, bp);
1305         if (cm != NULL)
1306                 aac_release_command(cm);
1307         return(ENOMEM);
1308 }
1309
1310 /*
1311  * Handle a bio-instigated command that has been completed.
1312  */
1313 static void
1314 aac_bio_complete(struct aac_command *cm)
1315 {
1316         struct aac_blockread_response *brr;
1317         struct aac_blockwrite_response *bwr;
1318         struct bio *bp;
1319         AAC_FSAStatus status;
1320
1321         /* fetch relevant status and then release the command */
1322         bp = (struct bio *)cm->cm_private;
1323         if (bp->bio_cmd == BIO_READ) {
1324                 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
1325                 status = brr->Status;
1326         } else {
1327                 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
1328                 status = bwr->Status;
1329         }
1330         aac_release_command(cm);
1331
1332         /* fix up the bio based on status */
1333         if (status == ST_OK) {
1334                 bp->bio_resid = 0;
1335         } else {
1336                 bp->bio_error = EIO;
1337                 bp->bio_flags |= BIO_ERROR;
1338         }
1339         aac_biodone(bp);
1340 }
1341
1342 /*
1343  * Submit a command to the controller, return when it completes.
1344  * XXX This is very dangerous!  If the card has gone out to lunch, we could
1345  *     be stuck here forever.  At the same time, signals are not caught
1346  *     because there is a risk that a signal could wakeup the sleep before
1347  *     the card has a chance to complete the command.  Since there is no way
1348  *     to cancel a command that is in progress, we can't protect against the
1349  *     card completing a command late and spamming the command and data
1350  *     memory.  So, we are held hostage until the command completes.
1351  */
1352 static int
1353 aac_wait_command(struct aac_command *cm)
1354 {
1355         struct aac_softc *sc;
1356         int error;
1357
1358         sc = cm->cm_sc;
1359         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1360
1361         /* Put the command on the ready queue and get things going */
1362         aac_enqueue_ready(cm);
1363         aac_startio(sc);
1364         error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
1365         return(error);
1366 }
1367
1368 /*
1369  *Command Buffer Management
1370  */
1371
1372 /*
1373  * Allocate a command.
1374  */
1375 int
1376 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1377 {
1378         struct aac_command *cm;
1379
1380         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1381
1382         if ((cm = aac_dequeue_free(sc)) == NULL) {
1383                 if (sc->total_fibs < sc->aac_max_fibs) {
1384                         mtx_lock(&sc->aac_io_lock);
1385                         sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1386                         mtx_unlock(&sc->aac_io_lock);
1387                         wakeup(sc->aifthread);
1388                 }
1389                 return (EBUSY);
1390         }
1391
1392         *cmp = cm;
1393         return(0);
1394 }
1395
1396 /*
1397  * Release a command back to the freelist.
1398  */
1399 void
1400 aac_release_command(struct aac_command *cm)
1401 {
1402         struct aac_event *event;
1403         struct aac_softc *sc;
1404
1405         sc = cm->cm_sc;
1406         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1407
1408         /* (re)initialize the command/FIB */
1409         cm->cm_sgtable = NULL;
1410         cm->cm_flags = 0;
1411         cm->cm_complete = NULL;
1412         cm->cm_private = NULL;
1413         cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1414         cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1415         cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1416         cm->cm_fib->Header.Flags = 0;
1417         cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
1418
1419         /*
1420          * These are duplicated in aac_start to cover the case where an
1421          * intermediate stage may have destroyed them.  They're left
1422          * initialized here for debugging purposes only.
1423          */
1424         cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1425         cm->cm_fib->Header.SenderData = 0;
1426
1427         aac_enqueue_free(cm);
1428
1429         if ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
1430                 TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
1431                 event->ev_callback(sc, event, event->ev_arg);
1432         }
1433 }
1434
1435 /*
1436  * Map helper for command/FIB allocation.
1437  */
1438 static void
1439 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1440 {
1441         uint64_t        *fibphys;
1442
1443         fibphys = (uint64_t *)arg;
1444
1445         *fibphys = segs[0].ds_addr;
1446 }
1447
1448 /*
1449  * Allocate and initialize commands/FIBs for this adapter.
1450  */
1451 static int
1452 aac_alloc_commands(struct aac_softc *sc)
1453 {
1454         struct aac_command *cm;
1455         struct aac_fibmap *fm;
1456         uint64_t fibphys;
1457         int i, error;
1458
1459         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1460
1461         if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
1462                 return (ENOMEM);
1463
1464         fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
1465         if (fm == NULL)
1466                 return (ENOMEM);
1467
1468         /* allocate the FIBs in DMAable memory and load them */
1469         if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1470                              BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1471                 device_printf(sc->aac_dev,
1472                               "Not enough contiguous memory available.\n");
1473                 free(fm, M_AACBUF);
1474                 return (ENOMEM);
1475         }
1476
1477         /* Ignore errors since this doesn't bounce */
1478         (void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1479                               sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
1480                               aac_map_command_helper, &fibphys, 0);
1481
1482         /* initialize constant fields in the command structure */
1483         bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
1484         for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
1485                 cm = sc->aac_commands + sc->total_fibs;
1486                 fm->aac_commands = cm;
1487                 cm->cm_sc = sc;
1488                 cm->cm_fib = (struct aac_fib *)
1489                         ((u_int8_t *)fm->aac_fibs + i*sc->aac_max_fib_size);
1490                 cm->cm_fibphys = fibphys + i*sc->aac_max_fib_size;
1491                 cm->cm_index = sc->total_fibs;
1492
1493                 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1494                                                &cm->cm_datamap)) != 0)
1495                         break;
1496                 mtx_lock(&sc->aac_io_lock);
1497                 aac_release_command(cm);
1498                 sc->total_fibs++;
1499                 mtx_unlock(&sc->aac_io_lock);
1500         }
1501
1502         if (i > 0) {
1503                 mtx_lock(&sc->aac_io_lock);
1504                 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1505                 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs);
1506                 mtx_unlock(&sc->aac_io_lock);
1507                 return (0);
1508         }
1509
1510         bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1511         bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1512         free(fm, M_AACBUF);
1513         return (ENOMEM);
1514 }
1515
1516 /*
1517  * Free FIBs owned by this adapter.
1518  */
1519 static void
1520 aac_free_commands(struct aac_softc *sc)
1521 {
1522         struct aac_fibmap *fm;
1523         struct aac_command *cm;
1524         int i;
1525
1526         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1527
1528         while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1529
1530                 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1531                 /*
1532                  * We check against total_fibs to handle partially
1533                  * allocated blocks.
1534                  */
1535                 for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) {
1536                         cm = fm->aac_commands + i;
1537                         bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1538                 }
1539                 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1540                 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1541                 free(fm, M_AACBUF);
1542         }
1543 }
1544
1545 /*
1546  * Command-mapping helper function - populate this command's s/g table.
1547  */
1548 static void
1549 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1550 {
1551         struct aac_softc *sc;
1552         struct aac_command *cm;
1553         struct aac_fib *fib;
1554         int i;
1555
1556         cm = (struct aac_command *)arg;
1557         sc = cm->cm_sc;
1558         fib = cm->cm_fib;
1559         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1560
1561         /* copy into the FIB */
1562         if (cm->cm_sgtable != NULL) {
1563                 if (fib->Header.Command == RawIo) {
1564                         struct aac_sg_tableraw *sg;
1565                         sg = (struct aac_sg_tableraw *)cm->cm_sgtable;
1566                         sg->SgCount = nseg;
1567                         for (i = 0; i < nseg; i++) {
1568                                 sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr;
1569                                 sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len;
1570                                 sg->SgEntryRaw[i].Next = 0;
1571                                 sg->SgEntryRaw[i].Prev = 0;
1572                                 sg->SgEntryRaw[i].Flags = 0;
1573                         }
1574                         /* update the FIB size for the s/g count */
1575                         fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw);
1576                 } else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1577                         struct aac_sg_table *sg;
1578                         sg = cm->cm_sgtable;
1579                         sg->SgCount = nseg;
1580                         for (i = 0; i < nseg; i++) {
1581                                 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1582                                 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1583                         }
1584                         /* update the FIB size for the s/g count */
1585                         fib->Header.Size += nseg*sizeof(struct aac_sg_entry);
1586                 } else {
1587                         struct aac_sg_table64 *sg;
1588                         sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1589                         sg->SgCount = nseg;
1590                         for (i = 0; i < nseg; i++) {
1591                                 sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1592                                 sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1593                         }
1594                         /* update the FIB size for the s/g count */
1595                         fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1596                 }
1597         }
1598
1599         /* Fix up the address values in the FIB.  Use the command array index
1600          * instead of a pointer since these fields are only 32 bits.  Shift
1601          * the SenderFibAddress over to make room for the fast response bit
1602          * and for the AIF bit
1603          */
1604         cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2);
1605         cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1606
1607         /* save a pointer to the command for speedy reverse-lookup */
1608         cm->cm_fib->Header.SenderData = cm->cm_index;
1609
1610         if (cm->cm_flags & AAC_CMD_DATAIN)
1611                 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1612                                 BUS_DMASYNC_PREREAD);
1613         if (cm->cm_flags & AAC_CMD_DATAOUT)
1614                 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1615                                 BUS_DMASYNC_PREWRITE);
1616         cm->cm_flags |= AAC_CMD_MAPPED;
1617
1618         if (sc->flags & AAC_FLAGS_NEW_COMM) {
1619                 int count = 10000000L;
1620                 while (AAC_SEND_COMMAND(sc, cm) != 0) {
1621                         if (--count == 0) {
1622                                 aac_unmap_command(cm);
1623                                 sc->flags |= AAC_QUEUE_FRZN;
1624                                 aac_requeue_ready(cm);
1625                         }
1626                         DELAY(5);                       /* wait 5 usec. */
1627                 }
1628         } else {
1629                 /* Put the FIB on the outbound queue */
1630                 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1631                         aac_unmap_command(cm);
1632                         sc->flags |= AAC_QUEUE_FRZN;
1633                         aac_requeue_ready(cm);
1634                 }
1635         }
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 }
2366
2367 /*
2368  * Interface Function Vectors
2369  */
2370
2371 /*
2372  * Read the current firmware status word.
2373  */
2374 static int
2375 aac_sa_get_fwstatus(struct aac_softc *sc)
2376 {
2377         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2378
2379         return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
2380 }
2381
2382 static int
2383 aac_rx_get_fwstatus(struct aac_softc *sc)
2384 {
2385         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2386
2387         return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2388             AAC_RX_OMR0 : AAC_RX_FWSTATUS));
2389 }
2390
2391 static int
2392 aac_rkt_get_fwstatus(struct aac_softc *sc)
2393 {
2394         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2395
2396         return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2397             AAC_RKT_OMR0 : AAC_RKT_FWSTATUS));
2398 }
2399
2400 /*
2401  * Notify the controller of a change in a given queue
2402  */
2403
2404 static void
2405 aac_sa_qnotify(struct aac_softc *sc, int qbit)
2406 {
2407         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2408
2409         AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
2410 }
2411
2412 static void
2413 aac_rx_qnotify(struct aac_softc *sc, int qbit)
2414 {
2415         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2416
2417         AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
2418 }
2419
2420 static void
2421 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
2422 {
2423         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2424
2425         AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
2426 }
2427
2428 /*
2429  * Get the interrupt reason bits
2430  */
2431 static int
2432 aac_sa_get_istatus(struct aac_softc *sc)
2433 {
2434         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2435
2436         return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
2437 }
2438
2439 static int
2440 aac_rx_get_istatus(struct aac_softc *sc)
2441 {
2442         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2443
2444         return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
2445 }
2446
2447 static int
2448 aac_rkt_get_istatus(struct aac_softc *sc)
2449 {
2450         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2451
2452         return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
2453 }
2454
2455 /*
2456  * Clear some interrupt reason bits
2457  */
2458 static void
2459 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
2460 {
2461         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2462
2463         AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
2464 }
2465
2466 static void
2467 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
2468 {
2469         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2470
2471         AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
2472 }
2473
2474 static void
2475 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
2476 {
2477         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2478
2479         AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
2480 }
2481
2482 /*
2483  * Populate the mailbox and set the command word
2484  */
2485 static void
2486 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2487                 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2488 {
2489         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2490
2491         AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX, command);
2492         AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
2493         AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
2494         AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
2495         AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
2496 }
2497
2498 static void
2499 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
2500                 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2501 {
2502         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2503
2504         AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX, command);
2505         AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2506         AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2507         AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2508         AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2509 }
2510
2511 static void
2512 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2513                     u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2514 {
2515         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2516
2517         AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX, command);
2518         AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
2519         AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
2520         AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
2521         AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
2522 }
2523
2524 /*
2525  * Fetch the immediate command status word
2526  */
2527 static int
2528 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2529 {
2530         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2531
2532         return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2533 }
2534
2535 static int
2536 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2537 {
2538         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2539
2540         return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2541 }
2542
2543 static int
2544 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2545 {
2546         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2547
2548         return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2549 }
2550
2551 /*
2552  * Set/clear interrupt masks
2553  */
2554 static void
2555 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2556 {
2557         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2558
2559         if (enable) {
2560                 AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2561         } else {
2562                 AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2563         }
2564 }
2565
2566 static void
2567 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2568 {
2569         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2570
2571         if (enable) {
2572                 if (sc->flags & AAC_FLAGS_NEW_COMM)
2573                         AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
2574                 else
2575                         AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2576         } else {
2577                 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
2578         }
2579 }
2580
2581 static void
2582 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2583 {
2584         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2585
2586         if (enable) {
2587                 if (sc->flags & AAC_FLAGS_NEW_COMM)
2588                         AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
2589                 else
2590                         AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2591         } else {
2592                 AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
2593         }
2594 }
2595
2596 /*
2597  * New comm. interface: Send command functions
2598  */
2599 static int
2600 aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm)
2601 {
2602         u_int32_t index, device;
2603
2604         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2605
2606         index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2607         if (index == 0xffffffffL)
2608                 index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2609         if (index == 0xffffffffL)
2610                 return index;
2611         aac_enqueue_busy(cm);
2612         device = index;
2613         AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2614         device += 4;
2615         AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2616         device += 4;
2617         AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2618         AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
2619         return 0;
2620 }
2621
2622 static int
2623 aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
2624 {
2625         u_int32_t index, device;
2626
2627         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2628
2629         index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2630         if (index == 0xffffffffL)
2631                 index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2632         if (index == 0xffffffffL)
2633                 return index;
2634         aac_enqueue_busy(cm);
2635         device = index;
2636         AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2637         device += 4;
2638         AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2639         device += 4;
2640         AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2641         AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
2642         return 0;
2643 }
2644
2645 /*
2646  * New comm. interface: get, set outbound queue index
2647  */
2648 static int
2649 aac_rx_get_outb_queue(struct aac_softc *sc)
2650 {
2651         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2652
2653         return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
2654 }
2655
2656 static int
2657 aac_rkt_get_outb_queue(struct aac_softc *sc)
2658 {
2659         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2660
2661         return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
2662 }
2663
2664 static void
2665 aac_rx_set_outb_queue(struct aac_softc *sc, int index)
2666 {
2667         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2668
2669         AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
2670 }
2671
2672 static void
2673 aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
2674 {
2675         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2676
2677         AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
2678 }
2679
2680 /*
2681  * Debugging and Diagnostics
2682  */
2683
2684 /*
2685  * Print some information about the controller.
2686  */
2687 static void
2688 aac_describe_controller(struct aac_softc *sc)
2689 {
2690         struct aac_fib *fib;
2691         struct aac_adapter_info *info;
2692         char *adapter_type = "Adaptec RAID controller";
2693
2694         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2695
2696         mtx_lock(&sc->aac_io_lock);
2697         aac_alloc_sync_fib(sc, &fib);
2698
2699         fib->data[0] = 0;
2700         if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2701                 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2702                 aac_release_sync_fib(sc);
2703                 mtx_unlock(&sc->aac_io_lock);
2704                 return;
2705         }
2706
2707         /* save the kernel revision structure for later use */
2708         info = (struct aac_adapter_info *)&fib->data[0];
2709         sc->aac_revision = info->KernelRevision;
2710
2711         if (bootverbose) {
2712                 device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
2713                     "(%dMB cache, %dMB execution), %s\n",
2714                     aac_describe_code(aac_cpu_variant, info->CpuVariant),
2715                     info->ClockSpeed, info->TotalMem / (1024 * 1024),
2716                     info->BufferMem / (1024 * 1024),
2717                     info->ExecutionMem / (1024 * 1024),
2718                     aac_describe_code(aac_battery_platform,
2719                     info->batteryPlatform));
2720
2721                 device_printf(sc->aac_dev,
2722                     "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2723                     info->KernelRevision.external.comp.major,
2724                     info->KernelRevision.external.comp.minor,
2725                     info->KernelRevision.external.comp.dash,
2726                     info->KernelRevision.buildNumber,
2727                     (u_int32_t)(info->SerialNumber & 0xffffff));
2728
2729                 device_printf(sc->aac_dev, "Supported Options=%b\n",
2730                               sc->supported_options,
2731                               "\20"
2732                               "\1SNAPSHOT"
2733                               "\2CLUSTERS"
2734                               "\3WCACHE"
2735                               "\4DATA64"
2736                               "\5HOSTTIME"
2737                               "\6RAID50"
2738                               "\7WINDOW4GB"
2739                               "\10SCSIUPGD"
2740                               "\11SOFTERR"
2741                               "\12NORECOND"
2742                               "\13SGMAP64"
2743                               "\14ALARM"
2744                               "\15NONDASD"
2745                               "\16SCSIMGT"
2746                               "\17RAIDSCSI"
2747                               "\21ADPTINFO"
2748                               "\22NEWCOMM"
2749                               "\23ARRAY64BIT"
2750                               "\24HEATSENSOR");
2751         }
2752
2753         if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
2754                 fib->data[0] = 0;
2755                 if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
2756                         device_printf(sc->aac_dev,
2757                             "RequestSupplementAdapterInfo failed\n");
2758                 else
2759                         adapter_type = ((struct aac_supplement_adapter_info *)
2760                             &fib->data[0])->AdapterTypeText;
2761         }
2762         device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
2763                 adapter_type,
2764                 AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
2765                 AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
2766
2767         aac_release_sync_fib(sc);
2768         mtx_unlock(&sc->aac_io_lock);
2769 }
2770
2771 /*
2772  * Look up a text description of a numeric error code and return a pointer to
2773  * same.
2774  */
2775 static const char *
2776 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
2777 {
2778         int i;
2779
2780         for (i = 0; table[i].string != NULL; i++)
2781                 if (table[i].code == code)
2782                         return(table[i].string);
2783         return(table[i + 1].string);
2784 }
2785
2786 /*
2787  * Management Interface
2788  */
2789
2790 static int
2791 aac_open(struct cdev *dev, int flags, int fmt, struct thread *td)
2792 {
2793         struct aac_softc *sc;
2794
2795         sc = dev->si_drv1;
2796         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2797         device_busy(sc->aac_dev);
2798         devfs_set_cdevpriv(sc, aac_cdevpriv_dtor);
2799
2800         return 0;
2801 }
2802
2803 static int
2804 aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
2805 {
2806         union aac_statrequest *as;
2807         struct aac_softc *sc;
2808         int error = 0;
2809
2810         as = (union aac_statrequest *)arg;
2811         sc = dev->si_drv1;
2812         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2813
2814         switch (cmd) {
2815         case AACIO_STATS:
2816                 switch (as->as_item) {
2817                 case AACQ_FREE:
2818                 case AACQ_BIO:
2819                 case AACQ_READY:
2820                 case AACQ_BUSY:
2821                         bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2822                               sizeof(struct aac_qstat));
2823                         break;
2824                 default:
2825                         error = ENOENT;
2826                         break;
2827                 }
2828         break;
2829
2830         case FSACTL_SENDFIB:
2831         case FSACTL_SEND_LARGE_FIB:
2832                 arg = *(caddr_t*)arg;
2833         case FSACTL_LNX_SENDFIB:
2834         case FSACTL_LNX_SEND_LARGE_FIB:
2835                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SENDFIB");
2836                 error = aac_ioctl_sendfib(sc, arg);
2837                 break;
2838         case FSACTL_SEND_RAW_SRB:
2839                 arg = *(caddr_t*)arg;
2840         case FSACTL_LNX_SEND_RAW_SRB:
2841                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SEND_RAW_SRB");
2842                 error = aac_ioctl_send_raw_srb(sc, arg);
2843                 break;
2844         case FSACTL_AIF_THREAD:
2845         case FSACTL_LNX_AIF_THREAD:
2846                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_AIF_THREAD");
2847                 error = EINVAL;
2848                 break;
2849         case FSACTL_OPEN_GET_ADAPTER_FIB:
2850                 arg = *(caddr_t*)arg;
2851         case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2852                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_OPEN_GET_ADAPTER_FIB");
2853                 error = aac_open_aif(sc, arg);
2854                 break;
2855         case FSACTL_GET_NEXT_ADAPTER_FIB:
2856                 arg = *(caddr_t*)arg;
2857         case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2858                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_NEXT_ADAPTER_FIB");
2859                 error = aac_getnext_aif(sc, arg);
2860                 break;
2861         case FSACTL_CLOSE_GET_ADAPTER_FIB:
2862                 arg = *(caddr_t*)arg;
2863         case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2864                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2865                 error = aac_close_aif(sc, arg);
2866                 break;
2867         case FSACTL_MINIPORT_REV_CHECK:
2868                 arg = *(caddr_t*)arg;
2869         case FSACTL_LNX_MINIPORT_REV_CHECK:
2870                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_MINIPORT_REV_CHECK");
2871                 error = aac_rev_check(sc, arg);
2872                 break;
2873         case FSACTL_QUERY_DISK:
2874                 arg = *(caddr_t*)arg;
2875         case FSACTL_LNX_QUERY_DISK:
2876                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_QUERY_DISK");
2877                 error = aac_query_disk(sc, arg);
2878                 break;
2879         case FSACTL_DELETE_DISK:
2880         case FSACTL_LNX_DELETE_DISK:
2881                 /*
2882                  * We don't trust the underland to tell us when to delete a
2883                  * container, rather we rely on an AIF coming from the
2884                  * controller
2885                  */
2886                 error = 0;
2887                 break;
2888         case FSACTL_GET_PCI_INFO:
2889                 arg = *(caddr_t*)arg;
2890         case FSACTL_LNX_GET_PCI_INFO:
2891                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_PCI_INFO");
2892                 error = aac_get_pci_info(sc, arg);
2893                 break;
2894         case FSACTL_GET_FEATURES:
2895                 arg = *(caddr_t*)arg;
2896         case FSACTL_LNX_GET_FEATURES:
2897                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_FEATURES");
2898                 error = aac_supported_features(sc, arg);
2899                 break;
2900         default:
2901                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "unsupported cmd 0x%lx\n", cmd);
2902                 error = EINVAL;
2903                 break;
2904         }
2905         return(error);
2906 }
2907
2908 static int
2909 aac_poll(struct cdev *dev, int poll_events, struct thread *td)
2910 {
2911         struct aac_softc *sc;
2912         struct aac_fib_context *ctx;
2913         int revents;
2914
2915         sc = dev->si_drv1;
2916         revents = 0;
2917
2918         mtx_lock(&sc->aac_aifq_lock);
2919         if ((poll_events & (POLLRDNORM | POLLIN)) != 0) {
2920                 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
2921                         if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap) {
2922                                 revents |= poll_events & (POLLIN | POLLRDNORM);
2923                                 break;
2924                         }
2925                 }
2926         }
2927         mtx_unlock(&sc->aac_aifq_lock);
2928
2929         if (revents == 0) {
2930                 if (poll_events & (POLLIN | POLLRDNORM))
2931                         selrecord(td, &sc->rcv_select);
2932         }
2933
2934         return (revents);
2935 }
2936
2937 static void
2938 aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
2939 {
2940
2941         switch (event->ev_type) {
2942         case AAC_EVENT_CMFREE:
2943                 mtx_assert(&sc->aac_io_lock, MA_OWNED);
2944                 if (aac_alloc_command(sc, (struct aac_command **)arg)) {
2945                         aac_add_event(sc, event);
2946                         return;
2947                 }
2948                 free(event, M_AACBUF);
2949                 wakeup(arg);
2950                 break;
2951         default:
2952                 break;
2953         }
2954 }
2955
2956 /*
2957  * Send a FIB supplied from userspace
2958  */
2959 static int
2960 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2961 {
2962         struct aac_command *cm;
2963         int size, error;
2964
2965         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2966
2967         cm = NULL;
2968
2969         /*
2970          * Get a command
2971          */
2972         mtx_lock(&sc->aac_io_lock);
2973         if (aac_alloc_command(sc, &cm)) {
2974                 struct aac_event *event;
2975
2976                 event = malloc(sizeof(struct aac_event), M_AACBUF,
2977                     M_NOWAIT | M_ZERO);
2978                 if (event == NULL) {
2979                         error = EBUSY;
2980                         mtx_unlock(&sc->aac_io_lock);
2981                         goto out;
2982                 }
2983                 event->ev_type = AAC_EVENT_CMFREE;
2984                 event->ev_callback = aac_ioctl_event;
2985                 event->ev_arg = &cm;
2986                 aac_add_event(sc, event);
2987                 msleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
2988         }
2989         mtx_unlock(&sc->aac_io_lock);
2990
2991         /*
2992          * Fetch the FIB header, then re-copy to get data as well.
2993          */
2994         if ((error = copyin(ufib, cm->cm_fib,
2995                             sizeof(struct aac_fib_header))) != 0)
2996                 goto out;
2997         size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
2998         if (size > sc->aac_max_fib_size) {
2999                 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
3000                               size, sc->aac_max_fib_size);
3001                 size = sc->aac_max_fib_size;
3002         }
3003         if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
3004                 goto out;
3005         cm->cm_fib->Header.Size = size;
3006         cm->cm_timestamp = time_uptime;
3007
3008         /*
3009          * Pass the FIB to the controller, wait for it to complete.
3010          */
3011         mtx_lock(&sc->aac_io_lock);
3012         error = aac_wait_command(cm);
3013         mtx_unlock(&sc->aac_io_lock);
3014         if (error != 0) {
3015                 device_printf(sc->aac_dev,
3016                               "aac_wait_command return %d\n", error);
3017                 goto out;
3018         }
3019
3020         /*
3021          * Copy the FIB and data back out to the caller.
3022          */
3023         size = cm->cm_fib->Header.Size;
3024         if (size > sc->aac_max_fib_size) {
3025                 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
3026                               size, sc->aac_max_fib_size);
3027                 size = sc->aac_max_fib_size;
3028         }
3029         error = copyout(cm->cm_fib, ufib, size);
3030
3031 out:
3032         if (cm != NULL) {
3033                 mtx_lock(&sc->aac_io_lock);
3034                 aac_release_command(cm);
3035                 mtx_unlock(&sc->aac_io_lock);
3036         }
3037         return(error);
3038 }
3039
3040 /*
3041  * Send a passthrough FIB supplied from userspace
3042  */
3043 static int
3044 aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
3045 {
3046         struct aac_command *cm;
3047         struct aac_event *event;
3048         struct aac_fib *fib;
3049         struct aac_srb *srbcmd, *user_srb;
3050         struct aac_sg_entry *sge;
3051         struct aac_sg_entry64 *sge64;
3052         void *srb_sg_address, *ureply;
3053         uint32_t fibsize, srb_sg_bytecount;
3054         int error, transfer_data;
3055
3056         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3057
3058         cm = NULL;
3059         transfer_data = 0;
3060         fibsize = 0;
3061         user_srb = (struct aac_srb *)arg;
3062
3063         mtx_lock(&sc->aac_io_lock);
3064         if (aac_alloc_command(sc, &cm)) {
3065                  event = malloc(sizeof(struct aac_event), M_AACBUF,
3066                     M_NOWAIT | M_ZERO);
3067                 if (event == NULL) {
3068                         error = EBUSY;
3069                         mtx_unlock(&sc->aac_io_lock);
3070                         goto out;
3071                 }
3072                 event->ev_type = AAC_EVENT_CMFREE;
3073                 event->ev_callback = aac_ioctl_event;
3074                 event->ev_arg = &cm;
3075                 aac_add_event(sc, event);
3076                 msleep(cm, &sc->aac_io_lock, 0, "aacraw", 0);
3077         }
3078         mtx_unlock(&sc->aac_io_lock);
3079
3080         cm->cm_data = NULL;
3081         fib = cm->cm_fib;
3082         srbcmd = (struct aac_srb *)fib->data;
3083         error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t));
3084         if (error != 0)
3085                 goto out;
3086         if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) {
3087                 error = EINVAL;
3088                 goto out;
3089         }
3090         error = copyin(user_srb, srbcmd, fibsize);
3091         if (error != 0)
3092                 goto out;
3093         srbcmd->function = 0;
3094         srbcmd->retry_limit = 0;
3095         if (srbcmd->sg_map.SgCount > 1) {
3096                 error = EINVAL;
3097                 goto out;
3098         }
3099
3100         /* Retrieve correct SG entries. */
3101         if (fibsize == (sizeof(struct aac_srb) +
3102             srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
3103                 sge = srbcmd->sg_map.SgEntry;
3104                 sge64 = NULL;
3105                 srb_sg_bytecount = sge->SgByteCount;
3106                 srb_sg_address = (void *)(uintptr_t)sge->SgAddress;
3107         }
3108 #ifdef __amd64__
3109         else if (fibsize == (sizeof(struct aac_srb) +
3110             srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) {
3111                 sge = NULL;
3112                 sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry;
3113                 srb_sg_bytecount = sge64->SgByteCount;
3114                 srb_sg_address = (void *)sge64->SgAddress;
3115                 if (sge64->SgAddress > 0xffffffffull &&
3116                     (sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
3117                         error = EINVAL;
3118                         goto out;
3119                 }
3120         }
3121 #endif
3122         else {
3123                 error = EINVAL;
3124                 goto out;
3125         }
3126         ureply = (char *)arg + fibsize;
3127         srbcmd->data_len = srb_sg_bytecount;
3128         if (srbcmd->sg_map.SgCount == 1)
3129                 transfer_data = 1;
3130
3131         cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map;
3132         if (transfer_data) {
3133                 cm->cm_datalen = srb_sg_bytecount;
3134                 cm->cm_data = malloc(cm->cm_datalen, M_AACBUF, M_NOWAIT);
3135                 if (cm->cm_data == NULL) {
3136                         error = ENOMEM;
3137                         goto out;
3138                 }
3139                 if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)
3140                         cm->cm_flags |= AAC_CMD_DATAIN;
3141                 if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) {
3142                         cm->cm_flags |= AAC_CMD_DATAOUT;
3143                         error = copyin(srb_sg_address, cm->cm_data,
3144                             cm->cm_datalen);
3145                         if (error != 0)
3146                                 goto out;
3147                 }
3148         }
3149
3150         fib->Header.Size = sizeof(struct aac_fib_header) +
3151             sizeof(struct aac_srb);
3152         fib->Header.XferState =
3153             AAC_FIBSTATE_HOSTOWNED   |
3154             AAC_FIBSTATE_INITIALISED |
3155             AAC_FIBSTATE_EMPTY       |
3156             AAC_FIBSTATE_FROMHOST    |
3157             AAC_FIBSTATE_REXPECTED   |
3158             AAC_FIBSTATE_NORM        |
3159             AAC_FIBSTATE_ASYNC       |
3160             AAC_FIBSTATE_FAST_RESPONSE;
3161         fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ?
3162             ScsiPortCommandU64 : ScsiPortCommand;
3163
3164         mtx_lock(&sc->aac_io_lock);
3165         aac_wait_command(cm);
3166         mtx_unlock(&sc->aac_io_lock);
3167
3168         if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) {
3169                 error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen);
3170                 if (error != 0)
3171                         goto out;
3172         }
3173         error = copyout(fib->data, ureply, sizeof(struct aac_srb_response));
3174 out:
3175         if (cm != NULL) {
3176                 if (cm->cm_data != NULL)
3177                         free(cm->cm_data, M_AACBUF);
3178                 mtx_lock(&sc->aac_io_lock);
3179                 aac_release_command(cm);
3180                 mtx_unlock(&sc->aac_io_lock);
3181         }
3182         return(error);
3183 }
3184
3185 /*
3186  * cdevpriv interface private destructor.
3187  */
3188 static void
3189 aac_cdevpriv_dtor(void *arg)
3190 {
3191         struct aac_softc *sc;
3192
3193         sc = arg;
3194         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3195         mtx_lock(&Giant);
3196         device_unbusy(sc->aac_dev);
3197         mtx_unlock(&Giant);
3198 }
3199
3200 /*
3201  * Handle an AIF sent to us by the controller; queue it for later reference.
3202  * If the queue fills up, then drop the older entries.
3203  */
3204 static void
3205 aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
3206 {
3207         struct aac_aif_command *aif;
3208         struct aac_container *co, *co_next;
3209         struct aac_fib_context *ctx;
3210         struct aac_mntinforesp *mir;
3211         int next, current, found;
3212         int count = 0, added = 0, i = 0;
3213         uint32_t channel;
3214
3215         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3216
3217         aif = (struct aac_aif_command*)&fib->data[0];
3218         aac_print_aif(sc, aif);
3219
3220         /* Is it an event that we should care about? */
3221         switch (aif->command) {
3222         case AifCmdEventNotify:
3223                 switch (aif->data.EN.type) {
3224                 case AifEnAddContainer:
3225                 case AifEnDeleteContainer:
3226                         /*
3227                          * A container was added or deleted, but the message
3228                          * doesn't tell us anything else!  Re-enumerate the
3229                          * containers and sort things out.
3230                          */
3231                         aac_alloc_sync_fib(sc, &fib);
3232                         do {
3233                                 /*
3234                                  * Ask the controller for its containers one at
3235                                  * a time.
3236                                  * XXX What if the controller's list changes
3237                                  * midway through this enumaration?
3238                                  * XXX This should be done async.
3239                                  */
3240                                 if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
3241                                         continue;
3242                                 if (i == 0)
3243                                         count = mir->MntRespCount;
3244                                 /*
3245                                  * Check the container against our list.
3246                                  * co->co_found was already set to 0 in a
3247                                  * previous run.
3248                                  */
3249                                 if ((mir->Status == ST_OK) &&
3250                                     (mir->MntTable[0].VolType != CT_NONE)) {
3251                                         found = 0;
3252                                         TAILQ_FOREACH(co,
3253                                                       &sc->aac_container_tqh,
3254                                                       co_link) {
3255                                                 if (co->co_mntobj.ObjectId ==
3256                                                     mir->MntTable[0].ObjectId) {
3257                                                         co->co_found = 1;
3258                                                         found = 1;
3259                                                         break;
3260                                                 }
3261                                         }
3262                                         /*
3263                                          * If the container matched, continue
3264                                          * in the list.
3265                                          */
3266                                         if (found) {
3267                                                 i++;
3268                                                 continue;
3269                                         }
3270
3271                                         /*
3272                                          * This is a new container.  Do all the
3273                                          * appropriate things to set it up.
3274                                          */
3275                                         aac_add_container(sc, mir, 1);
3276                                         added = 1;
3277                                 }
3278                                 i++;
3279                         } while ((i < count) && (i < AAC_MAX_CONTAINERS));
3280                         aac_release_sync_fib(sc);
3281
3282                         /*
3283                          * Go through our list of containers and see which ones
3284                          * were not marked 'found'.  Since the controller didn't
3285                          * list them they must have been deleted.  Do the
3286                          * appropriate steps to destroy the device.  Also reset
3287                          * the co->co_found field.
3288                          */
3289                         co = TAILQ_FIRST(&sc->aac_container_tqh);
3290                         while (co != NULL) {
3291                                 if (co->co_found == 0) {
3292                                         mtx_unlock(&sc->aac_io_lock);
3293                                         mtx_lock(&Giant);
3294                                         device_delete_child(sc->aac_dev,
3295                                                             co->co_disk);
3296                                         mtx_unlock(&Giant);
3297                                         mtx_lock(&sc->aac_io_lock);
3298                                         co_next = TAILQ_NEXT(co, co_link);
3299                                         mtx_lock(&sc->aac_container_lock);
3300                                         TAILQ_REMOVE(&sc->aac_container_tqh, co,
3301                                                      co_link);
3302                                         mtx_unlock(&sc->aac_container_lock);
3303                                         free(co, M_AACBUF);
3304                                         co = co_next;
3305                                 } else {
3306                                         co->co_found = 0;
3307                                         co = TAILQ_NEXT(co, co_link);
3308                                 }
3309                         }
3310
3311                         /* Attach the newly created containers */
3312                         if (added) {
3313                                 mtx_unlock(&sc->aac_io_lock);
3314                                 mtx_lock(&Giant);
3315                                 bus_generic_attach(sc->aac_dev);
3316                                 mtx_unlock(&Giant);
3317                                 mtx_lock(&sc->aac_io_lock);
3318                         }
3319
3320                         break;
3321
3322                 case AifEnEnclosureManagement:
3323                         switch (aif->data.EN.data.EEE.eventType) {
3324                         case AIF_EM_DRIVE_INSERTION:
3325                         case AIF_EM_DRIVE_REMOVAL:
3326                                 channel = aif->data.EN.data.EEE.unitID;
3327                                 if (sc->cam_rescan_cb != NULL)
3328                                         sc->cam_rescan_cb(sc,
3329                                             (channel >> 24) & 0xF,
3330                                             (channel & 0xFFFF));
3331                                 break;
3332                         }
3333                         break;
3334
3335                 case AifEnAddJBOD:
3336                 case AifEnDeleteJBOD:
3337                         channel = aif->data.EN.data.ECE.container;
3338                         if (sc->cam_rescan_cb != NULL)
3339                                 sc->cam_rescan_cb(sc, (channel >> 24) & 0xF,
3340                                     AAC_CAM_TARGET_WILDCARD);
3341                         break;
3342
3343                 default:
3344                         break;
3345                 }
3346
3347         default:
3348                 break;
3349         }
3350
3351         /* Copy the AIF data to the AIF queue for ioctl retrieval */
3352         mtx_lock(&sc->aac_aifq_lock);
3353         current = sc->aifq_idx;
3354         next = (current + 1) % AAC_AIFQ_LENGTH;
3355         if (next == 0)
3356                 sc->aifq_filled = 1;
3357         bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib));
3358         /* modify AIF contexts */
3359         if (sc->aifq_filled) {
3360                 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3361                         if (next == ctx->ctx_idx)
3362                                 ctx->ctx_wrap = 1;
3363                         else if (current == ctx->ctx_idx && ctx->ctx_wrap)
3364                                 ctx->ctx_idx = next;
3365                 }       
3366         }
3367         sc->aifq_idx = next;
3368         /* On the off chance that someone is sleeping for an aif... */
3369         if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
3370                 wakeup(sc->aac_aifq);
3371         /* Wakeup any poll()ers */
3372         selwakeuppri(&sc->rcv_select, PRIBIO);
3373         mtx_unlock(&sc->aac_aifq_lock);
3374 }
3375
3376 /*
3377  * Return the Revision of the driver to userspace and check to see if the
3378  * userspace app is possibly compatible.  This is extremely bogus since
3379  * our driver doesn't follow Adaptec's versioning system.  Cheat by just
3380  * returning what the card reported.
3381  */
3382 static int
3383 aac_rev_check(struct aac_softc *sc, caddr_t udata)
3384 {
3385         struct aac_rev_check rev_check;
3386         struct aac_rev_check_resp rev_check_resp;
3387         int error = 0;
3388
3389         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3390
3391         /*
3392          * Copyin the revision struct from userspace
3393          */
3394         if ((error = copyin(udata, (caddr_t)&rev_check,
3395                         sizeof(struct aac_rev_check))) != 0) {
3396                 return error;
3397         }
3398
3399         fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "Userland revision= %d\n",
3400               rev_check.callingRevision.buildNumber);
3401
3402         /*
3403          * Doctor up the response struct.
3404          */
3405         rev_check_resp.possiblyCompatible = 1;
3406         rev_check_resp.adapterSWRevision.external.comp.major =
3407             AAC_DRIVER_MAJOR_VERSION;
3408         rev_check_resp.adapterSWRevision.external.comp.minor =
3409             AAC_DRIVER_MINOR_VERSION;
3410         rev_check_resp.adapterSWRevision.external.comp.type =
3411             AAC_DRIVER_TYPE;
3412         rev_check_resp.adapterSWRevision.external.comp.dash =
3413             AAC_DRIVER_BUGFIX_LEVEL;
3414         rev_check_resp.adapterSWRevision.buildNumber =
3415             AAC_DRIVER_BUILD;
3416
3417         return(copyout((caddr_t)&rev_check_resp, udata,
3418                         sizeof(struct aac_rev_check_resp)));
3419 }
3420
3421 /*
3422  * Pass the fib context to the caller
3423  */
3424 static int
3425 aac_open_aif(struct aac_softc *sc, caddr_t arg)
3426 {
3427         struct aac_fib_context *fibctx, *ctx;
3428         int error = 0;
3429
3430         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3431
3432         fibctx = malloc(sizeof(struct aac_fib_context), M_AACBUF, M_NOWAIT|M_ZERO);
3433         if (fibctx == NULL)
3434                 return (ENOMEM);
3435
3436         mtx_lock(&sc->aac_aifq_lock);
3437         /* all elements are already 0, add to queue */
3438         if (sc->fibctx == NULL)
3439                 sc->fibctx = fibctx;
3440         else {
3441                 for (ctx = sc->fibctx; ctx->next; ctx = ctx->next)
3442                         ;
3443                 ctx->next = fibctx;
3444                 fibctx->prev = ctx;
3445         }
3446
3447         /* evaluate unique value */
3448         fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
3449         ctx = sc->fibctx;
3450         while (ctx != fibctx) {
3451                 if (ctx->unique == fibctx->unique) {
3452                         fibctx->unique++;
3453                         ctx = sc->fibctx;
3454                 } else {
3455                         ctx = ctx->next;
3456                 }
3457         }
3458         mtx_unlock(&sc->aac_aifq_lock);
3459
3460         error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t));
3461         if (error)
3462                 aac_close_aif(sc, (caddr_t)ctx);
3463         return error;
3464 }
3465
3466 /*
3467  * Close the caller's fib context
3468  */
3469 static int
3470 aac_close_aif(struct aac_softc *sc, caddr_t arg)
3471 {
3472         struct aac_fib_context *ctx;
3473
3474         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3475
3476         mtx_lock(&sc->aac_aifq_lock);
3477         for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3478                 if (ctx->unique == *(uint32_t *)&arg) {
3479                         if (ctx == sc->fibctx)
3480                                 sc->fibctx = NULL;
3481                         else {
3482                                 ctx->prev->next = ctx->next;
3483                                 if (ctx->next)
3484                                         ctx->next->prev = ctx->prev;
3485                         }
3486                         break;
3487                 }
3488         }
3489         mtx_unlock(&sc->aac_aifq_lock);
3490         if (ctx)
3491                 free(ctx, M_AACBUF);
3492
3493         return 0;
3494 }
3495
3496 /*
3497  * Pass the caller the next AIF in their queue
3498  */
3499 static int
3500 aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
3501 {
3502         struct get_adapter_fib_ioctl agf;
3503         struct aac_fib_context *ctx;
3504         int error;
3505
3506         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3507
3508         if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
3509                 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3510                         if (agf.AdapterFibContext == ctx->unique)
3511                                 break;
3512                 }
3513                 if (!ctx)
3514                         return (EFAULT);
3515
3516                 error = aac_return_aif(sc, ctx, agf.AifFib);
3517                 if (error == EAGAIN && agf.Wait) {
3518                         fwprintf(sc, HBA_FLAGS_DBG_AIF_B, "aac_getnext_aif(): waiting for AIF");
3519                         sc->aac_state |= AAC_STATE_AIF_SLEEPER;
3520                         while (error == EAGAIN) {
3521                                 error = tsleep(sc->aac_aifq, PRIBIO |
3522                                                PCATCH, "aacaif", 0);
3523                                 if (error == 0)
3524                                         error = aac_return_aif(sc, ctx, agf.AifFib);
3525                         }
3526                         sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
3527                 }
3528         }
3529         return(error);
3530 }
3531
3532 /*
3533  * Hand the next AIF off the top of the queue out to userspace.
3534  */
3535 static int
3536 aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
3537 {
3538         int current, error;
3539
3540         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3541
3542         mtx_lock(&sc->aac_aifq_lock);
3543         current = ctx->ctx_idx;
3544         if (current == sc->aifq_idx && !ctx->ctx_wrap) {
3545                 /* empty */
3546                 mtx_unlock(&sc->aac_aifq_lock);
3547                 return (EAGAIN);
3548         }
3549         error =
3550                 copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
3551         if (error)
3552                 device_printf(sc->aac_dev,
3553                     "aac_return_aif: copyout returned %d\n", error);
3554         else {
3555                 ctx->ctx_wrap = 0;
3556                 ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
3557         }
3558         mtx_unlock(&sc->aac_aifq_lock);
3559         return(error);
3560 }
3561
3562 static int
3563 aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
3564 {
3565         struct aac_pci_info {
3566                 u_int32_t bus;
3567                 u_int32_t slot;
3568         } pciinf;
3569         int error;
3570
3571         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3572
3573         pciinf.bus = pci_get_bus(sc->aac_dev);
3574         pciinf.slot = pci_get_slot(sc->aac_dev);
3575
3576         error = copyout((caddr_t)&pciinf, uptr,
3577                         sizeof(struct aac_pci_info));
3578
3579         return (error);
3580 }
3581
3582 static int
3583 aac_supported_features(struct aac_softc *sc, caddr_t uptr)
3584 {
3585         struct aac_features f;
3586         int error;
3587
3588         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3589
3590         if ((error = copyin(uptr, &f, sizeof (f))) != 0)
3591                 return (error);
3592
3593         /*
3594          * When the management driver receives FSACTL_GET_FEATURES ioctl with
3595          * ALL zero in the featuresState, the driver will return the current
3596          * state of all the supported features, the data field will not be
3597          * valid.
3598          * When the management driver receives FSACTL_GET_FEATURES ioctl with
3599          * a specific bit set in the featuresState, the driver will return the
3600          * current state of this specific feature and whatever data that are
3601          * associated with the feature in the data field or perform whatever
3602          * action needed indicates in the data field.
3603          */
3604         if (f.feat.fValue == 0) {
3605                 f.feat.fBits.largeLBA =
3606                     (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3607                 /* TODO: In the future, add other features state here as well */
3608         } else {
3609                 if (f.feat.fBits.largeLBA)
3610                         f.feat.fBits.largeLBA =
3611                             (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3612                 /* TODO: Add other features state and data in the future */
3613         }
3614
3615         error = copyout(&f, uptr, sizeof (f));
3616         return (error);
3617 }
3618
3619 /*
3620  * Give the userland some information about the container.  The AAC arch
3621  * expects the driver to be a SCSI passthrough type driver, so it expects
3622  * the containers to have b:t:l numbers.  Fake it.
3623  */
3624 static int
3625 aac_query_disk(struct aac_softc *sc, caddr_t uptr)
3626 {
3627         struct aac_query_disk query_disk;
3628         struct aac_container *co;
3629         struct aac_disk *disk;
3630         int error, id;
3631
3632         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3633
3634         disk = NULL;
3635
3636         error = copyin(uptr, (caddr_t)&query_disk,
3637                        sizeof(struct aac_query_disk));
3638         if (error)
3639                 return (error);
3640
3641         id = query_disk.ContainerNumber;
3642         if (id == -1)
3643                 return (EINVAL);
3644
3645         mtx_lock(&sc->aac_container_lock);
3646         TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
3647                 if (co->co_mntobj.ObjectId == id)
3648                         break;
3649                 }
3650
3651         if (co == NULL) {
3652                         query_disk.Valid = 0;
3653                         query_disk.Locked = 0;
3654                         query_disk.Deleted = 1;         /* XXX is this right? */
3655         } else {
3656                 disk = device_get_softc(co->co_disk);
3657                 query_disk.Valid = 1;
3658                 query_disk.Locked =
3659                     (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
3660                 query_disk.Deleted = 0;
3661                 query_disk.Bus = device_get_unit(sc->aac_dev);
3662                 query_disk.Target = disk->unit;
3663                 query_disk.Lun = 0;
3664                 query_disk.UnMapped = 0;
3665                 sprintf(&query_disk.diskDeviceName[0], "%s%d",
3666                         disk->ad_disk->d_name, disk->ad_disk->d_unit);
3667         }
3668         mtx_unlock(&sc->aac_container_lock);
3669
3670         error = copyout((caddr_t)&query_disk, uptr,
3671                         sizeof(struct aac_query_disk));
3672
3673         return (error);
3674 }
3675
3676 static void
3677 aac_get_bus_info(struct aac_softc *sc)
3678 {
3679         struct aac_fib *fib;
3680         struct aac_ctcfg *c_cmd;
3681         struct aac_ctcfg_resp *c_resp;
3682         struct aac_vmioctl *vmi;
3683         struct aac_vmi_businf_resp *vmi_resp;
3684         struct aac_getbusinf businfo;
3685         struct aac_sim *caminf;
3686         device_t child;
3687         int i, found, error;
3688
3689         mtx_lock(&sc->aac_io_lock);
3690         aac_alloc_sync_fib(sc, &fib);
3691         c_cmd = (struct aac_ctcfg *)&fib->data[0];
3692         bzero(c_cmd, sizeof(struct aac_ctcfg));
3693
3694         c_cmd->Command = VM_ContainerConfig;
3695         c_cmd->cmd = CT_GET_SCSI_METHOD;
3696         c_cmd->param = 0;
3697
3698         error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3699             sizeof(struct aac_ctcfg));
3700         if (error) {
3701                 device_printf(sc->aac_dev, "Error %d sending "
3702                     "VM_ContainerConfig command\n", error);
3703                 aac_release_sync_fib(sc);
3704                 mtx_unlock(&sc->aac_io_lock);
3705                 return;
3706         }
3707
3708         c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
3709         if (c_resp->Status != ST_OK) {
3710                 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
3711                     c_resp->Status);
3712                 aac_release_sync_fib(sc);
3713                 mtx_unlock(&sc->aac_io_lock);
3714                 return;
3715         }
3716
3717         sc->scsi_method_id = c_resp->param;
3718
3719         vmi = (struct aac_vmioctl *)&fib->data[0];
3720         bzero(vmi, sizeof(struct aac_vmioctl));
3721
3722         vmi->Command = VM_Ioctl;
3723         vmi->ObjType = FT_DRIVE;
3724         vmi->MethId = sc->scsi_method_id;
3725         vmi->ObjId = 0;
3726         vmi->IoctlCmd = GetBusInfo;
3727
3728         error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3729             sizeof(struct aac_vmi_businf_resp));
3730         if (error) {
3731                 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
3732                     error);
3733                 aac_release_sync_fib(sc);
3734                 mtx_unlock(&sc->aac_io_lock);
3735                 return;
3736         }
3737
3738         vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
3739         if (vmi_resp->Status != ST_OK) {
3740                 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
3741                     vmi_resp->Status);
3742                 aac_release_sync_fib(sc);
3743                 mtx_unlock(&sc->aac_io_lock);
3744                 return;
3745         }
3746
3747         bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
3748         aac_release_sync_fib(sc);
3749         mtx_unlock(&sc->aac_io_lock);
3750
3751         found = 0;
3752         for (i = 0; i < businfo.BusCount; i++) {
3753                 if (businfo.BusValid[i] != AAC_BUS_VALID)
3754                         continue;
3755
3756                 caminf = (struct aac_sim *)malloc( sizeof(struct aac_sim),
3757                     M_AACBUF, M_NOWAIT | M_ZERO);
3758                 if (caminf == NULL) {
3759                         device_printf(sc->aac_dev,
3760                             "No memory to add passthrough bus %d\n", i);
3761                         break;
3762                 };
3763
3764                 child = device_add_child(sc->aac_dev, "aacp", -1);
3765                 if (child == NULL) {
3766                         device_printf(sc->aac_dev,
3767                             "device_add_child failed for passthrough bus %d\n",
3768                             i);
3769                         free(caminf, M_AACBUF);
3770                         break;
3771                 }
3772
3773                 caminf->TargetsPerBus = businfo.TargetsPerBus;
3774                 caminf->BusNumber = i;
3775                 caminf->InitiatorBusId = businfo.InitiatorBusId[i];
3776                 caminf->aac_sc = sc;
3777                 caminf->sim_dev = child;
3778
3779                 device_set_ivars(child, caminf);
3780                 device_set_desc(child, "SCSI Passthrough Bus");
3781                 TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
3782
3783                 found = 1;
3784         }
3785
3786         if (found)
3787                 bus_generic_attach(sc->aac_dev);
3788 }