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

Cache object: 2354d7603f39f25f75ecce488216bdce


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