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