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

Cache object: 3e7248ae25187d55fb86f068185f20f8


[ 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.