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

Cache object: 8e98726d12644bb51191f37ef5b3df3c


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