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