summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2014-08-15 02:27:03 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2014-08-15 02:27:03 +0000
commitd4c6fdba14c8b6b7961206f206cc676c18999e10 (patch)
treee3fc2acd38cfa5d021d201b94a46f06afbe116aa
parent37792d05050fa16b0ff6ee09fcc573f1a138a962 (diff)
Create a function which loads sgd in the mfi_iop_ops struct so that skinny
adapters can use "IEEE sgl". tested dlg yasuoka ok dlg jsg
-rw-r--r--sys/dev/ic/mfi.c83
-rw-r--r--sys/dev/ic/mfireg.h10
-rw-r--r--sys/dev/ic/mfivar.h3
3 files changed, 74 insertions, 22 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index 5f906cb5193..8ec4c95d8a2 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.154 2014/07/13 23:10:23 deraadt Exp $ */
+/* $OpenBSD: mfi.c,v 1.155 2014/08/15 02:27:02 yasuoka Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -93,6 +93,7 @@ void mfi_poll(struct mfi_softc *, struct mfi_ccb *);
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_xscale = {
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_ppc = {
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_gen2 = {
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_softc *);
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_skinny = {
#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 mfi_iop iop)
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, struct mfi_ccb *ccb, int flags)
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, struct mfi_ccb *ccb, int flags)
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"
@@ -2414,6 +2431,32 @@ mfi_skinny_post(struct mfi_softc *sc, struct mfi_ccb *ccb)
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
mfi_pd_scsi_probe(struct scsi_link *link)
{
diff --git a/sys/dev/ic/mfireg.h b/sys/dev/ic/mfireg.h
index 127f15098ee..d2a762ea89f 100644
--- a/sys/dev/ic/mfireg.h
+++ b/sys/dev/ic/mfireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfireg.h,v 1.40 2013/05/03 02:46:28 dlg Exp $ */
+/* $OpenBSD: mfireg.h,v 1.41 2014/08/15 02:27:02 yasuoka Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -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 */
diff --git a/sys/dev/ic/mfivar.h b/sys/dev/ic/mfivar.h
index cca07c77d7f..e6d3c953414 100644
--- a/sys/dev/ic/mfivar.h
+++ b/sys/dev/ic/mfivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfivar.h,v 1.53 2013/05/03 02:46:28 dlg Exp $ */
+/* $OpenBSD: mfivar.h,v 1.54 2014/08/15 02:27:02 yasuoka Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -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)