kernel: Add descriptions to the intrhooks that miss them.
[dragonfly.git] / sys / dev / raid / aac / aac.c
... / ...
CommitLineData
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: src/sys/dev/aac/aac.c,v 1.165 2010/09/29 14:22:00 emaste Exp $
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35#define AAC_DRIVERNAME "aac"
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>
46#include <sys/poll.h>
47
48#include <sys/bus.h>
49#include <sys/conf.h>
50#include <sys/signalvar.h>
51#include <sys/time.h>
52#include <sys/eventhandler.h>
53#include <sys/rman.h>
54
55#include <sys/bus_dma.h>
56#include <sys/device.h>
57#include <sys/mplock2.h>
58
59#include <bus/pci/pcireg.h>
60#include <bus/pci/pcivar.h>
61
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>
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);
71static void aac_daemon(void *arg);
72
73/* Command Processing */
74static void aac_timeout(struct aac_softc *sc);
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);
78static int aac_wait_command(struct aac_command *cm);
79static void aac_command_thread(void *arg);
80
81/* Command Buffer Management */
82static void aac_map_command_sg(void *arg, bus_dma_segment_t *segs,
83 int nseg, int error);
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);
88static void aac_unmap_command(struct aac_command *cm);
89
90/* Hardware Interface */
91static int aac_alloc(struct aac_softc *sc);
92static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
93 int error);
94static int aac_check_firmware(struct aac_softc *sc);
95static int aac_init(struct aac_softc *sc);
96static int aac_sync_command(struct aac_softc *sc, u_int32_t command,
97 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
98 u_int32_t arg3, u_int32_t *sp);
99static int aac_setup_intr(struct aac_softc *sc);
100static int aac_enqueue_fib(struct aac_softc *sc, int queue,
101 struct aac_command *cm);
102static int aac_dequeue_fib(struct aac_softc *sc, int queue,
103 u_int32_t *fib_size, struct aac_fib **fib_addr);
104static int aac_enqueue_response(struct aac_softc *sc, int queue,
105 struct aac_fib *fib);
106
107/* 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,
125 aac_sa_set_interrupts,
126 NULL, NULL, NULL
127};
128
129/* i960Rx interface */
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);
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);
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,
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
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;
192static d_kqfilter_t aac_kqfilter;
193static void aac_filter_detach(struct knote *kn);
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);
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);
200static int aac_open_aif(struct aac_softc *sc, caddr_t arg);
201static int aac_close_aif(struct aac_softc *sc, caddr_t arg);
202static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
203static int aac_return_aif(struct aac_softc *sc,
204 struct aac_fib_context *ctx, caddr_t uptr);
205static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
206static int aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
207static int aac_supported_features(struct aac_softc *sc, caddr_t uptr);
208static void aac_ioctl_event(struct aac_softc *sc,
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
213static struct dev_ops aac_ops = {
214 { "aac", 0, 0 },
215 .d_open = aac_open,
216 .d_close = aac_close,
217 .d_ioctl = aac_ioctl,
218 .d_kqfilter = aac_kqfilter
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/*
231 * Initialize the controller and softc
232 */
233int
234aac_attach(struct aac_softc *sc)
235{
236 int error, unit;
237
238 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
239
240 /*
241 * Initialize per-controller queues.
242 */
243 aac_initq_free(sc);
244 aac_initq_ready(sc);
245 aac_initq_busy(sc);
246 aac_initq_bio(sc);
247
248 /*
249 * Initialize command-completion task.
250 */
251 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
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
262 /*
263 * Initialize locks
264 */
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);
268 TAILQ_INIT(&sc->aac_container_tqh);
269 TAILQ_INIT(&sc->aac_ev_cmfree);
270
271 /* Initialize the clock daemon callout. */
272 callout_init(&sc->aac_daemontime);
273
274 /*
275 * Initialize the adapter.
276 */
277 if ((error = aac_alloc(sc)) != 0)
278 return(error);
279 if ((error = aac_init(sc)) != 0)
280 return(error);
281
282 /*
283 * Allocate and connect our interrupt.
284 */
285 if ((error = aac_setup_intr(sc)) != 0)
286 return(error);
287
288 /*
289 * Print a little information about the controller.
290 */
291 aac_describe_controller(sc);
292
293 /*
294 * Register to probe our containers later.
295 */
296 sc->aac_ich.ich_func = aac_startup;
297 sc->aac_ich.ich_arg = sc;
298 sc->aac_ich.ich_desc = "aac";
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);
309 sc->aac_dev_t = make_dev(&aac_ops, unit, UID_ROOT, GID_OPERATOR,
310 0640, "aac%d", unit);
311 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
312 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
313 sc->aac_dev_t->si_drv1 = sc;
314
315 /* Create the AIF thread */
316 if (kthread_create(aac_command_thread, sc,
317 &sc->aifthread, "aac%daif", unit))
318 panic("Could not create AIF thread");
319
320 /* Register the shutdown method to only be called post-dump */
321 if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
322 sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
323 device_printf(sc->aac_dev,
324 "shutdown event registration failed\n");
325
326 /* Register with CAM for the non-DASD devices */
327 if ((sc->flags & AAC_FLAGS_ENABLE_CAM) != 0) {
328 TAILQ_INIT(&sc->aac_sim_tqh);
329 aac_get_bus_info(sc);
330 }
331
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
336 return(0);
337}
338
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
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
378/*
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/*
403 * Probe for containers, create disks.
404 */
405static void
406aac_startup(void *arg)
407{
408 struct aac_softc *sc;
409 struct aac_fib *fib;
410 struct aac_mntinforesp *mir;
411 int count = 0, i = 0;
412
413 sc = (struct aac_softc *)arg;
414 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
415
416 /* disconnect ourselves from the intrhook chain */
417 config_intrhook_disestablish(&sc->aac_ich);
418
419 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
420 aac_alloc_sync_fib(sc, &fib);
421
422 /* loop over possible containers */
423 do {
424 if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
425 continue;
426 if (i == 0)
427 count = mir->MntRespCount;
428 aac_add_container(sc, mir, 0);
429 i++;
430 } while ((i < count) && (i < AAC_MAX_CONTAINERS));
431
432 aac_release_sync_fib(sc);
433 lockmgr(&sc->aac_io_lock, LK_RELEASE);
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);
444}
445
446/*
447 * Create a device to represent a new container
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
455 /*
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)) {
460 co = (struct aac_container *)kmalloc(sizeof *co, M_AACBUF,
461 M_INTWAIT | M_ZERO);
462 fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "id %x name '%.16s' size %u type %d",
463 mir->MntTable[0].ObjectId,
464 mir->MntTable[0].FileSystemName,
465 mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
466
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));
477 lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
478 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
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);
530 }
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);
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{
596
597 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
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 */
604 aac_free_commands(sc);
605 if (sc->aac_fib_dmat)
606 bus_dma_tag_destroy(sc->aac_fib_dmat);
607
608 kfree(sc->aac_commands, M_AACBUF);
609
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 */
635 if (sc->aac_regs_res0 != NULL)
636 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
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);
641 dev_ops_remove_minor(&aac_ops, device_get_unit(sc->aac_dev));
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;
651 struct aac_container *co;
652 struct aac_sim *sim;
653 int error;
654
655 sc = device_get_softc(dev);
656 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
657
658 callout_stop(&sc->aac_daemontime);
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 }
677
678 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
679 sc->aifflags |= AAC_AIFFLAGS_EXIT;
680 wakeup(sc->aifthread);
681 tsleep(sc->aac_dev, PCATCH, "aacdch", 30 * hz);
682 }
683
684 if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
685 panic("Cannot shutdown AIF thread");
686
687 if ((error = aac_shutdown(dev)))
688 return(error);
689
690 EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
691
692 aac_free(sc);
693
694 lockuninit(&sc->aac_aifq_lock);
695 lockuninit(&sc->aac_io_lock);
696 lockuninit(&sc->aac_container_lock);
697
698 return(0);
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 */
709int
710aac_shutdown(device_t dev)
711{
712 struct aac_softc *sc;
713 struct aac_fib *fib;
714 struct aac_close_command *cc;
715
716 sc = device_get_softc(dev);
717 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
718
719 sc->aac_state |= AAC_STATE_SUSPEND;
720
721 /*
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
728 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
729 aac_alloc_sync_fib(sc, &fib);
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)))
737 kprintf("FAILED.\n");
738 else
739 kprintf("done\n");
740#if 0
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)) {
751 kprintf("FAILED.\n");
752 } else {
753 kprintf("done.\n");
754 }
755 }
756#endif
757
758 AAC_MASK_INTERRUPTS(sc);
759 aac_release_sync_fib(sc);
760 lockmgr(&sc->aac_io_lock, LK_RELEASE);
761
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;
772
773 sc = device_get_softc(dev);
774
775 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
776 sc->aac_state |= AAC_STATE_SUSPEND;
777
778 AAC_MASK_INTERRUPTS(sc);
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
790 sc = device_get_softc(dev);
791
792 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
793 sc->aac_state &= ~AAC_STATE_SUSPEND;
794 AAC_UNMASK_INTERRUPTS(sc);
795 return(0);
796}
797
798/*
799 * Interrupt handler for NEW_COMM interface.
800 */
801void
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
810 sc = (struct aac_softc *)arg;
811
812 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
813 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
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)
832 ((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
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
870 lockmgr(&sc->aac_io_lock, LK_RELEASE);
871}
872
873/*
874 * Interrupt filter for !NEW_COMM interface.
875 */
876void
877aac_filter(void *arg)
878{
879 struct aac_softc *sc;
880 u_int16_t reason;
881
882 sc = (struct aac_softc *)arg;
883
884 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
885 /*
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.
890 */
891 reason = AAC_GET_ISTATUS(sc);
892 AAC_CLEAR_ISTATUS(sc, reason);
893
894 /* handle completion processing */
895 if (reason & AAC_DB_RESPONSE_READY)
896 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
897
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;
907
908 /*
909 * This might miss doing the actual wakeup. However, the
910 * lksleep that this is waking up has a timeout, so it will
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);
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;
930 int error;
931
932 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
933
934 for (;;) {
935 /*
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 /*
943 * Try to get a command that's been put off for lack of
944 * resources
945 */
946 cm = aac_dequeue_ready(sc);
947
948 /*
949 * Try to build a command off the bio queue (ignore error
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
959 /* don't map more than once */
960 if (cm->cm_flags & AAC_CMD_MAPPED)
961 panic("aac: command %p already mapped", cm);
962
963 /*
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.
967 */
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);
982 }
983}
984
985/*
986 * Handle notification of one or more FIBs coming from the controller.
987 */
988static void
989aac_command_thread(void *arg)
990{
991 struct aac_softc *sc = arg;
992 struct aac_fib *fib;
993 u_int32_t fib_size;
994 int size, retval;
995
996 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
997
998 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
999 sc->aifflags = AAC_AIFFLAGS_RUNNING;
1000
1001 while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
1002
1003 retval = 0;
1004 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
1005 retval = lksleep(sc->aifthread, &sc->aac_io_lock, 0,
1006 "aifthd", AAC_PERIODIC_INTERVAL * hz);
1007
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) {
1014 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1015 aac_alloc_commands(sc);
1016 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1017 sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
1018 aac_startio(sc);
1019 }
1020
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;
1036 for (;;) {
1037 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
1038 &fib_size, &fib))
1039 break;
1040
1041 AAC_PRINT_FIB(sc, fib);
1042
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
1053 if ((fib->Header.XferState == 0) ||
1054 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
1055 break;
1056 }
1057
1058 /* Return the AIF to the controller. */
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,
1075 AAC_ADAP_NORM_RESP_QUEUE,
1076 fib);
1077 }
1078 }
1079 }
1080 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
1081 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1082 wakeup(sc->aac_dev);
1083}
1084
1085/*
1086 * Process completed commands.
1087 */
1088static void
1089aac_complete(void *context, int pending)
1090{
1091 struct aac_softc *sc;
1092 struct aac_command *cm;
1093 struct aac_fib *fib;
1094 u_int32_t fib_size;
1095
1096 sc = (struct aac_softc *)context;
1097 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1098
1099 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1100
1101 /* pull completed commands off the queue */
1102 for (;;) {
1103 /* look for completed FIBs on our queue */
1104 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1105 &fib))
1106 break; /* nothing to do */
1107
1108 /* get the command, unmap and hand off for processing */
1109 cm = sc->aac_commands + fib->Header.SenderData;
1110 if (cm == NULL) {
1111 AAC_PRINT_FIB(sc, fib);
1112 break;
1113 }
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
1119 aac_remove_busy(cm);
1120
1121 aac_unmap_command(cm);
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 */
1134 sc->flags &= ~AAC_QUEUE_FRZN;
1135 aac_startio(sc);
1136
1137 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1138}
1139
1140/*
1141 * Handle a bio submitted from a disk device.
1142 */
1143void
1144aac_submit_bio(struct aac_disk *ad, struct bio *bio)
1145{
1146 struct aac_softc *sc;
1147
1148 bio->bio_driver_info = ad;
1149 sc = ad->ad_controller;
1150 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1151
1152 /* queue the BIO and try to get some work done */
1153 aac_enqueue_bio(sc, bio);
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;
1165 struct aac_disk *ad;
1166 struct bio *bio;
1167 struct buf *bp;
1168
1169 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1170
1171 /* get the resources we will need */
1172 cm = NULL;
1173 bio = NULL;
1174 if (aac_alloc_command(sc, &cm)) /* get a command */
1175 goto fail;
1176 if ((bio = aac_dequeue_bio(sc)) == NULL)
1177 goto fail;
1178
1179 /* fill out the command */
1180 bp = bio->bio_buf;
1181 cm->cm_data = (void *)bp->b_data;
1182 cm->cm_datalen = bp->b_bcount;
1183 cm->cm_complete = aac_bio_complete;
1184 cm->cm_private = bio;
1185 cm->cm_timestamp = time_second;
1186
1187 /* build the FIB */
1188 fib = cm->cm_fib;
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 |
1194 AAC_FIBSTATE_FROMHOST |
1195 AAC_FIBSTATE_REXPECTED |
1196 AAC_FIBSTATE_NORM |
1197 AAC_FIBSTATE_ASYNC |
1198 AAC_FIBSTATE_FAST_RESPONSE;
1199
1200 /* build the read/write request */
1201 ad = (struct aac_disk *)bio->bio_driver_info;
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 }
1245 } else {
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);
1257 cm->cm_flags |= AAC_CMD_DATAIN;
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);
1269 cm->cm_flags |= AAC_CMD_DATAOUT;
1270 cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
1271 }
1272 }
1273
1274 *cmp = cm;
1275 return(0);
1276
1277fail:
1278 if (bio != NULL)
1279 aac_enqueue_bio(sc, bio);
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;
1293 struct bio *bio;
1294 struct buf *bp;
1295 const char *code;
1296 AAC_FSAStatus status;
1297
1298 /* fetch relevant status and then release the command */
1299 bio = (struct bio *)cm->cm_private;
1300 bp = bio->bio_buf;
1301 if (bp->b_cmd == BUF_CMD_READ) {
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) {
1312 bp->b_resid = 0;
1313 code = NULL;
1314 } else {
1315 bp->b_error = EIO;
1316 bp->b_flags |= B_ERROR;
1317 /* pass an error string out to the disk layer */
1318 code = aac_describe_code(aac_command_status_table, status);
1319 }
1320 aac_biodone(bio, code);
1321}
1322
1323/*
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
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.
1332 */
1333static int
1334aac_wait_command(struct aac_command *cm)
1335{
1336 struct aac_softc *sc;
1337 int error;
1338
1339 sc = cm->cm_sc;
1340 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1341
1342 /* Put the command on the ready queue and get things going */
1343 aac_enqueue_ready(cm);
1344 aac_startio(sc);
1345 error = lksleep(cm, &sc->aac_io_lock, 0, "aacwait", 0);
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
1361 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1362
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 }
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{
1381 struct aac_event *event;
1382 struct aac_softc *sc;
1383
1384 sc = cm->cm_sc;
1385 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1386
1387 /* (re)initialize the command/FIB */
1388 cm->cm_sgtable = NULL;
1389 cm->cm_flags = 0;
1390 cm->cm_complete = NULL;
1391 cm->cm_private = NULL;
1392 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
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;
1396 cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
1397
1398 /*
1399 * These are duplicated in aac_start to cover the case where an
1400 * intermediate stage may have destroyed them. They're left
1401 * initialized here for debugging purposes only.
1402 */
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);
1407
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) {
1413 TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
1414 event->ev_callback(sc, event, event->ev_arg);
1415 }
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{
1424 uint64_t *fibphys;
1425
1426 fibphys = (uint64_t *)arg;
1427
1428 *fibphys = segs[0].ds_addr;
1429}
1430
1431/*
1432 * Allocate and initialize commands/FIBs for this adapter.
1433 */
1434static int
1435aac_alloc_commands(struct aac_softc *sc)
1436{
1437 struct aac_command *cm;
1438 struct aac_fibmap *fm;
1439 uint64_t fibphys;
1440 int i, error;
1441
1442 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
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);
1448
1449 /* allocate the FIBs in DMAable memory and load them */
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);
1456 }
1457
1458 /* Ignore errors since this doesn't bounce */
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);
1462
1463 /* initialize constant fields in the command structure */
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;
1468 cm->cm_sc = sc;
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;
1473
1474 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1475 &cm->cm_datamap)) != 0)
1476 break;
1477 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1478 aac_release_command(cm);
1479 sc->total_fibs++;
1480 lockmgr(&sc->aac_io_lock, LK_RELEASE);
1481 }
1482
1483 if (i > 0) {
1484 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1485 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1486 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs);
1487 lockmgr(&sc->aac_io_lock, LK_RELEASE);
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);
1495}
1496
1497/*
1498 * Free FIBs owned by this adapter.
1499 */
1500static void
1501aac_free_commands(struct aac_softc *sc)
1502{
1503 struct aac_fibmap *fm;
1504 struct aac_command *cm;
1505 int i;
1506
1507 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1508
1509 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1510
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 }
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{
1532 struct aac_softc *sc;
1533 struct aac_command *cm;
1534 struct aac_fib *fib;
1535 int i;
1536
1537 cm = (struct aac_command *)arg;
1538 sc = cm->cm_sc;
1539 fib = cm->cm_fib;
1540 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1541
1542 /* copy into the FIB */
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 }
1579
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;
1587
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;
1598
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 }
1616 }
1617
1618 return;
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
1629 sc = cm->cm_sc;
1630 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
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/*
1653 * Initialize the adapter.
1654 */
1655static void
1656aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1657{
1658 struct aac_softc *sc;
1659
1660 sc = (struct aac_softc *)arg;
1661 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1662
1663 sc->aac_common_busaddr = segs[0].ds_addr;
1664}
1665
1666static int
1667aac_check_firmware(struct aac_softc *sc)
1668{
1669 u_int32_t code, major, minor, options = 0, atu_size = 0;
1670 int status;
1671 time_t then;
1672
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));
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
1722 * work-arounds to enable. Some firmware revs don't support this
1723 * command.
1724 */
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) &&
1759 atu_size > rman_get_size(sc->aac_regs_res1)) {
1760 bus_release_resource(
1761 sc->aac_dev, SYS_RES_MEMORY,
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,
1765 0ul, ~0ul, atu_size, RF_ACTIVE);
1766 if (sc->aac_regs_res1 == NULL) {
1767 sc->aac_regs_res1 = bus_alloc_resource_any(
1768 sc->aac_dev, SYS_RES_MEMORY,
1769 &sc->aac_regs_rid1, RF_ACTIVE);
1770 if (sc->aac_regs_res1 == NULL) {
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 }
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 }
1786 }
1787
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
1793 - sizeof(struct aac_blockwrite64))
1794 / sizeof(struct aac_sg_entry64);
1795 else
1796 sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1797 - sizeof(struct aac_blockwrite))
1798 / sizeof(struct aac_sg_entry);
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;
1812
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
1823 return (0);
1824}
1825
1826static int
1827aac_init(struct aac_softc *sc)
1828{
1829 struct aac_adapter_init *ip;
1830 u_int32_t qoffset;
1831 int error;
1832
1833 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
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;
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 }
1845 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1846
1847 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1848 offsetof(struct aac_common, ac_fibs);
1849 ip->AdapterFibsVirtualAddress = 0;
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
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 */
1863 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1864 if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1865 ip->HostPhysMemPages =
1866 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1867 }
1868 ip->HostElapsedSeconds = time_second; /* reset later if invalid */
1869
1870 ip->InitFlags = 0;
1871 if (sc->flags & AAC_FLAGS_NEW_COMM) {
1872 ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED;
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
1880 /*
1881 * Initialize FIB queues. Note that it appears that the layout of the
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
1886 * of the sizes of the respective queues, and theoretically it could
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 *
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
1893 * list manipulation functions which 'know' the size of each list by
1894 * virtue of a table.
1895 */
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;
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:
1956 AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, ~0);
1957 break;
1958 case AAC_HWIF_RKT:
1959 AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, ~0);
1960 break;
1961 default:
1962 break;
1963 }
1964
1965 /*
1966 * Give the init structure to the controller.
1967 */
1968 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
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
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
2013/*
2014 * Send a synchronous command to the controller and wait for a result.
2015 * Indicate if the controller completed the command with an error status.
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
2025 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
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)) {
2040 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "timed out");
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;
2052
2053 if (status != AAC_SRB_STS_SUCCESS)
2054 return (-1);
2055 return(0);
2056}
2057
2058int
2059aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
2060 struct aac_fib *fib, u_int16_t datasize)
2061{
2062 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2063#if 0 /* XXX swildner */
2064 KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
2065#endif
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;
2079 fib->Header.Size = sizeof(struct aac_fib_header) + datasize;
2080 fib->Header.SenderSize = sizeof(struct aac_fib);
2081 fib->Header.SenderFibAddress = 0; /* Not needed */
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)) {
2091 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error");
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;
2131 int error;
2132 u_int32_t fib_size;
2133 u_int32_t fib_addr;
2134
2135 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2136
2137 fib_size = cm->cm_fib->Header.Size;
2138 fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
2139
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 }
2153
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
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
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:
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;
2186 u_int32_t fib_index;
2187 int error;
2188 int notify;
2189
2190 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2191
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 }
2201
2202 /* wrap the pi so the following test works */
2203 if (pi >= aac_qinfo[queue].size)
2204 pi = 0;
2205
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;
2216
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;
2260 }
2261
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:
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;
2281 int error;
2282 u_int32_t fib_size;
2283 u_int32_t fib_addr;
2284
2285 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2286
2287 /* Tell the adapter where the FIB is */
2288 fib_size = fib->Header.Size;
2289 fib_addr = fib->Header.SenderFibAddress;
2290 fib->Header.ReceiverFibAddress = fib_addr;
2291
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:
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
2328aac_timeout(struct aac_softc *sc)
2329{
2330 struct aac_command *cm;
2331 time_t deadline;
2332 int timedout, code;
2333
2334 /*
2335 * Traverse the busy command list, bitch about late commands once
2336 * only.
2337 */
2338 timedout = 0;
2339 deadline = time_second - AAC_CMD_TIMEOUT;
2340 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
2341 if ((cm->cm_timestamp < deadline)
2342 && !(cm->cm_flags & AAC_CMD_TIMEDOUT)) {
2343 cm->cm_flags |= AAC_CMD_TIMEDOUT;
2344 device_printf(sc->aac_dev,
2345 "COMMAND %p (TYPE %d) TIMEOUT AFTER %d SECONDS\n",
2346 cm, cm->cm_fib->Header.Command,
2347 (int)(time_second-cm->cm_timestamp));
2348 AAC_PRINT_FIB(sc, cm->cm_fib);
2349 timedout++;
2350 }
2351 }
2352
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);
2358 }
2359 }
2360 return;
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{
2373 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2374
2375 return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
2376}
2377
2378static int
2379aac_rx_get_fwstatus(struct aac_softc *sc)
2380{
2381 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2382
2383 return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2384 AAC_RX_OMR0 : AAC_RX_FWSTATUS));
2385}
2386
2387static int
2388aac_rkt_get_fwstatus(struct aac_softc *sc)
2389{
2390 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2391
2392 return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2393 AAC_RKT_OMR0 : AAC_RKT_FWSTATUS));
2394}
2395
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{
2403 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2404
2405 AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
2406}
2407
2408static void
2409aac_rx_qnotify(struct aac_softc *sc, int qbit)
2410{
2411 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2412
2413 AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
2414}
2415
2416static void
2417aac_rkt_qnotify(struct aac_softc *sc, int qbit)
2418{
2419 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2420
2421 AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
2422}
2423
2424/*
2425 * Get the interrupt reason bits
2426 */
2427static int
2428aac_sa_get_istatus(struct aac_softc *sc)
2429{
2430 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2431
2432 return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
2433}
2434
2435static int
2436aac_rx_get_istatus(struct aac_softc *sc)
2437{
2438 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2439
2440 return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
2441}
2442
2443static int
2444aac_rkt_get_istatus(struct aac_softc *sc)
2445{
2446 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2447
2448 return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
2449}
2450
2451/*
2452 * Clear some interrupt reason bits
2453 */
2454static void
2455aac_sa_clear_istatus(struct aac_softc *sc, int mask)
2456{
2457 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2458
2459 AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
2460}
2461
2462static void
2463aac_rx_clear_istatus(struct aac_softc *sc, int mask)
2464{
2465 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2466
2467 AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
2468}
2469
2470static void
2471aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
2472{
2473 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2474
2475 AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
2476}
2477
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{
2485 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2486
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);
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{
2498 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2499
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);
2505}
2506
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{
2511 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2512
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);
2518}
2519
2520/*
2521 * Fetch the immediate command status word
2522 */
2523static int
2524aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2525{
2526 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2527
2528 return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2529}
2530
2531static int
2532aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2533{
2534 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2535
2536 return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2537}
2538
2539static int
2540aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2541{
2542 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2543
2544 return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2545}
2546
2547/*
2548 * Set/clear interrupt masks
2549 */
2550static void
2551aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2552{
2553 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2554
2555 if (enable) {
2556 AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2557 } else {
2558 AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2559 }
2560}
2561
2562static void
2563aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2564{
2565 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2566
2567 if (enable) {
2568 if (sc->flags & AAC_FLAGS_NEW_COMM)
2569 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
2570 else
2571 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2572 } else {
2573 AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
2574 }
2575}
2576
2577static void
2578aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2579{
2580 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2581
2582 if (enable) {
2583 if (sc->flags & AAC_FLAGS_NEW_COMM)
2584 AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
2585 else
2586 AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2587 } else {
2588 AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
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
2600 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2601
2602 index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2603 if (index == 0xffffffffL)
2604 index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2605 if (index == 0xffffffffL)
2606 return index;
2607 aac_enqueue_busy(cm);
2608 device = index;
2609 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2610 device += 4;
2611 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2612 device += 4;
2613 AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2614 AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
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
2623 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2624
2625 index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2626 if (index == 0xffffffffL)
2627 index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2628 if (index == 0xffffffffL)
2629 return index;
2630 aac_enqueue_busy(cm);
2631 device = index;
2632 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2633 device += 4;
2634 AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2635 device += 4;
2636 AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2637 AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
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{
2647 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2648
2649 return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
2650}
2651
2652static int
2653aac_rkt_get_outb_queue(struct aac_softc *sc)
2654{
2655 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2656
2657 return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
2658}
2659
2660static void
2661aac_rx_set_outb_queue(struct aac_softc *sc, int index)
2662{
2663 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2664
2665 AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
2666}
2667
2668static void
2669aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
2670{
2671 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2672
2673 AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
2674}
2675
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;
2688 char *adapter_type = "Adaptec RAID controller";
2689
2690 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2691
2692 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
2693 aac_alloc_sync_fib(sc, &fib);
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);
2699 lockmgr(&sc->aac_io_lock, LK_RELEASE);
2700 return;
2701 }
2702
2703 /* save the kernel revision structure for later use */
2704 info = (struct aac_adapter_info *)&fib->data[0];
2705 sc->aac_revision = info->KernelRevision;
2706
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));
2724
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"
2740 "\15NONDASD"
2741 "\16SCSIMGT"
2742 "\17RAIDSCSI"
2743 "\21ADPTINFO"
2744 "\22NEWCOMM"
2745 "\23ARRAY64BIT"
2746 "\24HEATSENSOR");
2747 }
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
2763 aac_release_sync_fib(sc);
2764 lockmgr(&sc->aac_io_lock, LK_RELEASE);
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
2787aac_open(struct dev_open_args *ap)
2788{
2789 cdev_t dev = ap->a_head.a_dev;
2790 struct aac_softc *sc;
2791
2792 sc = dev->si_drv1;
2793 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2794 device_busy(sc->aac_dev);
2795
2796 return 0;
2797}
2798
2799static int
2800aac_ioctl(struct dev_ioctl_args *ap)
2801{
2802 caddr_t arg = ap->a_data;
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;
2807 int error = 0;
2808
2809 as = (union aac_statrequest *)arg;
2810 sc = dev->si_drv1;
2811 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2812
2813 switch (cmd) {
2814 case AACIO_STATS:
2815 switch (as->as_item) {
2816 case AACQ_FREE:
2817 case AACQ_BIO:
2818 case AACQ_READY:
2819 case AACQ_BUSY:
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 }
2827 break;
2828
2829 case FSACTL_SENDFIB:
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");
2835 error = aac_ioctl_sendfib(sc, arg);
2836 break;
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;
2843 case FSACTL_AIF_THREAD:
2844 case FSACTL_LNX_AIF_THREAD:
2845 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_AIF_THREAD");
2846 error = EINVAL;
2847 break;
2848 case FSACTL_OPEN_GET_ADAPTER_FIB:
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);
2853 break;
2854 case FSACTL_GET_NEXT_ADAPTER_FIB:
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");
2858 error = aac_getnext_aif(sc, arg);
2859 break;
2860 case FSACTL_CLOSE_GET_ADAPTER_FIB:
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);
2865 break;
2866 case FSACTL_MINIPORT_REV_CHECK:
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");
2870 error = aac_rev_check(sc, arg);
2871 break;
2872 case FSACTL_QUERY_DISK:
2873 arg = *(caddr_t*)arg;
2874 case FSACTL_LNX_QUERY_DISK:
2875 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_QUERY_DISK");
2876 error = aac_query_disk(sc, arg);
2877 break;
2878 case FSACTL_DELETE_DISK:
2879 case FSACTL_LNX_DELETE_DISK:
2880 /*
2881 * We don't trust the underland to tell us when to delete a
2882 * container, rather we rely on an AIF coming from the
2883 * controller
2884 */
2885 error = 0;
2886 break;
2887 case FSACTL_GET_PCI_INFO:
2888 arg = *(caddr_t*)arg;
2889 case FSACTL_LNX_GET_PCI_INFO:
2890 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_PCI_INFO");
2891 error = aac_get_pci_info(sc, arg);
2892 break;
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;
2899 default:
2900 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "unsupported cmd 0x%lx\n", cmd);
2901 error = EINVAL;
2902 break;
2903 }
2904 return(error);
2905}
2906
2907static struct filterops aac_filterops =
2908 { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, aac_filter_detach, aac_filter_read };
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:
2926 ap->a_result = EOPNOTSUPP;
2927 return (0);
2928 }
2929
2930 klist = &sc->rcv_kq.ki_note;
2931 knote_insert(klist, kn);
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
2942 klist = &sc->rcv_kq.ki_note;
2943 knote_remove(klist, kn);
2944}
2945
2946static int
2947aac_filter_read(struct knote *kn, long hint)
2948{
2949 struct aac_softc *sc;
2950 struct aac_fib_context *ctx;
2951
2952 sc = (struct aac_softc *)kn->kn_hook;
2953
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);
2959
2960 return (0);
2961}
2962
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:
2969 KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
2970 if (aac_alloc_command(sc, (struct aac_command **)arg)) {
2971 aac_add_event(sc, event);
2972 return;
2973 }
2974 kfree(event, M_AACBUF);
2975 wakeup(arg);
2976 break;
2977 default:
2978 break;
2979 }
2980}
2981
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
2991 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2992
2993 cm = NULL;
2994
2995 /*
2996 * Get a command
2997 */
2998 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
2999 if (aac_alloc_command(sc, &cm)) {
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);
3008 lksleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
3009 }
3010 lockmgr(&sc->aac_io_lock, LK_RELEASE);
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);
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;
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 */
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) {
3036 device_printf(sc->aac_dev,
3037 "aac_wait_command return %d\n", error);
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;
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;
3049 }
3050 error = copyout(cm->cm_fib, ufib, size);
3051
3052out:
3053 if (cm != NULL) {
3054 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3055 aac_release_command(cm);
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 }
3169 }
3170
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 }
3203 return(error);
3204}
3205
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
3221/*
3222 * Handle an AIF sent to us by the controller; queue it for later reference.
3223 * If the queue fills up, then drop the older entries.
3224 */
3225static void
3226aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
3227{
3228 struct aac_aif_command *aif;
3229 struct aac_container *co, *co_next;
3230 struct aac_fib_context *ctx;
3231 struct aac_mntinforesp *mir;
3232 int next, current, found;
3233 int count = 0, added = 0, i = 0;
3234 uint32_t channel;
3235
3236 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
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 /*
3248 * A container was added or deleted, but the message
3249 * doesn't tell us anything else! Re-enumerate the
3250 * containers and sort things out.
3251 */
3252 aac_alloc_sync_fib(sc, &fib);
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 */
3261 if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
3262 continue;
3263 if (i == 0)
3264 count = mir->MntRespCount;
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,
3274 &sc->aac_container_tqh,
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
3294 * appropriate things to set it up.
3295 */
3296 aac_add_container(sc, mir, 1);
3297 added = 1;
3298 }
3299 i++;
3300 } while ((i < count) && (i < AAC_MAX_CONTAINERS));
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) {
3313 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3314 get_mplock();
3315 device_delete_child(sc->aac_dev,
3316 co->co_disk);
3317 rel_mplock();
3318 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3319 co_next = TAILQ_NEXT(co, co_link);
3320 lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
3321 TAILQ_REMOVE(&sc->aac_container_tqh, co,
3322 co_link);
3323 lockmgr(&sc->aac_container_lock, LK_RELEASE);
3324 kfree(co, M_AACBUF);
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 */
3333 if (added) {
3334 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3335 get_mplock();
3336 bus_generic_attach(sc->aac_dev);
3337 rel_mplock();
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;
3353 }
3354 break;
3355
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);
3362 break;
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 */
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);
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
3414 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
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
3424 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "Userland revision= %d\n",
3425 rev_check.callingRevision.buildNumber);
3426
3427 /*
3428 * Doctor up the response struct.
3429 */
3430 rev_check_resp.possiblyCompatible = 1;
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;
3439 rev_check_resp.adapterSWRevision.buildNumber =
3440 AAC_DRIVER_BUILD;
3441
3442 return(copyout((caddr_t)&rev_check_resp, udata,
3443 sizeof(struct aac_rev_check_resp)));
3444}
3445
3446/*
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/*
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;
3528 struct aac_fib_context *ctx;
3529 int error;
3530
3531 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3532
3533 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
3534 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3535 if (agf.AdapterFibContext == ctx->unique)
3536 break;
3537 }
3538 if (!ctx)
3539 return (EFAULT);
3540
3541 error = aac_return_aif(sc, ctx, agf.AifFib);
3542 if (error == EAGAIN && agf.Wait) {
3543 fwprintf(sc, HBA_FLAGS_DBG_AIF_B, "aac_getnext_aif(): waiting for AIF");
3544 sc->aac_state |= AAC_STATE_AIF_SLEEPER;
3545 while (error == EAGAIN) {
3546 error = tsleep(sc->aac_aifq,
3547 PCATCH, "aacaif", 0);
3548 if (error == 0)
3549 error = aac_return_aif(sc, ctx, agf.AifFib);
3550 }
3551 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
3552 }
3553 }
3554 return(error);
3555}
3556
3557/*
3558 * Hand the next AIF off the top of the queue out to userspace.
3559 */
3560static int
3561aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
3562{
3563 int current, error;
3564
3565 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3566
3567 lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3568 current = ctx->ctx_idx;
3569 if (current == sc->aifq_idx && !ctx->ctx_wrap) {
3570 /* empty */
3571 lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3572 return (EAGAIN);
3573 }
3574 error =
3575 copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
3576 if (error)
3577 device_printf(sc->aac_dev,
3578 "aac_return_aif: copyout returned %d\n", error);
3579 else {
3580 ctx->ctx_wrap = 0;
3581 ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
3582 }
3583 lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3584 return(error);
3585}
3586
3587static int
3588aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
3589{
3590 struct aac_pci_info {
3591 u_int32_t bus;
3592 u_int32_t slot;
3593 } pciinf;
3594 int error;
3595
3596 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3597
3598 pciinf.bus = pci_get_bus(sc->aac_dev);
3599 pciinf.slot = pci_get_slot(sc->aac_dev);
3600
3601 error = copyout((caddr_t)&pciinf, uptr,
3602 sizeof(struct aac_pci_info));
3603
3604 return (error);
3605}
3606
3607static int
3608aac_supported_features(struct aac_softc *sc, caddr_t uptr)
3609{
3610 struct aac_features f;
3611 int error;
3612
3613 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3614
3615 if ((error = copyin(uptr, &f, sizeof (f))) != 0)
3616 return (error);
3617
3618 /*
3619 * When the management driver receives FSACTL_GET_FEATURES ioctl with
3620 * ALL zero in the featuresState, the driver will return the current
3621 * state of all the supported features, the data field will not be
3622 * valid.
3623 * When the management driver receives FSACTL_GET_FEATURES ioctl with
3624 * a specific bit set in the featuresState, the driver will return the
3625 * current state of this specific feature and whatever data that are
3626 * associated with the feature in the data field or perform whatever
3627 * action needed indicates in the data field.
3628 */
3629 if (f.feat.fValue == 0) {
3630 f.feat.fBits.largeLBA =
3631 (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3632 /* TODO: In the future, add other features state here as well */
3633 } else {
3634 if (f.feat.fBits.largeLBA)
3635 f.feat.fBits.largeLBA =
3636 (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3637 /* TODO: Add other features state and data in the future */
3638 }
3639
3640 error = copyout(&f, uptr, sizeof (f));
3641 return (error);
3642}
3643
3644/*
3645 * Give the userland some information about the container. The AAC arch
3646 * expects the driver to be a SCSI passthrough type driver, so it expects
3647 * the containers to have b:t:l numbers. Fake it.
3648 */
3649static int
3650aac_query_disk(struct aac_softc *sc, caddr_t uptr)
3651{
3652 struct aac_query_disk query_disk;
3653 struct aac_container *co;
3654 struct aac_disk *disk;
3655 int error, id;
3656
3657 fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3658
3659 disk = NULL;
3660
3661 error = copyin(uptr, (caddr_t)&query_disk,
3662 sizeof(struct aac_query_disk));
3663 if (error)
3664 return (error);
3665
3666 id = query_disk.ContainerNumber;
3667 if (id == -1)
3668 return (EINVAL);
3669
3670 lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
3671 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
3672 if (co->co_mntobj.ObjectId == id)
3673 break;
3674 }
3675
3676 if (co == NULL) {
3677 query_disk.Valid = 0;
3678 query_disk.Locked = 0;
3679 query_disk.Deleted = 1; /* XXX is this right? */
3680 } else {
3681 disk = device_get_softc(co->co_disk);
3682 query_disk.Valid = 1;
3683 query_disk.Locked =
3684 (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
3685 query_disk.Deleted = 0;
3686 query_disk.Bus = device_get_unit(sc->aac_dev);
3687 query_disk.Target = disk->unit;
3688 query_disk.Lun = 0;
3689 query_disk.UnMapped = 0;
3690 bcopy(disk->ad_dev_t->si_name,
3691 &query_disk.diskDeviceName[0], 10);
3692 }
3693 lockmgr(&sc->aac_container_lock, LK_RELEASE);
3694
3695 error = copyout((caddr_t)&query_disk, uptr,
3696 sizeof(struct aac_query_disk));
3697
3698 return (error);
3699}
3700
3701static void
3702aac_get_bus_info(struct aac_softc *sc)
3703{
3704 struct aac_fib *fib;
3705 struct aac_ctcfg *c_cmd;
3706 struct aac_ctcfg_resp *c_resp;
3707 struct aac_vmioctl *vmi;
3708 struct aac_vmi_businf_resp *vmi_resp;
3709 struct aac_getbusinf businfo;
3710 struct aac_sim *caminf;
3711 device_t child;
3712 int i, found, error;
3713
3714 lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3715 aac_alloc_sync_fib(sc, &fib);
3716 c_cmd = (struct aac_ctcfg *)&fib->data[0];
3717 bzero(c_cmd, sizeof(struct aac_ctcfg));
3718
3719 c_cmd->Command = VM_ContainerConfig;
3720 c_cmd->cmd = CT_GET_SCSI_METHOD;
3721 c_cmd->param = 0;
3722
3723 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3724 sizeof(struct aac_ctcfg));
3725 if (error) {
3726 device_printf(sc->aac_dev, "Error %d sending "
3727 "VM_ContainerConfig command\n", error);
3728 aac_release_sync_fib(sc);
3729 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3730 return;
3731 }
3732
3733 c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
3734 if (c_resp->Status != ST_OK) {
3735 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
3736 c_resp->Status);
3737 aac_release_sync_fib(sc);
3738 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3739 return;
3740 }
3741
3742 sc->scsi_method_id = c_resp->param;
3743
3744 vmi = (struct aac_vmioctl *)&fib->data[0];
3745 bzero(vmi, sizeof(struct aac_vmioctl));
3746
3747 vmi->Command = VM_Ioctl;
3748 vmi->ObjType = FT_DRIVE;
3749 vmi->MethId = sc->scsi_method_id;
3750 vmi->ObjId = 0;
3751 vmi->IoctlCmd = GetBusInfo;
3752
3753 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3754 sizeof(struct aac_vmi_businf_resp));
3755 if (error) {
3756 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
3757 error);
3758 aac_release_sync_fib(sc);
3759 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3760 return;
3761 }
3762
3763 vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
3764 if (vmi_resp->Status != ST_OK) {
3765 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
3766 vmi_resp->Status);
3767 aac_release_sync_fib(sc);
3768 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3769 return;
3770 }
3771
3772 bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
3773 aac_release_sync_fib(sc);
3774 lockmgr(&sc->aac_io_lock, LK_RELEASE);
3775
3776 found = 0;
3777 for (i = 0; i < businfo.BusCount; i++) {
3778 if (businfo.BusValid[i] != AAC_BUS_VALID)
3779 continue;
3780
3781 caminf = (struct aac_sim *)kmalloc(sizeof(struct aac_sim),
3782 M_AACBUF, M_INTWAIT | M_ZERO);
3783
3784 child = device_add_child(sc->aac_dev, "aacp", -1);
3785 if (child == NULL) {
3786 device_printf(sc->aac_dev,
3787 "device_add_child failed for passthrough bus %d\n",
3788 i);
3789 kfree(caminf, M_AACBUF);
3790 break;
3791 }
3792
3793 caminf->TargetsPerBus = businfo.TargetsPerBus;
3794 caminf->BusNumber = i;
3795 caminf->InitiatorBusId = businfo.InitiatorBusId[i];
3796 caminf->aac_sc = sc;
3797 caminf->sim_dev = child;
3798
3799 device_set_ivars(child, caminf);
3800 device_set_desc(child, "SCSI Passthrough Bus");
3801 TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
3802
3803 found = 1;
3804 }
3805
3806 if (found)
3807 bus_generic_attach(sc->aac_dev);
3808
3809 return;
3810}