Index: mfi.c =================================================================== RCS file: /cvs/src/sys/dev/ic/mfi.c,v retrieving revision 1.154 diff -u -p -r1.154 mfi.c --- mfi.c 13 Jul 2014 23:10:23 -0000 1.154 +++ mfi.c 13 Aug 2014 09:52:36 -0000 @@ -93,6 +93,7 @@ void mfi_poll(struct mfi_softc *, struc void mfi_exec(struct mfi_softc *, struct mfi_ccb *); void mfi_exec_done(struct mfi_softc *, struct mfi_ccb *); int mfi_create_sgl(struct mfi_softc *, struct mfi_ccb *, int); +u_int mfi_default_sgd_load(struct mfi_softc *, struct mfi_ccb *); int mfi_syspd(struct mfi_softc *); /* commands */ @@ -136,6 +137,7 @@ static const struct mfi_iop_ops mfi_iop_ mfi_xscale_intr_ena, mfi_xscale_intr, mfi_xscale_post, + mfi_default_sgd_load, 0, }; @@ -149,6 +151,7 @@ static const struct mfi_iop_ops mfi_iop_ mfi_ppc_intr_ena, mfi_ppc_intr, mfi_ppc_post, + mfi_default_sgd_load, MFI_IDB, 0 }; @@ -163,6 +166,7 @@ static const struct mfi_iop_ops mfi_iop_ mfi_gen2_intr_ena, mfi_gen2_intr, mfi_gen2_post, + mfi_default_sgd_load, MFI_IDB, 0 }; @@ -171,12 +175,14 @@ u_int32_t mfi_skinny_fw_state(struct mfi void mfi_skinny_intr_ena(struct mfi_softc *); int mfi_skinny_intr(struct mfi_softc *); void mfi_skinny_post(struct mfi_softc *, struct mfi_ccb *); +u_int mfi_skinny_sgd_load(struct mfi_softc *, struct mfi_ccb *); static const struct mfi_iop_ops mfi_iop_skinny = { mfi_skinny_fw_state, mfi_skinny_intr_ena, mfi_skinny_intr, mfi_skinny_post, + mfi_skinny_sgd_load, MFI_SKINNY_IDB, MFI_IOP_F_SYSPD }; @@ -185,6 +191,7 @@ static const struct mfi_iop_ops mfi_iop_ #define mfi_intr_enable(_s) ((_s)->sc_iop->mio_intr_ena(_s)) #define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s)) #define mfi_post(_s, _c) ((_s)->sc_iop->mio_post((_s), (_c))) +#define mfi_sgd_load(_s, _c) ((_s)->sc_iop->mio_sgd_load((_s), (_c))) void * mfi_get_ccb(void *cookie) @@ -709,6 +716,8 @@ mfi_attach(struct mfi_softc *sc, enum mf sc->sc_sgl_size = sizeof(struct mfi_sg32); sc->sc_sgl_flags = MFI_FRAME_SGL32; } + if (iop == MFI_IOP_SKINNY) + sc->sc_sgl_size = sizeof(struct mfi_sg_skinny); DNPRINTF(MFI_D_MISC, "%s: 64bit: %d max commands: %u, max sgl: %u\n", DEVNAME(sc), sc->sc_64bit_dma, sc->sc_max_cmds, sc->sc_max_sgl); @@ -1235,13 +1244,36 @@ complete: scsi_done(xs); } +u_int +mfi_default_sgd_load(struct mfi_softc *sc, struct mfi_ccb *ccb) +{ + union mfi_sgl *sgl = ccb->ccb_sgl; + bus_dma_segment_t *sgd = ccb->ccb_dmamap->dm_segs; + int i; + + for (i = 0; i < ccb->ccb_dmamap->dm_nsegs; i++) { + if (sc->sc_64bit_dma) { + sgl->sg64[i].addr = htole64(sgd[i].ds_addr); + sgl->sg64[i].len = htole32(sgd[i].ds_len); + DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", + DEVNAME(sc), sgl->sg64[i].addr, sgl->sg64[i].len); + } else { + sgl->sg32[i].addr = htole32(sgd[i].ds_addr); + sgl->sg32[i].len = htole32(sgd[i].ds_len); + DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", + DEVNAME(sc), sgl->sg32[i].addr, sgl->sg32[i].len); + } + } + + return (ccb->ccb_dmamap->dm_nsegs * + (sc->sc_64bit_dma ? sizeof(sgl->sg64) : sizeof(sgl->sg32))); +} + int mfi_create_sgl(struct mfi_softc *sc, struct mfi_ccb *ccb, int flags) { struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; - bus_dma_segment_t *sgd; - union mfi_sgl *sgl; - int error, i; + int error; DNPRINTF(MFI_D_DMA, "%s: mfi_create_sgl %#x\n", DEVNAME(sc), ccb->ccb_data); @@ -1262,21 +1294,7 @@ mfi_create_sgl(struct mfi_softc *sc, str return (1); } - sgl = ccb->ccb_sgl; - sgd = ccb->ccb_dmamap->dm_segs; - for (i = 0; i < ccb->ccb_dmamap->dm_nsegs; i++) { - if (sc->sc_64bit_dma) { - sgl->sg64[i].addr = htole64(sgd[i].ds_addr); - sgl->sg64[i].len = htole32(sgd[i].ds_len); - DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", - DEVNAME(sc), sgl->sg64[i].addr, sgl->sg64[i].len); - } else { - sgl->sg32[i].addr = htole32(sgd[i].ds_addr); - sgl->sg32[i].len = htole32(sgd[i].ds_len); - DNPRINTF(MFI_D_DMA, "%s: addr: %#x len: %#x\n", - DEVNAME(sc), sgl->sg32[i].addr, sgl->sg32[i].len); - } - } + ccb->ccb_frame_size += mfi_sgd_load(sc, ccb); if (ccb->ccb_direction == MFI_DATA_IN) { hdr->mfh_flags |= MFI_FRAME_DIR_READ; @@ -1290,7 +1308,6 @@ mfi_create_sgl(struct mfi_softc *sc, str hdr->mfh_flags |= sc->sc_sgl_flags; hdr->mfh_sg_count = ccb->ccb_dmamap->dm_nsegs; - ccb->ccb_frame_size += sc->sc_sgl_size * ccb->ccb_dmamap->dm_nsegs; ccb->ccb_extra_frames = (ccb->ccb_frame_size - 1) / MFI_FRAME_SIZE; DNPRINTF(MFI_D_DMA, "%s: sg_count: %d frame_size: %d frames_size: %d" @@ -2412,6 +2429,32 @@ mfi_skinny_post(struct mfi_softc *sc, st mfi_write(sc, MFI_IQPL, 0x1 | ccb->ccb_pframe | (ccb->ccb_extra_frames << 1)); mfi_write(sc, MFI_IQPH, 0x00000000); +} + +u_int +mfi_skinny_sgd_load(struct mfi_softc *sc, struct mfi_ccb *ccb) +{ + struct mfi_frame_header *hdr = &ccb->ccb_frame->mfr_header; + union mfi_sgl *sgl = ccb->ccb_sgl; + bus_dma_segment_t *sgd = ccb->ccb_dmamap->dm_segs; + int i; + + switch (hdr->mfh_cmd) { + case MFI_CMD_LD_READ: + case MFI_CMD_LD_WRITE: + case MFI_CMD_PD_SCSI_IO: + /* Use MF_FRAME_IEEE for some IO commands on skinny adapters */ + for (i = 0; i < ccb->ccb_dmamap->dm_nsegs; i++) { + sgl->sg_skinny[i].addr = htole64(sgd[i].ds_addr); + sgl->sg_skinny[i].len = htole32(sgd[i].ds_len); + sgl->sg_skinny[i].flag = 0; + } + hdr->mfh_flags |= MFI_FRAME_IEEE; + + return (ccb->ccb_dmamap->dm_nsegs * sizeof(sgl->sg_skinny)); + default: + return (mfi_default_sgd_load(sc, ccb)); + } } int Index: mfireg.h =================================================================== RCS file: /cvs/src/sys/dev/ic/mfireg.h,v retrieving revision 1.40 diff -u -p -r1.40 mfireg.h --- mfireg.h 3 May 2013 02:46:28 -0000 1.40 +++ mfireg.h 13 Aug 2014 09:52:36 -0000 @@ -86,6 +86,7 @@ #define MFI_FRAME_DIR_WRITE 0x0008 #define MFI_FRAME_DIR_READ 0x0010 #define MFI_FRAME_DIR_BOTH 0x0018 +#define MFI_FRAME_IEEE 0x0020 /* mfi command opcodes */ #define MFI_CMD_INIT 0x00 @@ -275,9 +276,16 @@ struct mfi_sg64 { uint32_t len; } __packed; +struct mfi_sg_skinny { + uint64_t addr; + uint32_t len; + uint32_t flag; +} __packed; + union mfi_sgl { struct mfi_sg32 sg32[1]; struct mfi_sg64 sg64[1]; + struct mfi_sg_skinny sg_skinny[1]; } __packed; /* message frame */ Index: mfivar.h =================================================================== RCS file: /cvs/src/sys/dev/ic/mfivar.h,v retrieving revision 1.53 diff -u -p -r1.53 mfivar.h --- mfivar.h 3 May 2013 02:46:28 -0000 1.53 +++ mfivar.h 13 Aug 2014 09:52:36 -0000 @@ -105,6 +105,7 @@ struct mfi_iop_ops { void (*mio_intr_ena)(struct mfi_softc *); int (*mio_intr)(struct mfi_softc *); void (*mio_post)(struct mfi_softc *, struct mfi_ccb *); + u_int (*mio_sgd_load)(struct mfi_softc *, struct mfi_ccb *); u_int32_t mio_idb; u_int32_t mio_flags; #define MFI_IOP_F_SYSPD (1 << 0)