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