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