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/mfi/mfi.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) 2006 IronPort Systems
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/6.2/sys/dev/mfi/mfi.c 163554 2006-10-21 05:28:50Z scottl $");
   29 
   30 #include "opt_mfi.h"
   31 
   32 #include <sys/param.h>
   33 #include <sys/systm.h>
   34 #include <sys/sysctl.h>
   35 #include <sys/malloc.h>
   36 #include <sys/kernel.h>
   37 #include <sys/poll.h>
   38 #include <sys/selinfo.h>
   39 #include <sys/bus.h>
   40 #include <sys/conf.h>
   41 #include <sys/eventhandler.h>
   42 #include <sys/rman.h>
   43 #include <sys/bus_dma.h>
   44 #include <sys/bio.h>
   45 #include <sys/ioccom.h>
   46 #include <sys/uio.h>
   47 #include <sys/proc.h>
   48 #include <sys/signalvar.h>
   49 
   50 #include <machine/bus.h>
   51 #include <machine/resource.h>
   52 
   53 #include <dev/mfi/mfireg.h>
   54 #include <dev/mfi/mfi_ioctl.h>
   55 #include <dev/mfi/mfivar.h>
   56 
   57 static int      mfi_alloc_commands(struct mfi_softc *);
   58 static void     mfi_release_command(struct mfi_command *cm);
   59 static int      mfi_comms_init(struct mfi_softc *);
   60 static int      mfi_polled_command(struct mfi_softc *, struct mfi_command *);
   61 static int      mfi_wait_command(struct mfi_softc *, struct mfi_command *);
   62 static int      mfi_get_controller_info(struct mfi_softc *);
   63 static int      mfi_get_log_state(struct mfi_softc *,
   64                     struct mfi_evt_log_state **);
   65 static int      mfi_get_entry(struct mfi_softc *, int);
   66 static int      mfi_dcmd_command(struct mfi_softc *, struct mfi_command **,
   67                     uint32_t, void **, size_t);
   68 static void     mfi_data_cb(void *, bus_dma_segment_t *, int, int);
   69 static void     mfi_startup(void *arg);
   70 static void     mfi_intr(void *arg);
   71 static void     mfi_enable_intr(struct mfi_softc *sc);
   72 static void     mfi_ldprobe(struct mfi_softc *sc);
   73 static int      mfi_aen_register(struct mfi_softc *sc, int seq, int locale);
   74 static void     mfi_aen_complete(struct mfi_command *);
   75 static int      mfi_aen_setup(struct mfi_softc *, uint32_t);
   76 static int      mfi_add_ld(struct mfi_softc *sc, int);
   77 static void     mfi_add_ld_complete(struct mfi_command *);
   78 static struct mfi_command * mfi_bio_command(struct mfi_softc *);
   79 static void     mfi_bio_complete(struct mfi_command *);
   80 static int      mfi_mapcmd(struct mfi_softc *, struct mfi_command *);
   81 static int      mfi_send_frame(struct mfi_softc *, struct mfi_command *);
   82 static void     mfi_complete(struct mfi_softc *, struct mfi_command *);
   83 static int      mfi_abort(struct mfi_softc *, struct mfi_command *);
   84 static int      mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int, d_thread_t *);
   85 static void     mfi_timeout(void *);
   86 
   87 
   88 SYSCTL_NODE(_hw, OID_AUTO, mfi, CTLFLAG_RD, 0, "MFI driver parameters");
   89 static int      mfi_event_locale = MFI_EVT_LOCALE_ALL;
   90 TUNABLE_INT("hw.mfi.event_locale", &mfi_event_locale);
   91 SYSCTL_INT(_hw_mfi, OID_AUTO, event_locale, CTLFLAG_RW, &mfi_event_locale,
   92             0, "event message locale");
   93 
   94 static int      mfi_event_class =  MFI_EVT_CLASS_DEBUG;
   95 TUNABLE_INT("hw.mfi.event_class", &mfi_event_class);
   96 SYSCTL_INT(_hw_mfi, OID_AUTO, event_class, CTLFLAG_RW, &mfi_event_class,
   97           0, "event message class");
   98 
   99 /* Management interface */
  100 static d_open_t         mfi_open;
  101 static d_close_t        mfi_close;
  102 static d_ioctl_t        mfi_ioctl;
  103 static d_poll_t         mfi_poll;
  104 
  105 static struct cdevsw mfi_cdevsw = {
  106         .d_version =    D_VERSION,
  107         .d_flags =      0,
  108         .d_open =       mfi_open,
  109         .d_close =      mfi_close,
  110         .d_ioctl =      mfi_ioctl,
  111         .d_poll =       mfi_poll,
  112         .d_name =       "mfi",
  113 };
  114 
  115 MALLOC_DEFINE(M_MFIBUF, "mfibuf", "Buffers for the MFI driver");
  116 
  117 #define MFI_INQ_LENGTH SHORT_INQUIRY_LENGTH
  118 
  119 static int
  120 mfi_transition_firmware(struct mfi_softc *sc)
  121 {
  122         int32_t fw_state, cur_state;
  123         int max_wait, i;
  124 
  125         fw_state = MFI_READ4(sc, MFI_OMSG0) & MFI_FWSTATE_MASK;
  126         while (fw_state != MFI_FWSTATE_READY) {
  127                 if (bootverbose)
  128                         device_printf(sc->mfi_dev, "Waiting for firmware to "
  129                             "become ready\n");
  130                 cur_state = fw_state;
  131                 switch (fw_state) {
  132                 case MFI_FWSTATE_FAULT:
  133                         device_printf(sc->mfi_dev, "Firmware fault\n");
  134                         return (ENXIO);
  135                 case MFI_FWSTATE_WAIT_HANDSHAKE:
  136                         MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_CLEAR_HANDSHAKE);
  137                         max_wait = 2;
  138                         break;
  139                 case MFI_FWSTATE_OPERATIONAL:
  140                         MFI_WRITE4(sc, MFI_IDB, MFI_FWINIT_READY);
  141                         max_wait = 10;
  142                         break;
  143                 case MFI_FWSTATE_UNDEFINED:
  144                 case MFI_FWSTATE_BB_INIT:
  145                         max_wait = 2;
  146                         break;
  147                 case MFI_FWSTATE_FW_INIT:
  148                 case MFI_FWSTATE_DEVICE_SCAN:
  149                 case MFI_FWSTATE_FLUSH_CACHE:
  150                         max_wait = 20;
  151                         break;
  152                 default:
  153                         device_printf(sc->mfi_dev,"Unknown firmware state %d\n",
  154                             fw_state);
  155                         return (ENXIO);
  156                 }
  157                 for (i = 0; i < (max_wait * 10); i++) {
  158                         fw_state = MFI_READ4(sc, MFI_OMSG0) & MFI_FWSTATE_MASK;
  159                         if (fw_state == cur_state)
  160                                 DELAY(100000);
  161                         else
  162                                 break;
  163                 }
  164                 if (fw_state == cur_state) {
  165                         device_printf(sc->mfi_dev, "firmware stuck in state "
  166                             "%#x\n", fw_state);
  167                         return (ENXIO);
  168                 }
  169         }
  170         return (0);
  171 }
  172 
  173 static void
  174 mfi_addr32_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
  175 {
  176         uint32_t *addr;
  177 
  178         addr = arg;
  179         *addr = segs[0].ds_addr;
  180 }
  181 
  182 int
  183 mfi_attach(struct mfi_softc *sc)
  184 {
  185         uint32_t status;
  186         int error, commsz, framessz, sensesz;
  187         int frames, unit, max_fw_sge;
  188 
  189         mtx_init(&sc->mfi_io_lock, "MFI I/O lock", NULL, MTX_DEF);
  190         TAILQ_INIT(&sc->mfi_ld_tqh);
  191         TAILQ_INIT(&sc->mfi_aen_pids);
  192 
  193         mfi_initq_free(sc);
  194         mfi_initq_ready(sc);
  195         mfi_initq_busy(sc);
  196         mfi_initq_bio(sc);
  197 
  198         /* Before we get too far, see if the firmware is working */
  199         if ((error = mfi_transition_firmware(sc)) != 0) {
  200                 device_printf(sc->mfi_dev, "Firmware not in READY state, "
  201                     "error %d\n", error);
  202                 return (ENXIO);
  203         }
  204 
  205         /*
  206          * Get information needed for sizing the contiguous memory for the
  207          * frame pool.  Size down the sgl parameter since we know that
  208          * we will never need more than what's required for MAXPHYS.
  209          * It would be nice if these constants were available at runtime
  210          * instead of compile time.
  211          */
  212         status = MFI_READ4(sc, MFI_OMSG0);
  213         sc->mfi_max_fw_cmds = status & MFI_FWSTATE_MAXCMD_MASK;
  214         max_fw_sge = (status & MFI_FWSTATE_MAXSGL_MASK) >> 16;
  215         sc->mfi_max_sge = min(max_fw_sge, ((MAXPHYS / PAGE_SIZE) + 1));
  216 
  217         /*
  218          * Create the dma tag for data buffers.  Used both for block I/O
  219          * and for various internal data queries.
  220          */
  221         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
  222                                 1, 0,                   /* algnmnt, boundary */
  223                                 BUS_SPACE_MAXADDR,      /* lowaddr */
  224                                 BUS_SPACE_MAXADDR,      /* highaddr */
  225                                 NULL, NULL,             /* filter, filterarg */
  226                                 BUS_SPACE_MAXSIZE_32BIT,/* maxsize */
  227                                 sc->mfi_max_sge,        /* nsegments */
  228                                 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
  229                                 BUS_DMA_ALLOCNOW,       /* flags */
  230                                 busdma_lock_mutex,      /* lockfunc */
  231                                 &sc->mfi_io_lock,       /* lockfuncarg */
  232                                 &sc->mfi_buffer_dmat)) {
  233                 device_printf(sc->mfi_dev, "Cannot allocate buffer DMA tag\n");
  234                 return (ENOMEM);
  235         }
  236 
  237         /*
  238          * Allocate DMA memory for the comms queues.  Keep it under 4GB for
  239          * efficiency.  The mfi_hwcomms struct includes space for 1 reply queue
  240          * entry, so the calculated size here will be will be 1 more than
  241          * mfi_max_fw_cmds.  This is apparently a requirement of the hardware.
  242          */
  243         commsz = (sizeof(uint32_t) * sc->mfi_max_fw_cmds) +
  244             sizeof(struct mfi_hwcomms);
  245         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
  246                                 1, 0,                   /* algnmnt, boundary */
  247                                 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
  248                                 BUS_SPACE_MAXADDR,      /* highaddr */
  249                                 NULL, NULL,             /* filter, filterarg */
  250                                 commsz,                 /* maxsize */
  251                                 1,                      /* msegments */
  252                                 commsz,                 /* maxsegsize */
  253                                 0,                      /* flags */
  254                                 NULL, NULL,             /* lockfunc, lockarg */
  255                                 &sc->mfi_comms_dmat)) {
  256                 device_printf(sc->mfi_dev, "Cannot allocate comms DMA tag\n");
  257                 return (ENOMEM);
  258         }
  259         if (bus_dmamem_alloc(sc->mfi_comms_dmat, (void **)&sc->mfi_comms,
  260             BUS_DMA_NOWAIT, &sc->mfi_comms_dmamap)) {
  261                 device_printf(sc->mfi_dev, "Cannot allocate comms memory\n");
  262                 return (ENOMEM);
  263         }
  264         bzero(sc->mfi_comms, commsz);
  265         bus_dmamap_load(sc->mfi_comms_dmat, sc->mfi_comms_dmamap,
  266             sc->mfi_comms, commsz, mfi_addr32_cb, &sc->mfi_comms_busaddr, 0);
  267 
  268         /*
  269          * Allocate DMA memory for the command frames.  Keep them in the
  270          * lower 4GB for efficiency.  Calculate the size of the commands at
  271          * the same time; each command is one 64 byte frame plus a set of
  272          * additional frames for holding sg lists or other data.
  273          * The assumption here is that the SG list will start at the second
  274          * frame and not use the unused bytes in the first frame.  While this
  275          * isn't technically correct, it simplifies the calculation and allows
  276          * for command frames that might be larger than an mfi_io_frame.
  277          */
  278         if (sizeof(bus_addr_t) == 8) {
  279                 sc->mfi_sge_size = sizeof(struct mfi_sg64);
  280                 sc->mfi_flags |= MFI_FLAGS_SG64;
  281         } else {
  282                 sc->mfi_sge_size = sizeof(struct mfi_sg32);
  283         }
  284         frames = (sc->mfi_sge_size * sc->mfi_max_sge - 1) / MFI_FRAME_SIZE + 2;
  285         sc->mfi_cmd_size = frames * MFI_FRAME_SIZE;
  286         framessz = sc->mfi_cmd_size * sc->mfi_max_fw_cmds;
  287         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
  288                                 64, 0,                  /* algnmnt, boundary */
  289                                 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
  290                                 BUS_SPACE_MAXADDR,      /* highaddr */
  291                                 NULL, NULL,             /* filter, filterarg */
  292                                 framessz,               /* maxsize */
  293                                 1,                      /* nsegments */
  294                                 framessz,               /* maxsegsize */
  295                                 0,                      /* flags */
  296                                 NULL, NULL,             /* lockfunc, lockarg */
  297                                 &sc->mfi_frames_dmat)) {
  298                 device_printf(sc->mfi_dev, "Cannot allocate frame DMA tag\n");
  299                 return (ENOMEM);
  300         }
  301         if (bus_dmamem_alloc(sc->mfi_frames_dmat, (void **)&sc->mfi_frames,
  302             BUS_DMA_NOWAIT, &sc->mfi_frames_dmamap)) {
  303                 device_printf(sc->mfi_dev, "Cannot allocate frames memory\n");
  304                 return (ENOMEM);
  305         }
  306         bzero(sc->mfi_frames, framessz);
  307         bus_dmamap_load(sc->mfi_frames_dmat, sc->mfi_frames_dmamap,
  308             sc->mfi_frames, framessz, mfi_addr32_cb, &sc->mfi_frames_busaddr,0);
  309 
  310         /*
  311          * Allocate DMA memory for the frame sense data.  Keep them in the
  312          * lower 4GB for efficiency
  313          */
  314         sensesz = sc->mfi_max_fw_cmds * MFI_SENSE_LEN;
  315         if (bus_dma_tag_create( sc->mfi_parent_dmat,    /* parent */
  316                                 4, 0,                   /* algnmnt, boundary */
  317                                 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
  318                                 BUS_SPACE_MAXADDR,      /* highaddr */
  319                                 NULL, NULL,             /* filter, filterarg */
  320                                 sensesz,                /* maxsize */
  321                                 1,                      /* nsegments */
  322                                 sensesz,                /* maxsegsize */
  323                                 0,                      /* flags */
  324                                 NULL, NULL,             /* lockfunc, lockarg */
  325                                 &sc->mfi_sense_dmat)) {
  326                 device_printf(sc->mfi_dev, "Cannot allocate sense DMA tag\n");
  327                 return (ENOMEM);
  328         }
  329         if (bus_dmamem_alloc(sc->mfi_sense_dmat, (void **)&sc->mfi_sense,
  330             BUS_DMA_NOWAIT, &sc->mfi_sense_dmamap)) {
  331                 device_printf(sc->mfi_dev, "Cannot allocate sense memory\n");
  332                 return (ENOMEM);
  333         }
  334         bus_dmamap_load(sc->mfi_sense_dmat, sc->mfi_sense_dmamap,
  335             sc->mfi_sense, sensesz, mfi_addr32_cb, &sc->mfi_sense_busaddr, 0);
  336 
  337         if ((error = mfi_alloc_commands(sc)) != 0)
  338                 return (error);
  339 
  340         if ((error = mfi_comms_init(sc)) != 0)
  341                 return (error);
  342 
  343         if ((error = mfi_get_controller_info(sc)) != 0)
  344                 return (error);
  345 
  346         mtx_lock(&sc->mfi_io_lock);
  347         if ((error = mfi_aen_setup(sc, 0), 0) != 0) {
  348                 mtx_unlock(&sc->mfi_io_lock);
  349                 return (error);
  350         }
  351         mtx_unlock(&sc->mfi_io_lock);
  352 
  353         /*
  354          * Set up the interrupt handler.  XXX This should happen in
  355          * mfi_pci.c
  356          */
  357         sc->mfi_irq_rid = 0;
  358         if ((sc->mfi_irq = bus_alloc_resource_any(sc->mfi_dev, SYS_RES_IRQ,
  359             &sc->mfi_irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) {
  360                 device_printf(sc->mfi_dev, "Cannot allocate interrupt\n");
  361                 return (EINVAL);
  362         }
  363         if (bus_setup_intr(sc->mfi_dev, sc->mfi_irq, INTR_MPSAFE|INTR_TYPE_BIO,
  364             mfi_intr, sc, &sc->mfi_intr)) {
  365                 device_printf(sc->mfi_dev, "Cannot set up interrupt\n");
  366                 return (EINVAL);
  367         }
  368 
  369         /* Register a config hook to probe the bus for arrays */
  370         sc->mfi_ich.ich_func = mfi_startup;
  371         sc->mfi_ich.ich_arg = sc;
  372         if (config_intrhook_establish(&sc->mfi_ich) != 0) {
  373                 device_printf(sc->mfi_dev, "Cannot establish configuration "
  374                     "hook\n");
  375                 return (EINVAL);
  376         }
  377 
  378         /*
  379          * Register a shutdown handler.
  380          */
  381         if ((sc->mfi_eh = EVENTHANDLER_REGISTER(shutdown_final, mfi_shutdown,
  382             sc, SHUTDOWN_PRI_DEFAULT)) == NULL) {
  383                 device_printf(sc->mfi_dev, "Warning: shutdown event "
  384                     "registration failed\n");
  385         }
  386 
  387         /*
  388          * Create the control device for doing management
  389          */
  390         unit = device_get_unit(sc->mfi_dev);
  391         sc->mfi_cdev = make_dev(&mfi_cdevsw, unit, UID_ROOT, GID_OPERATOR,
  392             0640, "mfi%d", unit);
  393         if (unit == 0)
  394                 make_dev_alias(sc->mfi_cdev, "megaraid_sas_ioctl_node");
  395         if (sc->mfi_cdev != NULL)
  396                 sc->mfi_cdev->si_drv1 = sc;
  397 
  398         /* Start the timeout watchdog */
  399         callout_init(&sc->mfi_watchdog_callout, 1);
  400         callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,
  401             mfi_timeout, sc);
  402 
  403         return (0);
  404 }
  405 
  406 static int
  407 mfi_alloc_commands(struct mfi_softc *sc)
  408 {
  409         struct mfi_command *cm;
  410         int i, ncmds;
  411 
  412         /*
  413          * XXX Should we allocate all the commands up front, or allocate on
  414          * demand later like 'aac' does?
  415          */
  416         ncmds = sc->mfi_max_fw_cmds;
  417         sc->mfi_commands = malloc(sizeof(struct mfi_command) * ncmds, M_MFIBUF,
  418             M_WAITOK | M_ZERO);
  419 
  420         for (i = 0; i < ncmds; i++) {
  421                 cm = &sc->mfi_commands[i];
  422                 cm->cm_frame = (union mfi_frame *)((uintptr_t)sc->mfi_frames +
  423                     sc->mfi_cmd_size * i);
  424                 cm->cm_frame_busaddr = sc->mfi_frames_busaddr +
  425                     sc->mfi_cmd_size * i;
  426                 cm->cm_frame->header.context = i;
  427                 cm->cm_sense = &sc->mfi_sense[i];
  428                 cm->cm_sense_busaddr= sc->mfi_sense_busaddr + MFI_SENSE_LEN * i;
  429                 cm->cm_sc = sc;
  430                 cm->cm_index = i;
  431                 if (bus_dmamap_create(sc->mfi_buffer_dmat, 0,
  432                     &cm->cm_dmamap) == 0)
  433                         mfi_release_command(cm);
  434                 else
  435                         break;
  436                 sc->mfi_total_cmds++;
  437         }
  438 
  439         return (0);
  440 }
  441 
  442 static void
  443 mfi_release_command(struct mfi_command *cm)
  444 {
  445         struct mfi_frame_header *hdr;
  446         uint32_t *hdr_data;
  447 
  448         /*
  449          * Zero out the important fields of the frame, but make sure the
  450          * context field is preserved
  451          */
  452         hdr_data = (uint32_t *)cm->cm_frame;
  453         hdr_data[0] = 0;
  454         hdr_data[1] = 0;
  455 
  456         hdr = &cm->cm_frame->header;
  457         if (hdr->sg_count) {
  458                 cm->cm_sg->sg32[0].len = 0;
  459                 cm->cm_sg->sg32[0].addr = 0;
  460         }
  461         cm->cm_extra_frames = 0;
  462         cm->cm_flags = 0;
  463         cm->cm_complete = NULL;
  464         cm->cm_private = NULL;
  465         cm->cm_sg = 0;
  466         cm->cm_total_frame_size = 0;
  467 
  468         mfi_enqueue_free(cm);
  469 }
  470 
  471 static int
  472 mfi_dcmd_command(struct mfi_softc *sc, struct mfi_command **cmp, uint32_t opcode,
  473     void **bufp, size_t bufsize)
  474 {
  475         struct mfi_command *cm;
  476         struct mfi_dcmd_frame *dcmd;
  477         void *buf = NULL;
  478         
  479         mtx_assert(&sc->mfi_io_lock, MA_OWNED);
  480         
  481         cm = mfi_dequeue_free(sc);
  482         if (cm == NULL)
  483                 return (EBUSY);
  484 
  485         if ((bufsize > 0) && (bufp != NULL)) {
  486                 if (*bufp == NULL) {
  487                         buf = malloc(bufsize, M_MFIBUF, M_NOWAIT|M_ZERO);
  488                         if (buf == NULL) {
  489                                 mfi_release_command(cm);
  490                                 return (ENOMEM);
  491                         }
  492                         *bufp = buf;
  493                 } else {
  494                         buf = *bufp;
  495                 }
  496         }
  497 
  498         dcmd =  &cm->cm_frame->dcmd;
  499         bzero(dcmd->mbox, MFI_MBOX_SIZE);
  500         dcmd->header.cmd = MFI_CMD_DCMD;
  501         dcmd->header.timeout = 0;
  502         dcmd->header.flags = 0;
  503         dcmd->header.data_len = bufsize;
  504         dcmd->opcode = opcode;
  505         cm->cm_sg = &dcmd->sgl;
  506         cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
  507         cm->cm_flags = 0;
  508         cm->cm_data = buf;
  509         cm->cm_private = buf;
  510         cm->cm_len = bufsize;
  511 
  512         *cmp = cm;
  513         if ((bufp != NULL) && (*bufp == NULL) && (buf != NULL))
  514                 *bufp = buf;
  515         return (0);
  516 }
  517 
  518 static int
  519 mfi_comms_init(struct mfi_softc *sc)
  520 {
  521         struct mfi_command *cm;
  522         struct mfi_init_frame *init;
  523         struct mfi_init_qinfo *qinfo;
  524         int error;
  525 
  526         mtx_lock(&sc->mfi_io_lock);
  527         if ((cm = mfi_dequeue_free(sc)) == NULL)
  528                 return (EBUSY);
  529 
  530         /*
  531          * Abuse the SG list area of the frame to hold the init_qinfo
  532          * object;
  533          */
  534         init = &cm->cm_frame->init;
  535         qinfo = (struct mfi_init_qinfo *)((uintptr_t)init + MFI_FRAME_SIZE);
  536 
  537         bzero(qinfo, sizeof(struct mfi_init_qinfo));
  538         qinfo->rq_entries = sc->mfi_max_fw_cmds + 1;
  539         qinfo->rq_addr_lo = sc->mfi_comms_busaddr +
  540             offsetof(struct mfi_hwcomms, hw_reply_q);
  541         qinfo->pi_addr_lo = sc->mfi_comms_busaddr +
  542             offsetof(struct mfi_hwcomms, hw_pi);
  543         qinfo->ci_addr_lo = sc->mfi_comms_busaddr +
  544             offsetof(struct mfi_hwcomms, hw_ci);
  545 
  546         init->header.cmd = MFI_CMD_INIT;
  547         init->header.data_len = sizeof(struct mfi_init_qinfo);
  548         init->qinfo_new_addr_lo = cm->cm_frame_busaddr + MFI_FRAME_SIZE;
  549 
  550         if ((error = mfi_polled_command(sc, cm)) != 0) {
  551                 device_printf(sc->mfi_dev, "failed to send init command\n");
  552                 mtx_unlock(&sc->mfi_io_lock);
  553                 return (error);
  554         }
  555         mfi_release_command(cm);
  556         mtx_unlock(&sc->mfi_io_lock);
  557 
  558         return (0);
  559 }
  560 
  561 static int
  562 mfi_get_controller_info(struct mfi_softc *sc)
  563 {
  564         struct mfi_command *cm = NULL;
  565         struct mfi_ctrl_info *ci = NULL;
  566         uint32_t max_sectors_1, max_sectors_2;
  567         int error;
  568 
  569         mtx_lock(&sc->mfi_io_lock);
  570         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_GETINFO,
  571             (void **)&ci, sizeof(*ci));
  572         if (error)
  573                 goto out;
  574         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
  575 
  576         if ((error = mfi_mapcmd(sc, cm)) != 0) {
  577                 device_printf(sc->mfi_dev, "Controller info buffer map failed\n");
  578                 free(ci, M_MFIBUF);
  579                 mfi_release_command(cm);
  580                 mtx_unlock(&sc->mfi_io_lock);
  581                 return (error);
  582         }
  583 
  584         /* It's ok if this fails, just use default info instead */
  585         if ((error = mfi_polled_command(sc, cm)) != 0) {
  586                 device_printf(sc->mfi_dev, "Failed to get controller info\n");
  587                 sc->mfi_max_io = (sc->mfi_max_sge - 1) * PAGE_SIZE /
  588                     MFI_SECTOR_LEN;
  589                 error = 0;
  590                 goto out;
  591         }
  592 
  593         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
  594             BUS_DMASYNC_POSTREAD);
  595         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
  596 
  597         max_sectors_1 = (1 << ci->stripe_sz_ops.min) * ci->max_strips_per_io;
  598         max_sectors_2 = ci->max_request_size;
  599         sc->mfi_max_io = min(max_sectors_1, max_sectors_2);
  600 
  601 out:
  602         if (ci)
  603                 free(ci, M_MFIBUF);
  604         if (cm)
  605                 mfi_release_command(cm);
  606         mtx_unlock(&sc->mfi_io_lock);
  607         return (error);
  608 }
  609 
  610 static int
  611 mfi_get_log_state(struct mfi_softc *sc, struct mfi_evt_log_state **log_state)
  612 {
  613         struct mfi_command *cm = NULL;
  614         int error;
  615 
  616         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_GETINFO,
  617             (void **)log_state, sizeof(**log_state));
  618         if (error)
  619                 goto out;
  620         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
  621 
  622         if ((error = mfi_mapcmd(sc, cm)) != 0) {
  623                 device_printf(sc->mfi_dev, "Log state buffer map failed\n");
  624                 goto out;
  625         }
  626 
  627         if ((error = mfi_polled_command(sc, cm)) != 0) {
  628                 device_printf(sc->mfi_dev, "Failed to get log state\n");
  629                 goto out;
  630         }
  631 
  632         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
  633             BUS_DMASYNC_POSTREAD);
  634         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
  635 
  636 out:
  637         if (cm)
  638                 mfi_release_command(cm);
  639 
  640         return (error);
  641 }
  642 
  643 static int
  644 mfi_aen_setup(struct mfi_softc *sc, uint32_t seq_start)
  645 {
  646         struct mfi_evt_log_state *log_state = NULL;
  647         union mfi_evt class_locale;
  648         int error = 0;
  649         uint32_t seq;
  650 
  651         class_locale.members.reserved = 0;
  652         class_locale.members.locale = mfi_event_locale;
  653         class_locale.members.class  = mfi_event_class;
  654 
  655         if (seq_start == 0) {
  656                 error = mfi_get_log_state(sc, &log_state);
  657                 if (error) {
  658                         if (log_state)
  659                                 free(log_state, M_MFIBUF);
  660                         return (error);
  661                 }
  662                 /*
  663                  * Don't run them yet since we can't parse them.
  664                  * We can indirectly get the contents from
  665                  * the AEN mechanism via setting it lower then
  666                  * current.  The firmware will iterate through them.
  667                  */
  668                 for (seq = log_state->shutdown_seq_num;
  669                      seq <= log_state->newest_seq_num; seq++) {
  670                         mfi_get_entry(sc, seq);
  671                 }
  672         } else
  673                 seq = seq_start;
  674         mfi_aen_register(sc, seq, class_locale.word);
  675         free(log_state, M_MFIBUF);
  676 
  677         return 0;
  678 }
  679 
  680 static int
  681 mfi_polled_command(struct mfi_softc *sc, struct mfi_command *cm)
  682 {
  683         struct mfi_frame_header *hdr;
  684         int tm = MFI_POLL_TIMEOUT_SECS * 1000000;
  685 
  686         mtx_assert(&sc->mfi_io_lock, MA_OWNED);
  687 
  688         hdr = &cm->cm_frame->header;
  689         hdr->cmd_status = 0xff;
  690         hdr->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
  691 
  692         mfi_send_frame(sc, cm);
  693 
  694         while (hdr->cmd_status == 0xff) {
  695                 DELAY(1000);
  696                 tm -= 1000;
  697                 if (tm <= 0)
  698                         break;
  699         }
  700 
  701         if (hdr->cmd_status == 0xff) {
  702                 device_printf(sc->mfi_dev, "Frame %p timed out\n", hdr);
  703                 return (ETIMEDOUT);
  704         }
  705 
  706         return (0);
  707 }
  708 
  709 static int
  710 mfi_wait_command(struct mfi_softc *sc, struct mfi_command *cm)
  711 {
  712 
  713         mtx_assert(&sc->mfi_io_lock, MA_OWNED);
  714         cm->cm_complete = NULL;
  715 
  716         mfi_enqueue_ready(cm);
  717         mfi_startio(sc);
  718         return (msleep(cm, &sc->mfi_io_lock, PRIBIO, "mfiwait", 0));
  719 }
  720 
  721 void
  722 mfi_free(struct mfi_softc *sc)
  723 {
  724         struct mfi_command *cm;
  725         int i;
  726 
  727         callout_drain(&sc->mfi_watchdog_callout);
  728 
  729         if (sc->mfi_cdev != NULL)
  730                 destroy_dev(sc->mfi_cdev);
  731 
  732         if (sc->mfi_total_cmds != 0) {
  733                 for (i = 0; i < sc->mfi_total_cmds; i++) {
  734                         cm = &sc->mfi_commands[i];
  735                         bus_dmamap_destroy(sc->mfi_buffer_dmat, cm->cm_dmamap);
  736                 }
  737                 free(sc->mfi_commands, M_MFIBUF);
  738         }
  739 
  740         if (sc->mfi_intr)
  741                 bus_teardown_intr(sc->mfi_dev, sc->mfi_irq, sc->mfi_intr);
  742         if (sc->mfi_irq != NULL)
  743                 bus_release_resource(sc->mfi_dev, SYS_RES_IRQ, sc->mfi_irq_rid,
  744                     sc->mfi_irq);
  745 
  746         if (sc->mfi_sense_busaddr != 0)
  747                 bus_dmamap_unload(sc->mfi_sense_dmat, sc->mfi_sense_dmamap);
  748         if (sc->mfi_sense != NULL)
  749                 bus_dmamem_free(sc->mfi_sense_dmat, sc->mfi_sense,
  750                     sc->mfi_sense_dmamap);
  751         if (sc->mfi_sense_dmat != NULL)
  752                 bus_dma_tag_destroy(sc->mfi_sense_dmat);
  753 
  754         if (sc->mfi_frames_busaddr != 0)
  755                 bus_dmamap_unload(sc->mfi_frames_dmat, sc->mfi_frames_dmamap);
  756         if (sc->mfi_frames != NULL)
  757                 bus_dmamem_free(sc->mfi_frames_dmat, sc->mfi_frames,
  758                     sc->mfi_frames_dmamap);
  759         if (sc->mfi_frames_dmat != NULL)
  760                 bus_dma_tag_destroy(sc->mfi_frames_dmat);
  761 
  762         if (sc->mfi_comms_busaddr != 0)
  763                 bus_dmamap_unload(sc->mfi_comms_dmat, sc->mfi_comms_dmamap);
  764         if (sc->mfi_comms != NULL)
  765                 bus_dmamem_free(sc->mfi_comms_dmat, sc->mfi_comms,
  766                     sc->mfi_comms_dmamap);
  767         if (sc->mfi_comms_dmat != NULL)
  768                 bus_dma_tag_destroy(sc->mfi_comms_dmat);
  769 
  770         if (sc->mfi_buffer_dmat != NULL)
  771                 bus_dma_tag_destroy(sc->mfi_buffer_dmat);
  772         if (sc->mfi_parent_dmat != NULL)
  773                 bus_dma_tag_destroy(sc->mfi_parent_dmat);
  774 
  775         if (mtx_initialized(&sc->mfi_io_lock))
  776                 mtx_destroy(&sc->mfi_io_lock);
  777 
  778         return;
  779 }
  780 
  781 static void
  782 mfi_startup(void *arg)
  783 {
  784         struct mfi_softc *sc;
  785 
  786         sc = (struct mfi_softc *)arg;
  787 
  788         config_intrhook_disestablish(&sc->mfi_ich);
  789 
  790         mfi_enable_intr(sc);
  791         mtx_lock(&sc->mfi_io_lock);
  792         mfi_ldprobe(sc);
  793         mtx_unlock(&sc->mfi_io_lock);
  794 }
  795 
  796 static void
  797 mfi_intr(void *arg)
  798 {
  799         struct mfi_softc *sc;
  800         struct mfi_command *cm;
  801         uint32_t status, pi, ci, context;
  802 
  803         sc = (struct mfi_softc *)arg;
  804 
  805         status = MFI_READ4(sc, MFI_OSTS);
  806         if ((status & MFI_OSTS_INTR_VALID) == 0)
  807                 return;
  808 
  809         MFI_WRITE4(sc, MFI_OSTS, status);
  810 
  811         pi = sc->mfi_comms->hw_pi;
  812         ci = sc->mfi_comms->hw_ci;
  813         mtx_lock(&sc->mfi_io_lock);
  814         while (ci != pi) {
  815                 context = sc->mfi_comms->hw_reply_q[ci];
  816                 cm = &sc->mfi_commands[context];
  817                 mfi_remove_busy(cm);
  818                 mfi_complete(sc, cm);
  819                 if (++ci == (sc->mfi_max_fw_cmds + 1)) {
  820                         ci = 0;
  821                 }
  822         }
  823 
  824         sc->mfi_comms->hw_ci = ci;
  825 
  826         /* Give defered I/O a chance to run */
  827         if (sc->mfi_flags & MFI_FLAGS_QFRZN)
  828                 sc->mfi_flags &= ~MFI_FLAGS_QFRZN;
  829         mfi_startio(sc);
  830         mtx_unlock(&sc->mfi_io_lock);
  831 
  832         return;
  833 }
  834 
  835 int
  836 mfi_shutdown(struct mfi_softc *sc)
  837 {
  838         struct mfi_dcmd_frame *dcmd;
  839         struct mfi_command *cm;
  840         int error;
  841 
  842         mtx_lock(&sc->mfi_io_lock);
  843         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_SHUTDOWN, NULL, 0);
  844         if (error) {
  845                 mtx_unlock(&sc->mfi_io_lock);
  846                 return (error);
  847         }
  848 
  849         if (sc->mfi_aen_cm != NULL)
  850                 mfi_abort(sc, sc->mfi_aen_cm);
  851 
  852         dcmd = &cm->cm_frame->dcmd;
  853         dcmd->header.flags = MFI_FRAME_DIR_NONE;
  854 
  855         if ((error = mfi_polled_command(sc, cm)) != 0) {
  856                 device_printf(sc->mfi_dev, "Failed to shutdown controller\n");
  857         }
  858 
  859         mfi_release_command(cm);
  860         mtx_unlock(&sc->mfi_io_lock);
  861         return (error);
  862 }
  863 
  864 static void
  865 mfi_enable_intr(struct mfi_softc *sc)
  866 {
  867 
  868         MFI_WRITE4(sc, MFI_OMSK, 0x01);
  869 }
  870 
  871 static void
  872 mfi_ldprobe(struct mfi_softc *sc)
  873 {
  874         struct mfi_frame_header *hdr;
  875         struct mfi_command *cm = NULL;
  876         struct mfi_ld_list *list = NULL;
  877         int error, i;
  878 
  879         mtx_assert(&sc->mfi_io_lock, MA_OWNED);
  880 
  881         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_LIST,
  882             (void **)&list, sizeof(*list));
  883         if (error)
  884                 goto out;
  885 
  886         cm->cm_flags = MFI_CMD_DATAIN;
  887         if (mfi_wait_command(sc, cm) != 0) {
  888                 device_printf(sc->mfi_dev, "Failed to get device listing\n");
  889                 goto out;
  890         }
  891 
  892         hdr = &cm->cm_frame->header;
  893         if (hdr->cmd_status != MFI_STAT_OK) {
  894                 device_printf(sc->mfi_dev, "MFI_DCMD_LD_GET_LIST failed %x\n",
  895                     hdr->cmd_status);
  896                 goto out;
  897         }
  898 
  899         for (i = 0; i < list->ld_count; i++)
  900                 mfi_add_ld(sc, list->ld_list[i].ld.v.target_id);
  901 out:
  902         if (list)
  903                 free(list, M_MFIBUF);
  904         if (cm)
  905                 mfi_release_command(cm);
  906 
  907         return;
  908 }
  909 
  910 static void
  911 mfi_decode_evt(struct mfi_softc *sc, struct mfi_evt_detail *detail)
  912 {
  913         switch (detail->arg_type) {
  914         case MR_EVT_ARGS_NONE:
  915                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - %s\n",
  916                     detail->seq,
  917                     detail->time,
  918                     detail->class.members.locale,
  919                     detail->class.members.class,
  920                     detail->description
  921                     );
  922                 break;
  923         case MR_EVT_ARGS_CDB_SENSE:
  924                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PD %02d(e%d/s%d) CDB %*D"
  925                     "Sense %*D\n: %s\n",
  926                     detail->seq,
  927                     detail->time,
  928                     detail->class.members.locale,
  929                     detail->class.members.class,
  930                     detail->args.cdb_sense.pd.device_id,
  931                     detail->args.cdb_sense.pd.enclosure_index,
  932                     detail->args.cdb_sense.pd.slot_number,
  933                     detail->args.cdb_sense.cdb_len,
  934                     detail->args.cdb_sense.cdb,
  935                     ":",
  936                     detail->args.cdb_sense.sense_len,
  937                     detail->args.cdb_sense.sense,
  938                     ":",
  939                     detail->description
  940                     );
  941                 break;
  942         case MR_EVT_ARGS_LD:
  943                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
  944                     "event: %s\n",
  945                     detail->seq,
  946                     detail->time,
  947                     detail->class.members.locale,
  948                     detail->class.members.class,
  949                     detail->args.ld.ld_index,
  950                     detail->args.ld.target_id,
  951                     detail->description
  952                     );
  953                 break;
  954         case MR_EVT_ARGS_LD_COUNT:
  955                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
  956                     "count %lld: %s\n",
  957                     detail->seq,
  958                     detail->time,
  959                     detail->class.members.locale,
  960                     detail->class.members.class,
  961                     detail->args.ld_count.ld.ld_index,
  962                     detail->args.ld_count.ld.target_id,
  963                     (long long)detail->args.ld_count.count,
  964                     detail->description
  965                     );
  966                 break;
  967         case MR_EVT_ARGS_LD_LBA:
  968                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
  969                     "lba %lld: %s\n",
  970                     detail->seq,
  971                     detail->time,
  972                     detail->class.members.locale,
  973                     detail->class.members.class,
  974                     detail->args.ld_lba.ld.ld_index,
  975                     detail->args.ld_lba.ld.target_id,
  976                     (long long)detail->args.ld_lba.lba,
  977                     detail->description
  978                     );
  979                 break;
  980         case MR_EVT_ARGS_LD_OWNER:
  981                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
  982                     "owner changed: prior %d, new %d: %s\n",
  983                     detail->seq,
  984                     detail->time,
  985                     detail->class.members.locale,
  986                     detail->class.members.class,
  987                     detail->args.ld_owner.ld.ld_index,
  988                     detail->args.ld_owner.ld.target_id,
  989                     detail->args.ld_owner.pre_owner,
  990                     detail->args.ld_owner.new_owner,
  991                     detail->description
  992                     );
  993                 break;
  994         case MR_EVT_ARGS_LD_LBA_PD_LBA:
  995                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
  996                     "lba %lld, physical drive PD %02d(e%d/s%d) lba %lld: %s\n",
  997                     detail->seq,
  998                     detail->time,
  999                     detail->class.members.locale,
 1000                     detail->class.members.class,
 1001                     detail->args.ld_lba_pd_lba.ld.ld_index,
 1002                     detail->args.ld_lba_pd_lba.ld.target_id,
 1003                     (long long)detail->args.ld_lba_pd_lba.ld_lba,
 1004                     detail->args.ld_lba_pd_lba.pd.device_id,
 1005                     detail->args.ld_lba_pd_lba.pd.enclosure_index,
 1006                     detail->args.ld_lba_pd_lba.pd.slot_number,
 1007                     (long long)detail->args.ld_lba_pd_lba.pd_lba,
 1008                     detail->description
 1009                     );
 1010                 break;
 1011         case MR_EVT_ARGS_LD_PROG:
 1012                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
 1013                     "progress %d%% in %ds: %s\n",
 1014                     detail->seq,
 1015                     detail->time,
 1016                     detail->class.members.locale,
 1017                     detail->class.members.class,
 1018                     detail->args.ld_prog.ld.ld_index,
 1019                     detail->args.ld_prog.ld.target_id,
 1020                     detail->args.ld_prog.prog.progress/655,
 1021                     detail->args.ld_prog.prog.elapsed_seconds,
 1022                     detail->description
 1023                     );
 1024                 break;
 1025         case MR_EVT_ARGS_LD_STATE:
 1026                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
 1027                     "state prior %d new %d: %s\n",
 1028                     detail->seq,
 1029                     detail->time,
 1030                     detail->class.members.locale,
 1031                     detail->class.members.class,
 1032                     detail->args.ld_state.ld.ld_index,
 1033                     detail->args.ld_state.ld.target_id,
 1034                     detail->args.ld_state.prev_state,
 1035                     detail->args.ld_state.new_state,
 1036                     detail->description
 1037                     );
 1038                 break;
 1039         case MR_EVT_ARGS_LD_STRIP:
 1040                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - VD %02d/%d "
 1041                     "strip %lld: %s\n",
 1042                     detail->seq,
 1043                     detail->time,
 1044                     detail->class.members.locale,
 1045                     detail->class.members.class,
 1046                     detail->args.ld_strip.ld.ld_index,
 1047                     detail->args.ld_strip.ld.target_id,
 1048                     (long long)detail->args.ld_strip.strip,
 1049                     detail->description
 1050                     );
 1051                 break;
 1052         case MR_EVT_ARGS_PD:
 1053                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PD %02d(e%d/s%d) "
 1054                     "event: %s\n",
 1055                     detail->seq,
 1056                     detail->time,
 1057                     detail->class.members.locale,
 1058                     detail->class.members.class,
 1059                     detail->args.pd.device_id,
 1060                     detail->args.pd.enclosure_index,
 1061                     detail->args.pd.slot_number,
 1062                     detail->description
 1063                     );
 1064                 break;
 1065         case MR_EVT_ARGS_PD_ERR:
 1066                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PD %02d(e%d/s%d) "
 1067                     "err %d: %s\n",
 1068                     detail->seq,
 1069                     detail->time,
 1070                     detail->class.members.locale,
 1071                     detail->class.members.class,
 1072                     detail->args.pd_err.pd.device_id,
 1073                     detail->args.pd_err.pd.enclosure_index,
 1074                     detail->args.pd_err.pd.slot_number,
 1075                     detail->args.pd_err.err,
 1076                     detail->description
 1077                     );
 1078                 break;
 1079         case MR_EVT_ARGS_PD_LBA:
 1080                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PD %02d(e%d/s%d) "
 1081                     "lba %lld: %s\n",
 1082                     detail->seq,
 1083                     detail->time,
 1084                     detail->class.members.locale,
 1085                     detail->class.members.class,
 1086                     detail->args.pd_lba.pd.device_id,
 1087                     detail->args.pd_lba.pd.enclosure_index,
 1088                     detail->args.pd_lba.pd.slot_number,
 1089                     (long long)detail->args.pd_lba.lba,
 1090                     detail->description
 1091                     );
 1092                 break;
 1093         case MR_EVT_ARGS_PD_LBA_LD:
 1094                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PD %02d(e%d/s%d) "
 1095                     "lba %lld VD %02d/%d: %s\n",
 1096                     detail->seq,
 1097                     detail->time,
 1098                     detail->class.members.locale,
 1099                     detail->class.members.class,
 1100                     detail->args.pd_lba_ld.pd.device_id,
 1101                     detail->args.pd_lba_ld.pd.enclosure_index,
 1102                     detail->args.pd_lba_ld.pd.slot_number,
 1103                     (long long)detail->args.pd_lba.lba,
 1104                     detail->args.pd_lba_ld.ld.ld_index,
 1105                     detail->args.pd_lba_ld.ld.target_id,
 1106                     detail->description
 1107                     );
 1108                 break;
 1109         case MR_EVT_ARGS_PD_PROG:
 1110                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PD %02d(e%d/s%d) "
 1111                     "progress %d%% seconds %ds: %s\n",
 1112                     detail->seq,
 1113                     detail->time,
 1114                     detail->class.members.locale,
 1115                     detail->class.members.class,
 1116                     detail->args.pd_prog.pd.device_id,
 1117                     detail->args.pd_prog.pd.enclosure_index,
 1118                     detail->args.pd_prog.pd.slot_number,
 1119                     detail->args.pd_prog.prog.progress/655,
 1120                     detail->args.pd_prog.prog.elapsed_seconds,
 1121                     detail->description
 1122                     );
 1123                 break;
 1124         case MR_EVT_ARGS_PD_STATE:
 1125                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PD %02d(e%d/s%d) "
 1126                     "state prior %d new %d: %s\n",
 1127                     detail->seq,
 1128                     detail->time,
 1129                     detail->class.members.locale,
 1130                     detail->class.members.class,
 1131                     detail->args.pd_prog.pd.device_id,
 1132                     detail->args.pd_prog.pd.enclosure_index,
 1133                     detail->args.pd_prog.pd.slot_number,
 1134                     detail->args.pd_state.prev_state,
 1135                     detail->args.pd_state.new_state,
 1136                     detail->description
 1137                     );
 1138                 break;
 1139         case MR_EVT_ARGS_PCI:
 1140                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - PCI 0x04%x 0x04%x "
 1141                     "0x04%x 0x04%x: %s\n",
 1142                     detail->seq,
 1143                     detail->time,
 1144                     detail->class.members.locale,
 1145                     detail->class.members.class,
 1146                     detail->args.pci.venderId,
 1147                     detail->args.pci.deviceId,
 1148                     detail->args.pci.subVenderId,
 1149                     detail->args.pci.subDeviceId,
 1150                     detail->description
 1151                     );
 1152                 break;
 1153         case MR_EVT_ARGS_RATE:
 1154                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - Rebuild rate %d: %s\n",
 1155                     detail->seq,
 1156                     detail->time,
 1157                     detail->class.members.locale,
 1158                     detail->class.members.class,
 1159                     detail->args.rate,
 1160                     detail->description
 1161                     );
 1162                 break;
 1163         case MR_EVT_ARGS_TIME:
 1164                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - Adapter ticks %d "
 1165                     "elapsed %ds: %s\n",
 1166                     detail->seq,
 1167                     detail->time,
 1168                     detail->class.members.locale,
 1169                     detail->class.members.class,
 1170                     detail->args.time.rtc,
 1171                     detail->args.time.elapsedSeconds,
 1172                     detail->description
 1173                     );
 1174                 break;
 1175         case MR_EVT_ARGS_ECC:
 1176                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - Adapter ECC %x,%x: %s: %s\n",
 1177                     detail->seq,
 1178                     detail->time,
 1179                     detail->class.members.locale,
 1180                     detail->class.members.class,
 1181                     detail->args.ecc.ecar,
 1182                     detail->args.ecc.elog,
 1183                     detail->args.ecc.str,
 1184                     detail->description
 1185                     );
 1186                 break;
 1187         default:
 1188                 device_printf(sc->mfi_dev, "%d (%us/0x%04x/%d) - Type %d: %s\n",
 1189                     detail->seq,
 1190                     detail->time,
 1191                     detail->class.members.locale,
 1192                     detail->class.members.class,
 1193                     detail->arg_type, detail->description
 1194                     );
 1195         }
 1196 }
 1197 
 1198 static int
 1199 mfi_aen_register(struct mfi_softc *sc, int seq, int locale)
 1200 {
 1201         struct mfi_command *cm;
 1202         struct mfi_dcmd_frame *dcmd;
 1203         union mfi_evt current_aen, prior_aen;
 1204         struct mfi_evt_detail *ed = NULL;
 1205         int error = 0;
 1206 
 1207         current_aen.word = locale;
 1208         if (sc->mfi_aen_cm != NULL) {
 1209                 prior_aen.word =
 1210                     ((uint32_t *)&sc->mfi_aen_cm->cm_frame->dcmd.mbox)[1];
 1211                 if (prior_aen.members.class <= current_aen.members.class &&
 1212                     !((prior_aen.members.locale & current_aen.members.locale)
 1213                     ^current_aen.members.locale)) {
 1214                         return (0);
 1215                 } else {
 1216                         prior_aen.members.locale |= current_aen.members.locale;
 1217                         if (prior_aen.members.class
 1218                             < current_aen.members.class)
 1219                                 current_aen.members.class =
 1220                                     prior_aen.members.class;
 1221                         mfi_abort(sc, sc->mfi_aen_cm);
 1222                 }
 1223         }
 1224 
 1225         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_CTRL_EVENT_WAIT,
 1226             (void **)&ed, sizeof(*ed));
 1227         if (error) {
 1228                 goto out;
 1229         }
 1230 
 1231         dcmd = &cm->cm_frame->dcmd;
 1232         ((uint32_t *)&dcmd->mbox)[0] = seq;
 1233         ((uint32_t *)&dcmd->mbox)[1] = locale;
 1234         cm->cm_flags = MFI_CMD_DATAIN;
 1235         cm->cm_complete = mfi_aen_complete;
 1236 
 1237         sc->mfi_aen_cm = cm;
 1238 
 1239         mfi_enqueue_ready(cm);
 1240         mfi_startio(sc);
 1241 
 1242 out:
 1243         return (error);
 1244 }
 1245 
 1246 static void
 1247 mfi_aen_complete(struct mfi_command *cm)
 1248 {
 1249         struct mfi_frame_header *hdr;
 1250         struct mfi_softc *sc;
 1251         struct mfi_evt_detail *detail;
 1252         struct mfi_aen *mfi_aen_entry, *tmp;
 1253         int seq = 0, aborted = 0;
 1254 
 1255         sc = cm->cm_sc;
 1256         hdr = &cm->cm_frame->header;
 1257 
 1258         if (sc->mfi_aen_cm == NULL)
 1259                 return;
 1260 
 1261         if (sc->mfi_aen_cm->cm_aen_abort || hdr->cmd_status == 0xff) {
 1262                 sc->mfi_aen_cm->cm_aen_abort = 0;
 1263                 aborted = 1;
 1264         } else {
 1265                 sc->mfi_aen_triggered = 1;
 1266                 if (sc->mfi_poll_waiting) {
 1267                         sc->mfi_poll_waiting = 0;
 1268                         selwakeup(&sc->mfi_select);
 1269                 }
 1270                 detail = cm->cm_data;
 1271                 /*
 1272                  * XXX If this function is too expensive or is recursive, then
 1273                  * events should be put onto a queue and processed later.
 1274                  */
 1275                 mtx_unlock(&sc->mfi_io_lock);
 1276                 mfi_decode_evt(sc, detail);
 1277                 mtx_lock(&sc->mfi_io_lock);
 1278                 seq = detail->seq + 1;
 1279                 TAILQ_FOREACH_SAFE(mfi_aen_entry, &sc->mfi_aen_pids, aen_link, tmp) {
 1280                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
 1281                             aen_link);
 1282                         PROC_LOCK(mfi_aen_entry->p);
 1283                         psignal(mfi_aen_entry->p, SIGIO);
 1284                         PROC_UNLOCK(mfi_aen_entry->p);
 1285                         free(mfi_aen_entry, M_MFIBUF);
 1286                 }
 1287         }
 1288 
 1289         free(cm->cm_data, M_MFIBUF);
 1290         sc->mfi_aen_cm = NULL;
 1291         wakeup(&sc->mfi_aen_cm);
 1292         mfi_release_command(cm);
 1293 
 1294         /* set it up again so the driver can catch more events */
 1295         if (!aborted) {
 1296                 mfi_aen_setup(sc, seq);
 1297         }
 1298 }
 1299 
 1300 /* Only do one event for now so we can easily iterate through them */
 1301 #define MAX_EVENTS 1
 1302 static int
 1303 mfi_get_entry(struct mfi_softc *sc, int seq)
 1304 {
 1305         struct mfi_command *cm;
 1306         struct mfi_dcmd_frame *dcmd;
 1307         struct mfi_evt_list *el;
 1308         int error;
 1309         int i;
 1310         int size;
 1311 
 1312         if ((cm = mfi_dequeue_free(sc)) == NULL) {
 1313                 return (EBUSY);
 1314         }
 1315 
 1316         size = sizeof(struct mfi_evt_list) + sizeof(struct mfi_evt_detail)
 1317                 * (MAX_EVENTS - 1);
 1318         el = malloc(size, M_MFIBUF, M_NOWAIT | M_ZERO);
 1319         if (el == NULL) {
 1320                 mfi_release_command(cm);
 1321                 return (ENOMEM);
 1322         }
 1323 
 1324         dcmd = &cm->cm_frame->dcmd;
 1325         bzero(dcmd->mbox, MFI_MBOX_SIZE);
 1326         dcmd->header.cmd = MFI_CMD_DCMD;
 1327         dcmd->header.timeout = 0;
 1328         dcmd->header.data_len = size;
 1329         dcmd->opcode = MFI_DCMD_CTRL_EVENT_GET;
 1330         ((uint32_t *)&dcmd->mbox)[0] = seq;
 1331         ((uint32_t *)&dcmd->mbox)[1] = MFI_EVT_LOCALE_ALL;
 1332         cm->cm_sg = &dcmd->sgl;
 1333         cm->cm_total_frame_size = MFI_DCMD_FRAME_SIZE;
 1334         cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_POLLED;
 1335         cm->cm_data = el;
 1336         cm->cm_len = size;
 1337 
 1338         if ((error = mfi_mapcmd(sc, cm)) != 0) {
 1339                 device_printf(sc->mfi_dev, "Controller info buffer map failed");
 1340                 free(el, M_MFIBUF);
 1341                 mfi_release_command(cm);
 1342                 return (error);
 1343         }
 1344 
 1345         if ((error = mfi_polled_command(sc, cm)) != 0) {
 1346                 device_printf(sc->mfi_dev, "Failed to get controller entry\n");
 1347                 sc->mfi_max_io = (sc->mfi_max_sge - 1) * PAGE_SIZE /
 1348                     MFI_SECTOR_LEN;
 1349                 free(el, M_MFIBUF);
 1350                 mfi_release_command(cm);
 1351                 return (0);
 1352         }
 1353 
 1354         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
 1355             BUS_DMASYNC_POSTREAD);
 1356         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
 1357 
 1358         if (dcmd->header.cmd_status != MFI_STAT_NOT_FOUND) {
 1359                 for (i = 0; i < el->count; i++) {
 1360                         if (seq + i == el->event[i].seq)
 1361                                 mfi_decode_evt(sc, &el->event[i]);
 1362                 }
 1363         }
 1364 
 1365         free(cm->cm_data, M_MFIBUF);
 1366         mfi_release_command(cm);
 1367         return (0);
 1368 }
 1369 
 1370 static int
 1371 mfi_add_ld(struct mfi_softc *sc, int id)
 1372 {
 1373         struct mfi_command *cm;
 1374         struct mfi_dcmd_frame *dcmd = NULL;
 1375         struct mfi_ld_info *ld_info = NULL;
 1376         int error;
 1377 
 1378         mtx_assert(&sc->mfi_io_lock, MA_OWNED);
 1379 
 1380         error = mfi_dcmd_command(sc, &cm, MFI_DCMD_LD_GET_INFO,
 1381             (void **)&ld_info, sizeof(*ld_info));
 1382         if (error) {
 1383                 device_printf(sc->mfi_dev,
 1384                     "Failed to allocate for MFI_DCMD_LD_GET_INFO %d\n", error);
 1385                 if (ld_info)
 1386                         free(ld_info, M_MFIBUF);
 1387                 return (error);
 1388         }
 1389         cm->cm_flags = MFI_CMD_DATAIN;
 1390         dcmd = &cm->cm_frame->dcmd;
 1391         dcmd->mbox[0] = id;
 1392         if (mfi_wait_command(sc, cm) != 0) {
 1393                 device_printf(sc->mfi_dev,
 1394                     "Failed to get logical drive: %d\n", id);
 1395                 free(ld_info, M_MFIBUF);
 1396                 return (0);
 1397         }
 1398 
 1399         mfi_add_ld_complete(cm);
 1400         return (0);
 1401 }
 1402 
 1403 static void
 1404 mfi_add_ld_complete(struct mfi_command *cm)
 1405 {
 1406         struct mfi_frame_header *hdr;
 1407         struct mfi_ld_info *ld_info;
 1408         struct mfi_softc *sc;
 1409         struct mfi_ld *ld;
 1410         device_t child;
 1411 
 1412         sc = cm->cm_sc;
 1413         hdr = &cm->cm_frame->header;
 1414         ld_info = cm->cm_private;
 1415 
 1416         if (hdr->cmd_status != MFI_STAT_OK) {
 1417                 free(ld_info, M_MFIBUF);
 1418                 mfi_release_command(cm);
 1419                 return;
 1420         }
 1421         mfi_release_command(cm);
 1422 
 1423         ld = malloc(sizeof(struct mfi_ld), M_MFIBUF, M_NOWAIT|M_ZERO);
 1424         if (ld == NULL) {
 1425                 device_printf(sc->mfi_dev, "Cannot allocate ld\n");
 1426                 free(ld_info, M_MFIBUF);
 1427                 return;
 1428         }
 1429 
 1430         if ((child = device_add_child(sc->mfi_dev, "mfid", -1)) == NULL) {
 1431                 device_printf(sc->mfi_dev, "Failed to add logical disk\n");
 1432                 free(ld, M_MFIBUF);
 1433                 free(ld_info, M_MFIBUF);
 1434                 return;
 1435         }
 1436 
 1437         ld->ld_id = ld_info->ld_config.properties.ld.v.target_id;
 1438         ld->ld_disk = child;
 1439         ld->ld_info = ld_info;
 1440 
 1441         device_set_ivars(child, ld);
 1442         device_set_desc(child, "MFI Logical Disk");
 1443         mtx_unlock(&sc->mfi_io_lock);
 1444         mtx_lock(&Giant);
 1445         bus_generic_attach(sc->mfi_dev);
 1446         mtx_unlock(&Giant);
 1447         mtx_lock(&sc->mfi_io_lock);
 1448 }
 1449 
 1450 static struct mfi_command *
 1451 mfi_bio_command(struct mfi_softc *sc)
 1452 {
 1453         struct mfi_io_frame *io;
 1454         struct mfi_command *cm;
 1455         struct bio *bio;
 1456         int flags, blkcount;
 1457 
 1458         if ((cm = mfi_dequeue_free(sc)) == NULL)
 1459                 return (NULL);
 1460 
 1461         if ((bio = mfi_dequeue_bio(sc)) == NULL) {
 1462                 mfi_release_command(cm);
 1463                 return (NULL);
 1464         }
 1465 
 1466         io = &cm->cm_frame->io;
 1467         switch (bio->bio_cmd & 0x03) {
 1468         case BIO_READ:
 1469                 io->header.cmd = MFI_CMD_LD_READ;
 1470                 flags = MFI_CMD_DATAIN;
 1471                 break;
 1472         case BIO_WRITE:
 1473                 io->header.cmd = MFI_CMD_LD_WRITE;
 1474                 flags = MFI_CMD_DATAOUT;
 1475                 break;
 1476         default:
 1477                 panic("Invalid bio command");
 1478         }
 1479 
 1480         /* Cheat with the sector length to avoid a non-constant division */
 1481         blkcount = (bio->bio_bcount + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
 1482         io->header.target_id = (uintptr_t)bio->bio_driver1;
 1483         io->header.timeout = 0;
 1484         io->header.flags = 0;
 1485         io->header.sense_len = MFI_SENSE_LEN;
 1486         io->header.data_len = blkcount;
 1487         io->sense_addr_lo = cm->cm_sense_busaddr;
 1488         io->sense_addr_hi = 0;
 1489         io->lba_hi = (bio->bio_pblkno & 0xffffffff00000000) >> 32;
 1490         io->lba_lo = bio->bio_pblkno & 0xffffffff;
 1491         cm->cm_complete = mfi_bio_complete;
 1492         cm->cm_private = bio;
 1493         cm->cm_data = bio->bio_data;
 1494         cm->cm_len = bio->bio_bcount;
 1495         cm->cm_sg = &io->sgl;
 1496         cm->cm_total_frame_size = MFI_IO_FRAME_SIZE;
 1497         cm->cm_flags = flags;
 1498         return (cm);
 1499 }
 1500 
 1501 static void
 1502 mfi_bio_complete(struct mfi_command *cm)
 1503 {
 1504         struct bio *bio;
 1505         struct mfi_frame_header *hdr;
 1506         struct mfi_softc *sc;
 1507 
 1508         bio = cm->cm_private;
 1509         hdr = &cm->cm_frame->header;
 1510         sc = cm->cm_sc;
 1511 
 1512         if ((hdr->cmd_status != 0) || (hdr->scsi_status != 0)) {
 1513                 bio->bio_flags |= BIO_ERROR;
 1514                 bio->bio_error = EIO;
 1515                 device_printf(sc->mfi_dev, "I/O error, status= %d "
 1516                     "scsi_status= %d\n", hdr->cmd_status, hdr->scsi_status);
 1517                 mfi_print_sense(cm->cm_sc, cm->cm_sense);
 1518         }
 1519 
 1520         mfi_release_command(cm);
 1521         mfi_disk_complete(bio);
 1522 }
 1523 
 1524 void
 1525 mfi_startio(struct mfi_softc *sc)
 1526 {
 1527         struct mfi_command *cm;
 1528 
 1529         for (;;) {
 1530                 /* Don't bother if we're short on resources */
 1531                 if (sc->mfi_flags & MFI_FLAGS_QFRZN)
 1532                         break;
 1533 
 1534                 /* Try a command that has already been prepared */
 1535                 cm = mfi_dequeue_ready(sc);
 1536 
 1537                 /* Nope, so look for work on the bioq */
 1538                 if (cm == NULL)
 1539                         cm = mfi_bio_command(sc);
 1540 
 1541                 /* No work available, so exit */
 1542                 if (cm == NULL)
 1543                         break;
 1544 
 1545                 /* Send the command to the controller */
 1546                 if (mfi_mapcmd(sc, cm) != 0) {
 1547                         mfi_requeue_ready(cm);
 1548                         break;
 1549                 }
 1550         }
 1551 }
 1552 
 1553 static int
 1554 mfi_mapcmd(struct mfi_softc *sc, struct mfi_command *cm)
 1555 {
 1556         int error, polled;
 1557 
 1558         mtx_assert(&sc->mfi_io_lock, MA_OWNED);
 1559 
 1560         if (cm->cm_data != NULL) {
 1561                 polled = (cm->cm_flags & MFI_CMD_POLLED) ? BUS_DMA_NOWAIT : 0;
 1562                 error = bus_dmamap_load(sc->mfi_buffer_dmat, cm->cm_dmamap,
 1563                     cm->cm_data, cm->cm_len, mfi_data_cb, cm, polled);
 1564                 if (error == EINPROGRESS) {
 1565                         sc->mfi_flags |= MFI_FLAGS_QFRZN;
 1566                         return (0);
 1567                 }
 1568         } else {
 1569                 cm->cm_timestamp = time_uptime;
 1570                 mfi_enqueue_busy(cm);
 1571                 error = mfi_send_frame(sc, cm);
 1572         }
 1573 
 1574         return (error);
 1575 }
 1576 
 1577 static void
 1578 mfi_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 1579 {
 1580         struct mfi_frame_header *hdr;
 1581         struct mfi_command *cm;
 1582         union mfi_sgl *sgl;
 1583         struct mfi_softc *sc;
 1584         int i, dir;
 1585 
 1586         if (error)
 1587                 return;
 1588 
 1589         cm = (struct mfi_command *)arg;
 1590         sc = cm->cm_sc;
 1591         hdr = &cm->cm_frame->header;
 1592         sgl = cm->cm_sg;
 1593 
 1594         if ((sc->mfi_flags & MFI_FLAGS_SG64) == 0) {
 1595                 for (i = 0; i < nsegs; i++) {
 1596                         sgl->sg32[i].addr = segs[i].ds_addr;
 1597                         sgl->sg32[i].len = segs[i].ds_len;
 1598                 }
 1599         } else {
 1600                 for (i = 0; i < nsegs; i++) {
 1601                         sgl->sg64[i].addr = segs[i].ds_addr;
 1602                         sgl->sg64[i].len = segs[i].ds_len;
 1603                 }
 1604                 hdr->flags |= MFI_FRAME_SGL64;
 1605         }
 1606         hdr->sg_count = nsegs;
 1607 
 1608         dir = 0;
 1609         if (cm->cm_flags & MFI_CMD_DATAIN) {
 1610                 dir |= BUS_DMASYNC_PREREAD;
 1611                 hdr->flags |= MFI_FRAME_DIR_READ;
 1612         }
 1613         if (cm->cm_flags & MFI_CMD_DATAOUT) {
 1614                 dir |= BUS_DMASYNC_PREWRITE;
 1615                 hdr->flags |= MFI_FRAME_DIR_WRITE;
 1616         }
 1617         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
 1618         cm->cm_flags |= MFI_CMD_MAPPED;
 1619 
 1620         /*
 1621          * Instead of calculating the total number of frames in the
 1622          * compound frame, it's already assumed that there will be at
 1623          * least 1 frame, so don't compensate for the modulo of the
 1624          * following division.
 1625          */
 1626         cm->cm_total_frame_size += (sc->mfi_sge_size * nsegs);
 1627         cm->cm_extra_frames = (cm->cm_total_frame_size - 1) / MFI_FRAME_SIZE;
 1628 
 1629         /* The caller will take care of delivering polled commands */
 1630         if ((cm->cm_flags & MFI_CMD_POLLED) == 0) {
 1631                 cm->cm_timestamp = time_uptime;
 1632                 mfi_enqueue_busy(cm);
 1633                 mfi_send_frame(sc, cm);
 1634         }
 1635 
 1636         return;
 1637 }
 1638 
 1639 static int
 1640 mfi_send_frame(struct mfi_softc *sc, struct mfi_command *cm)
 1641 {
 1642 
 1643         /*
 1644          * The bus address of the command is aligned on a 64 byte boundary,
 1645          * leaving the least 6 bits as zero.  For whatever reason, the
 1646          * hardware wants the address shifted right by three, leaving just
 1647          * 3 zero bits.  These three bits are then used as a prefetching
 1648          * hint for the hardware to predict how many frames need to be
 1649          * fetched across the bus.  If a command has more than 8 frames
 1650          * then the 3 bits are set to 0x7 and the firmware uses other
 1651          * information in the command to determine the total amount to fetch.
 1652          * However, FreeBSD doesn't support I/O larger than 128K, so 8 frames
 1653          * is enough for both 32bit and 64bit systems.
 1654          */
 1655         if (cm->cm_extra_frames > 7)
 1656                 cm->cm_extra_frames = 7;
 1657 
 1658         MFI_WRITE4(sc, MFI_IQP, (cm->cm_frame_busaddr >> 3) |
 1659             cm->cm_extra_frames);
 1660         return (0);
 1661 }
 1662 
 1663 static void
 1664 mfi_complete(struct mfi_softc *sc, struct mfi_command *cm)
 1665 {
 1666         int dir;
 1667 
 1668         if ((cm->cm_flags & MFI_CMD_MAPPED) != 0) {
 1669                 dir = 0;
 1670                 if (cm->cm_flags & MFI_CMD_DATAIN)
 1671                         dir |= BUS_DMASYNC_POSTREAD;
 1672                 if (cm->cm_flags & MFI_CMD_DATAOUT)
 1673                         dir |= BUS_DMASYNC_POSTWRITE;
 1674 
 1675                 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap, dir);
 1676                 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
 1677                 cm->cm_flags &= ~MFI_CMD_MAPPED;
 1678         }
 1679 
 1680         if (cm->cm_complete != NULL)
 1681                 cm->cm_complete(cm);
 1682         else
 1683                 wakeup(cm);
 1684 }
 1685 
 1686 static int
 1687 mfi_abort(struct mfi_softc *sc, struct mfi_command *cm_abort)
 1688 {
 1689         struct mfi_command *cm;
 1690         struct mfi_abort_frame *abort;
 1691 
 1692         mtx_assert(&sc->mfi_io_lock, MA_OWNED);
 1693 
 1694         if ((cm = mfi_dequeue_free(sc)) == NULL) {
 1695                 return (EBUSY);
 1696         }
 1697 
 1698         abort = &cm->cm_frame->abort;
 1699         abort->header.cmd = MFI_CMD_ABORT;
 1700         abort->header.flags = 0;
 1701         abort->abort_context = cm_abort->cm_frame->header.context;
 1702         abort->abort_mfi_addr_lo = cm_abort->cm_frame_busaddr;
 1703         abort->abort_mfi_addr_hi = 0;
 1704         cm->cm_data = NULL;
 1705 
 1706         sc->mfi_aen_cm->cm_aen_abort = 1;
 1707         mfi_mapcmd(sc, cm);
 1708         mfi_polled_command(sc, cm);
 1709         mfi_release_command(cm);
 1710 
 1711         while (sc->mfi_aen_cm != NULL) {
 1712                 msleep(&sc->mfi_aen_cm, &sc->mfi_io_lock, 0, "mfiabort", 5 * hz);
 1713         }
 1714 
 1715         return (0);
 1716 }
 1717 
 1718 int
 1719 mfi_dump_blocks(struct mfi_softc *sc, int id, uint64_t lba, void *virt, int len)
 1720 {
 1721         struct mfi_command *cm;
 1722         struct mfi_io_frame *io;
 1723         int error;
 1724 
 1725         if ((cm = mfi_dequeue_free(sc)) == NULL)
 1726                 return (EBUSY);
 1727 
 1728         io = &cm->cm_frame->io;
 1729         io->header.cmd = MFI_CMD_LD_WRITE;
 1730         io->header.target_id = id;
 1731         io->header.timeout = 0;
 1732         io->header.flags = 0;
 1733         io->header.sense_len = MFI_SENSE_LEN;
 1734         io->header.data_len = (len + MFI_SECTOR_LEN - 1) / MFI_SECTOR_LEN;
 1735         io->sense_addr_lo = cm->cm_sense_busaddr;
 1736         io->sense_addr_hi = 0;
 1737         io->lba_hi = (lba & 0xffffffff00000000) >> 32;
 1738         io->lba_lo = lba & 0xffffffff;
 1739         cm->cm_data = virt;
 1740         cm->cm_len = len;
 1741         cm->cm_sg = &io->sgl;
 1742         cm->cm_total_frame_size = MFI_IO_FRAME_SIZE;
 1743         cm->cm_flags = MFI_CMD_POLLED | MFI_CMD_DATAOUT;
 1744 
 1745         if ((error = mfi_mapcmd(sc, cm)) != 0) {
 1746                 mfi_release_command(cm);
 1747                 return (error);
 1748         }
 1749 
 1750         error = mfi_polled_command(sc, cm);
 1751         bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
 1752             BUS_DMASYNC_POSTWRITE);
 1753         bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
 1754         mfi_release_command(cm);
 1755 
 1756         return (error);
 1757 }
 1758 
 1759 static int
 1760 mfi_open(struct cdev *dev, int flags, int fmt, d_thread_t *td)
 1761 {
 1762         struct mfi_softc *sc;
 1763 
 1764         sc = dev->si_drv1;
 1765 
 1766         mtx_lock(&sc->mfi_io_lock);
 1767         sc->mfi_flags |= MFI_FLAGS_OPEN;
 1768         mtx_unlock(&sc->mfi_io_lock);
 1769 
 1770         return (0);
 1771 }
 1772 
 1773 static int
 1774 mfi_close(struct cdev *dev, int flags, int fmt, d_thread_t *td)
 1775 {
 1776         struct mfi_softc *sc;
 1777         struct mfi_aen *mfi_aen_entry, *tmp;
 1778 
 1779         sc = dev->si_drv1;
 1780 
 1781         mtx_lock(&sc->mfi_io_lock);
 1782         sc->mfi_flags &= ~MFI_FLAGS_OPEN;
 1783 
 1784         TAILQ_FOREACH_SAFE(mfi_aen_entry, &sc->mfi_aen_pids, aen_link, tmp) {
 1785                 if (mfi_aen_entry->p == curproc) {
 1786                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
 1787                             aen_link);
 1788                         free(mfi_aen_entry, M_MFIBUF);
 1789                 }
 1790         }
 1791         mtx_unlock(&sc->mfi_io_lock);
 1792         return (0);
 1793 }
 1794 
 1795 static int
 1796 mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
 1797 {
 1798         struct mfi_softc *sc;
 1799         union mfi_statrequest *ms;
 1800         int error;
 1801 
 1802         sc = dev->si_drv1;
 1803         error = 0;
 1804 
 1805         switch (cmd) {
 1806         case MFIIO_STATS:
 1807                 ms = (union mfi_statrequest *)arg;
 1808                 switch (ms->ms_item) {
 1809                 case MFIQ_FREE:
 1810                 case MFIQ_BIO:
 1811                 case MFIQ_READY:
 1812                 case MFIQ_BUSY:
 1813                         bcopy(&sc->mfi_qstat[ms->ms_item], &ms->ms_qstat,
 1814                             sizeof(struct mfi_qstat));
 1815                         break;
 1816                 default:
 1817                         error = ENOIOCTL;
 1818                         break;
 1819                 }
 1820                 break;
 1821         case 0xc1144d01: /* Firmware Linux ioctl shim */
 1822                 {
 1823                         devclass_t devclass;
 1824                         struct mfi_linux_ioc_packet l_ioc;
 1825                         int adapter;
 1826 
 1827                         devclass = devclass_find("mfi");
 1828                         if (devclass == NULL)
 1829                                 return (ENOENT);
 1830 
 1831                         error = copyin(arg, &l_ioc, sizeof(l_ioc));
 1832                         if (error)
 1833                                 return (error);
 1834                         adapter = l_ioc.lioc_adapter_no;
 1835                         sc = devclass_get_softc(devclass, adapter);
 1836                         if (sc == NULL)
 1837                                 return (ENOENT);
 1838                         return (mfi_linux_ioctl_int(sc->mfi_cdev,
 1839                             cmd, arg, flag, td));
 1840                         break;
 1841                 }
 1842         case 0x400c4d03: /* AEN Linux ioctl shim */
 1843                 {
 1844                         devclass_t devclass;
 1845                         struct mfi_linux_ioc_aen l_aen;
 1846                         int adapter;
 1847 
 1848                         devclass = devclass_find("mfi");
 1849                         if (devclass == NULL)
 1850                                 return (ENOENT);
 1851 
 1852                         error = copyin(arg, &l_aen, sizeof(l_aen));
 1853                         if (error)
 1854                                 return (error);
 1855                         adapter = l_aen.laen_adapter_no;
 1856                         sc = devclass_get_softc(devclass, adapter);
 1857                         if (sc == NULL)
 1858                                 return (ENOENT);
 1859                         return (mfi_linux_ioctl_int(sc->mfi_cdev,
 1860                             cmd, arg, flag, td));
 1861                         break;
 1862                 }
 1863         default:
 1864                 device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd);
 1865                 error = ENOENT;
 1866                 break;
 1867         }
 1868 
 1869         return (error);
 1870 }
 1871 
 1872 static int
 1873 mfi_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
 1874 {
 1875         struct mfi_softc *sc;
 1876         struct mfi_linux_ioc_packet l_ioc;
 1877         struct mfi_linux_ioc_aen l_aen;
 1878         struct mfi_command *cm = NULL;
 1879         struct mfi_aen *mfi_aen_entry;
 1880         uint32_t *sense_ptr;
 1881         uint32_t context;
 1882         uint8_t *data = NULL, *temp;
 1883         int i;
 1884         int error;
 1885 
 1886         sc = dev->si_drv1;
 1887         error = 0;
 1888         switch (cmd) {
 1889         case 0xc1144d01: /* Firmware Linux ioctl shim */
 1890                 error = copyin(arg, &l_ioc, sizeof(l_ioc));
 1891                 if (error != 0)
 1892                         return (error);
 1893 
 1894                 if (l_ioc.lioc_sge_count > MAX_LINUX_IOCTL_SGE) {
 1895                         return (EINVAL);
 1896                 }
 1897 
 1898                 mtx_lock(&sc->mfi_io_lock);
 1899                 if ((cm = mfi_dequeue_free(sc)) == NULL) {
 1900                         mtx_unlock(&sc->mfi_io_lock);
 1901                         return (EBUSY);
 1902                 }
 1903                 mtx_unlock(&sc->mfi_io_lock);
 1904 
 1905                 /*
 1906                  * save off original context since copying from user
 1907                  * will clobber some data
 1908                  */
 1909                 context = cm->cm_frame->header.context;
 1910 
 1911                 bcopy(l_ioc.lioc_frame.raw, cm->cm_frame,
 1912                       l_ioc.lioc_sgl_off); /* Linux can do 2 frames ? */
 1913                 cm->cm_total_frame_size = l_ioc.lioc_sgl_off;
 1914                 cm->cm_sg =
 1915                     (union mfi_sgl *)&cm->cm_frame->bytes[l_ioc.lioc_sgl_off];
 1916                 cm->cm_flags = MFI_CMD_DATAIN | MFI_CMD_DATAOUT
 1917                         | MFI_CMD_POLLED;
 1918                 cm->cm_len = cm->cm_frame->header.data_len;
 1919                 cm->cm_data = data = malloc(cm->cm_len, M_MFIBUF,
 1920                                             M_WAITOK | M_ZERO);
 1921 
 1922                 /* restore header context */
 1923                 cm->cm_frame->header.context = context;
 1924 
 1925                 temp = data;
 1926                 for (i = 0; i < l_ioc.lioc_sge_count; i++) {
 1927                         error = copyin(l_ioc.lioc_sgl[i].iov_base,
 1928                                temp,
 1929                                l_ioc.lioc_sgl[i].iov_len);
 1930                         if (error != 0) {
 1931                                 device_printf(sc->mfi_dev,
 1932                                     "Copy in failed");
 1933                                 goto out;
 1934                         }
 1935                         temp = &temp[l_ioc.lioc_sgl[i].iov_len];
 1936                 }
 1937 
 1938                 if (l_ioc.lioc_sense_len) {
 1939                         sense_ptr =
 1940                             (void *)&cm->cm_frame->bytes[l_ioc.lioc_sense_off];
 1941                         *sense_ptr = cm->cm_sense_busaddr;
 1942                 }
 1943 
 1944                 mtx_lock(&sc->mfi_io_lock);
 1945                 if ((error = mfi_mapcmd(sc, cm)) != 0) {
 1946                         device_printf(sc->mfi_dev,
 1947                             "Controller info buffer map failed");
 1948                         mtx_unlock(&sc->mfi_io_lock);
 1949                         goto out;
 1950                 }
 1951 
 1952                 if ((error = mfi_polled_command(sc, cm)) != 0) {
 1953                         device_printf(sc->mfi_dev,
 1954                             "Controller polled failed");
 1955                         mtx_unlock(&sc->mfi_io_lock);
 1956                         goto out;
 1957                 }
 1958 
 1959                 bus_dmamap_sync(sc->mfi_buffer_dmat, cm->cm_dmamap,
 1960                                 BUS_DMASYNC_POSTREAD);
 1961                 bus_dmamap_unload(sc->mfi_buffer_dmat, cm->cm_dmamap);
 1962                 mtx_unlock(&sc->mfi_io_lock);
 1963 
 1964                 temp = data;
 1965                 for (i = 0; i < l_ioc.lioc_sge_count; i++) {
 1966                         error = copyout(temp,
 1967                                 l_ioc.lioc_sgl[i].iov_base,
 1968                                 l_ioc.lioc_sgl[i].iov_len);
 1969                         if (error != 0) {
 1970                                 device_printf(sc->mfi_dev,
 1971                                     "Copy out failed");
 1972                                 goto out;
 1973                         }
 1974                         temp = &temp[l_ioc.lioc_sgl[i].iov_len];
 1975                 }
 1976 
 1977                 if (l_ioc.lioc_sense_len) {
 1978                         /* copy out sense */
 1979                         sense_ptr = (void *)
 1980                             &l_ioc.lioc_frame.raw[l_ioc.lioc_sense_off];
 1981                         temp = 0;
 1982                         temp += cm->cm_sense_busaddr;
 1983                         error = copyout(temp, sense_ptr,
 1984                             l_ioc.lioc_sense_len);
 1985                         if (error != 0) {
 1986                                 device_printf(sc->mfi_dev,
 1987                                     "Copy out failed");
 1988                                 goto out;
 1989                         }
 1990                 }
 1991 
 1992                 error = copyout(&cm->cm_frame->header.cmd_status,
 1993                         &((struct mfi_linux_ioc_packet*)arg)
 1994                         ->lioc_frame.hdr.cmd_status,
 1995                         1);
 1996                 if (error != 0) {
 1997                         device_printf(sc->mfi_dev,
 1998                                       "Copy out failed");
 1999                         goto out;
 2000                 }
 2001 
 2002                 if (cm->cm_frame->header.cmd_status == MFI_STAT_OK) {
 2003                         switch (cm->cm_frame->dcmd.opcode) {
 2004                         case MFI_DCMD_CFG_CLEAR:
 2005                         case MFI_DCMD_CFG_ADD:
 2006                                 /* mfi_ldrescan(sc); */
 2007                                 break;
 2008                         }
 2009                 }
 2010 out:
 2011                 if (data)
 2012                         free(data, M_MFIBUF);
 2013                 if (cm) {
 2014                         mtx_lock(&sc->mfi_io_lock);
 2015                         mfi_release_command(cm);
 2016                         mtx_unlock(&sc->mfi_io_lock);
 2017                 }
 2018 
 2019                 return (error);
 2020         case 0x400c4d03: /* AEN Linux ioctl shim */
 2021                 error = copyin(arg, &l_aen, sizeof(l_aen));
 2022                 if (error != 0)
 2023                         return (error);
 2024                 printf("AEN IMPLEMENTED for pid %d\n", curproc->p_pid);
 2025                 mfi_aen_entry = malloc(sizeof(struct mfi_aen), M_MFIBUF,
 2026                     M_WAITOK);
 2027                 mtx_lock(&sc->mfi_io_lock);
 2028                 if (mfi_aen_entry != NULL) {
 2029                         mfi_aen_entry->p = curproc;
 2030                         TAILQ_INSERT_TAIL(&sc->mfi_aen_pids, mfi_aen_entry,
 2031                             aen_link);
 2032                 }
 2033                 error = mfi_aen_register(sc, l_aen.laen_seq_num,
 2034                     l_aen.laen_class_locale);
 2035 
 2036                 if (error != 0) {
 2037                         TAILQ_REMOVE(&sc->mfi_aen_pids, mfi_aen_entry,
 2038                             aen_link);
 2039                         free(mfi_aen_entry, M_MFIBUF);
 2040                 }
 2041                 mtx_unlock(&sc->mfi_io_lock);
 2042 
 2043                 return (error);
 2044         default:
 2045                 device_printf(sc->mfi_dev, "IOCTL 0x%lx not handled\n", cmd);
 2046                 error = ENOENT;
 2047                 break;
 2048         }
 2049 
 2050         return (error);
 2051 }
 2052 
 2053 static int
 2054 mfi_poll(struct cdev *dev, int poll_events, struct thread *td)
 2055 {
 2056         struct mfi_softc *sc;
 2057         int revents = 0;
 2058 
 2059         sc = dev->si_drv1;
 2060 
 2061         if (poll_events & (POLLIN | POLLRDNORM)) {
 2062                 if (sc->mfi_aen_triggered != 0) {
 2063                         revents |= poll_events & (POLLIN | POLLRDNORM);
 2064                         sc->mfi_aen_triggered = 0;
 2065                 }
 2066                 if (sc->mfi_aen_triggered == 0 && sc->mfi_aen_cm == NULL) {
 2067                         revents |= POLLERR;
 2068                 }
 2069         }
 2070 
 2071         if (revents == 0) {
 2072                 if (poll_events & (POLLIN | POLLRDNORM)) {
 2073                         sc->mfi_poll_waiting = 1;
 2074                         selrecord(td, &sc->mfi_select);
 2075                 }
 2076         }
 2077 
 2078         return revents;
 2079 }
 2080 
 2081 
 2082 static void
 2083 mfi_dump_all(void)
 2084 {
 2085         struct mfi_softc *sc;
 2086         struct mfi_command *cm;
 2087         devclass_t dc;
 2088         time_t deadline;
 2089         int timedout;
 2090         int i;
 2091 
 2092         dc = devclass_find("mfi");
 2093         if (dc == NULL) {
 2094                 printf("No mfi dev class\n");
 2095                 return;
 2096         }
 2097 
 2098         for (i = 0; ; i++) {
 2099                 sc = devclass_get_softc(dc, i);
 2100                 if (sc == NULL)
 2101                         break;
 2102                 device_printf(sc->mfi_dev, "Dumping\n\n");
 2103                 timedout = 0;
 2104                 deadline = time_uptime - MFI_CMD_TIMEOUT;
 2105                 mtx_lock(&sc->mfi_io_lock);
 2106                 TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {
 2107                         if (cm->cm_timestamp < deadline) {
 2108                                 device_printf(sc->mfi_dev,
 2109                                     "COMMAND %p TIMEOUT AFTER %d SECONDS\n", cm,
 2110                                     (int)(time_uptime - cm->cm_timestamp));
 2111                                 MFI_PRINT_CMD(cm);
 2112                                 timedout++;
 2113                         }
 2114                 }
 2115 
 2116 #if 0
 2117                 if (timedout)
 2118                         MFI_DUMP_CMDS(SC);
 2119 #endif
 2120 
 2121                 mtx_unlock(&sc->mfi_io_lock);
 2122         }
 2123 
 2124         return;
 2125 }
 2126 
 2127 static void
 2128 mfi_timeout(void *data)
 2129 {
 2130         struct mfi_softc *sc = (struct mfi_softc *)data;
 2131         struct mfi_command *cm;
 2132         time_t deadline;
 2133         int timedout = 0;
 2134 
 2135         deadline = time_uptime - MFI_CMD_TIMEOUT;
 2136         mtx_lock(&sc->mfi_io_lock);
 2137         TAILQ_FOREACH(cm, &sc->mfi_busy, cm_link) {
 2138                 if (sc->mfi_aen_cm == cm)
 2139                         continue;
 2140                 if ((sc->mfi_aen_cm != cm) && (cm->cm_timestamp < deadline)) {
 2141                         device_printf(sc->mfi_dev,
 2142                             "COMMAND %p TIMEOUT AFTER %d SECONDS\n", cm,
 2143                             (int)(time_uptime - cm->cm_timestamp));
 2144                         MFI_PRINT_CMD(cm);
 2145                         MFI_VALIDATE_CMD(sc, cm);
 2146                         timedout++;
 2147                 }
 2148         }
 2149 
 2150 #if 0
 2151         if (timedout)
 2152                 MFI_DUMP_CMDS(SC);
 2153 #endif
 2154 
 2155         mtx_unlock(&sc->mfi_io_lock);
 2156 
 2157         callout_reset(&sc->mfi_watchdog_callout, MFI_CMD_TIMEOUT * hz,
 2158             mfi_timeout, sc);
 2159 
 2160         if (0)
 2161                 mfi_dump_all();
 2162         return;
 2163 }

Cache object: f6b4f991a003acbfa7bad62a8ccab2b2


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