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