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