Hi tech@,

while trying to add bio(4) support to mfii(4), we noticed that SAS2208
based card with cache memory hangs on boot.
 https://marc.info/?t=147738428600001&r=1&w=2

after investigation, we made conclusion that MPII SCSI PASSTHRU feature
need to be used for sending MFI commands (such as DCMD_*) instead of
using MFA request.

this patch shouldn't change any functionality/behavior, but this is
required for upcoming bio(4) support.

tested on: SAS2208, SAS3008, and SAS3108

--- sys/dev/pci/mfii.c
+++ sys/dev/pci/mfii.c
@@ -44,6 +44,8 @@
 
 #define MFII_OSTS_INTR_VALID   0x00000009
 #define MFII_RPI               0x6c /* reply post host index */
+#define MFII_OSP2              0xb4 /* outbound scratch pad 2 */
+#define MFII_OSP3              0xb8 /* outbound scratch pad 3 */
 
 #define MFII_REQ_TYPE_SCSI     MPII_REQ_DESCR_SCSI_IO
 #define MFII_REQ_TYPE_LDIO     (0x7 << 1)
@@ -51,20 +53,42 @@
 #define MFII_REQ_TYPE_NO_LOCK  (0x2 << 1)
 #define MFII_REQ_TYPE_HI_PRI   (0x6 << 1)
 
-#define MFII_REQ_MFA(_a)       htole64((_a) | MFII_REQ_TYPE_MFA)
-
 #define MFII_FUNCTION_PASSTHRU_IO                      (0xf0)
 #define MFII_FUNCTION_LDIO_REQUEST                     (0xf1)
 
-struct mfii_request_descr {
+#define MFII_MAX_CHAIN_UNIT    0x00400000
+#define MFII_MAX_CHAIN_MASK    0x000003E0
+#define MFII_MAX_CHAIN_SHIFT   5
+
+#define MFII_256K_IO           128
+#define MFII_1MB_IO            (MFII_256K_IO * 4)
+
+#define MFII_CHAIN_FRAME_MIN   1024
+
+struct mfii_scsi_io_request_descr {
        u_int8_t        flags;
        u_int8_t        msix_index;
        u_int16_t       smid;
-
        u_int16_t       lmid;
        u_int16_t       dev_handle;
 } __packed;
 
+struct mfii_mfa_io_request_descr {
+       u_int32_t       flags:8;
+       u_int32_t       addr1:24;
+       u_int32_t       addr2;
+} __packed;
+
+union mfii_request_descr {
+       struct mfii_scsi_io_request_descr       scsi;
+       struct mfii_mfa_io_request_descr        mfa;
+       struct {
+               u_int32_t                       lo;
+               u_int32_t                       hi;
+       } __packed u;
+       u_int64_t                               word;
+};
+
 #define MFII_RAID_CTX_IO_TYPE_SYSPD    (0x1 << 4)
 #define MFII_RAID_CTX_TYPE_CUDA                (0x2 << 4)
 
@@ -180,6 +204,10 @@ struct mfii_ccb {
        u_int64_t               ccb_request_dva;
        bus_addr_t              ccb_request_offset;
 
+       void                    *ccb_mfi;
+       u_int64_t               ccb_mfi_dva;
+       bus_addr_t              ccb_mfi_offset;
+
        struct mfi_sense        *ccb_sense;
        u_int64_t               ccb_sense_dva;
        bus_addr_t              ccb_sense_offset;
@@ -189,7 +217,7 @@ struct mfii_ccb {
        bus_addr_t              ccb_sgl_offset;
        u_int                   ccb_sgl_len;
 
-       struct mfii_request_descr ccb_req;
+       union mfii_request_descr ccb_req;
 
        bus_dmamap_t            ccb_dmamap;
 
@@ -250,6 +278,7 @@ struct mfii_softc {
        struct mutex            sc_ccb_mtx;
        struct mutex            sc_post_mtx;
 
+       u_int                   sc_max_fw_cmds;
        u_int                   sc_max_cmds;
        u_int                   sc_max_sgl;
 
@@ -259,6 +288,7 @@ struct mfii_softc {
        struct mfii_dmamem      *sc_reply_postq;
 
        struct mfii_dmamem      *sc_requests;
+       struct mfii_dmamem      *sc_mfi;
        struct mfii_dmamem      *sc_sense;
        struct mfii_dmamem      *sc_sgl;
 
@@ -280,6 +310,32 @@ struct mfii_softc {
        struct mfi_ctrl_info    sc_info;
 };
 
+#ifdef MFII_DEBUG
+#define DPRINTF(x...)          do { if (mfii_debug) printf(x); } while(0)
+#define DNPRINTF(n,x...)       do { if (mfii_debug & n) printf(x); } while(0)
+#define        MFII_D_CMD              0x0001
+#define        MFII_D_INTR             0x0002
+#define        MFII_D_MISC             0x0004
+#define        MFII_D_DMA              0x0008
+#define        MFII_D_IOCTL            0x0010
+#define        MFII_D_RW               0x0020
+#define        MFII_D_MEM              0x0040
+#define        MFII_D_CCB              0x0080
+uint32_t       mfii_debug = 0
+/*                 | MFII_D_CMD */
+/*                 | MFII_D_INTR */
+/*                 | MFII_D_MISC */
+/*                 | MFII_D_DMA */
+/*                 | MFII_D_IOCTL */
+/*                 | MFII_D_RW */
+/*                 | MFII_D_MEM */
+/*                 | MFII_D_CCB */
+               ;
+#else
+#define DPRINTF(x...)
+#define DNPRINTF(n,x...)
+#endif
+
 int            mfii_match(struct device *, void *, void *);
 void           mfii_attach(struct device *, struct device *, void *);
 int            mfii_detach(struct device *, int);
@@ -356,6 +412,7 @@ int                 mfii_mfa_poll(struct mfii_softc *, 
struct mfii_ccb *);
 int                    mfii_mgmt(struct mfii_softc *, struct mfii_ccb *,
                            u_int32_t, const union mfi_mbox *,
                            void *, size_t, int);
+void                   mfii_empty_done(struct mfii_softc *, struct mfii_ccb *);
 
 int                    mfii_scsi_cmd_io(struct mfii_softc *,
                            struct scsi_xfer *);
@@ -517,7 +574,8 @@ mfii_attach(struct device *parent, struct device *self, 
void *aux)
        pcireg_t memtype;
        pci_intr_handle_t ih;
        struct scsibus_attach_args saa;
-       u_int32_t status;
+       u_int32_t status, scpad2, scpad3;
+       int chain_frame_sz, nsge_in_io, nsge_in_chain;
 
        /* init sc */
        sc->sc_iop = mfii_find_iop(aux);
@@ -556,9 +614,43 @@ mfii_attach(struct device *parent, struct device *self, 
void *aux)
        if (mfii_transition_firmware(sc))
                goto pci_unmap;
 
+       /* determine max_cmds (refer to the Linux megaraid_sas driver) */
+       scpad3 = mfii_read(sc, MFII_OSP3);
        status = mfii_fw_state(sc);
-       sc->sc_max_cmds = status & MFI_STATE_MAXCMD_MASK;
-       sc->sc_max_sgl = (status & MFI_STATE_MAXSGL_MASK) >> 16;
+       sc->sc_max_fw_cmds = scpad3 & MFI_STATE_MAXCMD_MASK;
+       if (sc->sc_max_fw_cmds == 0)
+               sc->sc_max_fw_cmds = status & MFI_STATE_MAXCMD_MASK;
+       /*
+        * reduce max_cmds by 1 to ensure that the reply queue depth does not
+        * exceed FW supplied max_fw_cmds.
+        */
+       sc->sc_max_cmds = min(sc->sc_max_fw_cmds, 1024) - 1;
+
+       /* determine max_sgl (refer to the Linux megaraid_sas driver) */
+       scpad2 = mfii_read(sc, MFII_OSP2);
+       chain_frame_sz =
+               ((scpad2 & MFII_MAX_CHAIN_MASK) >> MFII_MAX_CHAIN_SHIFT) *
+               ((scpad2 & MFII_MAX_CHAIN_UNIT) ? MFII_1MB_IO : MFII_256K_IO);
+       if (chain_frame_sz < MFII_CHAIN_FRAME_MIN)
+               chain_frame_sz = MFII_CHAIN_FRAME_MIN;
+
+       nsge_in_io = (MFII_REQUEST_SIZE -
+               sizeof(struct mpii_msg_scsi_io) -
+               sizeof(struct mfii_raid_context)) / sizeof(struct mfii_sge);
+       nsge_in_chain = chain_frame_sz / sizeof(struct mfii_sge);
+
+       /* round down to nearlest power of two */
+       sc->sc_max_sgl = 1;
+       while ((sc->sc_max_sgl << 1) <= (nsge_in_io + nsge_in_chain))
+               sc->sc_max_sgl <<= 1;
+
+       DNPRINTF(MFII_D_MISC, "%s: OSP 0x%08x, OSP2 0x%08x, OSP3 0x%08x\n",
+           __func__, status, scpad2, scpad3);
+       DNPRINTF(MFII_D_MISC, "%s: max_fw_cmds %d, max_cmds %d\n",
+           __func__, sc->sc_max_fw_cmds, sc->sc_max_cmds);
+       DNPRINTF(MFII_D_MISC, "%s: nsge_in_io %d, nsge_in_chain %d, "
+           "max_sgl %d\n", __func__, nsge_in_io, nsge_in_chain,
+           sc->sc_max_sgl);
 
        /* sense memory */
        CTASSERT(sizeof(struct mfi_sense) == MFI_SENSE_SIZE);
@@ -568,7 +660,8 @@ mfii_attach(struct device *parent, struct device *self, 
void *aux)
                goto pci_unmap;
        }
 
-       sc->sc_reply_postq_depth = roundup(sc->sc_max_cmds, 16);
+       /* reply post queue */
+       sc->sc_reply_postq_depth = roundup(sc->sc_max_fw_cmds, 16);
 
        sc->sc_reply_postq = mfii_dmamem_alloc(sc,
            sc->sc_reply_postq_depth * sizeof(struct mpii_reply_descr));
@@ -578,15 +671,22 @@ mfii_attach(struct device *parent, struct device *self, 
void *aux)
        memset(MFII_DMA_KVA(sc->sc_reply_postq), 0xff,
            MFII_DMA_LEN(sc->sc_reply_postq));
 
+       /* MPII request frame array */
        sc->sc_requests = mfii_dmamem_alloc(sc,
            MFII_REQUEST_SIZE * (sc->sc_max_cmds + 1));
        if (sc->sc_requests == NULL)
                goto free_reply_postq;
 
+       /* MFI command frame array */
+       sc->sc_mfi = mfii_dmamem_alloc(sc, sc->sc_max_cmds * MFI_FRAME_SIZE);
+       if (sc->sc_mfi == NULL)
+               goto free_requests;
+
+       /* MPII SGL array */
        sc->sc_sgl = mfii_dmamem_alloc(sc, sc->sc_max_cmds *
            sizeof(struct mfii_sge) * sc->sc_max_sgl);
        if (sc->sc_sgl == NULL)
-               goto free_requests;
+               goto free_mfi;
 
        if (mfii_init_ccb(sc) != 0) {
                printf("%s: could not init ccb list\n", DEVNAME(sc));
@@ -644,6 +744,8 @@ intr_disestablish:
        pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
 free_sgl:
        mfii_dmamem_free(sc, sc->sc_sgl);
+free_mfi:
+       mfii_dmamem_free(sc, sc->sc_mfi);
 free_requests:
        mfii_dmamem_free(sc, sc->sc_requests);
 free_reply_postq:
@@ -762,6 +864,7 @@ mfii_detach(struct device *self, int flags)
        mfii_aen_unregister(sc);
        pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
        mfii_dmamem_free(sc, sc->sc_sgl);
+       mfii_dmamem_free(sc, sc->sc_mfi);
        mfii_dmamem_free(sc, sc->sc_requests);
        mfii_dmamem_free(sc, sc->sc_reply_postq);
        mfii_dmamem_free(sc, sc->sc_sense);
@@ -853,8 +956,8 @@ mfii_dcmd_start(struct mfii_softc *sc, struct mfii_ccb *ccb)
        htolem32(&sge->sg_len, sizeof(*ccb->ccb_sense));
        sge->sg_flags = MFII_SGE_CHAIN_ELEMENT | MFII_SGE_ADDR_IOCPLBNTA;
 
-       ccb->ccb_req.flags = MFII_REQ_TYPE_SCSI;
-       ccb->ccb_req.smid = letoh16(ccb->ccb_smid);
+       ccb->ccb_req.scsi.flags = MFII_REQ_TYPE_SCSI;
+       ccb->ccb_req.scsi.smid = letoh16(ccb->ccb_smid);
 
        mfii_start(sc, ccb);
 }
@@ -1279,8 +1382,14 @@ mfii_get_info(struct mfii_softc *sc)
 int
 mfii_mfa_poll(struct mfii_softc *sc, struct mfii_ccb *ccb)
 {
+       /*
+        * Since the frame address passed to the F/W through Inbound Queue
+        * Port register must be aligned to 256 byte boundary, this means
+        * that we can not use MFI frame memory (ccb->ccb_mfi) which is 128
+        * byte boundary here.  Caller must ensure that the MFI frame is built
+        * in the MPII frame memory (ccb->ccb_request).
+        */
        struct mfi_frame_header *hdr = ccb->ccb_request;
-       u_int64_t r;
        int to = 0, rv = 0;
 
 #ifdef DIAGNOSTIC
@@ -1289,11 +1398,12 @@ mfii_mfa_poll(struct mfii_softc *sc, struct mfii_ccb 
*ccb)
 #endif
 
        hdr->mfh_context = ccb->ccb_smid;
-       hdr->mfh_cmd_status = 0xff;
+       hdr->mfh_cmd_status = MFI_STAT_INVALID_STATUS;
        hdr->mfh_flags |= htole16(MFI_FRAME_DONT_POST_IN_REPLY_QUEUE);
 
-       r = MFII_REQ_MFA(ccb->ccb_request_dva);
-       memcpy(&ccb->ccb_req, &r, sizeof(ccb->ccb_req));
+       ccb->ccb_req.u.lo = htole32(ccb->ccb_request_dva);
+       ccb->ccb_req.u.hi = htole32(ccb->ccb_request_dva >> 32);
+       ccb->ccb_req.mfa.flags |= MFII_REQ_TYPE_MFA;
 
        mfii_start(sc, ccb);
 
@@ -1302,7 +1412,7 @@ mfii_mfa_poll(struct mfii_softc *sc, struct mfii_ccb *ccb)
                    ccb->ccb_request_offset, MFII_REQUEST_SIZE,
                    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
 
-               if (hdr->mfh_cmd_status != 0xff)
+               if (hdr->mfh_cmd_status != MFI_STAT_INVALID_STATUS)
                        break;
 
                if (to++ > 5000) { /* XXX 5 seconds busywait sucks */
@@ -1379,6 +1489,8 @@ mfii_exec(struct mfii_softc *sc, struct mfii_ccb *ccb)
        ccb->ccb_cookie = &m;
        ccb->ccb_done = mfii_exec_done;
 
+       mfii_start(sc, ccb);
+
        mtx_enter(&m);
        while (ccb->ccb_cookie != NULL)
                msleep(ccb, &m, PRIBIO, "mfiiexec", 0);
@@ -1403,11 +1515,13 @@ mfii_mgmt(struct mfii_softc *sc, struct mfii_ccb *ccb,
     u_int32_t opc, const union mfi_mbox *mbox, void *buf, size_t len,
     int flags)
 {
-       struct mfi_dcmd_frame *dcmd = ccb->ccb_request;
-       struct mfi_frame_header *hdr = &dcmd->mdf_header;
-       u_int64_t r;
+       struct mpii_msg_scsi_io *io = ccb->ccb_request;
+       struct mfii_raid_context *ctx = (struct mfii_raid_context *)(io + 1);
+       struct mfii_sge *sge = (struct mfii_sge *)(ctx + 1);
+       struct mfi_dcmd_frame *dcmd = ccb->ccb_mfi;
+       struct mfi_frame_header *hdr = &dcmd->mdf_header;
        u_int8_t *dma_buf;
-       int rv = EIO;
+       int rv = 0;
 
        dma_buf = dma_alloc(len, PR_WAITOK);
        if (dma_buf == NULL)
@@ -1444,27 +1558,55 @@ mfii_mgmt(struct mfii_softc *sc, struct mfii_ccb *ccb,
        if (mbox != NULL)
                memcpy(&dcmd->mdf_mbox, mbox, sizeof(dcmd->mdf_mbox));
 
-       if (ISSET(flags, SCSI_NOSLEEP))
-               mfii_mfa_poll(sc, ccb);
-       else {
-               r = MFII_REQ_MFA(ccb->ccb_request_dva);
-               memcpy(&ccb->ccb_req, &r, sizeof(ccb->ccb_req));
+       io->function = MFII_FUNCTION_PASSTHRU_IO;
+       io->sgl_offset0 = ((u_int8_t *)sge - (u_int8_t *)io) / 4;
+       io->chain_offset = ((u_int8_t *)sge - (u_int8_t *)io) / 16;
+
+       htolem64(&sge->sg_addr, ccb->ccb_mfi_dva);
+       htolem32(&sge->sg_len, MFI_FRAME_SIZE);
+       sge->sg_flags = MFII_SGE_CHAIN_ELEMENT | MFII_SGE_ADDR_IOCPLBNTA;
+
+       ccb->ccb_req.scsi.flags = MFII_REQ_TYPE_SCSI;
+       ccb->ccb_req.scsi.smid = letoh16(ccb->ccb_smid);
+
+       if (ISSET(flags, SCSI_NOSLEEP)) {
+               /* busy-loop polling with done handler */
+               ccb->ccb_cookie = NULL;
+               ccb->ccb_done = mfii_empty_done;
+               mfii_poll(sc, ccb);
+       } else {
+               /* sleep/wakeup without done handler */
+               ccb->ccb_cookie = NULL;
+               ccb->ccb_done = NULL;
                mfii_exec(sc, ccb);
        }
 
-       if (hdr->mfh_cmd_status == MFI_STAT_OK) {
-               rv = 0;
+       if (ccb->ccb_len > 0) {
+               bus_dmamap_sync(sc->sc_dmat, ccb->ccb_dmamap,
+                   0, ccb->ccb_dmamap->dm_mapsize,
+                   (ccb->ccb_direction == MFII_DATA_IN) ?
+                   BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
 
-               if (ccb->ccb_direction == MFII_DATA_IN)
-                       memcpy(buf, dma_buf, len);
+               bus_dmamap_unload(sc->sc_dmat, ccb->ccb_dmamap);
        }
 
+       rv = hdr->mfh_cmd_status == MFI_STAT_OK ? 0 : 1;
+
+       if (rv == 0 && ccb->ccb_direction == MFII_DATA_IN)
+               memcpy(buf, dma_buf, len);
+
 done:
        dma_free(dma_buf, len);
 
        return (rv);
 }
 
+void
+mfii_empty_done(struct mfii_softc *sc, struct mfii_ccb *ccb)
+{
+       return;
+}
+
 int
 mfii_load_mfa(struct mfii_softc *sc, struct mfii_ccb *ccb,
     void *sglp, int nosleep)
@@ -1500,21 +1642,22 @@ mfii_load_mfa(struct mfii_softc *sc, struct mfii_ccb 
*ccb,
 void
 mfii_start(struct mfii_softc *sc, struct mfii_ccb *ccb)
 {
-       u_long *r = (u_long *)&ccb->ccb_req;
-
        bus_dmamap_sync(sc->sc_dmat, MFII_DMA_MAP(sc->sc_requests),
            ccb->ccb_request_offset, MFII_REQUEST_SIZE,
            BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 
 #if defined(__LP64__)
-       bus_space_write_raw_8(sc->sc_iot, sc->sc_ioh, MFI_IQPL, *r);
+       bus_space_write_raw_8(sc->sc_iot, sc->sc_ioh,
+           MFI_IQPL, ccb->ccb_req.word);
 #else
        mtx_enter(&sc->sc_post_mtx);
-       bus_space_write_raw_4(sc->sc_iot, sc->sc_ioh, MFI_IQPL, r[0]);
+       bus_space_write_raw_4(sc->sc_iot, sc->sc_ioh,
+           MFI_IQPL, ccb->ccb_req.u.lo);
        bus_space_barrier(sc->sc_iot, sc->sc_ioh,
            MFI_IQPL, 8, BUS_SPACE_BARRIER_WRITE);
 
-       bus_space_write_raw_4(sc->sc_iot, sc->sc_ioh, MFI_IQPH, r[1]);
+       bus_space_write_raw_4(sc->sc_iot, sc->sc_ioh,
+           MFI_IQPH, ccb->ccb_req.u.hi);
        bus_space_barrier(sc->sc_iot, sc->sc_ioh,
            MFI_IQPH, 8, BUS_SPACE_BARRIER_WRITE);
        mtx_leave(&sc->sc_post_mtx);
@@ -1839,8 +1982,8 @@ mfii_scsi_cmd_io(struct mfii_softc *sc, struct scsi_xfer 
*xs)
                break;
        }
 
-       ccb->ccb_req.flags = sc->sc_iop->ldio_req_type;
-       ccb->ccb_req.smid = letoh16(ccb->ccb_smid);
+       ccb->ccb_req.scsi.flags = sc->sc_iop->ldio_req_type;
+       ccb->ccb_req.scsi.smid = letoh16(ccb->ccb_smid);
 
        return (0);
 }
@@ -1886,8 +2029,8 @@ mfii_scsi_cmd_cdb(struct mfii_softc *sc, struct scsi_xfer 
*xs)
 
        ctx->num_sge = (ccb->ccb_len == 0) ? 0 : ccb->ccb_dmamap->dm_nsegs;
 
-       ccb->ccb_req.flags = MFII_REQ_TYPE_SCSI;
-       ccb->ccb_req.smid = letoh16(ccb->ccb_smid);
+       ccb->ccb_req.scsi.flags = MFII_REQ_TYPE_SCSI;
+       ccb->ccb_req.scsi.smid = letoh16(ccb->ccb_smid);
 
        return (0);
 }
@@ -2007,9 +2150,9 @@ mfii_pd_scsi_cmd_cdb(struct mfii_softc *sc, struct 
scsi_xfer *xs)
 
        ctx->num_sge = (ccb->ccb_len == 0) ? 0 : ccb->ccb_dmamap->dm_nsegs;
 
-       ccb->ccb_req.flags = MFII_REQ_TYPE_HI_PRI;
-       ccb->ccb_req.smid = letoh16(ccb->ccb_smid);
-       ccb->ccb_req.dev_handle = dev_handle;
+       ccb->ccb_req.scsi.flags = MFII_REQ_TYPE_HI_PRI;
+       ccb->ccb_req.scsi.smid = letoh16(ccb->ccb_smid);
+       ccb->ccb_req.scsi.dev_handle = dev_handle;
 
        return (XS_NOERROR);
 }
@@ -2153,8 +2296,8 @@ mfii_abort(struct mfii_softc *sc, struct mfii_ccb *accb, 
uint16_t dev_handle,
        htolem16(&req->task_mid, smid);
        msg->flags = flags;
 
-       accb->ccb_req.flags = MFII_REQ_TYPE_HI_PRI;
-       accb->ccb_req.smid = letoh16(accb->ccb_smid);
+       accb->ccb_req.scsi.flags = MFII_REQ_TYPE_HI_PRI;
+       accb->ccb_req.scsi.smid = letoh16(accb->ccb_smid);
 }
 
 void
@@ -2200,6 +2343,7 @@ mfii_scrub_ccb(struct mfii_ccb *ccb)
 
        memset(&ccb->ccb_req, 0, sizeof(ccb->ccb_req));
        memset(ccb->ccb_request, 0, MFII_REQUEST_SIZE);
+       memset(ccb->ccb_mfi, 0, MFI_FRAME_SIZE);
 }
 
 void
@@ -2218,6 +2362,7 @@ mfii_init_ccb(struct mfii_softc *sc)
 {
        struct mfii_ccb *ccb;
        u_int8_t *request = MFII_DMA_KVA(sc->sc_requests);
+       u_int8_t *mfi = MFII_DMA_KVA(sc->sc_mfi);
        u_int8_t *sense = MFII_DMA_KVA(sc->sc_sense);
        u_int8_t *sgl = MFII_DMA_KVA(sc->sc_sgl);
        u_int i;
@@ -2246,6 +2391,12 @@ mfii_init_ccb(struct mfii_softc *sc)
                ccb->ccb_request_dva = MFII_DMA_DVA(sc->sc_requests) +
                    ccb->ccb_request_offset;
 
+               /* select i'th MFI command frame */
+               ccb->ccb_mfi_offset = MFI_FRAME_SIZE * i;
+               ccb->ccb_mfi = mfi + ccb->ccb_mfi_offset;
+               ccb->ccb_mfi_dva = MFII_DMA_DVA(sc->sc_mfi) +
+                   ccb->ccb_mfi_offset;
+
                /* select i'th sense */
                ccb->ccb_sense_offset = MFI_SENSE_SIZE * i;
                ccb->ccb_sense = (struct mfi_sense *)(sense +

--
FUKAUMI Naoki

Reply via email to