summaryrefslogtreecommitdiff
path: root/sys/dev/ic/mfi.c
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2009-01-28 23:45:14 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2009-01-28 23:45:14 +0000
commitadb0f8055811d210b8d23380b978df9b5184c366 (patch)
treee8ee8c4761f61cb42ef0b516a2cb0066ed5d04e9 /sys/dev/ic/mfi.c
parent23697c413a15d456b77c9ec40de9685fcacde4bf (diff)
Add support for next generation megaraid sas raid controllers.
From Jim Giannoules <gortag@gmail.com>
Diffstat (limited to 'sys/dev/ic/mfi.c')
-rw-r--r--sys/dev/ic/mfi.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index 2a24027598f..8166d17a33f 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.87 2008/10/31 21:39:04 marco Exp $ */
+/* $OpenBSD: mfi.c,v 1.88 2009/01/28 23:45:12 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -131,6 +131,18 @@ static const struct mfi_iop_ops mfi_iop_ppc = {
mfi_ppc_post
};
+u_int32_t mfi_gen2_fw_state(struct mfi_softc *sc);
+void mfi_gen2_intr_ena(struct mfi_softc *sc);
+int mfi_gen2_intr(struct mfi_softc *sc);
+void mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb);
+
+static const struct mfi_iop_ops mfi_iop_gen2 = {
+ mfi_gen2_fw_state,
+ mfi_gen2_intr_ena,
+ mfi_gen2_intr,
+ mfi_gen2_post
+};
+
#define mfi_fw_state(_s) ((_s)->sc_iop->mio_fw_state(_s))
#define mfi_intr_enable(_s) ((_s)->sc_iop->mio_intr_ena(_s))
#define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s))
@@ -612,6 +624,9 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop)
case MFI_IOP_PPC:
sc->sc_iop = &mfi_iop_ppc;
break;
+ case MFI_IOP_GEN2:
+ sc->sc_iop = &mfi_iop_gen2;
+ break;
default:
panic("%s: unknown iop %d", DEVNAME(sc), iop);
}
@@ -2029,3 +2044,38 @@ mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb)
mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe |
(ccb->ccb_extra_frames << 1));
}
+
+u_int32_t
+mfi_gen2_fw_state(struct mfi_softc *sc)
+{
+ return (mfi_read(sc, MFI_OSP));
+}
+
+void
+mfi_gen2_intr_ena(struct mfi_softc *sc)
+{
+ mfi_write(sc, MFI_ODC, 0xffffffff);
+ mfi_write(sc, MFI_OMSK, ~MFI_OSTS_GEN2_INTR_VALID);
+}
+
+int
+mfi_gen2_intr(struct mfi_softc *sc)
+{
+ u_int32_t status;
+
+ status = mfi_read(sc, MFI_OSTS);
+ if (!ISSET(status, MFI_OSTS_GEN2_INTR_VALID))
+ return (0);
+
+ /* write status back to acknowledge interrupt */
+ mfi_write(sc, MFI_ODC, status);
+
+ return (1);
+}
+
+void
+mfi_gen2_post(struct mfi_softc *sc, struct mfi_ccb *ccb)
+{
+ mfi_write(sc, MFI_IQP, 0x1 | ccb->ccb_pframe |
+ (ccb->ccb_extra_frames << 1));
+}