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