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

Cache object: 034c7c0a179f67ff42f1b87eec771168


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