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