The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/aac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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
  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
  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
  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
  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
  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 *
  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     "\2\1SNAPSHOT\2CLUSTERS\3WCACHE\4DATA64\5HOSTTIME\6RAID50"
  364     "\7WINDOW4GB"
  365     "\10SCSIUPGD\11SOFTERR\12NORECOND\13SGMAP64\14ALARM\15NONDASD";
  366 
  367 static void
  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
  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
  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
  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
  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
  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
  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
 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
 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
 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
 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 *
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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
 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             "\2"
 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
 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 }

Cache object: feaa99cc6a4067071884746669d477cc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.