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

Cache object: d625241863ca19932a56493af01f45c9


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