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