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