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