kernel/disk: Remove use of "%b" format.
[dragonfly.git] / sys / dev / raid / aac / aac.c
blob80ae06675c83932b67cd23b0149365d37593bff4
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.
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.
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.
29 * $FreeBSD: head/sys/dev/aac/aac.c 260044 2013-12-29 17:37:32Z marius $
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
35 #define AAC_DRIVERNAME "aac"
37 #include "opt_aac.h"
39 /* #include <stddef.h> */
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/malloc.h>
43 #include <sys/kernel.h>
44 #include <sys/kthread.h>
45 #include <sys/poll.h>
47 #include <sys/bus.h>
48 #include <sys/conf.h>
49 #include <sys/signalvar.h>
50 #include <sys/time.h>
51 #include <sys/eventhandler.h>
52 #include <sys/rman.h>
54 #include <sys/bus_dma.h>
55 #include <sys/device.h>
56 #include <sys/mplock2.h>
58 #include <bus/pci/pcireg.h>
59 #include <bus/pci/pcivar.h>
61 #include <dev/raid/aac/aacreg.h>
62 #include <dev/raid/aac/aac_ioctl.h>
63 #include <dev/raid/aac/aacvar.h>
64 #include <dev/raid/aac/aac_tables.h>
66 static void aac_startup(void *arg);
67 static void aac_add_container(struct aac_softc *sc,
68 struct aac_mntinforesp *mir, int f);
69 static void aac_get_bus_info(struct aac_softc *sc);
70 static void aac_daemon(void *arg);
72 /* Command Processing */
73 static void aac_timeout(struct aac_softc *sc);
74 static void aac_complete(void *context, int pending);
75 static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
76 static void aac_bio_complete(struct aac_command *cm);
77 static int aac_wait_command(struct aac_command *cm);
78 static void aac_command_thread(void *arg);
80 /* Command Buffer Management */
81 static void aac_map_command_sg(void *arg, bus_dma_segment_t *segs,
82 int nseg, int error);
83 static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
84 int nseg, int error);
85 static int aac_alloc_commands(struct aac_softc *sc);
86 static void aac_free_commands(struct aac_softc *sc);
87 static void aac_unmap_command(struct aac_command *cm);
89 /* Hardware Interface */
90 static int aac_alloc(struct aac_softc *sc);
91 static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
92 int error);
93 static int aac_check_firmware(struct aac_softc *sc);
94 static int aac_init(struct aac_softc *sc);
95 static int aac_sync_command(struct aac_softc *sc, u_int32_t command,
96 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
97 u_int32_t arg3, u_int32_t *sp);
98 static int aac_setup_intr(struct aac_softc *sc);
99 static int aac_enqueue_fib(struct aac_softc *sc, int queue,
100 struct aac_command *cm);
101 static int aac_dequeue_fib(struct aac_softc *sc, int queue,
102 u_int32_t *fib_size, struct aac_fib **fib_addr);
103 static int aac_enqueue_response(struct aac_softc *sc, int queue,
104 struct aac_fib *fib);
106 /* StrongARM interface */
107 static int aac_sa_get_fwstatus(struct aac_softc *sc);
108 static void aac_sa_qnotify(struct aac_softc *sc, int qbit);
109 static int aac_sa_get_istatus(struct aac_softc *sc);
110 static void aac_sa_clear_istatus(struct aac_softc *sc, int mask);
111 static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
112 u_int32_t arg0, u_int32_t arg1,
113 u_int32_t arg2, u_int32_t arg3);
114 static int aac_sa_get_mailbox(struct aac_softc *sc, int mb);
115 static void aac_sa_set_interrupts(struct aac_softc *sc, int enable);
117 const struct aac_interface aac_sa_interface = {
118 aac_sa_get_fwstatus,
119 aac_sa_qnotify,
120 aac_sa_get_istatus,
121 aac_sa_clear_istatus,
122 aac_sa_set_mailbox,
123 aac_sa_get_mailbox,
124 aac_sa_set_interrupts,
125 NULL, NULL, NULL
128 /* i960Rx interface */
129 static int aac_rx_get_fwstatus(struct aac_softc *sc);
130 static void aac_rx_qnotify(struct aac_softc *sc, int qbit);
131 static int aac_rx_get_istatus(struct aac_softc *sc);
132 static void aac_rx_clear_istatus(struct aac_softc *sc, int mask);
133 static void aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
134 u_int32_t arg0, u_int32_t arg1,
135 u_int32_t arg2, u_int32_t arg3);
136 static int aac_rx_get_mailbox(struct aac_softc *sc, int mb);
137 static void aac_rx_set_interrupts(struct aac_softc *sc, int enable);
138 static int aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm);
139 static int aac_rx_get_outb_queue(struct aac_softc *sc);
140 static void aac_rx_set_outb_queue(struct aac_softc *sc, int index);
142 const struct aac_interface aac_rx_interface = {
143 aac_rx_get_fwstatus,
144 aac_rx_qnotify,
145 aac_rx_get_istatus,
146 aac_rx_clear_istatus,
147 aac_rx_set_mailbox,
148 aac_rx_get_mailbox,
149 aac_rx_set_interrupts,
150 aac_rx_send_command,
151 aac_rx_get_outb_queue,
152 aac_rx_set_outb_queue
155 /* Rocket/MIPS interface */
156 static int aac_rkt_get_fwstatus(struct aac_softc *sc);
157 static void aac_rkt_qnotify(struct aac_softc *sc, int qbit);
158 static int aac_rkt_get_istatus(struct aac_softc *sc);
159 static void aac_rkt_clear_istatus(struct aac_softc *sc, int mask);
160 static void aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command,
161 u_int32_t arg0, u_int32_t arg1,
162 u_int32_t arg2, u_int32_t arg3);
163 static int aac_rkt_get_mailbox(struct aac_softc *sc, int mb);
164 static void aac_rkt_set_interrupts(struct aac_softc *sc, int enable);
165 static int aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm);
166 static int aac_rkt_get_outb_queue(struct aac_softc *sc);
167 static void aac_rkt_set_outb_queue(struct aac_softc *sc, int index);
169 const struct aac_interface aac_rkt_interface = {
170 aac_rkt_get_fwstatus,
171 aac_rkt_qnotify,
172 aac_rkt_get_istatus,
173 aac_rkt_clear_istatus,
174 aac_rkt_set_mailbox,
175 aac_rkt_get_mailbox,
176 aac_rkt_set_interrupts,
177 aac_rkt_send_command,
178 aac_rkt_get_outb_queue,
179 aac_rkt_set_outb_queue
182 /* Debugging and Diagnostics */
183 static void aac_describe_controller(struct aac_softc *sc);
184 static const char *aac_describe_code(const struct aac_code_lookup *table,
185 u_int32_t code);
187 /* Management Interface */
188 static d_open_t aac_open;
189 static d_close_t aac_close;
190 static d_ioctl_t aac_ioctl;
191 static d_kqfilter_t aac_kqfilter;
192 static void aac_filter_detach(struct knote *kn);
193 static int aac_filter_read(struct knote *kn, long hint);
194 static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
195 static int aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
196 static void aac_handle_aif(struct aac_softc *sc,
197 struct aac_fib *fib);
198 static int aac_rev_check(struct aac_softc *sc, caddr_t udata);
199 static int aac_open_aif(struct aac_softc *sc, caddr_t arg);
200 static int aac_close_aif(struct aac_softc *sc, caddr_t arg);
201 static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
202 static int aac_return_aif(struct aac_softc *sc,
203 struct aac_fib_context *ctx, caddr_t uptr);
204 static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
205 static int aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
206 static int aac_supported_features(struct aac_softc *sc, caddr_t uptr);
207 static void aac_ioctl_event(struct aac_softc *sc,
208 struct aac_event *event, void *arg);
209 static struct aac_mntinforesp *
210 aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
212 static struct dev_ops aac_ops = {
213 { "aac", 0, 0 },
214 .d_open = aac_open,
215 .d_close = aac_close,
216 .d_ioctl = aac_ioctl,
217 .d_kqfilter = aac_kqfilter
220 static MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
222 /* sysctl node */
223 SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
226 * Device Interface
230 * Initialize the controller and softc
233 aac_attach(struct aac_softc *sc)
235 int error, unit;
237 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
240 * Initialize per-controller queues.
242 aac_initq_free(sc);
243 aac_initq_ready(sc);
244 aac_initq_busy(sc);
245 aac_initq_bio(sc);
248 * Initialize command-completion task.
250 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
252 /* mark controller as suspended until we get ourselves organised */
253 sc->aac_state |= AAC_STATE_SUSPEND;
256 * Check that the firmware on the card is supported.
258 if ((error = aac_check_firmware(sc)) != 0)
259 return(error);
262 * Initialize locks
264 lockinit(&sc->aac_aifq_lock, "AAC AIF lock", 0, LK_CANRECURSE);
265 lockinit(&sc->aac_io_lock, "AAC I/O lock", 0, LK_CANRECURSE);
266 lockinit(&sc->aac_container_lock, "AAC container lock", 0, LK_CANRECURSE);
267 TAILQ_INIT(&sc->aac_container_tqh);
268 TAILQ_INIT(&sc->aac_ev_cmfree);
270 /* Initialize the clock daemon callout. */
271 callout_init_mp(&sc->aac_daemontime);
274 * Initialize the adapter.
276 if ((error = aac_alloc(sc)) != 0)
277 return(error);
278 if ((error = aac_init(sc)) != 0)
279 return(error);
282 * Allocate and connect our interrupt.
284 if ((error = aac_setup_intr(sc)) != 0)
285 return(error);
288 * Print a little information about the controller.
290 aac_describe_controller(sc);
293 * Add sysctls.
295 SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->aac_dev),
296 SYSCTL_CHILDREN(device_get_sysctl_tree(sc->aac_dev)),
297 OID_AUTO, "firmware_build", CTLFLAG_RD,
298 &sc->aac_revision.buildNumber, 0,
299 "firmware build number");
302 * Register to probe our containers later.
304 sc->aac_ich.ich_func = aac_startup;
305 sc->aac_ich.ich_arg = sc;
306 sc->aac_ich.ich_desc = "aac";
307 if (config_intrhook_establish(&sc->aac_ich) != 0) {
308 device_printf(sc->aac_dev,
309 "can't establish configuration hook\n");
310 return(ENXIO);
314 * Make the control device.
316 unit = device_get_unit(sc->aac_dev);
317 sc->aac_dev_t = make_dev(&aac_ops, unit, UID_ROOT, GID_OPERATOR,
318 0640, "aac%d", unit);
319 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
320 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
321 sc->aac_dev_t->si_drv1 = sc;
323 /* Create the AIF thread */
324 if (kthread_create(aac_command_thread, sc,
325 &sc->aifthread, "aac%daif", unit))
326 panic("Could not create AIF thread");
328 /* Register the shutdown method to only be called post-dump */
329 if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
330 sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
331 device_printf(sc->aac_dev,
332 "shutdown event registration failed\n");
334 /* Register with CAM for the non-DASD devices */
335 if ((sc->flags & AAC_FLAGS_ENABLE_CAM) != 0) {
336 TAILQ_INIT(&sc->aac_sim_tqh);
337 aac_get_bus_info(sc);
340 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
341 callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc);
342 lockmgr(&sc->aac_io_lock, LK_RELEASE);
344 return(0);
347 static void
348 aac_daemon(void *arg)
350 struct timeval tv;
351 struct aac_softc *sc;
352 struct aac_fib *fib;
354 sc = arg;
355 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
357 if (callout_pending(&sc->aac_daemontime) ||
358 callout_active(&sc->aac_daemontime) == 0) {
359 lockmgr(&sc->aac_io_lock, LK_RELEASE);
360 return;
362 getmicrotime(&tv);
363 aac_alloc_sync_fib(sc, &fib);
364 *(uint32_t *)fib->data = tv.tv_sec;
365 aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t));
366 aac_release_sync_fib(sc);
367 callout_reset(&sc->aac_daemontime, 30 * 60 * hz, aac_daemon, sc);
368 lockmgr(&sc->aac_io_lock, LK_RELEASE);
371 void
372 aac_add_event(struct aac_softc *sc, struct aac_event *event)
375 switch (event->ev_type & AAC_EVENT_MASK) {
376 case AAC_EVENT_CMFREE:
377 TAILQ_INSERT_TAIL(&sc->aac_ev_cmfree, event, ev_links);
378 break;
379 default:
380 device_printf(sc->aac_dev, "aac_add event: unknown event %d\n",
381 event->ev_type);
382 break;
387 * Request information of container #cid
389 static struct aac_mntinforesp *
390 aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid)
392 struct aac_mntinfo *mi;
394 mi = (struct aac_mntinfo *)&fib->data[0];
395 /* use 64-bit LBA if enabled */
396 mi->Command = (sc->flags & AAC_FLAGS_LBA_64BIT) ?
397 VM_NameServe64 : VM_NameServe;
398 mi->MntType = FT_FILESYS;
399 mi->MntCount = cid;
401 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
402 sizeof(struct aac_mntinfo))) {
403 device_printf(sc->aac_dev, "Error probing container %d\n", cid);
404 return (NULL);
407 return ((struct aac_mntinforesp *)&fib->data[0]);
411 * Probe for containers, create disks.
413 static void
414 aac_startup(void *arg)
416 struct aac_softc *sc;
417 struct aac_fib *fib;
418 struct aac_mntinforesp *mir;
419 int count = 0, i = 0;
421 sc = (struct aac_softc *)arg;
422 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
424 /* disconnect ourselves from the intrhook chain */
425 config_intrhook_disestablish(&sc->aac_ich);
427 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
428 aac_alloc_sync_fib(sc, &fib);
430 /* loop over possible containers */
431 do {
432 if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
433 continue;
434 if (i == 0)
435 count = mir->MntRespCount;
436 aac_add_container(sc, mir, 0);
437 i++;
438 } while ((i < count) && (i < AAC_MAX_CONTAINERS));
440 aac_release_sync_fib(sc);
441 lockmgr(&sc->aac_io_lock, LK_RELEASE);
443 /* poke the bus to actually attach the child devices */
444 if (bus_generic_attach(sc->aac_dev))
445 device_printf(sc->aac_dev, "bus_generic_attach failed\n");
447 /* mark the controller up */
448 sc->aac_state &= ~AAC_STATE_SUSPEND;
450 /* enable interrupts now */
451 AAC_UNMASK_INTERRUPTS(sc);
455 * Create a device to represent a new container
457 static void
458 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
460 struct aac_container *co;
461 device_t child;
464 * Check container volume type for validity. Note that many of
465 * the possible types may never show up.
467 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
468 co = (struct aac_container *)kmalloc(sizeof *co, M_AACBUF,
469 M_INTWAIT | M_ZERO);
470 fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "id %x name '%.16s' size %u type %d",
471 mir->MntTable[0].ObjectId,
472 mir->MntTable[0].FileSystemName,
473 mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
475 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
476 device_printf(sc->aac_dev, "device_add_child failed\n");
477 else
478 device_set_ivars(child, co);
479 device_set_desc(child, aac_describe_code(aac_container_types,
480 mir->MntTable[0].VolType));
481 co->co_disk = child;
482 co->co_found = f;
483 bcopy(&mir->MntTable[0], &co->co_mntobj,
484 sizeof(struct aac_mntobj));
485 lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
486 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
487 lockmgr(&sc->aac_container_lock, LK_RELEASE);
492 * Allocate resources associated with (sc)
494 static int
495 aac_alloc(struct aac_softc *sc)
498 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
501 * Create DMA tag for mapping buffers into controller-addressable space.
503 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
504 1, 0, /* algnmnt, boundary */
505 (sc->flags & AAC_FLAGS_SG_64BIT) ?
506 BUS_SPACE_MAXADDR :
507 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
508 BUS_SPACE_MAXADDR, /* highaddr */
509 NULL, NULL, /* filter, filterarg */
510 MAXBSIZE, /* maxsize */
511 sc->aac_sg_tablesize, /* nsegments */
512 MAXBSIZE, /* maxsegsize */
513 BUS_DMA_ALLOCNOW, /* flags */
514 &sc->aac_buffer_dmat)) {
515 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
516 return (ENOMEM);
520 * Create DMA tag for mapping FIBs into controller-addressable space..
522 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
523 1, 0, /* algnmnt, boundary */
524 (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
525 BUS_SPACE_MAXADDR_32BIT :
526 0x7fffffff, /* lowaddr */
527 BUS_SPACE_MAXADDR, /* highaddr */
528 NULL, NULL, /* filter, filterarg */
529 sc->aac_max_fibs_alloc *
530 sc->aac_max_fib_size, /* maxsize */
531 1, /* nsegments */
532 sc->aac_max_fibs_alloc *
533 sc->aac_max_fib_size, /* maxsize */
534 0, /* flags */
535 &sc->aac_fib_dmat)) {
536 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
537 return (ENOMEM);
541 * Create DMA tag for the common structure and allocate it.
543 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
544 1, 0, /* algnmnt, boundary */
545 (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
546 BUS_SPACE_MAXADDR_32BIT :
547 0x7fffffff, /* lowaddr */
548 BUS_SPACE_MAXADDR, /* highaddr */
549 NULL, NULL, /* filter, filterarg */
550 8192 + sizeof(struct aac_common), /* maxsize */
551 1, /* nsegments */
552 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
553 0, /* flags */
554 &sc->aac_common_dmat)) {
555 device_printf(sc->aac_dev,
556 "can't allocate common structure DMA tag\n");
557 return (ENOMEM);
559 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
560 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
561 device_printf(sc->aac_dev, "can't allocate common structure\n");
562 return (ENOMEM);
566 * Work around a bug in the 2120 and 2200 that cannot DMA commands
567 * below address 8192 in physical memory.
568 * XXX If the padding is not needed, can it be put to use instead
569 * of ignored?
571 (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
572 sc->aac_common, 8192 + sizeof(*sc->aac_common),
573 aac_common_map, sc, 0);
575 if (sc->aac_common_busaddr < 8192) {
576 sc->aac_common = (struct aac_common *)
577 ((uint8_t *)sc->aac_common + 8192);
578 sc->aac_common_busaddr += 8192;
580 bzero(sc->aac_common, sizeof(*sc->aac_common));
582 /* Allocate some FIBs and associated command structs */
583 TAILQ_INIT(&sc->aac_fibmap_tqh);
584 sc->aac_commands = kmalloc(sc->aac_max_fibs * sizeof(struct aac_command),
585 M_AACBUF, M_WAITOK|M_ZERO);
586 while (sc->total_fibs < sc->aac_max_fibs) {
587 if (aac_alloc_commands(sc) != 0)
588 break;
590 if (sc->total_fibs == 0)
591 return (ENOMEM);
593 return (0);
597 * Free all of the resources associated with (sc)
599 * Should not be called if the controller is active.
601 void
602 aac_free(struct aac_softc *sc)
605 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
607 /* remove the control device */
608 if (sc->aac_dev_t != NULL)
609 destroy_dev(sc->aac_dev_t);
611 /* throw away any FIB buffers, discard the FIB DMA tag */
612 aac_free_commands(sc);
613 if (sc->aac_fib_dmat)
614 bus_dma_tag_destroy(sc->aac_fib_dmat);
616 kfree(sc->aac_commands, M_AACBUF);
618 /* destroy the common area */
619 if (sc->aac_common) {
620 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
621 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
622 sc->aac_common_dmamap);
624 if (sc->aac_common_dmat)
625 bus_dma_tag_destroy(sc->aac_common_dmat);
627 /* disconnect the interrupt handler */
628 if (sc->aac_intr)
629 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
630 if (sc->aac_irq != NULL) {
631 bus_release_resource(sc->aac_dev, SYS_RES_IRQ,
632 rman_get_rid(sc->aac_irq), sc->aac_irq);
633 if (sc->aac_irq_type == PCI_INTR_TYPE_MSI)
634 pci_release_msi(sc->aac_dev);
637 /* destroy data-transfer DMA tag */
638 if (sc->aac_buffer_dmat)
639 bus_dma_tag_destroy(sc->aac_buffer_dmat);
641 /* destroy the parent DMA tag */
642 if (sc->aac_parent_dmat)
643 bus_dma_tag_destroy(sc->aac_parent_dmat);
645 /* release the register window mapping */
646 if (sc->aac_regs_res0 != NULL)
647 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
648 rman_get_rid(sc->aac_regs_res0), sc->aac_regs_res0);
649 if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL)
650 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
651 rman_get_rid(sc->aac_regs_res1), sc->aac_regs_res1);
652 dev_ops_remove_minor(&aac_ops, device_get_unit(sc->aac_dev));
656 * Disconnect from the controller completely, in preparation for unload.
659 aac_detach(device_t dev)
661 struct aac_softc *sc;
662 struct aac_container *co;
663 struct aac_sim *sim;
664 int error;
666 sc = device_get_softc(dev);
667 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
669 callout_stop_sync(&sc->aac_daemontime);
671 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
672 while (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
673 sc->aifflags |= AAC_AIFFLAGS_EXIT;
674 wakeup(sc->aifthread);
675 lksleep(sc->aac_dev, &sc->aac_io_lock, 0, "aacdch", 0);
677 lockmgr(&sc->aac_io_lock, LK_RELEASE);
678 KASSERT((sc->aifflags & AAC_AIFFLAGS_RUNNING) == 0,
679 ("%s: invalid detach state", __func__));
681 /* Remove the child containers */
682 while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
683 error = device_delete_child(dev, co->co_disk);
684 if (error)
685 return (error);
686 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
687 kfree(co, M_AACBUF);
690 /* Remove the CAM SIMs */
691 while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
692 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
693 error = device_delete_child(dev, sim->sim_dev);
694 if (error)
695 return (error);
696 kfree(sim, M_AACBUF);
699 if ((error = aac_shutdown(dev)))
700 return(error);
702 EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
704 aac_free(sc);
706 lockuninit(&sc->aac_aifq_lock);
707 lockuninit(&sc->aac_io_lock);
708 lockuninit(&sc->aac_container_lock);
710 return(0);
714 * Bring the controller down to a dormant state and detach all child devices.
716 * This function is called before detach or system shutdown.
718 * Note that we can assume that the bioq on the controller is empty, as we won't
719 * allow shutdown if any device is open.
722 aac_shutdown(device_t dev)
724 struct aac_softc *sc;
725 struct aac_fib *fib;
726 struct aac_close_command *cc;
728 sc = device_get_softc(dev);
729 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
731 sc->aac_state |= AAC_STATE_SUSPEND;
734 * Send a Container shutdown followed by a HostShutdown FIB to the
735 * controller to convince it that we don't want to talk to it anymore.
736 * We've been closed and all I/O completed already
738 device_printf(sc->aac_dev, "shutting down controller...");
740 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
741 aac_alloc_sync_fib(sc, &fib);
742 cc = (struct aac_close_command *)&fib->data[0];
744 bzero(cc, sizeof(struct aac_close_command));
745 cc->Command = VM_CloseAll;
746 cc->ContainerId = 0xffffffff;
747 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
748 sizeof(struct aac_close_command)))
749 kprintf("FAILED.\n");
750 else
751 kprintf("done\n");
752 #if 0
753 else {
754 fib->data[0] = 0;
756 * XXX Issuing this command to the controller makes it shut down
757 * but also keeps it from coming back up without a reset of the
758 * PCI bus. This is not desirable if you are just unloading the
759 * driver module with the intent to reload it later.
761 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
762 fib, 1)) {
763 kprintf("FAILED.\n");
764 } else {
765 kprintf("done.\n");
768 #endif
770 AAC_MASK_INTERRUPTS(sc);
771 aac_release_sync_fib(sc);
772 lockmgr(&sc->aac_io_lock, LK_RELEASE);
774 return(0);
778 * Bring the controller to a quiescent state, ready for system suspend.
781 aac_suspend(device_t dev)
783 struct aac_softc *sc;
785 sc = device_get_softc(dev);
787 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
788 sc->aac_state |= AAC_STATE_SUSPEND;
790 AAC_MASK_INTERRUPTS(sc);
791 return(0);
795 * Bring the controller back to a state ready for operation.
798 aac_resume(device_t dev)
800 struct aac_softc *sc;
802 sc = device_get_softc(dev);
804 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
805 sc->aac_state &= ~AAC_STATE_SUSPEND;
806 AAC_UNMASK_INTERRUPTS(sc);
807 return(0);
811 * Interrupt handler for NEW_COMM interface.
813 void
814 aac_new_intr(void *arg)
816 struct aac_softc *sc;
817 u_int32_t index, fast;
818 struct aac_command *cm;
819 struct aac_fib *fib;
820 int i;
822 sc = (struct aac_softc *)arg;
824 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
825 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
826 while (1) {
827 index = AAC_GET_OUTB_QUEUE(sc);
828 if (index == 0xffffffff)
829 index = AAC_GET_OUTB_QUEUE(sc);
830 if (index == 0xffffffff)
831 break;
832 if (index & 2) {
833 if (index == 0xfffffffe) {
834 /* XXX This means that the controller wants
835 * more work. Ignore it for now.
837 continue;
839 /* AIF */
840 fib = (struct aac_fib *)kmalloc(sizeof *fib, M_AACBUF,
841 M_INTWAIT | M_ZERO);
842 index &= ~2;
843 for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
844 ((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
845 aac_handle_aif(sc, fib);
846 kfree(fib, M_AACBUF);
849 * AIF memory is owned by the adapter, so let it
850 * know that we are done with it.
852 AAC_SET_OUTB_QUEUE(sc, index);
853 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
854 } else {
855 fast = index & 1;
856 cm = sc->aac_commands + (index >> 2);
857 fib = cm->cm_fib;
858 if (fast) {
859 fib->Header.XferState |= AAC_FIBSTATE_DONEADAP;
860 *((u_int32_t *)(fib->data)) = AAC_ERROR_NORMAL;
862 aac_remove_busy(cm);
863 aac_unmap_command(cm);
864 cm->cm_flags |= AAC_CMD_COMPLETED;
866 /* is there a completion handler? */
867 if (cm->cm_complete != NULL) {
868 cm->cm_complete(cm);
869 } else {
870 /* assume that someone is sleeping on this
871 * command
873 wakeup(cm);
875 sc->flags &= ~AAC_QUEUE_FRZN;
878 /* see if we can start some more I/O */
879 if ((sc->flags & AAC_QUEUE_FRZN) == 0)
880 aac_startio(sc);
882 lockmgr(&sc->aac_io_lock, LK_RELEASE);
886 * Interrupt filter for !NEW_COMM interface.
888 void
889 aac_filter(void *arg)
891 struct aac_softc *sc;
892 u_int16_t reason;
894 sc = (struct aac_softc *)arg;
896 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
898 * Read the status register directly. This is faster than taking the
899 * driver lock and reading the queues directly. It also saves having
900 * to turn parts of the driver lock into a spin mutex, which would be
901 * ugly.
903 reason = AAC_GET_ISTATUS(sc);
904 AAC_CLEAR_ISTATUS(sc, reason);
906 /* handle completion processing */
907 if (reason & AAC_DB_RESPONSE_READY)
908 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
910 /* controller wants to talk to us */
911 if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY)) {
913 * XXX Make sure that we don't get fooled by strange messages
914 * that start with a NULL.
916 if ((reason & AAC_DB_PRINTF) &&
917 (sc->aac_common->ac_printf[0] == 0))
918 sc->aac_common->ac_printf[0] = 32;
921 * This might miss doing the actual wakeup. However, the
922 * lksleep that this is waking up has a timeout, so it will
923 * wake up eventually. AIFs and printfs are low enough
924 * priority that they can handle hanging out for a few seconds
925 * if needed.
927 wakeup(sc->aifthread);
932 * Command Processing
936 * Start as much queued I/O as possible on the controller
938 void
939 aac_startio(struct aac_softc *sc)
941 struct aac_command *cm;
942 int error;
944 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
946 for (;;) {
948 * This flag might be set if the card is out of resources.
949 * Checking it here prevents an infinite loop of deferrals.
951 if (sc->flags & AAC_QUEUE_FRZN)
952 break;
955 * Try to get a command that's been put off for lack of
956 * resources
958 cm = aac_dequeue_ready(sc);
961 * Try to build a command off the bio queue (ignore error
962 * return)
964 if (cm == NULL)
965 aac_bio_command(sc, &cm);
967 /* nothing to do? */
968 if (cm == NULL)
969 break;
971 /* don't map more than once */
972 if (cm->cm_flags & AAC_CMD_MAPPED)
973 panic("aac: command %p already mapped", cm);
976 * Set up the command to go to the controller. If there are no
977 * data buffers associated with the command then it can bypass
978 * busdma.
980 if (cm->cm_datalen != 0) {
981 error = bus_dmamap_load(sc->aac_buffer_dmat,
982 cm->cm_datamap, cm->cm_data,
983 cm->cm_datalen,
984 aac_map_command_sg, cm, 0);
985 if (error == EINPROGRESS) {
986 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "freezing queue\n");
987 sc->flags |= AAC_QUEUE_FRZN;
988 error = 0;
989 } else if (error != 0)
990 panic("aac_startio: unexpected error %d from "
991 "busdma", error);
992 } else
993 aac_map_command_sg(cm, NULL, 0, 0);
998 * Handle notification of one or more FIBs coming from the controller.
1000 static void
1001 aac_command_thread(void *arg)
1003 struct aac_softc *sc = arg;
1004 struct aac_fib *fib;
1005 u_int32_t fib_size;
1006 int size, retval;
1008 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1010 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1011 sc->aifflags = AAC_AIFFLAGS_RUNNING;
1013 while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
1015 retval = 0;
1016 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
1017 retval = lksleep(sc->aifthread, &sc->aac_io_lock, 0,
1018 "aifthd", AAC_PERIODIC_INTERVAL * hz);
1021 * First see if any FIBs need to be allocated. This needs
1022 * to be called without the driver lock because contigmalloc
1023 * can sleep.
1025 if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
1026 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1027 aac_alloc_commands(sc);
1028 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1029 sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
1030 aac_startio(sc);
1034 * While we're here, check to see if any commands are stuck.
1035 * This is pretty low-priority, so it's ok if it doesn't
1036 * always fire.
1038 if (retval == EWOULDBLOCK)
1039 aac_timeout(sc);
1041 /* Check the hardware printf message buffer */
1042 if (sc->aac_common->ac_printf[0] != 0)
1043 aac_print_printf(sc);
1045 /* Also check to see if the adapter has a command for us. */
1046 if (sc->flags & AAC_FLAGS_NEW_COMM)
1047 continue;
1048 for (;;) {
1049 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
1050 &fib_size, &fib))
1051 break;
1053 AAC_PRINT_FIB(sc, fib);
1055 switch (fib->Header.Command) {
1056 case AifRequest:
1057 aac_handle_aif(sc, fib);
1058 break;
1059 default:
1060 device_printf(sc->aac_dev, "unknown command "
1061 "from controller\n");
1062 break;
1065 if ((fib->Header.XferState == 0) ||
1066 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
1067 break;
1070 /* Return the AIF to the controller. */
1071 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
1072 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
1073 *(AAC_FSAStatus*)fib->data = ST_OK;
1075 /* XXX Compute the Size field? */
1076 size = fib->Header.Size;
1077 if (size > sizeof(struct aac_fib)) {
1078 size = sizeof(struct aac_fib);
1079 fib->Header.Size = size;
1082 * Since we did not generate this command, it
1083 * cannot go through the normal
1084 * enqueue->startio chain.
1086 aac_enqueue_response(sc,
1087 AAC_ADAP_NORM_RESP_QUEUE,
1088 fib);
1092 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
1093 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1094 wakeup(sc->aac_dev);
1098 * Process completed commands.
1100 static void
1101 aac_complete(void *context, int pending)
1103 struct aac_softc *sc;
1104 struct aac_command *cm;
1105 struct aac_fib *fib;
1106 u_int32_t fib_size;
1108 sc = (struct aac_softc *)context;
1109 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1111 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1113 /* pull completed commands off the queue */
1114 for (;;) {
1115 /* look for completed FIBs on our queue */
1116 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1117 &fib))
1118 break; /* nothing to do */
1120 /* get the command, unmap and hand off for processing */
1121 cm = sc->aac_commands + fib->Header.SenderData;
1122 if (cm == NULL) {
1123 AAC_PRINT_FIB(sc, fib);
1124 break;
1126 if ((cm->cm_flags & AAC_CMD_TIMEDOUT) != 0)
1127 device_printf(sc->aac_dev,
1128 "COMMAND %p COMPLETED AFTER %d SECONDS\n",
1129 cm, (int)(time_uptime - cm->cm_timestamp));
1131 aac_remove_busy(cm);
1133 aac_unmap_command(cm);
1134 cm->cm_flags |= AAC_CMD_COMPLETED;
1136 /* is there a completion handler? */
1137 if (cm->cm_complete != NULL) {
1138 cm->cm_complete(cm);
1139 } else {
1140 /* assume that someone is sleeping on this command */
1141 wakeup(cm);
1145 /* see if we can start some more I/O */
1146 sc->flags &= ~AAC_QUEUE_FRZN;
1147 aac_startio(sc);
1149 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1153 * Handle a bio submitted from a disk device.
1155 void
1156 aac_submit_bio(struct aac_disk *ad, struct bio *bio)
1158 struct aac_softc *sc;
1160 bio->bio_driver_info = ad;
1161 sc = ad->ad_controller;
1162 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1164 /* queue the BIO and try to get some work done */
1165 aac_enqueue_bio(sc, bio);
1166 aac_startio(sc);
1170 * Get a bio and build a command to go with it.
1172 static int
1173 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
1175 struct aac_command *cm;
1176 struct aac_fib *fib;
1177 struct aac_disk *ad;
1178 struct bio *bio;
1179 struct buf *bp;
1181 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1183 /* get the resources we will need */
1184 cm = NULL;
1185 bio = NULL;
1186 if (aac_alloc_command(sc, &cm)) /* get a command */
1187 goto fail;
1188 if ((bio = aac_dequeue_bio(sc)) == NULL)
1189 goto fail;
1191 /* fill out the command */
1192 bp = bio->bio_buf;
1193 cm->cm_data = (void *)bp->b_data;
1194 cm->cm_datalen = bp->b_bcount;
1195 cm->cm_complete = aac_bio_complete;
1196 cm->cm_private = bio;
1197 cm->cm_timestamp = time_uptime;
1199 /* build the FIB */
1200 fib = cm->cm_fib;
1201 fib->Header.Size = sizeof(struct aac_fib_header);
1202 fib->Header.XferState =
1203 AAC_FIBSTATE_HOSTOWNED |
1204 AAC_FIBSTATE_INITIALISED |
1205 AAC_FIBSTATE_EMPTY |
1206 AAC_FIBSTATE_FROMHOST |
1207 AAC_FIBSTATE_REXPECTED |
1208 AAC_FIBSTATE_NORM |
1209 AAC_FIBSTATE_ASYNC |
1210 AAC_FIBSTATE_FAST_RESPONSE;
1212 /* build the read/write request */
1213 ad = (struct aac_disk *)bio->bio_driver_info;
1215 if (sc->flags & AAC_FLAGS_RAW_IO) {
1216 struct aac_raw_io *raw;
1217 raw = (struct aac_raw_io *)&fib->data[0];
1218 fib->Header.Command = RawIo;
1219 raw->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1220 raw->ByteCount = bp->b_bcount;
1221 raw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1222 raw->BpTotal = 0;
1223 raw->BpComplete = 0;
1224 fib->Header.Size += sizeof(struct aac_raw_io);
1225 cm->cm_sgtable = (struct aac_sg_table *)&raw->SgMapRaw;
1226 if (bp->b_cmd == BUF_CMD_READ) {
1227 raw->Flags = 1;
1228 cm->cm_flags |= AAC_CMD_DATAIN;
1229 } else {
1230 raw->Flags = 0;
1231 cm->cm_flags |= AAC_CMD_DATAOUT;
1233 } else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1234 fib->Header.Command = ContainerCommand;
1235 if (bp->b_cmd == BUF_CMD_READ) {
1236 struct aac_blockread *br;
1237 br = (struct aac_blockread *)&fib->data[0];
1238 br->Command = VM_CtBlockRead;
1239 br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1240 br->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1241 br->ByteCount = bp->b_bcount;
1242 fib->Header.Size += sizeof(struct aac_blockread);
1243 cm->cm_sgtable = &br->SgMap;
1244 cm->cm_flags |= AAC_CMD_DATAIN;
1245 } else {
1246 struct aac_blockwrite *bw;
1247 bw = (struct aac_blockwrite *)&fib->data[0];
1248 bw->Command = VM_CtBlockWrite;
1249 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1250 bw->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1251 bw->ByteCount = bp->b_bcount;
1252 bw->Stable = CUNSTABLE;
1253 fib->Header.Size += sizeof(struct aac_blockwrite);
1254 cm->cm_flags |= AAC_CMD_DATAOUT;
1255 cm->cm_sgtable = &bw->SgMap;
1257 } else {
1258 fib->Header.Command = ContainerCommand64;
1259 if (bp->b_cmd == BUF_CMD_READ) {
1260 struct aac_blockread64 *br;
1261 br = (struct aac_blockread64 *)&fib->data[0];
1262 br->Command = VM_CtHostRead64;
1263 br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1264 br->SectorCount = bp->b_bcount / AAC_BLOCK_SIZE;
1265 br->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1266 br->Pad = 0;
1267 br->Flags = 0;
1268 fib->Header.Size += sizeof(struct aac_blockread64);
1269 cm->cm_flags |= AAC_CMD_DATAIN;
1270 cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
1271 } else {
1272 struct aac_blockwrite64 *bw;
1273 bw = (struct aac_blockwrite64 *)&fib->data[0];
1274 bw->Command = VM_CtHostWrite64;
1275 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1276 bw->SectorCount = bp->b_bcount / AAC_BLOCK_SIZE;
1277 bw->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1278 bw->Pad = 0;
1279 bw->Flags = 0;
1280 fib->Header.Size += sizeof(struct aac_blockwrite64);
1281 cm->cm_flags |= AAC_CMD_DATAOUT;
1282 cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
1286 *cmp = cm;
1287 return(0);
1289 fail:
1290 if (bio != NULL)
1291 aac_enqueue_bio(sc, bio);
1292 if (cm != NULL)
1293 aac_release_command(cm);
1294 return(ENOMEM);
1298 * Handle a bio-instigated command that has been completed.
1300 static void
1301 aac_bio_complete(struct aac_command *cm)
1303 struct aac_blockread_response *brr;
1304 struct aac_blockwrite_response *bwr;
1305 struct bio *bio;
1306 struct buf *bp;
1307 const char *code;
1308 AAC_FSAStatus status;
1310 /* fetch relevant status and then release the command */
1311 bio = (struct bio *)cm->cm_private;
1312 bp = bio->bio_buf;
1313 if (bp->b_cmd == BUF_CMD_READ) {
1314 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
1315 status = brr->Status;
1316 } else {
1317 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
1318 status = bwr->Status;
1320 aac_release_command(cm);
1322 /* fix up the bio based on status */
1323 if (status == ST_OK) {
1324 bp->b_resid = 0;
1325 code = NULL;
1326 } else {
1327 bp->b_error = EIO;
1328 bp->b_flags |= B_ERROR;
1330 aac_biodone(bio, code);
1334 * Submit a command to the controller, return when it completes.
1335 * XXX This is very dangerous! If the card has gone out to lunch, we could
1336 * be stuck here forever. At the same time, signals are not caught
1337 * because there is a risk that a signal could wakeup the sleep before
1338 * the card has a chance to complete the command. Since there is no way
1339 * to cancel a command that is in progress, we can't protect against the
1340 * card completing a command late and spamming the command and data
1341 * memory. So, we are held hostage until the command completes.
1343 static int
1344 aac_wait_command(struct aac_command *cm)
1346 struct aac_softc *sc;
1347 int error;
1349 sc = cm->cm_sc;
1350 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1352 /* Put the command on the ready queue and get things going */
1353 aac_enqueue_ready(cm);
1354 aac_startio(sc);
1355 error = lksleep(cm, &sc->aac_io_lock, 0, "aacwait", 0);
1356 return(error);
1360 *Command Buffer Management
1364 * Allocate a command.
1367 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1369 struct aac_command *cm;
1371 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1373 if ((cm = aac_dequeue_free(sc)) == NULL) {
1374 if (sc->total_fibs < sc->aac_max_fibs) {
1375 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1376 sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1377 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1378 wakeup(sc->aifthread);
1380 return (EBUSY);
1383 *cmp = cm;
1384 return(0);
1388 * Release a command back to the freelist.
1390 void
1391 aac_release_command(struct aac_command *cm)
1393 struct aac_event *event;
1394 struct aac_softc *sc;
1396 sc = cm->cm_sc;
1397 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1399 /* (re)initialize the command/FIB */
1400 cm->cm_sgtable = NULL;
1401 cm->cm_flags = 0;
1402 cm->cm_complete = NULL;
1403 cm->cm_private = NULL;
1404 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1405 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1406 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1407 cm->cm_fib->Header.Flags = 0;
1408 cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
1411 * These are duplicated in aac_start to cover the case where an
1412 * intermediate stage may have destroyed them. They're left
1413 * initialized here for debugging purposes only.
1415 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1416 cm->cm_fib->Header.SenderData = 0;
1418 aac_enqueue_free(cm);
1420 if ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
1421 TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
1422 event->ev_callback(sc, event, event->ev_arg);
1427 * Map helper for command/FIB allocation.
1429 static void
1430 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1432 uint64_t *fibphys;
1434 fibphys = (uint64_t *)arg;
1436 *fibphys = segs[0].ds_addr;
1440 * Allocate and initialize commands/FIBs for this adapter.
1442 static int
1443 aac_alloc_commands(struct aac_softc *sc)
1445 struct aac_command *cm;
1446 struct aac_fibmap *fm;
1447 uint64_t fibphys;
1448 int i, error;
1450 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1452 if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
1453 return (ENOMEM);
1455 fm = kmalloc(sizeof(struct aac_fibmap), M_AACBUF, M_INTWAIT | M_ZERO);
1457 /* allocate the FIBs in DMAable memory and load them */
1458 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1459 BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1460 device_printf(sc->aac_dev,
1461 "Not enough contiguous memory available.\n");
1462 kfree(fm, M_AACBUF);
1463 return (ENOMEM);
1466 /* Ignore errors since this doesn't bounce */
1467 (void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1468 sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
1469 aac_map_command_helper, &fibphys, 0);
1471 /* initialize constant fields in the command structure */
1472 bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
1473 for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
1474 cm = sc->aac_commands + sc->total_fibs;
1475 fm->aac_commands = cm;
1476 cm->cm_sc = sc;
1477 cm->cm_fib = (struct aac_fib *)
1478 ((u_int8_t *)fm->aac_fibs + i*sc->aac_max_fib_size);
1479 cm->cm_fibphys = fibphys + i*sc->aac_max_fib_size;
1480 cm->cm_index = sc->total_fibs;
1482 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1483 &cm->cm_datamap)) != 0)
1484 break;
1485 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1486 aac_release_command(cm);
1487 sc->total_fibs++;
1488 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1491 if (i > 0) {
1492 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1493 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1494 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs);
1495 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1496 return (0);
1499 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1500 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1501 kfree(fm, M_AACBUF);
1502 return (ENOMEM);
1506 * Free FIBs owned by this adapter.
1508 static void
1509 aac_free_commands(struct aac_softc *sc)
1511 struct aac_fibmap *fm;
1512 struct aac_command *cm;
1513 int i;
1515 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1517 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1519 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1521 * We check against total_fibs to handle partially
1522 * allocated blocks.
1524 for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) {
1525 cm = fm->aac_commands + i;
1526 bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1528 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1529 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1530 kfree(fm, M_AACBUF);
1535 * Command-mapping helper function - populate this command's s/g table.
1537 static void
1538 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1540 struct aac_softc *sc;
1541 struct aac_command *cm;
1542 struct aac_fib *fib;
1543 int i;
1545 cm = (struct aac_command *)arg;
1546 sc = cm->cm_sc;
1547 fib = cm->cm_fib;
1548 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1550 /* copy into the FIB */
1551 if (cm->cm_sgtable != NULL) {
1552 if (fib->Header.Command == RawIo) {
1553 struct aac_sg_tableraw *sg;
1554 sg = (struct aac_sg_tableraw *)cm->cm_sgtable;
1555 sg->SgCount = nseg;
1556 for (i = 0; i < nseg; i++) {
1557 sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr;
1558 sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len;
1559 sg->SgEntryRaw[i].Next = 0;
1560 sg->SgEntryRaw[i].Prev = 0;
1561 sg->SgEntryRaw[i].Flags = 0;
1563 /* update the FIB size for the s/g count */
1564 fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw);
1565 } else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1566 struct aac_sg_table *sg;
1567 sg = cm->cm_sgtable;
1568 sg->SgCount = nseg;
1569 for (i = 0; i < nseg; i++) {
1570 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1571 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1573 /* update the FIB size for the s/g count */
1574 fib->Header.Size += nseg*sizeof(struct aac_sg_entry);
1575 } else {
1576 struct aac_sg_table64 *sg;
1577 sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1578 sg->SgCount = nseg;
1579 for (i = 0; i < nseg; i++) {
1580 sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1581 sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1583 /* update the FIB size for the s/g count */
1584 fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1588 /* Fix up the address values in the FIB. Use the command array index
1589 * instead of a pointer since these fields are only 32 bits. Shift
1590 * the SenderFibAddress over to make room for the fast response bit
1591 * and for the AIF bit
1593 cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2);
1594 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1596 /* save a pointer to the command for speedy reverse-lookup */
1597 cm->cm_fib->Header.SenderData = cm->cm_index;
1599 if (cm->cm_flags & AAC_CMD_DATAIN)
1600 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1601 BUS_DMASYNC_PREREAD);
1602 if (cm->cm_flags & AAC_CMD_DATAOUT)
1603 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1604 BUS_DMASYNC_PREWRITE);
1605 cm->cm_flags |= AAC_CMD_MAPPED;
1607 if (sc->flags & AAC_FLAGS_NEW_COMM) {
1608 int count = 10000000L;
1609 while (AAC_SEND_COMMAND(sc, cm) != 0) {
1610 if (--count == 0) {
1611 aac_unmap_command(cm);
1612 sc->flags |= AAC_QUEUE_FRZN;
1613 aac_requeue_ready(cm);
1615 DELAY(5); /* wait 5 usec. */
1617 } else {
1618 /* Put the FIB on the outbound queue */
1619 if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1620 aac_unmap_command(cm);
1621 sc->flags |= AAC_QUEUE_FRZN;
1622 aac_requeue_ready(cm);
1628 * Unmap a command from controller-visible space.
1630 static void
1631 aac_unmap_command(struct aac_command *cm)
1633 struct aac_softc *sc;
1635 sc = cm->cm_sc;
1636 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1638 if (!(cm->cm_flags & AAC_CMD_MAPPED))
1639 return;
1641 if (cm->cm_datalen != 0) {
1642 if (cm->cm_flags & AAC_CMD_DATAIN)
1643 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1644 BUS_DMASYNC_POSTREAD);
1645 if (cm->cm_flags & AAC_CMD_DATAOUT)
1646 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1647 BUS_DMASYNC_POSTWRITE);
1649 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1651 cm->cm_flags &= ~AAC_CMD_MAPPED;
1655 * Hardware Interface
1659 * Initialize the adapter.
1661 static void
1662 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1664 struct aac_softc *sc;
1666 sc = (struct aac_softc *)arg;
1667 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1669 sc->aac_common_busaddr = segs[0].ds_addr;
1672 static int
1673 aac_check_firmware(struct aac_softc *sc)
1675 u_int32_t code, major, minor, options = 0, atu_size = 0;
1676 int rid, status;
1677 time_t then;
1679 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1681 * Wait for the adapter to come ready.
1683 then = time_uptime;
1684 do {
1685 code = AAC_GET_FWSTATUS(sc);
1686 if (code & AAC_SELF_TEST_FAILED) {
1687 device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1688 return(ENXIO);
1690 if (code & AAC_KERNEL_PANIC) {
1691 device_printf(sc->aac_dev,
1692 "FATAL: controller kernel panic");
1693 return(ENXIO);
1695 if (time_uptime > (then + AAC_BOOT_TIMEOUT)) {
1696 device_printf(sc->aac_dev,
1697 "FATAL: controller not coming ready, "
1698 "status %x\n", code);
1699 return(ENXIO);
1701 } while (!(code & AAC_UP_AND_RUNNING));
1704 * Retrieve the firmware version numbers. Dell PERC2/QC cards with
1705 * firmware version 1.x are not compatible with this driver.
1707 if (sc->flags & AAC_FLAGS_PERC2QC) {
1708 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1709 NULL)) {
1710 device_printf(sc->aac_dev,
1711 "Error reading firmware version\n");
1712 return (EIO);
1715 /* These numbers are stored as ASCII! */
1716 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1717 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1718 if (major == 1) {
1719 device_printf(sc->aac_dev,
1720 "Firmware version %d.%d is not supported.\n",
1721 major, minor);
1722 return (EINVAL);
1727 * Retrieve the capabilities/supported options word so we know what
1728 * work-arounds to enable. Some firmware revs don't support this
1729 * command.
1731 if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
1732 if (status != AAC_SRB_STS_INVALID_REQUEST) {
1733 device_printf(sc->aac_dev,
1734 "RequestAdapterInfo failed\n");
1735 return (EIO);
1737 } else {
1738 options = AAC_GET_MAILBOX(sc, 1);
1739 atu_size = AAC_GET_MAILBOX(sc, 2);
1740 sc->supported_options = options;
1742 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1743 (sc->flags & AAC_FLAGS_NO4GB) == 0)
1744 sc->flags |= AAC_FLAGS_4GB_WINDOW;
1745 if (options & AAC_SUPPORTED_NONDASD)
1746 sc->flags |= AAC_FLAGS_ENABLE_CAM;
1747 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1748 && (sizeof(bus_addr_t) > 4)) {
1749 device_printf(sc->aac_dev,
1750 "Enabling 64-bit address support\n");
1751 sc->flags |= AAC_FLAGS_SG_64BIT;
1753 if ((options & AAC_SUPPORTED_NEW_COMM)
1754 && sc->aac_if->aif_send_command)
1755 sc->flags |= AAC_FLAGS_NEW_COMM;
1756 if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
1757 sc->flags |= AAC_FLAGS_ARRAY_64BIT;
1760 /* Check for broken hardware that does a lower number of commands */
1761 sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512);
1763 /* Remap mem. resource, if required */
1764 if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
1765 atu_size > rman_get_size(sc->aac_regs_res1)) {
1766 rid = rman_get_rid(sc->aac_regs_res1);
1767 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, rid,
1768 sc->aac_regs_res1);
1769 sc->aac_regs_res1 = bus_alloc_resource(sc->aac_dev,
1770 SYS_RES_MEMORY, &rid, 0ul, ~0ul, atu_size, RF_ACTIVE);
1771 if (sc->aac_regs_res1 == NULL) {
1772 sc->aac_regs_res1 = bus_alloc_resource_any(
1773 sc->aac_dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
1774 if (sc->aac_regs_res1 == NULL) {
1775 device_printf(sc->aac_dev,
1776 "couldn't allocate register window\n");
1777 return (ENXIO);
1779 sc->flags &= ~AAC_FLAGS_NEW_COMM;
1781 sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
1782 sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
1784 if (sc->aac_hwif == AAC_HWIF_NARK) {
1785 sc->aac_regs_res0 = sc->aac_regs_res1;
1786 sc->aac_btag0 = sc->aac_btag1;
1787 sc->aac_bhandle0 = sc->aac_bhandle1;
1791 /* Read preferred settings */
1792 sc->aac_max_fib_size = sizeof(struct aac_fib);
1793 sc->aac_max_sectors = 128; /* 64KB */
1794 if (sc->flags & AAC_FLAGS_SG_64BIT)
1795 sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1796 - sizeof(struct aac_blockwrite64))
1797 / sizeof(struct aac_sg_entry64);
1798 else
1799 sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1800 - sizeof(struct aac_blockwrite))
1801 / sizeof(struct aac_sg_entry);
1803 if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
1804 options = AAC_GET_MAILBOX(sc, 1);
1805 sc->aac_max_fib_size = (options & 0xFFFF);
1806 sc->aac_max_sectors = (options >> 16) << 1;
1807 options = AAC_GET_MAILBOX(sc, 2);
1808 sc->aac_sg_tablesize = (options >> 16);
1809 options = AAC_GET_MAILBOX(sc, 3);
1810 sc->aac_max_fibs = (options & 0xFFFF);
1812 if (sc->aac_max_fib_size > PAGE_SIZE)
1813 sc->aac_max_fib_size = PAGE_SIZE;
1814 sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size;
1816 if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1817 sc->flags |= AAC_FLAGS_RAW_IO;
1818 device_printf(sc->aac_dev, "Enable Raw I/O\n");
1820 if ((sc->flags & AAC_FLAGS_RAW_IO) &&
1821 (sc->flags & AAC_FLAGS_ARRAY_64BIT)) {
1822 sc->flags |= AAC_FLAGS_LBA_64BIT;
1823 device_printf(sc->aac_dev, "Enable 64-bit array\n");
1826 return (0);
1829 static int
1830 aac_init(struct aac_softc *sc)
1832 struct aac_adapter_init *ip;
1833 u_int32_t qoffset;
1834 int error;
1836 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1839 * Fill in the init structure. This tells the adapter about the
1840 * physical location of various important shared data structures.
1842 ip = &sc->aac_common->ac_init;
1843 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1844 if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1845 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_4;
1846 sc->flags |= AAC_FLAGS_RAW_IO;
1848 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1850 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1851 offsetof(struct aac_common, ac_fibs);
1852 ip->AdapterFibsVirtualAddress = 0;
1853 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1854 ip->AdapterFibAlign = sizeof(struct aac_fib);
1856 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1857 offsetof(struct aac_common, ac_printf);
1858 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1861 * The adapter assumes that pages are 4K in size, except on some
1862 * broken firmware versions that do the page->byte conversion twice,
1863 * therefore 'assuming' that this value is in 16MB units (2^24).
1864 * Round up since the granularity is so high.
1866 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1867 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1868 ip->HostPhysMemPages =
1869 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1871 ip->HostElapsedSeconds = time_uptime; /* reset later if invalid */
1873 ip->InitFlags = 0;
1874 if (sc->flags & AAC_FLAGS_NEW_COMM) {
1875 ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED;
1876 device_printf(sc->aac_dev, "New comm. interface enabled\n");
1879 ip->MaxIoCommands = sc->aac_max_fibs;
1880 ip->MaxIoSize = sc->aac_max_sectors << 9;
1881 ip->MaxFibSize = sc->aac_max_fib_size;
1884 * Initialize FIB queues. Note that it appears that the layout of the
1885 * indexes and the segmentation of the entries may be mandated by the
1886 * adapter, which is only told about the base of the queue index fields.
1888 * The initial values of the indices are assumed to inform the adapter
1889 * of the sizes of the respective queues, and theoretically it could
1890 * work out the entire layout of the queue structures from this. We
1891 * take the easy route and just lay this area out like everyone else
1892 * does.
1894 * The Linux driver uses a much more complex scheme whereby several
1895 * header records are kept for each queue. We use a couple of generic
1896 * list manipulation functions which 'know' the size of each list by
1897 * virtue of a table.
1899 qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1900 qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1901 sc->aac_queues =
1902 (struct aac_queue_table *)((uintptr_t)sc->aac_common + qoffset);
1903 ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1905 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1906 AAC_HOST_NORM_CMD_ENTRIES;
1907 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1908 AAC_HOST_NORM_CMD_ENTRIES;
1909 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1910 AAC_HOST_HIGH_CMD_ENTRIES;
1911 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1912 AAC_HOST_HIGH_CMD_ENTRIES;
1913 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1914 AAC_ADAP_NORM_CMD_ENTRIES;
1915 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1916 AAC_ADAP_NORM_CMD_ENTRIES;
1917 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1918 AAC_ADAP_HIGH_CMD_ENTRIES;
1919 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1920 AAC_ADAP_HIGH_CMD_ENTRIES;
1921 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1922 AAC_HOST_NORM_RESP_ENTRIES;
1923 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1924 AAC_HOST_NORM_RESP_ENTRIES;
1925 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1926 AAC_HOST_HIGH_RESP_ENTRIES;
1927 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1928 AAC_HOST_HIGH_RESP_ENTRIES;
1929 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1930 AAC_ADAP_NORM_RESP_ENTRIES;
1931 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1932 AAC_ADAP_NORM_RESP_ENTRIES;
1933 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1934 AAC_ADAP_HIGH_RESP_ENTRIES;
1935 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1936 AAC_ADAP_HIGH_RESP_ENTRIES;
1937 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1938 &sc->aac_queues->qt_HostNormCmdQueue[0];
1939 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1940 &sc->aac_queues->qt_HostHighCmdQueue[0];
1941 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1942 &sc->aac_queues->qt_AdapNormCmdQueue[0];
1943 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1944 &sc->aac_queues->qt_AdapHighCmdQueue[0];
1945 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1946 &sc->aac_queues->qt_HostNormRespQueue[0];
1947 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1948 &sc->aac_queues->qt_HostHighRespQueue[0];
1949 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1950 &sc->aac_queues->qt_AdapNormRespQueue[0];
1951 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1952 &sc->aac_queues->qt_AdapHighRespQueue[0];
1955 * Do controller-type-specific initialisation
1957 switch (sc->aac_hwif) {
1958 case AAC_HWIF_I960RX:
1959 AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, ~0);
1960 break;
1961 case AAC_HWIF_RKT:
1962 AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, ~0);
1963 break;
1964 default:
1965 break;
1969 * Give the init structure to the controller.
1971 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1972 sc->aac_common_busaddr +
1973 offsetof(struct aac_common, ac_init), 0, 0, 0,
1974 NULL)) {
1975 device_printf(sc->aac_dev,
1976 "error establishing init structure\n");
1977 error = EIO;
1978 goto out;
1981 error = 0;
1982 out:
1983 return(error);
1986 static int
1987 aac_setup_intr(struct aac_softc *sc)
1990 if (sc->flags & AAC_FLAGS_NEW_COMM) {
1991 if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
1992 INTR_MPSAFE,
1993 aac_new_intr, sc, &sc->aac_intr, NULL)) {
1994 device_printf(sc->aac_dev, "can't set up interrupt\n");
1995 return (EINVAL);
1997 } else {
1998 if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
1999 0, aac_filter,
2000 sc, &sc->aac_intr, NULL)) {
2001 device_printf(sc->aac_dev,
2002 "can't set up interrupt filter\n");
2003 return (EINVAL);
2006 return (0);
2010 * Send a synchronous command to the controller and wait for a result.
2011 * Indicate if the controller completed the command with an error status.
2013 static int
2014 aac_sync_command(struct aac_softc *sc, u_int32_t command,
2015 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
2016 u_int32_t *sp)
2018 time_t then;
2019 u_int32_t status;
2021 if (sp != NULL)
2022 *sp = 0; /* avoid gcc warnings */
2023 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2025 /* populate the mailbox */
2026 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
2028 /* ensure the sync command doorbell flag is cleared */
2029 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2031 /* then set it to signal the adapter */
2032 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
2034 /* spin waiting for the command to complete */
2035 then = time_uptime;
2036 do {
2037 if (time_uptime > (then + AAC_IMMEDIATE_TIMEOUT)) {
2038 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "timed out");
2039 return(EIO);
2041 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
2043 /* clear the completion flag */
2044 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2046 /* get the command status */
2047 status = AAC_GET_MAILBOX(sc, 0);
2048 if (sp != NULL)
2049 *sp = status;
2051 if (status != AAC_SRB_STS_SUCCESS)
2052 return (-1);
2053 return(0);
2057 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
2058 struct aac_fib *fib, u_int16_t datasize)
2060 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2061 #if 0 /* XXX swildner */
2062 KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
2063 #endif
2065 if (datasize > AAC_FIB_DATASIZE)
2066 return(EINVAL);
2069 * Set up the sync FIB
2071 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
2072 AAC_FIBSTATE_INITIALISED |
2073 AAC_FIBSTATE_EMPTY;
2074 fib->Header.XferState |= xferstate;
2075 fib->Header.Command = command;
2076 fib->Header.StructType = AAC_FIBTYPE_TFIB;
2077 fib->Header.Size = sizeof(struct aac_fib_header) + datasize;
2078 fib->Header.SenderSize = sizeof(struct aac_fib);
2079 fib->Header.SenderFibAddress = 0; /* Not needed */
2080 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
2081 offsetof(struct aac_common,
2082 ac_sync_fib);
2085 * Give the FIB to the controller, wait for a response.
2087 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
2088 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
2089 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error");
2090 return(EIO);
2093 return (0);
2097 * Adapter-space FIB queue manipulation
2099 * Note that the queue implementation here is a little funky; neither the PI or
2100 * CI will ever be zero. This behaviour is a controller feature.
2102 static const struct {
2103 int size;
2104 int notify;
2105 } aac_qinfo[] = {
2106 {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
2107 {AAC_HOST_HIGH_CMD_ENTRIES, 0},
2108 {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
2109 {AAC_ADAP_HIGH_CMD_ENTRIES, 0},
2110 {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
2111 {AAC_HOST_HIGH_RESP_ENTRIES, 0},
2112 {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
2113 {AAC_ADAP_HIGH_RESP_ENTRIES, 0}
2117 * Atomically insert an entry into the nominated queue, returns 0 on success or
2118 * EBUSY if the queue is full.
2120 * Note: it would be more efficient to defer notifying the controller in
2121 * the case where we may be inserting several entries in rapid succession,
2122 * but implementing this usefully may be difficult (it would involve a
2123 * separate queue/notify interface).
2125 static int
2126 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
2128 u_int32_t pi, ci;
2129 int error;
2130 u_int32_t fib_size;
2131 u_int32_t fib_addr;
2133 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2135 fib_size = cm->cm_fib->Header.Size;
2136 fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
2138 /* get the producer/consumer indices */
2139 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2140 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2142 /* wrap the queue? */
2143 if (pi >= aac_qinfo[queue].size)
2144 pi = 0;
2146 /* check for queue full */
2147 if ((pi + 1) == ci) {
2148 error = EBUSY;
2149 goto out;
2153 * To avoid a race with its completion interrupt, place this command on
2154 * the busy queue prior to advertising it to the controller.
2156 aac_enqueue_busy(cm);
2158 /* populate queue entry */
2159 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2160 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2162 /* update producer index */
2163 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2165 /* notify the adapter if we know how */
2166 if (aac_qinfo[queue].notify != 0)
2167 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2169 error = 0;
2171 out:
2172 return(error);
2176 * Atomically remove one entry from the nominated queue, returns 0 on
2177 * success or ENOENT if the queue is empty.
2179 static int
2180 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
2181 struct aac_fib **fib_addr)
2183 u_int32_t pi, ci;
2184 u_int32_t fib_index;
2185 int error;
2186 int notify;
2188 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2190 /* get the producer/consumer indices */
2191 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2192 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2194 /* check for queue empty */
2195 if (ci == pi) {
2196 error = ENOENT;
2197 goto out;
2200 /* wrap the pi so the following test works */
2201 if (pi >= aac_qinfo[queue].size)
2202 pi = 0;
2204 notify = 0;
2205 if (ci == pi + 1)
2206 notify++;
2208 /* wrap the queue? */
2209 if (ci >= aac_qinfo[queue].size)
2210 ci = 0;
2212 /* fetch the entry */
2213 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
2215 switch (queue) {
2216 case AAC_HOST_NORM_CMD_QUEUE:
2217 case AAC_HOST_HIGH_CMD_QUEUE:
2219 * The aq_fib_addr is only 32 bits wide so it can't be counted
2220 * on to hold an address. For AIF's, the adapter assumes
2221 * that it's giving us an address into the array of AIF fibs.
2222 * Therefore, we have to convert it to an index.
2224 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
2225 sizeof(struct aac_fib);
2226 *fib_addr = &sc->aac_common->ac_fibs[fib_index];
2227 break;
2229 case AAC_HOST_NORM_RESP_QUEUE:
2230 case AAC_HOST_HIGH_RESP_QUEUE:
2232 struct aac_command *cm;
2235 * As above, an index is used instead of an actual address.
2236 * Gotta shift the index to account for the fast response
2237 * bit. No other correction is needed since this value was
2238 * originally provided by the driver via the SenderFibAddress
2239 * field.
2241 fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
2242 cm = sc->aac_commands + (fib_index >> 2);
2243 *fib_addr = cm->cm_fib;
2246 * Is this a fast response? If it is, update the fib fields in
2247 * local memory since the whole fib isn't DMA'd back up.
2249 if (fib_index & 0x01) {
2250 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
2251 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
2253 break;
2255 default:
2256 panic("Invalid queue in aac_dequeue_fib()");
2257 break;
2260 /* update consumer index */
2261 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
2263 /* if we have made the queue un-full, notify the adapter */
2264 if (notify && (aac_qinfo[queue].notify != 0))
2265 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2266 error = 0;
2268 out:
2269 return(error);
2273 * Put our response to an Adapter Initialed Fib on the response queue
2275 static int
2276 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
2278 u_int32_t pi, ci;
2279 int error;
2280 u_int32_t fib_size;
2281 u_int32_t fib_addr;
2283 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2285 /* Tell the adapter where the FIB is */
2286 fib_size = fib->Header.Size;
2287 fib_addr = fib->Header.SenderFibAddress;
2288 fib->Header.ReceiverFibAddress = fib_addr;
2290 /* get the producer/consumer indices */
2291 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2292 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2294 /* wrap the queue? */
2295 if (pi >= aac_qinfo[queue].size)
2296 pi = 0;
2298 /* check for queue full */
2299 if ((pi + 1) == ci) {
2300 error = EBUSY;
2301 goto out;
2304 /* populate queue entry */
2305 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2306 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2308 /* update producer index */
2309 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2311 /* notify the adapter if we know how */
2312 if (aac_qinfo[queue].notify != 0)
2313 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2315 error = 0;
2317 out:
2318 return(error);
2322 * Check for commands that have been outstanding for a suspiciously long time,
2323 * and complain about them.
2325 static void
2326 aac_timeout(struct aac_softc *sc)
2328 struct aac_command *cm;
2329 time_t deadline;
2330 int timedout, code;
2333 * Traverse the busy command list, bitch about late commands once
2334 * only.
2336 timedout = 0;
2337 deadline = time_uptime - AAC_CMD_TIMEOUT;
2338 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
2339 if ((cm->cm_timestamp < deadline)
2340 && !(cm->cm_flags & AAC_CMD_TIMEDOUT)) {
2341 cm->cm_flags |= AAC_CMD_TIMEDOUT;
2342 device_printf(sc->aac_dev,
2343 "COMMAND %p (TYPE %d) TIMEOUT AFTER %d SECONDS\n",
2344 cm, cm->cm_fib->Header.Command,
2345 (int)(time_uptime-cm->cm_timestamp));
2346 AAC_PRINT_FIB(sc, cm->cm_fib);
2347 timedout++;
2351 if (timedout) {
2352 code = AAC_GET_FWSTATUS(sc);
2353 if (code != AAC_UP_AND_RUNNING) {
2354 device_printf(sc->aac_dev, "WARNING! Controller is no "
2355 "longer running! code= 0x%x\n", code);
2361 * Interface Function Vectors
2365 * Read the current firmware status word.
2367 static int
2368 aac_sa_get_fwstatus(struct aac_softc *sc)
2370 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2372 return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
2375 static int
2376 aac_rx_get_fwstatus(struct aac_softc *sc)
2378 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2380 return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2381 AAC_RX_OMR0 : AAC_RX_FWSTATUS));
2384 static int
2385 aac_rkt_get_fwstatus(struct aac_softc *sc)
2387 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2389 return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2390 AAC_RKT_OMR0 : AAC_RKT_FWSTATUS));
2394 * Notify the controller of a change in a given queue
2397 static void
2398 aac_sa_qnotify(struct aac_softc *sc, int qbit)
2400 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2402 AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
2405 static void
2406 aac_rx_qnotify(struct aac_softc *sc, int qbit)
2408 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2410 AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
2413 static void
2414 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
2416 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2418 AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
2422 * Get the interrupt reason bits
2424 static int
2425 aac_sa_get_istatus(struct aac_softc *sc)
2427 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2429 return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
2432 static int
2433 aac_rx_get_istatus(struct aac_softc *sc)
2435 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2437 return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
2440 static int
2441 aac_rkt_get_istatus(struct aac_softc *sc)
2443 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2445 return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
2449 * Clear some interrupt reason bits
2451 static void
2452 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
2454 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2456 AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
2459 static void
2460 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
2462 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2464 AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
2467 static void
2468 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
2470 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2472 AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
2476 * Populate the mailbox and set the command word
2478 static void
2479 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2480 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2482 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2484 AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX, command);
2485 AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
2486 AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
2487 AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
2488 AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
2491 static void
2492 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
2493 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2495 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2497 AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX, command);
2498 AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2499 AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2500 AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2501 AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2504 static void
2505 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2506 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2508 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2510 AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX, command);
2511 AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
2512 AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
2513 AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
2514 AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
2518 * Fetch the immediate command status word
2520 static int
2521 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2523 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2525 return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2528 static int
2529 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2531 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2533 return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2536 static int
2537 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2539 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2541 return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2545 * Set/clear interrupt masks
2547 static void
2548 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2550 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2552 if (enable) {
2553 AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2554 } else {
2555 AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2559 static void
2560 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2562 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2564 if (enable) {
2565 if (sc->flags & AAC_FLAGS_NEW_COMM)
2566 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
2567 else
2568 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2569 } else {
2570 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
2574 static void
2575 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2577 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2579 if (enable) {
2580 if (sc->flags & AAC_FLAGS_NEW_COMM)
2581 AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
2582 else
2583 AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2584 } else {
2585 AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
2590 * New comm. interface: Send command functions
2592 static int
2593 aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm)
2595 u_int32_t index, device;
2597 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2599 index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2600 if (index == 0xffffffffL)
2601 index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2602 if (index == 0xffffffffL)
2603 return index;
2604 aac_enqueue_busy(cm);
2605 device = index;
2606 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2607 device += 4;
2608 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2609 device += 4;
2610 AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2611 AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
2612 return 0;
2615 static int
2616 aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
2618 u_int32_t index, device;
2620 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2622 index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2623 if (index == 0xffffffffL)
2624 index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2625 if (index == 0xffffffffL)
2626 return index;
2627 aac_enqueue_busy(cm);
2628 device = index;
2629 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2630 device += 4;
2631 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2632 device += 4;
2633 AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2634 AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
2635 return 0;
2639 * New comm. interface: get, set outbound queue index
2641 static int
2642 aac_rx_get_outb_queue(struct aac_softc *sc)
2644 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2646 return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
2649 static int
2650 aac_rkt_get_outb_queue(struct aac_softc *sc)
2652 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2654 return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
2657 static void
2658 aac_rx_set_outb_queue(struct aac_softc *sc, int index)
2660 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2662 AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
2665 static void
2666 aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
2668 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2670 AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
2674 * Debugging and Diagnostics
2678 * Print some information about the controller.
2680 static void
2681 aac_describe_controller(struct aac_softc *sc)
2683 struct aac_fib *fib;
2684 struct aac_adapter_info *info;
2685 char *adapter_type = "Adaptec RAID controller";
2687 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2689 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
2690 aac_alloc_sync_fib(sc, &fib);
2692 fib->data[0] = 0;
2693 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2694 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2695 aac_release_sync_fib(sc);
2696 lockmgr(&sc->aac_io_lock, LK_RELEASE);
2697 return;
2700 /* save the kernel revision structure for later use */
2701 info = (struct aac_adapter_info *)&fib->data[0];
2702 sc->aac_revision = info->KernelRevision;
2704 if (bootverbose) {
2705 device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
2706 "(%dMB cache, %dMB execution), %s\n",
2707 aac_describe_code(aac_cpu_variant, info->CpuVariant),
2708 info->ClockSpeed, info->TotalMem / (1024 * 1024),
2709 info->BufferMem / (1024 * 1024),
2710 info->ExecutionMem / (1024 * 1024),
2711 aac_describe_code(aac_battery_platform,
2712 info->batteryPlatform));
2714 device_printf(sc->aac_dev,
2715 "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2716 info->KernelRevision.external.comp.major,
2717 info->KernelRevision.external.comp.minor,
2718 info->KernelRevision.external.comp.dash,
2719 info->KernelRevision.buildNumber,
2720 (u_int32_t)(info->SerialNumber & 0xffffff));
2722 device_printf(sc->aac_dev, "Supported Options=%pb%i\n",
2723 "\20"
2724 "\1SNAPSHOT"
2725 "\2CLUSTERS"
2726 "\3WCACHE"
2727 "\4DATA64"
2728 "\5HOSTTIME"
2729 "\6RAID50"
2730 "\7WINDOW4GB"
2731 "\10SCSIUPGD"
2732 "\11SOFTERR"
2733 "\12NORECOND"
2734 "\13SGMAP64"
2735 "\14ALARM"
2736 "\15NONDASD"
2737 "\16SCSIMGT"
2738 "\17RAIDSCSI"
2739 "\21ADPTINFO"
2740 "\22NEWCOMM"
2741 "\23ARRAY64BIT"
2742 "\24HEATSENSOR"
2743 , sc->supported_options);
2746 if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
2747 fib->data[0] = 0;
2748 if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
2749 device_printf(sc->aac_dev,
2750 "RequestSupplementAdapterInfo failed\n");
2751 else
2752 adapter_type = ((struct aac_supplement_adapter_info *)
2753 &fib->data[0])->AdapterTypeText;
2755 device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
2756 adapter_type,
2757 AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
2758 AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
2760 aac_release_sync_fib(sc);
2761 lockmgr(&sc->aac_io_lock, LK_RELEASE);
2765 * Look up a text description of a numeric error code and return a pointer to
2766 * same.
2768 static const char *
2769 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
2771 int i;
2773 for (i = 0; table[i].string != NULL; i++)
2774 if (table[i].code == code)
2775 return(table[i].string);
2776 return(table[i + 1].string);
2780 * Management Interface
2783 static int
2784 aac_open(struct dev_open_args *ap)
2786 cdev_t dev = ap->a_head.a_dev;
2787 struct aac_softc *sc;
2789 sc = dev->si_drv1;
2790 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2791 device_busy(sc->aac_dev);
2793 return 0;
2796 static int
2797 aac_ioctl(struct dev_ioctl_args *ap)
2799 caddr_t arg = ap->a_data;
2800 cdev_t dev = ap->a_head.a_dev;
2801 u_long cmd = ap->a_cmd;
2802 union aac_statrequest *as;
2803 struct aac_softc *sc;
2804 int error = 0;
2806 as = (union aac_statrequest *)arg;
2807 sc = dev->si_drv1;
2808 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2810 switch (cmd) {
2811 case AACIO_STATS:
2812 switch (as->as_item) {
2813 case AACQ_FREE:
2814 case AACQ_BIO:
2815 case AACQ_READY:
2816 case AACQ_BUSY:
2817 bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2818 sizeof(struct aac_qstat));
2819 break;
2820 default:
2821 error = ENOENT;
2822 break;
2824 break;
2826 case FSACTL_SENDFIB:
2827 case FSACTL_SEND_LARGE_FIB:
2828 arg = *(caddr_t*)arg;
2829 case FSACTL_LNX_SENDFIB:
2830 case FSACTL_LNX_SEND_LARGE_FIB:
2831 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SENDFIB");
2832 error = aac_ioctl_sendfib(sc, arg);
2833 break;
2834 case FSACTL_SEND_RAW_SRB:
2835 arg = *(caddr_t*)arg;
2836 case FSACTL_LNX_SEND_RAW_SRB:
2837 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SEND_RAW_SRB");
2838 error = aac_ioctl_send_raw_srb(sc, arg);
2839 break;
2840 case FSACTL_AIF_THREAD:
2841 case FSACTL_LNX_AIF_THREAD:
2842 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_AIF_THREAD");
2843 error = EINVAL;
2844 break;
2845 case FSACTL_OPEN_GET_ADAPTER_FIB:
2846 arg = *(caddr_t*)arg;
2847 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2848 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_OPEN_GET_ADAPTER_FIB");
2849 error = aac_open_aif(sc, arg);
2850 break;
2851 case FSACTL_GET_NEXT_ADAPTER_FIB:
2852 arg = *(caddr_t*)arg;
2853 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2854 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_NEXT_ADAPTER_FIB");
2855 error = aac_getnext_aif(sc, arg);
2856 break;
2857 case FSACTL_CLOSE_GET_ADAPTER_FIB:
2858 arg = *(caddr_t*)arg;
2859 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2860 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2861 error = aac_close_aif(sc, arg);
2862 break;
2863 case FSACTL_MINIPORT_REV_CHECK:
2864 arg = *(caddr_t*)arg;
2865 case FSACTL_LNX_MINIPORT_REV_CHECK:
2866 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_MINIPORT_REV_CHECK");
2867 error = aac_rev_check(sc, arg);
2868 break;
2869 case FSACTL_QUERY_DISK:
2870 arg = *(caddr_t*)arg;
2871 case FSACTL_LNX_QUERY_DISK:
2872 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_QUERY_DISK");
2873 error = aac_query_disk(sc, arg);
2874 break;
2875 case FSACTL_DELETE_DISK:
2876 case FSACTL_LNX_DELETE_DISK:
2878 * We don't trust the underland to tell us when to delete a
2879 * container, rather we rely on an AIF coming from the
2880 * controller
2882 error = 0;
2883 break;
2884 case FSACTL_GET_PCI_INFO:
2885 arg = *(caddr_t*)arg;
2886 case FSACTL_LNX_GET_PCI_INFO:
2887 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_PCI_INFO");
2888 error = aac_get_pci_info(sc, arg);
2889 break;
2890 case FSACTL_GET_FEATURES:
2891 arg = *(caddr_t*)arg;
2892 case FSACTL_LNX_GET_FEATURES:
2893 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_FEATURES");
2894 error = aac_supported_features(sc, arg);
2895 break;
2896 default:
2897 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "unsupported cmd 0x%lx\n", cmd);
2898 error = EINVAL;
2899 break;
2901 return(error);
2904 static struct filterops aac_filterops =
2905 { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, aac_filter_detach, aac_filter_read };
2907 static int
2908 aac_kqfilter(struct dev_kqfilter_args *ap)
2910 cdev_t dev = ap->a_head.a_dev;
2911 struct aac_softc *sc = dev->si_drv1;
2912 struct knote *kn = ap->a_kn;
2913 struct klist *klist;
2915 ap->a_result = 0;
2917 switch (kn->kn_filter) {
2918 case EVFILT_READ:
2919 kn->kn_fop = &aac_filterops;
2920 kn->kn_hook = (caddr_t)sc;
2921 break;
2922 default:
2923 ap->a_result = EOPNOTSUPP;
2924 return (0);
2927 klist = &sc->rcv_kq.ki_note;
2928 knote_insert(klist, kn);
2930 return (0);
2933 static void
2934 aac_filter_detach(struct knote *kn)
2936 struct aac_softc *sc = (struct aac_softc *)kn->kn_hook;
2937 struct klist *klist;
2939 klist = &sc->rcv_kq.ki_note;
2940 knote_remove(klist, kn);
2943 static int
2944 aac_filter_read(struct knote *kn, long hint)
2946 struct aac_softc *sc;
2947 struct aac_fib_context *ctx;
2948 int ret = 0;
2950 sc = (struct aac_softc *)kn->kn_hook;
2952 lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
2953 for (ctx = sc->fibctx; ctx; ctx = ctx->next)
2954 if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap)
2955 ret = 1;
2956 lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
2958 return(ret);
2961 static void
2962 aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
2965 switch (event->ev_type) {
2966 case AAC_EVENT_CMFREE:
2967 KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
2968 if (aac_alloc_command(sc, (struct aac_command **)arg)) {
2969 aac_add_event(sc, event);
2970 return;
2972 kfree(event, M_AACBUF);
2973 wakeup(arg);
2974 break;
2975 default:
2976 break;
2981 * Send a FIB supplied from userspace
2983 static int
2984 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2986 struct aac_command *cm;
2987 int size, error;
2989 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2991 cm = NULL;
2994 * Get a command
2996 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
2997 if (aac_alloc_command(sc, &cm)) {
2998 struct aac_event *event;
3000 event = kmalloc(sizeof(struct aac_event), M_AACBUF,
3001 M_INTWAIT | M_ZERO);
3002 event->ev_type = AAC_EVENT_CMFREE;
3003 event->ev_callback = aac_ioctl_event;
3004 event->ev_arg = &cm;
3005 aac_add_event(sc, event);
3006 lksleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
3008 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3011 * Fetch the FIB header, then re-copy to get data as well.
3013 if ((error = copyin(ufib, cm->cm_fib,
3014 sizeof(struct aac_fib_header))) != 0)
3015 goto out;
3016 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
3017 if (size > sc->aac_max_fib_size) {
3018 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
3019 size, sc->aac_max_fib_size);
3020 size = sc->aac_max_fib_size;
3022 if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
3023 goto out;
3024 cm->cm_fib->Header.Size = size;
3025 cm->cm_timestamp = time_uptime;
3028 * Pass the FIB to the controller, wait for it to complete.
3030 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3031 error = aac_wait_command(cm);
3032 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3033 if (error != 0) {
3034 device_printf(sc->aac_dev,
3035 "aac_wait_command return %d\n", error);
3036 goto out;
3040 * Copy the FIB and data back out to the caller.
3042 size = cm->cm_fib->Header.Size;
3043 if (size > sc->aac_max_fib_size) {
3044 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
3045 size, sc->aac_max_fib_size);
3046 size = sc->aac_max_fib_size;
3048 error = copyout(cm->cm_fib, ufib, size);
3050 out:
3051 if (cm != NULL) {
3052 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3053 aac_release_command(cm);
3054 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3056 return(error);
3060 * Send a passthrough FIB supplied from userspace
3062 static int
3063 aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
3065 struct aac_command *cm;
3066 struct aac_event *event;
3067 struct aac_fib *fib;
3068 struct aac_srb *srbcmd, *user_srb;
3069 struct aac_sg_entry *sge;
3070 #ifdef __x86_64__
3071 struct aac_sg_entry64 *sge64;
3072 #endif
3073 void *srb_sg_address, *ureply;
3074 uint32_t fibsize, srb_sg_bytecount;
3075 int error, transfer_data;
3077 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3079 cm = NULL;
3080 transfer_data = 0;
3081 fibsize = 0;
3082 user_srb = (struct aac_srb *)arg;
3084 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3085 if (aac_alloc_command(sc, &cm)) {
3086 event = kmalloc(sizeof(struct aac_event), M_AACBUF,
3087 M_NOWAIT | M_ZERO);
3088 if (event == NULL) {
3089 error = EBUSY;
3090 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3091 goto out;
3093 event->ev_type = AAC_EVENT_CMFREE;
3094 event->ev_callback = aac_ioctl_event;
3095 event->ev_arg = &cm;
3096 aac_add_event(sc, event);
3097 lksleep(cm, &sc->aac_io_lock, 0, "aacraw", 0);
3099 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3101 cm->cm_data = NULL;
3102 fib = cm->cm_fib;
3103 srbcmd = (struct aac_srb *)fib->data;
3104 error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t));
3105 if (error != 0)
3106 goto out;
3107 if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) {
3108 error = EINVAL;
3109 goto out;
3111 error = copyin(user_srb, srbcmd, fibsize);
3112 if (error != 0)
3113 goto out;
3114 srbcmd->function = 0;
3115 srbcmd->retry_limit = 0;
3116 if (srbcmd->sg_map.SgCount > 1) {
3117 error = EINVAL;
3118 goto out;
3121 /* Retrieve correct SG entries. */
3122 if (fibsize == (sizeof(struct aac_srb) +
3123 srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
3124 sge = srbcmd->sg_map.SgEntry;
3125 srb_sg_bytecount = sge->SgByteCount;
3126 srb_sg_address = (void *)(uintptr_t)sge->SgAddress;
3128 #ifdef __x86_64__
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;
3141 #endif
3142 else {
3143 error = EINVAL;
3144 goto out;
3146 ureply = (char *)arg + fibsize;
3147 srbcmd->data_len = srb_sg_bytecount;
3148 if (srbcmd->sg_map.SgCount == 1)
3149 transfer_data = 1;
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;
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;
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;
3184 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3185 aac_wait_command(cm);
3186 lockmgr(&sc->aac_io_lock, LK_RELEASE);
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;
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);
3202 return(error);
3205 static int
3206 aac_close(struct dev_close_args *ap)
3208 cdev_t dev = ap->a_head.a_dev;
3209 struct aac_softc *sc;
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();
3217 return 0;
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.
3224 static void
3225 aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
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;
3235 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3237 aif = (struct aac_aif_command*)&fib->data[0];
3238 aac_print_aif(sc, aif);
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:
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.
3251 aac_alloc_sync_fib(sc, &fib);
3252 do {
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.
3260 if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
3261 continue;
3262 if (i == 0)
3263 count = mir->MntRespCount;
3265 * Check the container against our list.
3266 * co->co_found was already set to 0 in a
3267 * previous run.
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;
3283 * If the container matched, continue
3284 * in the list.
3286 if (found) {
3287 i++;
3288 continue;
3292 * This is a new container. Do all the
3293 * appropriate things to set it up.
3295 aac_add_container(sc, mir, 1);
3296 added = 1;
3298 i++;
3299 } while ((i < count) && (i < AAC_MAX_CONTAINERS));
3300 aac_release_sync_fib(sc);
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.
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);
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);
3340 break;
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;
3353 break;
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;
3363 default:
3364 break;
3367 default:
3368 break;
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;
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);
3399 * Return the Revision of the driver to userspace and check to see if the
3400 * userspace app is possibly compatible. This is extremely bogus since
3401 * our driver doesn't follow Adaptec's versioning system. Cheat by just
3402 * returning what the card reported.
3404 static int
3405 aac_rev_check(struct aac_softc *sc, caddr_t udata)
3407 struct aac_rev_check rev_check;
3408 struct aac_rev_check_resp rev_check_resp;
3409 int error = 0;
3411 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3414 * Copyin the revision struct from userspace
3416 if ((error = copyin(udata, (caddr_t)&rev_check,
3417 sizeof(struct aac_rev_check))) != 0) {
3418 return error;
3421 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "Userland revision= %d\n",
3422 rev_check.callingRevision.buildNumber);
3425 * Doctor up the response struct.
3427 rev_check_resp.possiblyCompatible = 1;
3428 rev_check_resp.adapterSWRevision.external.comp.major =
3429 AAC_DRIVER_MAJOR_VERSION;
3430 rev_check_resp.adapterSWRevision.external.comp.minor =
3431 AAC_DRIVER_MINOR_VERSION;
3432 rev_check_resp.adapterSWRevision.external.comp.type =
3433 AAC_DRIVER_TYPE;
3434 rev_check_resp.adapterSWRevision.external.comp.dash =
3435 AAC_DRIVER_BUGFIX_LEVEL;
3436 rev_check_resp.adapterSWRevision.buildNumber =
3437 AAC_DRIVER_BUILD;
3439 return(copyout((caddr_t)&rev_check_resp, udata,
3440 sizeof(struct aac_rev_check_resp)));
3444 * Pass the fib context to the caller
3446 static int
3447 aac_open_aif(struct aac_softc *sc, caddr_t arg)
3449 struct aac_fib_context *fibctx, *ctx;
3450 int error = 0;
3452 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3454 fibctx = kmalloc(sizeof(struct aac_fib_context), M_AACBUF, M_NOWAIT|M_ZERO);
3455 if (fibctx == NULL)
3456 return (ENOMEM);
3458 lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3459 /* all elements are already 0, add to queue */
3460 if (sc->fibctx == NULL)
3461 sc->fibctx = fibctx;
3462 else {
3463 for (ctx = sc->fibctx; ctx->next; ctx = ctx->next)
3465 ctx->next = fibctx;
3466 fibctx->prev = ctx;
3469 /* evaluate unique value */
3470 fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
3471 ctx = sc->fibctx;
3472 while (ctx != fibctx) {
3473 if (ctx->unique == fibctx->unique) {
3474 fibctx->unique++;
3475 ctx = sc->fibctx;
3476 } else {
3477 ctx = ctx->next;
3480 lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3482 error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t));
3483 if (error)
3484 aac_close_aif(sc, (caddr_t)ctx);
3485 return error;
3489 * Close the caller's fib context
3491 static int
3492 aac_close_aif(struct aac_softc *sc, caddr_t arg)
3494 struct aac_fib_context *ctx;
3496 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3498 lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3499 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3500 if (ctx->unique == *(uint32_t *)&arg) {
3501 if (ctx == sc->fibctx)
3502 sc->fibctx = NULL;
3503 else {
3504 ctx->prev->next = ctx->next;
3505 if (ctx->next)
3506 ctx->next->prev = ctx->prev;
3508 break;
3511 lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3512 if (ctx)
3513 kfree(ctx, M_AACBUF);
3515 return 0;
3519 * Pass the caller the next AIF in their queue
3521 static int
3522 aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
3524 struct get_adapter_fib_ioctl agf;
3525 struct aac_fib_context *ctx;
3526 int error;
3528 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3530 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
3531 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3532 if (agf.AdapterFibContext == ctx->unique)
3533 break;
3535 if (!ctx)
3536 return (EFAULT);
3538 error = aac_return_aif(sc, ctx, agf.AifFib);
3539 if (error == EAGAIN && agf.Wait) {
3540 fwprintf(sc, HBA_FLAGS_DBG_AIF_B, "aac_getnext_aif(): waiting for AIF");
3541 sc->aac_state |= AAC_STATE_AIF_SLEEPER;
3542 while (error == EAGAIN) {
3543 error = tsleep(sc->aac_aifq,
3544 PCATCH, "aacaif", 0);
3545 if (error == 0)
3546 error = aac_return_aif(sc, ctx, agf.AifFib);
3548 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
3551 return(error);
3555 * Hand the next AIF off the top of the queue out to userspace.
3557 static int
3558 aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
3560 int current, error;
3562 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3564 lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3565 current = ctx->ctx_idx;
3566 if (current == sc->aifq_idx && !ctx->ctx_wrap) {
3567 /* empty */
3568 lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3569 return (EAGAIN);
3571 error =
3572 copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
3573 if (error)
3574 device_printf(sc->aac_dev,
3575 "aac_return_aif: copyout returned %d\n", error);
3576 else {
3577 ctx->ctx_wrap = 0;
3578 ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
3580 lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3581 return(error);
3584 static int
3585 aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
3587 struct aac_pci_info {
3588 u_int32_t bus;
3589 u_int32_t slot;
3590 } pciinf;
3591 int error;
3593 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3595 pciinf.bus = pci_get_bus(sc->aac_dev);
3596 pciinf.slot = pci_get_slot(sc->aac_dev);
3598 error = copyout((caddr_t)&pciinf, uptr,
3599 sizeof(struct aac_pci_info));
3601 return (error);
3604 static int
3605 aac_supported_features(struct aac_softc *sc, caddr_t uptr)
3607 struct aac_features f;
3608 int error;
3610 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3612 if ((error = copyin(uptr, &f, sizeof (f))) != 0)
3613 return (error);
3616 * When the management driver receives FSACTL_GET_FEATURES ioctl with
3617 * ALL zero in the featuresState, the driver will return the current
3618 * state of all the supported features, the data field will not be
3619 * valid.
3620 * When the management driver receives FSACTL_GET_FEATURES ioctl with
3621 * a specific bit set in the featuresState, the driver will return the
3622 * current state of this specific feature and whatever data that are
3623 * associated with the feature in the data field or perform whatever
3624 * action needed indicates in the data field.
3626 if (f.feat.fValue == 0) {
3627 f.feat.fBits.largeLBA =
3628 (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3629 /* TODO: In the future, add other features state here as well */
3630 } else {
3631 if (f.feat.fBits.largeLBA)
3632 f.feat.fBits.largeLBA =
3633 (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3634 /* TODO: Add other features state and data in the future */
3637 error = copyout(&f, uptr, sizeof (f));
3638 return (error);
3642 * Give the userland some information about the container. The AAC arch
3643 * expects the driver to be a SCSI passthrough type driver, so it expects
3644 * the containers to have b:t:l numbers. Fake it.
3646 static int
3647 aac_query_disk(struct aac_softc *sc, caddr_t uptr)
3649 struct aac_query_disk query_disk;
3650 struct aac_container *co;
3651 struct aac_disk *disk;
3652 int error, id;
3654 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3656 disk = NULL;
3658 error = copyin(uptr, (caddr_t)&query_disk,
3659 sizeof(struct aac_query_disk));
3660 if (error)
3661 return (error);
3663 id = query_disk.ContainerNumber;
3664 if (id == -1)
3665 return (EINVAL);
3667 lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
3668 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
3669 if (co->co_mntobj.ObjectId == id)
3670 break;
3673 if (co == NULL) {
3674 query_disk.Valid = 0;
3675 query_disk.Locked = 0;
3676 query_disk.Deleted = 1; /* XXX is this right? */
3677 } else {
3678 disk = device_get_softc(co->co_disk);
3679 query_disk.Valid = 1;
3680 query_disk.Locked =
3681 (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
3682 query_disk.Deleted = 0;
3683 query_disk.Bus = device_get_unit(sc->aac_dev);
3684 query_disk.Target = disk->unit;
3685 query_disk.Lun = 0;
3686 query_disk.UnMapped = 0;
3687 bcopy(disk->ad_dev_t->si_name,
3688 &query_disk.diskDeviceName[0], 10);
3690 lockmgr(&sc->aac_container_lock, LK_RELEASE);
3692 error = copyout((caddr_t)&query_disk, uptr,
3693 sizeof(struct aac_query_disk));
3695 return (error);
3698 static void
3699 aac_get_bus_info(struct aac_softc *sc)
3701 struct aac_fib *fib;
3702 struct aac_ctcfg *c_cmd;
3703 struct aac_ctcfg_resp *c_resp;
3704 struct aac_vmioctl *vmi;
3705 struct aac_vmi_businf_resp *vmi_resp;
3706 struct aac_getbusinf businfo;
3707 struct aac_sim *caminf;
3708 device_t child;
3709 int i, found, error;
3711 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3712 aac_alloc_sync_fib(sc, &fib);
3713 c_cmd = (struct aac_ctcfg *)&fib->data[0];
3714 bzero(c_cmd, sizeof(struct aac_ctcfg));
3716 c_cmd->Command = VM_ContainerConfig;
3717 c_cmd->cmd = CT_GET_SCSI_METHOD;
3718 c_cmd->param = 0;
3720 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3721 sizeof(struct aac_ctcfg));
3722 if (error) {
3723 device_printf(sc->aac_dev, "Error %d sending "
3724 "VM_ContainerConfig command\n", error);
3725 aac_release_sync_fib(sc);
3726 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3727 return;
3730 c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
3731 if (c_resp->Status != ST_OK) {
3732 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
3733 c_resp->Status);
3734 aac_release_sync_fib(sc);
3735 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3736 return;
3739 sc->scsi_method_id = c_resp->param;
3741 vmi = (struct aac_vmioctl *)&fib->data[0];
3742 bzero(vmi, sizeof(struct aac_vmioctl));
3744 vmi->Command = VM_Ioctl;
3745 vmi->ObjType = FT_DRIVE;
3746 vmi->MethId = sc->scsi_method_id;
3747 vmi->ObjId = 0;
3748 vmi->IoctlCmd = GetBusInfo;
3750 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3751 sizeof(struct aac_vmi_businf_resp));
3752 if (error) {
3753 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
3754 error);
3755 aac_release_sync_fib(sc);
3756 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3757 return;
3760 vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
3761 if (vmi_resp->Status != ST_OK) {
3762 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
3763 vmi_resp->Status);
3764 aac_release_sync_fib(sc);
3765 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3766 return;
3769 bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
3770 aac_release_sync_fib(sc);
3771 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3773 found = 0;
3774 for (i = 0; i < businfo.BusCount; i++) {
3775 if (businfo.BusValid[i] != AAC_BUS_VALID)
3776 continue;
3778 caminf = (struct aac_sim *)kmalloc(sizeof(struct aac_sim),
3779 M_AACBUF, M_INTWAIT | M_ZERO);
3781 child = device_add_child(sc->aac_dev, "aacp", -1);
3782 if (child == NULL) {
3783 device_printf(sc->aac_dev,
3784 "device_add_child failed for passthrough bus %d\n",
3786 kfree(caminf, M_AACBUF);
3787 break;
3790 caminf->TargetsPerBus = businfo.TargetsPerBus;
3791 caminf->BusNumber = i;
3792 caminf->InitiatorBusId = businfo.InitiatorBusId[i];
3793 caminf->aac_sc = sc;
3794 caminf->sim_dev = child;
3796 device_set_ivars(child, caminf);
3797 device_set_desc(child, "SCSI Passthrough Bus");
3798 TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
3800 found = 1;
3803 if (found)
3804 bus_generic_attach(sc->aac_dev);