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