aac.c revision 1.32 1 /* $NetBSD: aac.c,v 1.32 2007/05/26 12:45:02 briggs Exp $ */
2
3 /*-
4 * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*-
40 * Copyright (c) 2001 Scott Long
41 * Copyright (c) 2001 Adaptec, Inc.
42 * Copyright (c) 2000 Michael Smith
43 * Copyright (c) 2000 BSDi
44 * Copyright (c) 2000 Niklas Hallqvist
45 * All rights reserved.
46 *
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
49 * are met:
50 * 1. Redistributions of source code must retain the above copyright
51 * notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66 * SUCH DAMAGE.
67 */
68
69 /*
70 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
71 *
72 * TODO:
73 *
74 * o Management interface.
75 * o Look again at some of the portability issues.
76 * o Handle various AIFs (e.g., notification that a container is going away).
77 */
78
79 #include <sys/cdefs.h>
80 __KERNEL_RCSID(0, "$NetBSD: aac.c,v 1.32 2007/05/26 12:45:02 briggs Exp $");
81
82 #include <sys/param.h>
83 #include <sys/systm.h>
84 #include <sys/buf.h>
85 #include <sys/device.h>
86 #include <sys/kernel.h>
87 #include <sys/malloc.h>
88
89 #include <machine/bus.h>
90
91 #include <uvm/uvm_extern.h>
92
93 #include <dev/ic/aacreg.h>
94 #include <dev/ic/aacvar.h>
95 #include <dev/ic/aac_tables.h>
96
97 #include "locators.h"
98
99 static int aac_check_firmware(struct aac_softc *);
100 static void aac_describe_controller(struct aac_softc *);
101 static int aac_dequeue_fib(struct aac_softc *, int, u_int32_t *,
102 struct aac_fib **);
103 static int aac_enqueue_fib(struct aac_softc *, int, struct aac_fib *);
104 static int aac_enqueue_response(struct aac_softc *, int, struct aac_fib *);
105 static void aac_host_command(struct aac_softc *);
106 static void aac_host_response(struct aac_softc *);
107 static int aac_init(struct aac_softc *);
108 static int aac_print(void *, const char *);
109 static void aac_shutdown(void *);
110 static void aac_startup(struct aac_softc *);
111 static int aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t,
112 u_int32_t, u_int32_t, u_int32_t, u_int32_t *);
113 static int aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, void *,
114 u_int16_t, void *, u_int16_t *);
115
116 #ifdef AAC_DEBUG
117 static void aac_print_fib(struct aac_softc *, struct aac_fib *, const char *);
118 #endif
119
120 /*
121 * Adapter-space FIB queue manipulation.
122 *
123 * Note that the queue implementation here is a little funky; neither the PI or
124 * CI will ever be zero. This behaviour is a controller feature.
125 */
126 static struct {
127 int size;
128 int notify;
129 } const aac_qinfo[] = {
130 { AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL },
131 { AAC_HOST_HIGH_CMD_ENTRIES, 0 },
132 { AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY },
133 { AAC_ADAP_HIGH_CMD_ENTRIES, 0 },
134 { AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL },
135 { AAC_HOST_HIGH_RESP_ENTRIES, 0 },
136 { AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY },
137 { AAC_ADAP_HIGH_RESP_ENTRIES, 0 }
138 };
139
140 #ifdef AAC_DEBUG
141 int aac_debug = AAC_DEBUG;
142 #endif
143
144 static void *aac_sdh;
145
146 extern struct cfdriver aac_cd;
147
148 int
149 aac_attach(struct aac_softc *sc)
150 {
151 struct aac_attach_args aaca;
152 int nsegs, i, rv, state, size;
153 struct aac_ccb *ac;
154 struct aac_fib *fib;
155 bus_addr_t fibpa;
156 int locs[AACCF_NLOCS];
157
158 SIMPLEQ_INIT(&sc->sc_ccb_free);
159 SIMPLEQ_INIT(&sc->sc_ccb_queue);
160 SIMPLEQ_INIT(&sc->sc_ccb_complete);
161
162 /*
163 * Disable interrupts before we do anything.
164 */
165 AAC_MASK_INTERRUPTS(sc);
166
167 /*
168 * Initialise the adapter.
169 */
170 if (aac_check_firmware(sc))
171 return (EINVAL);
172
173 if ((rv = aac_init(sc)) != 0)
174 return (rv);
175 aac_startup(sc);
176
177 /*
178 * Print a little information about the controller.
179 */
180 aac_describe_controller(sc);
181
182 /*
183 * Initialize the ccbs.
184 */
185 sc->sc_ccbs = malloc(sizeof(*ac) * AAC_NCCBS, M_DEVBUF,
186 M_NOWAIT | M_ZERO);
187 if (sc->sc_ccbs == NULL) {
188 aprint_error("%s: memory allocation failure\n",
189 sc->sc_dv.dv_xname);
190 return (ENOMEM);
191 }
192 state = 0;
193 size = sizeof(*fib) * AAC_NCCBS;
194
195 if ((rv = bus_dmamap_create(sc->sc_dmat, size, 1, size,
196 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_fibs_dmamap)) != 0) {
197 aprint_error("%s: cannot create fibs dmamap\n",
198 sc->sc_dv.dv_xname);
199 goto bail_out;
200 }
201 state++;
202 if ((rv = bus_dmamem_alloc(sc->sc_dmat, size, PAGE_SIZE, 0,
203 &sc->sc_fibs_seg, 1, &nsegs, BUS_DMA_NOWAIT)) != 0) {
204 aprint_error("%s: can't allocate fibs structure\n",
205 sc->sc_dv.dv_xname);
206 goto bail_out;
207 }
208 state++;
209 if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_fibs_seg, nsegs, size,
210 (void **)&sc->sc_fibs, 0)) != 0) {
211 aprint_error("%s: can't map fibs structure\n",
212 sc->sc_dv.dv_xname);
213 goto bail_out;
214 }
215 state++;
216 if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_fibs_dmamap, sc->sc_fibs,
217 size, NULL, BUS_DMA_NOWAIT)) != 0) {
218 aprint_error("%s: cannot load fibs dmamap\n",
219 sc->sc_dv.dv_xname);
220 goto bail_out;
221 }
222 state++;
223
224 memset(sc->sc_fibs, 0, size);
225 fibpa = sc->sc_fibs_seg.ds_addr;
226 fib = sc->sc_fibs;
227
228 for (i = 0, ac = sc->sc_ccbs; i < AAC_NCCBS; i++, ac++) {
229 rv = bus_dmamap_create(sc->sc_dmat, AAC_MAX_XFER,
230 AAC_MAX_SGENTRIES, AAC_MAX_XFER, 0,
231 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ac->ac_dmamap_xfer);
232 if (rv) {
233 while (--ac >= sc->sc_ccbs)
234 bus_dmamap_destroy(sc->sc_dmat,
235 ac->ac_dmamap_xfer);
236 aprint_error("%s: cannot create ccb dmamap (%d)",
237 sc->sc_dv.dv_xname, rv);
238 goto bail_out;
239 }
240
241 ac->ac_fib = fib++;
242 ac->ac_fibphys = fibpa;
243 fibpa += sizeof(*fib);
244 aac_ccb_free(sc, ac);
245 }
246
247 /*
248 * Attach devices.
249 */
250 for (i = 0; i < AAC_MAX_CONTAINERS; i++) {
251 if (!sc->sc_hdr[i].hd_present)
252 continue;
253 aaca.aaca_unit = i;
254
255 locs[AACCF_UNIT] = i;
256
257 config_found_sm_loc(&sc->sc_dv, "aac", locs, &aaca,
258 aac_print, config_stdsubmatch);
259 }
260
261 /*
262 * Enable interrupts, and register our shutdown hook.
263 */
264 sc->sc_flags |= AAC_ONLINE;
265 AAC_UNMASK_INTERRUPTS(sc);
266 if (aac_sdh != NULL)
267 shutdownhook_establish(aac_shutdown, NULL);
268 return (0);
269
270 bail_out:
271 bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap);
272 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_common,
273 sizeof(*sc->sc_common));
274 bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1);
275 bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap);
276
277 if (state > 3)
278 bus_dmamap_unload(sc->sc_dmat, sc->sc_fibs_dmamap);
279 if (state > 2)
280 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_fibs, size);
281 if (state > 1)
282 bus_dmamem_free(sc->sc_dmat, &sc->sc_fibs_seg, 1);
283 if (state > 0)
284 bus_dmamap_destroy(sc->sc_dmat, sc->sc_fibs_dmamap);
285
286 free(sc->sc_ccbs, M_DEVBUF);
287 return (rv);
288 }
289
290 /*
291 * Print autoconfiguration message for a sub-device.
292 */
293 static int
294 aac_print(void *aux, const char *pnp)
295 {
296 struct aac_attach_args *aaca;
297
298 aaca = aux;
299
300 if (pnp != NULL)
301 aprint_normal("block device at %s", pnp);
302 aprint_normal(" unit %d", aaca->aaca_unit);
303 return (UNCONF);
304 }
305
306 /*
307 * Look up a text description of a numeric error code and return a pointer to
308 * same.
309 */
310 const char *
311 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
312 {
313 int i;
314
315 for (i = 0; table[i].string != NULL; i++)
316 if (table[i].code == code)
317 return (table[i].string);
318
319 return (table[i + 1].string);
320 }
321
322 /*
323 * bitmask_snprintf(9) format string for the adapter options.
324 */
325 static const char *optfmt =
326 "\20\1SNAPSHOT\2CLUSTERS\3WCACHE\4DATA64\5HOSTTIME\6RAID50"
327 "\7WINDOW4GB"
328 "\10SCSIUPGD\11SOFTERR\12NORECOND\13SGMAP64\14ALARM\15NONDASD";
329
330 static void
331 aac_describe_controller(struct aac_softc *sc)
332 {
333 u_int8_t fmtbuf[256];
334 u_int8_t tbuf[AAC_FIB_DATASIZE];
335 u_int16_t bufsize;
336 struct aac_adapter_info *info;
337 u_int8_t arg;
338
339 arg = 0;
340 if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &tbuf,
341 &bufsize)) {
342 aprint_error("%s: RequestAdapterInfo failed\n",
343 sc->sc_dv.dv_xname);
344 return;
345 }
346 if (bufsize != sizeof(*info)) {
347 aprint_error("%s: "
348 "RequestAdapterInfo returned wrong data size (%d != %zu)\n",
349 sc->sc_dv.dv_xname, bufsize, sizeof(*info));
350 return;
351 }
352 info = (struct aac_adapter_info *)&tbuf[0];
353
354 aprint_normal("%s: %s at %dMHz, %dMB mem (%dMB cache), %s\n",
355 sc->sc_dv.dv_xname,
356 aac_describe_code(aac_cpu_variant, le32toh(info->CpuVariant)),
357 le32toh(info->ClockSpeed),
358 le32toh(info->TotalMem) / (1024 * 1024),
359 le32toh(info->BufferMem) / (1024 * 1024),
360 aac_describe_code(aac_battery_platform,
361 le32toh(info->batteryPlatform)));
362
363 aprint_verbose("%s: Kernel %d.%d-%d [Build %d], ",
364 sc->sc_dv.dv_xname,
365 info->KernelRevision.external.comp.major,
366 info->KernelRevision.external.comp.minor,
367 info->KernelRevision.external.comp.dash,
368 info->KernelRevision.buildNumber);
369
370 aprint_verbose("Monitor %d.%d-%d [Build %d], S/N %6X\n",
371 info->MonitorRevision.external.comp.major,
372 info->MonitorRevision.external.comp.minor,
373 info->MonitorRevision.external.comp.dash,
374 info->MonitorRevision.buildNumber,
375 ((u_int32_t)info->SerialNumber & 0xffffff));
376
377 aprint_verbose("%s: Controller supports: %s\n",
378 sc->sc_dv.dv_xname,
379 bitmask_snprintf(sc->sc_supported_options, optfmt, fmtbuf,
380 sizeof(fmtbuf)));
381
382 /* Save the kernel revision structure for later use. */
383 sc->sc_revision = info->KernelRevision;
384 }
385
386 /*
387 * Retrieve the firmware version numbers. Dell PERC2/QC cards with firmware
388 * version 1.x are not compatible with this driver.
389 */
390 static int
391 aac_check_firmware(struct aac_softc *sc)
392 {
393 u_int32_t major, minor, opts;
394
395 if ((sc->sc_quirks & AAC_QUIRK_PERC2QC) != 0) {
396 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
397 NULL)) {
398 aprint_error("%s: error reading firmware version\n",
399 sc->sc_dv.dv_xname);
400 return (1);
401 }
402
403 /* These numbers are stored as ASCII! */
404 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
405 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
406 if (major == 1) {
407 aprint_error(
408 "%s: firmware version %d.%d not supported.\n",
409 sc->sc_dv.dv_xname, major, minor);
410 return (1);
411 }
412 }
413
414 if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) {
415 aprint_error("%s: GETINFO failed\n", sc->sc_dv.dv_xname);
416 return (1);
417 }
418 opts = AAC_GET_MAILBOX(sc, 1);
419 sc->sc_supported_options = opts;
420
421 /* XXX -- Enable 64-bit sglists if we can */
422
423 return (0);
424 }
425
426 static int
427 aac_init(struct aac_softc *sc)
428 {
429 int nsegs, i, rv, state, norm, high;
430 struct aac_adapter_init *ip;
431 u_int32_t code, qoff;
432
433 state = 0;
434
435 /*
436 * First wait for the adapter to come ready.
437 */
438 for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
439 code = AAC_GET_FWSTATUS(sc);
440 if ((code & AAC_SELF_TEST_FAILED) != 0) {
441 aprint_error("%s: FATAL: selftest failed\n",
442 sc->sc_dv.dv_xname);
443 return (ENXIO);
444 }
445 if ((code & AAC_KERNEL_PANIC) != 0) {
446 aprint_error("%s: FATAL: controller kernel panic\n",
447 sc->sc_dv.dv_xname);
448 return (ENXIO);
449 }
450 if ((code & AAC_UP_AND_RUNNING) != 0)
451 break;
452 DELAY(1000);
453 }
454 if (i == AAC_BOOT_TIMEOUT * 1000) {
455 aprint_error(
456 "%s: FATAL: controller not coming ready, status %x\n",
457 sc->sc_dv.dv_xname, code);
458 return (ENXIO);
459 }
460
461 if ((rv = bus_dmamap_create(sc->sc_dmat, sizeof(*sc->sc_common), 1,
462 sizeof(*sc->sc_common), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
463 &sc->sc_common_dmamap)) != 0) {
464 aprint_error("%s: cannot create common dmamap\n",
465 sc->sc_dv.dv_xname);
466 return (rv);
467 }
468 if ((rv = bus_dmamem_alloc(sc->sc_dmat, sizeof(*sc->sc_common),
469 PAGE_SIZE, 0, &sc->sc_common_seg, 1, &nsegs,
470 BUS_DMA_NOWAIT)) != 0) {
471 aprint_error("%s: can't allocate common structure\n",
472 sc->sc_dv.dv_xname);
473 goto bail_out;
474 }
475 state++;
476 if ((rv = bus_dmamem_map(sc->sc_dmat, &sc->sc_common_seg, nsegs,
477 sizeof(*sc->sc_common), (void **)&sc->sc_common, 0)) != 0) {
478 aprint_error("%s: can't map common structure\n",
479 sc->sc_dv.dv_xname);
480 goto bail_out;
481 }
482 state++;
483 if ((rv = bus_dmamap_load(sc->sc_dmat, sc->sc_common_dmamap,
484 sc->sc_common, sizeof(*sc->sc_common), NULL,
485 BUS_DMA_NOWAIT)) != 0) {
486 aprint_error("%s: cannot load common dmamap\n",
487 sc->sc_dv.dv_xname);
488 goto bail_out;
489 }
490 state++;
491
492 memset(sc->sc_common, 0, sizeof(*sc->sc_common));
493
494 /*
495 * Fill in the init structure. This tells the adapter about the
496 * physical location of various important shared data structures.
497 */
498 ip = &sc->sc_common->ac_init;
499 ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION);
500
501 ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr +
502 offsetof(struct aac_common, ac_fibs));
503 ip->AdapterFibsVirtualAddress = 0;
504 ip->AdapterFibsSize =
505 htole32(AAC_ADAPTER_FIBS * sizeof(struct aac_fib));
506 ip->AdapterFibAlign = htole32(sizeof(struct aac_fib));
507
508 ip->PrintfBufferAddress = htole32(sc->sc_common_seg.ds_addr +
509 offsetof(struct aac_common, ac_printf));
510 ip->PrintfBufferSize = htole32(AAC_PRINTF_BUFSIZE);
511
512 /*
513 * The adapter assumes that pages are 4K in size, except on some
514 * broken firmware versions that do the page->byte conversion twice,
515 * therefore 'assuming' that this value is in 16MB units (2^24).
516 * Round up since the granularity is so high.
517 */
518 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
519 if (sc->sc_quirks & AAC_QUIRK_BROKEN_MMAP) {
520 ip->HostPhysMemPages =
521 (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
522 }
523 ip->HostElapsedSeconds = 0; /* reset later if invalid */
524
525 /*
526 * Initialise FIB queues. Note that it appears that the layout of
527 * the indexes and the segmentation of the entries is mandated by
528 * the adapter, which is only told about the base of the queue index
529 * fields.
530 *
531 * The initial values of the indices are assumed to inform the
532 * adapter of the sizes of the respective queues.
533 *
534 * The Linux driver uses a much more complex scheme whereby several
535 * header records are kept for each queue. We use a couple of
536 * generic list manipulation functions which 'know' the size of each
537 * list by virtue of a table.
538 */
539 qoff = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
540 qoff &= ~(AAC_QUEUE_ALIGN - 1);
541 sc->sc_queues = (struct aac_queue_table *)((uintptr_t)sc->sc_common + qoff);
542 ip->CommHeaderAddress = htole32(sc->sc_common_seg.ds_addr +
543 ((char *)sc->sc_queues - (char *)sc->sc_common));
544 memset(sc->sc_queues, 0, sizeof(struct aac_queue_table));
545
546 norm = htole32(AAC_HOST_NORM_CMD_ENTRIES);
547 high = htole32(AAC_HOST_HIGH_CMD_ENTRIES);
548
549 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
550 norm;
551 sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
552 norm;
553 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
554 high;
555 sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
556 high;
557
558 norm = htole32(AAC_ADAP_NORM_CMD_ENTRIES);
559 high = htole32(AAC_ADAP_HIGH_CMD_ENTRIES);
560
561 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
562 norm;
563 sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
564 norm;
565 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
566 high;
567 sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
568 high;
569
570 norm = htole32(AAC_HOST_NORM_RESP_ENTRIES);
571 high = htole32(AAC_HOST_HIGH_RESP_ENTRIES);
572
573 sc->sc_queues->
574 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
575 sc->sc_queues->
576 qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
577 sc->sc_queues->
578 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
579 sc->sc_queues->
580 qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
581
582 norm = htole32(AAC_ADAP_NORM_RESP_ENTRIES);
583 high = htole32(AAC_ADAP_HIGH_RESP_ENTRIES);
584
585 sc->sc_queues->
586 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] = norm;
587 sc->sc_queues->
588 qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] = norm;
589 sc->sc_queues->
590 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] = high;
591 sc->sc_queues->
592 qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] = high;
593
594 sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] =
595 &sc->sc_queues->qt_HostNormCmdQueue[0];
596 sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
597 &sc->sc_queues->qt_HostHighCmdQueue[0];
598 sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
599 &sc->sc_queues->qt_AdapNormCmdQueue[0];
600 sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
601 &sc->sc_queues->qt_AdapHighCmdQueue[0];
602 sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] =
603 &sc->sc_queues->qt_HostNormRespQueue[0];
604 sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
605 &sc->sc_queues->qt_HostHighRespQueue[0];
606 sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
607 &sc->sc_queues->qt_AdapNormRespQueue[0];
608 sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
609 &sc->sc_queues->qt_AdapHighRespQueue[0];
610
611 /*
612 * Do controller-type-specific initialisation
613 */
614 switch (sc->sc_hwif) {
615 case AAC_HWIF_I960RX:
616 AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
617 break;
618 }
619
620 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap, 0,
621 sizeof(*sc->sc_common),
622 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
623
624 /*
625 * Give the init structure to the controller.
626 */
627 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
628 sc->sc_common_seg.ds_addr + offsetof(struct aac_common, ac_init),
629 0, 0, 0, NULL)) {
630 aprint_error("%s: error establishing init structure\n",
631 sc->sc_dv.dv_xname);
632 rv = EIO;
633 goto bail_out;
634 }
635
636 return (0);
637
638 bail_out:
639 if (state > 2)
640 bus_dmamap_unload(sc->sc_dmat, sc->sc_common_dmamap);
641 if (state > 1)
642 bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_common,
643 sizeof(*sc->sc_common));
644 if (state > 0)
645 bus_dmamem_free(sc->sc_dmat, &sc->sc_common_seg, 1);
646 bus_dmamap_destroy(sc->sc_dmat, sc->sc_common_dmamap);
647
648 return (rv);
649 }
650
651 /*
652 * Probe for containers, create disks.
653 */
654 static void
655 aac_startup(struct aac_softc *sc)
656 {
657 struct aac_mntinfo mi;
658 struct aac_mntinforesponse mir;
659 struct aac_drive *hd;
660 u_int16_t rsize;
661 int i;
662
663 /*
664 * Loop over possible containers.
665 */
666 hd = sc->sc_hdr;
667
668 for (i = 0; i < AAC_MAX_CONTAINERS; i++, hd++) {
669 /*
670 * Request information on this container.
671 */
672 memset(&mi, 0, sizeof(mi));
673 mi.Command = htole32(VM_NameServe);
674 mi.MntType = htole32(FT_FILESYS);
675 mi.MntCount = htole32(i);
676 if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir,
677 &rsize)) {
678 aprint_error("%s: error probing container %d\n",
679 sc->sc_dv.dv_xname, i);
680 continue;
681 }
682 if (rsize != sizeof(mir)) {
683 aprint_error("%s: container info response wrong size "
684 "(%d should be %zu)\n",
685 sc->sc_dv.dv_xname, rsize, sizeof(mir));
686 continue;
687 }
688
689 /*
690 * Check container volume type for validity. Note that many
691 * of the possible types may never show up.
692 */
693 if (le32toh(mir.Status) != ST_OK ||
694 le32toh(mir.MntTable[0].VolType) == CT_NONE)
695 continue;
696
697 hd->hd_present = 1;
698 hd->hd_size = le32toh(mir.MntTable[0].Capacity);
699 hd->hd_devtype = le32toh(mir.MntTable[0].VolType);
700 hd->hd_size &= ~0x1f;
701 sc->sc_nunits++;
702 }
703 }
704
705 static void
706 aac_shutdown(void *cookie)
707 {
708 struct aac_softc *sc;
709 struct aac_close_command cc;
710 u_int32_t i;
711
712 for (i = 0; i < aac_cd.cd_ndevs; i++) {
713 if ((sc = device_lookup(&aac_cd, i)) == NULL)
714 continue;
715 if ((sc->sc_flags & AAC_ONLINE) == 0)
716 continue;
717
718 AAC_MASK_INTERRUPTS(sc);
719
720 /*
721 * Send a Container shutdown followed by a HostShutdown FIB
722 * to the controller to convince it that we don't want to
723 * talk to it anymore. We've been closed and all I/O
724 * completed already
725 */
726 memset(&cc, 0, sizeof(cc));
727 cc.Command = htole32(VM_CloseAll);
728 cc.ContainerId = 0xffffffff;
729 if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc),
730 NULL, NULL)) {
731 printf("%s: unable to halt controller\n",
732 sc->sc_dv.dv_xname);
733 continue;
734 }
735
736 /*
737 * Note that issuing this command to the controller makes it
738 * shut down but also keeps it from coming back up without a
739 * reset of the PCI bus.
740 */
741 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
742 &i, sizeof(i), NULL, NULL))
743 printf("%s: unable to halt controller\n",
744 sc->sc_dv.dv_xname);
745
746 sc->sc_flags &= ~AAC_ONLINE;
747 }
748 }
749
750 /*
751 * Take an interrupt.
752 */
753 int
754 aac_intr(void *cookie)
755 {
756 struct aac_softc *sc;
757 u_int16_t reason;
758 int claimed;
759
760 sc = cookie;
761 claimed = 0;
762
763 AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc));
764
765 reason = AAC_GET_ISTATUS(sc);
766 AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason));
767
768 /*
769 * Controller wants to talk to the log. XXX Should we defer this?
770 */
771 if ((reason & AAC_DB_PRINTF) != 0) {
772 if (sc->sc_common->ac_printf[0] == '\0')
773 sc->sc_common->ac_printf[0] = ' ';
774 printf("%s: WARNING: adapter logged message:\n",
775 sc->sc_dv.dv_xname);
776 printf("%s: %.*s", sc->sc_dv.dv_xname,
777 AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf);
778 sc->sc_common->ac_printf[0] = '\0';
779 AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
780 AAC_QNOTIFY(sc, AAC_DB_PRINTF);
781 claimed = 1;
782 }
783
784 /*
785 * Controller has a message for us?
786 */
787 if ((reason & AAC_DB_COMMAND_READY) != 0) {
788 aac_host_command(sc);
789 AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
790 claimed = 1;
791 }
792
793 /*
794 * Controller has a response for us?
795 */
796 if ((reason & AAC_DB_RESPONSE_READY) != 0) {
797 aac_host_response(sc);
798 AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
799 claimed = 1;
800 }
801
802 /*
803 * Spurious interrupts that we don't use - reset the mask and clear
804 * the interrupts.
805 */
806 if ((reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL |
807 AAC_DB_RESPONSE_NOT_FULL)) != 0) {
808 AAC_UNMASK_INTERRUPTS(sc);
809 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND |
810 AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
811 claimed = 1;
812 }
813
814 return (claimed);
815 }
816
817 /*
818 * Handle notification of one or more FIBs coming from the controller.
819 */
820 static void
821 aac_host_command(struct aac_softc *sc)
822 {
823 struct aac_fib *fib;
824 u_int32_t fib_size;
825
826 for (;;) {
827 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size,
828 &fib))
829 break; /* nothing to do */
830
831 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
832 (char *)fib - (char *)sc->sc_common, sizeof(*fib),
833 BUS_DMASYNC_POSTREAD);
834
835 switch (le16toh(fib->Header.Command)) {
836 case AifRequest:
837 #ifdef notyet
838 aac_handle_aif(sc,
839 (struct aac_aif_command *)&fib->data[0]);
840 #endif
841 AAC_PRINT_FIB(sc, fib);
842 break;
843 default:
844 printf("%s: unknown command from controller\n",
845 sc->sc_dv.dv_xname);
846 AAC_PRINT_FIB(sc, fib);
847 break;
848 }
849
850 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
851 (char *)fib - (char *)sc->sc_common, sizeof(*fib),
852 BUS_DMASYNC_PREREAD);
853
854 if ((fib->Header.XferState == 0) ||
855 (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
856 break; // continue; ???
857 }
858
859 /* XXX reply to FIBs requesting responses ?? */
860
861 /* Return the AIF/FIB to the controller */
862 if (le32toh(fib->Header.XferState) & AAC_FIBSTATE_FROMADAP) {
863 u_int16_t size;
864
865 fib->Header.XferState |=
866 htole32(AAC_FIBSTATE_DONEHOST);
867 *(u_int32_t*)fib->data = htole32(ST_OK);
868
869 /* XXX Compute the Size field? */
870 size = le16toh(fib->Header.Size);
871 if (size > sizeof(struct aac_fib)) {
872 size = sizeof(struct aac_fib);
873 fib->Header.Size = htole16(size);
874 }
875
876 /*
877 * Since we didn't generate this command, it can't
878 * go through the normal process.
879 */
880 aac_enqueue_response(sc,
881 AAC_ADAP_NORM_RESP_QUEUE, fib);
882 }
883 }
884 }
885
886 /*
887 * Handle notification of one or more FIBs completed by the controller
888 */
889 static void
890 aac_host_response(struct aac_softc *sc)
891 {
892 struct aac_ccb *ac;
893 struct aac_fib *fib;
894 u_int32_t fib_size;
895
896 /*
897 * Look for completed FIBs on our queue.
898 */
899 for (;;) {
900 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
901 &fib))
902 break; /* nothing to do */
903
904 bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap,
905 (char *)fib - (char *)sc->sc_fibs, sizeof(*fib),
906 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
907
908 if ((fib->Header.SenderData & 0x80000000) == 0) {
909 /* Not valid; not sent by us. */
910 AAC_PRINT_FIB(sc, fib);
911 } else {
912 ac = (struct aac_ccb *)((char *)sc->sc_ccbs +
913 (fib->Header.SenderData & 0x7fffffff));
914 fib->Header.SenderData = 0;
915 SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_complete, ac, ac_chain);
916 }
917 }
918
919 /*
920 * Deal with any completed commands.
921 */
922 while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_complete)) != NULL) {
923 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_complete, ac_chain);
924 ac->ac_flags |= AAC_CCB_COMPLETED;
925
926 if (ac->ac_intr != NULL)
927 (*ac->ac_intr)(ac);
928 }
929
930 /*
931 * Try to submit more commands.
932 */
933 if (! SIMPLEQ_EMPTY(&sc->sc_ccb_queue))
934 aac_ccb_enqueue(sc, NULL);
935 }
936
937 /*
938 * Send a synchronous command to the controller and wait for a result.
939 */
940 static int
941 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
942 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
943 {
944 int i;
945 u_int32_t status;
946 int s;
947
948 s = splbio();
949
950 /* Populate the mailbox. */
951 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
952
953 /* Ensure the sync command doorbell flag is cleared. */
954 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
955
956 /* ... then set it to signal the adapter. */
957 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
958 DELAY(AAC_SYNC_DELAY);
959
960 /* Spin waiting for the command to complete. */
961 for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
962 if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)
963 break;
964 DELAY(1000);
965 }
966 if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
967 splx(s);
968 return (EIO);
969 }
970
971 /* Clear the completion flag. */
972 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
973
974 /* Get the command status. */
975 status = AAC_GET_MAILBOXSTATUS(sc);
976 splx(s);
977 if (sp != NULL)
978 *sp = status;
979
980 return (0); /* XXX Check command return status? */
981 }
982
983 /*
984 * Send a synchronous FIB to the controller and wait for a result.
985 */
986 static int
987 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
988 void *data, u_int16_t datasize, void *result,
989 u_int16_t *resultsize)
990 {
991 struct aac_fib *fib;
992 u_int32_t fibpa, status;
993
994 fib = &sc->sc_common->ac_sync_fib;
995 fibpa = sc->sc_common_seg.ds_addr +
996 offsetof(struct aac_common, ac_sync_fib);
997
998 if (datasize > AAC_FIB_DATASIZE)
999 return (EINVAL);
1000
1001 /*
1002 * Set up the sync FIB.
1003 */
1004 fib->Header.XferState = htole32(AAC_FIBSTATE_HOSTOWNED |
1005 AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY | xferstate);
1006 fib->Header.Command = htole16(command);
1007 fib->Header.StructType = AAC_FIBTYPE_TFIB;
1008 fib->Header.Size = htole16(sizeof(*fib) + datasize);
1009 fib->Header.SenderSize = htole16(sizeof(*fib));
1010 fib->Header.SenderFibAddress = 0; /* not needed */
1011 fib->Header.ReceiverFibAddress = htole32(fibpa);
1012
1013 /*
1014 * Copy in data.
1015 */
1016 if (data != NULL) {
1017 memcpy(fib->data, data, datasize);
1018 fib->Header.XferState |=
1019 htole32(AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM);
1020 }
1021
1022 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1023 (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1024 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1025
1026 /*
1027 * Give the FIB to the controller, wait for a response.
1028 */
1029 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB, fibpa, 0, 0, 0, &status))
1030 return (EIO);
1031 if (status != 1) {
1032 printf("%s: syncfib command %04x status %08x\n",
1033 sc->sc_dv.dv_xname, command, status);
1034 }
1035
1036 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1037 (char *)fib - (char *)sc->sc_common, sizeof(*fib),
1038 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1039
1040 /*
1041 * Copy out the result
1042 */
1043 if (result != NULL) {
1044 *resultsize = le16toh(fib->Header.Size) - sizeof(fib->Header);
1045 memcpy(result, fib->data, *resultsize);
1046 }
1047
1048 return (0);
1049 }
1050
1051 struct aac_ccb *
1052 aac_ccb_alloc(struct aac_softc *sc, int flags)
1053 {
1054 struct aac_ccb *ac;
1055 int s;
1056
1057 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_alloc(%p, 0x%x) ", sc, flags));
1058
1059 s = splbio();
1060 ac = SIMPLEQ_FIRST(&sc->sc_ccb_free);
1061 #ifdef DIAGNOSTIC
1062 if (ac == NULL)
1063 panic("aac_ccb_get: no free CCBS");
1064 #endif
1065 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_free, ac_chain);
1066 splx(s);
1067
1068 ac->ac_flags = flags;
1069 return (ac);
1070 }
1071
1072 void
1073 aac_ccb_free(struct aac_softc *sc, struct aac_ccb *ac)
1074 {
1075 int s;
1076
1077 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_free(%p, %p) ", sc, ac));
1078
1079 ac->ac_flags = 0;
1080 ac->ac_intr = NULL;
1081 ac->ac_fib->Header.XferState = htole32(AAC_FIBSTATE_EMPTY);
1082 ac->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1083 ac->ac_fib->Header.Flags = 0;
1084 ac->ac_fib->Header.SenderSize = htole16(sizeof(*ac->ac_fib));
1085
1086 #ifdef AAC_DEBUG
1087 /*
1088 * These are duplicated in aac_ccb_submit() to cover the case where
1089 * an intermediate stage may have destroyed them. They're left
1090 * initialised here for debugging purposes only.
1091 */
1092 ac->ac_fib->Header.SenderFibAddress = htole32((u_int32_t)(intptr_t/*XXX LP64*/)ac->ac_fib);
1093 ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
1094 #endif
1095
1096 s = splbio();
1097 SIMPLEQ_INSERT_HEAD(&sc->sc_ccb_free, ac, ac_chain);
1098 splx(s);
1099 }
1100
1101 int
1102 aac_ccb_map(struct aac_softc *sc, struct aac_ccb *ac)
1103 {
1104 int error;
1105
1106 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_map(%p, %p) ", sc, ac));
1107
1108 #ifdef DIAGNOSTIC
1109 if ((ac->ac_flags & AAC_CCB_MAPPED) != 0)
1110 panic("aac_ccb_map: already mapped");
1111 #endif
1112
1113 error = bus_dmamap_load(sc->sc_dmat, ac->ac_dmamap_xfer, ac->ac_data,
1114 ac->ac_datalen, NULL, BUS_DMA_NOWAIT | BUS_DMA_STREAMING |
1115 ((ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMA_READ : BUS_DMA_WRITE));
1116 if (error) {
1117 printf("%s: aac_ccb_map: ", sc->sc_dv.dv_xname);
1118 if (error == EFBIG)
1119 printf("more than %d DMA segs\n", AAC_MAX_SGENTRIES);
1120 else
1121 printf("error %d loading DMA map\n", error);
1122 return (error);
1123 }
1124
1125 bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
1126 (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_PREREAD :
1127 BUS_DMASYNC_PREWRITE);
1128
1129 #ifdef DIAGNOSTIC
1130 ac->ac_flags |= AAC_CCB_MAPPED;
1131 #endif
1132 return (0);
1133 }
1134
1135 void
1136 aac_ccb_unmap(struct aac_softc *sc, struct aac_ccb *ac)
1137 {
1138
1139 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_unmap(%p, %p) ", sc, ac));
1140
1141 #ifdef DIAGNOSTIC
1142 if ((ac->ac_flags & AAC_CCB_MAPPED) == 0)
1143 panic("aac_ccb_unmap: not mapped");
1144 #endif
1145
1146 bus_dmamap_sync(sc->sc_dmat, ac->ac_dmamap_xfer, 0, ac->ac_datalen,
1147 (ac->ac_flags & AAC_CCB_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1148 BUS_DMASYNC_POSTWRITE);
1149 bus_dmamap_unload(sc->sc_dmat, ac->ac_dmamap_xfer);
1150
1151 #ifdef DIAGNOSTIC
1152 ac->ac_flags &= ~AAC_CCB_MAPPED;
1153 #endif
1154 }
1155
1156 void
1157 aac_ccb_enqueue(struct aac_softc *sc, struct aac_ccb *ac)
1158 {
1159 int s;
1160
1161 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_enqueue(%p, %p) ", sc, ac));
1162
1163 s = splbio();
1164
1165 if (ac != NULL)
1166 SIMPLEQ_INSERT_TAIL(&sc->sc_ccb_queue, ac, ac_chain);
1167
1168 while ((ac = SIMPLEQ_FIRST(&sc->sc_ccb_queue)) != NULL) {
1169 if (aac_ccb_submit(sc, ac))
1170 break;
1171 SIMPLEQ_REMOVE_HEAD(&sc->sc_ccb_queue, ac_chain);
1172 }
1173
1174 splx(s);
1175 }
1176
1177 int
1178 aac_ccb_submit(struct aac_softc *sc, struct aac_ccb *ac)
1179 {
1180 u_int32_t acidx;
1181
1182 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_submit(%p, %p) ", sc, ac));
1183
1184 acidx = (u_int32_t) ((char *)ac - (char *)sc->sc_ccbs);
1185 /* Fix up the address values. */
1186 ac->ac_fib->Header.SenderFibAddress = htole32(acidx << 2);
1187 ac->ac_fib->Header.ReceiverFibAddress = htole32(ac->ac_fibphys);
1188
1189 /* Save a pointer to the command for speedy reverse-lookup. */
1190 ac->ac_fib->Header.SenderData = acidx | 0x80000000;
1191
1192 bus_dmamap_sync(sc->sc_dmat, sc->sc_fibs_dmamap,
1193 (char *)ac->ac_fib - (char *)sc->sc_fibs, sizeof(*ac->ac_fib),
1194 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1195
1196 /* Put the FIB on the outbound queue. */
1197 return (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ac->ac_fib));
1198 }
1199
1200 int
1201 aac_ccb_poll(struct aac_softc *sc, struct aac_ccb *ac, int timo)
1202 {
1203 int rv, s;
1204
1205 AAC_DPRINTF(AAC_D_QUEUE, ("aac_ccb_poll(%p, %p, %d) ", sc, ac, timo));
1206
1207 s = splbio();
1208
1209 if ((rv = aac_ccb_submit(sc, ac)) != 0) {
1210 splx(s);
1211 return (rv);
1212 }
1213
1214 for (timo *= 1000; timo != 0; timo--) {
1215 aac_intr(sc);
1216 if ((ac->ac_flags & AAC_CCB_COMPLETED) != 0)
1217 break;
1218 DELAY(100);
1219 }
1220
1221 splx(s);
1222 return (timo == 0);
1223 }
1224
1225 /*
1226 * Atomically insert an entry into the nominated queue, returns 0 on success
1227 * or EBUSY if the queue is full.
1228 *
1229 * XXX Note that it would be more efficient to defer notifying the
1230 * controller in the case where we may be inserting several entries in rapid
1231 * succession, but implementing this usefully is difficult.
1232 */
1233 static int
1234 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_fib *fib)
1235 {
1236 u_int32_t fib_size, fib_addr, pi, ci;
1237
1238 fib_size = le16toh(fib->Header.Size);
1239 fib_addr = le32toh(fib->Header.ReceiverFibAddress);
1240
1241 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1242 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1243 sizeof(sc->sc_common->ac_qbuf),
1244 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1245
1246 /* Get the producer/consumer indices. */
1247 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1248 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1249
1250 /* Wrap the queue? */
1251 if (pi >= aac_qinfo[queue].size)
1252 pi = 0;
1253
1254 /* Check for queue full. */
1255 if ((pi + 1) == ci)
1256 return (EAGAIN);
1257
1258 /* Populate queue entry. */
1259 (sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
1260 (sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
1261
1262 /* Update producer index. */
1263 sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
1264
1265 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1266 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1267 sizeof(sc->sc_common->ac_qbuf),
1268 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1269
1270 /* Notify the adapter if we know how. */
1271 if (aac_qinfo[queue].notify != 0)
1272 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1273
1274 return (0);
1275 }
1276
1277 /*
1278 * Atomically remove one entry from the nominated queue, returns 0 on success
1279 * or ENOENT if the queue is empty.
1280 */
1281 static int
1282 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1283 struct aac_fib **fib_addr)
1284 {
1285 struct aac_ccb *ac;
1286 u_int32_t pi, ci, idx;
1287 int notify;
1288
1289 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1290 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1291 sizeof(sc->sc_common->ac_qbuf),
1292 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1293
1294 /* Get the producer/consumer indices. */
1295 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1296 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1297
1298 /* Check for queue empty. */
1299 if (ci == pi)
1300 return (ENOENT);
1301
1302 notify = 0;
1303 if (ci == pi + 1)
1304 notify = 1;
1305
1306 /* Wrap the queue? */
1307 if (ci >= aac_qinfo[queue].size)
1308 ci = 0;
1309
1310 /* Fetch the entry. */
1311 *fib_size = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_size);
1312
1313 switch (queue) {
1314 case AAC_HOST_NORM_CMD_QUEUE:
1315 case AAC_HOST_HIGH_CMD_QUEUE:
1316 idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
1317 idx /= sizeof(struct aac_fib);
1318 *fib_addr = &sc->sc_common->ac_fibs[idx];
1319 break;
1320 case AAC_HOST_NORM_RESP_QUEUE:
1321 case AAC_HOST_HIGH_RESP_QUEUE:
1322 idx = le32toh((sc->sc_qentries[queue] + ci)->aq_fib_addr);
1323 ac = (struct aac_ccb *) ((char *) sc->sc_ccbs + (idx >> 2));
1324 *fib_addr = ac->ac_fib;
1325 break;
1326 default:
1327 panic("Invalid queue in aac_dequeue_fib()");
1328 break;
1329 }
1330
1331 /* Update consumer index. */
1332 sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1333
1334 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1335 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1336 sizeof(sc->sc_common->ac_qbuf),
1337 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1338
1339 /* If we have made the queue un-full, notify the adapter. */
1340 if (notify && (aac_qinfo[queue].notify != 0))
1341 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1342
1343 return (0);
1344 }
1345
1346 /*
1347 * Put our response to an adapter-initiated fib (AIF) on the response queue.
1348 */
1349 static int
1350 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1351 {
1352 u_int32_t fib_size, fib_addr, pi, ci;
1353
1354 fib_size = le16toh(fib->Header.Size);
1355 fib_addr = fib->Header.SenderFibAddress;
1356 fib->Header.ReceiverFibAddress = fib_addr;
1357
1358 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1359 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1360 sizeof(sc->sc_common->ac_qbuf),
1361 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1362
1363 /* Get the producer/consumer indices. */
1364 pi = le32toh(sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX]);
1365 ci = le32toh(sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX]);
1366
1367 /* Wrap the queue? */
1368 if (pi >= aac_qinfo[queue].size)
1369 pi = 0;
1370
1371 /* Check for queue full. */
1372 if ((pi + 1) == ci)
1373 return (EAGAIN);
1374
1375 /* Populate queue entry. */
1376 (sc->sc_qentries[queue] + pi)->aq_fib_size = htole32(fib_size);
1377 (sc->sc_qentries[queue] + pi)->aq_fib_addr = htole32(fib_addr);
1378
1379 /* Update producer index. */
1380 sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = htole32(pi + 1);
1381
1382 bus_dmamap_sync(sc->sc_dmat, sc->sc_common_dmamap,
1383 (char *)sc->sc_common->ac_qbuf - (char *)sc->sc_common,
1384 sizeof(sc->sc_common->ac_qbuf),
1385 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1386
1387 /* Notify the adapter if we know how. */
1388 if (aac_qinfo[queue].notify != 0)
1389 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1390
1391 return (0);
1392 }
1393
1394 #ifdef AAC_DEBUG
1395 /*
1396 * Print a FIB
1397 */
1398 static void
1399 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib,
1400 const char *caller)
1401 {
1402 struct aac_blockread *br;
1403 struct aac_blockwrite *bw;
1404 struct aac_sg_table *sg;
1405 char tbuf[512];
1406 int i;
1407
1408 printf("%s: FIB @ %p\n", caller, fib);
1409 bitmask_snprintf(le32toh(fib->Header.XferState),
1410 "\20"
1411 "\1HOSTOWNED"
1412 "\2ADAPTEROWNED"
1413 "\3INITIALISED"
1414 "\4EMPTY"
1415 "\5FROMPOOL"
1416 "\6FROMHOST"
1417 "\7FROMADAP"
1418 "\10REXPECTED"
1419 "\11RNOTEXPECTED"
1420 "\12DONEADAP"
1421 "\13DONEHOST"
1422 "\14HIGH"
1423 "\15NORM"
1424 "\16ASYNC"
1425 "\17PAGEFILEIO"
1426 "\20SHUTDOWN"
1427 "\21LAZYWRITE"
1428 "\22ADAPMICROFIB"
1429 "\23BIOSFIB"
1430 "\24FAST_RESPONSE"
1431 "\25APIFIB\n",
1432 tbuf,
1433 sizeof(tbuf));
1434
1435 printf(" XferState %s\n", tbuf);
1436 printf(" Command %d\n", le16toh(fib->Header.Command));
1437 printf(" StructType %d\n", fib->Header.StructType);
1438 printf(" Flags 0x%x\n", fib->Header.Flags);
1439 printf(" Size %d\n", le16toh(fib->Header.Size));
1440 printf(" SenderSize %d\n", le16toh(fib->Header.SenderSize));
1441 printf(" SenderAddress 0x%x\n",
1442 le32toh(fib->Header.SenderFibAddress));
1443 printf(" ReceiverAddress 0x%x\n",
1444 le32toh(fib->Header.ReceiverFibAddress));
1445 printf(" SenderData 0x%x\n", fib->Header.SenderData);
1446
1447 switch (fib->Header.Command) {
1448 case ContainerCommand: {
1449 br = (struct aac_blockread *)fib->data;
1450 bw = (struct aac_blockwrite *)fib->data;
1451 sg = NULL;
1452
1453 if (le32toh(br->Command) == VM_CtBlockRead) {
1454 printf(" BlockRead: container %d 0x%x/%d\n",
1455 le32toh(br->ContainerId), le32toh(br->BlockNumber),
1456 le32toh(br->ByteCount));
1457 sg = &br->SgMap;
1458 }
1459 if (le32toh(bw->Command) == VM_CtBlockWrite) {
1460 printf(" BlockWrite: container %d 0x%x/%d (%s)\n",
1461 le32toh(bw->ContainerId), le32toh(bw->BlockNumber),
1462 le32toh(bw->ByteCount),
1463 le32toh(bw->Stable) == CSTABLE ?
1464 "stable" : "unstable");
1465 sg = &bw->SgMap;
1466 }
1467 if (sg != NULL) {
1468 printf(" %d s/g entries\n", le32toh(sg->SgCount));
1469 for (i = 0; i < le32toh(sg->SgCount); i++)
1470 printf(" 0x%08x/%d\n",
1471 le32toh(sg->SgEntry[i].SgAddress),
1472 le32toh(sg->SgEntry[i].SgByteCount));
1473 }
1474 break;
1475 }
1476 default:
1477 // dump first 32 bytes of fib->data
1478 printf(" Raw data:");
1479 for (i = 0; i < 32; i++)
1480 printf(" %02x", fib->data[i]);
1481 printf("\n");
1482 break;
1483 }
1484 }
1485 #endif /* AAC_DEBUG */
1486