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