summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ic/mfi.c62
-rw-r--r--sys/dev/ic/mfireg.h10
-rw-r--r--sys/dev/ic/mfivar.h6
-rw-r--r--sys/dev/pci/mfi_pci.c8
4 files changed, 78 insertions, 8 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c
index ef68f444187..95c00472604 100644
--- a/sys/dev/ic/mfi.c
+++ b/sys/dev/ic/mfi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi.c,v 1.121 2011/07/17 22:46:48 matthew Exp $ */
+/* $OpenBSD: mfi.c,v 1.122 2012/01/12 06:12:30 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -145,6 +145,18 @@ static const struct mfi_iop_ops mfi_iop_gen2 = {
mfi_gen2_post
};
+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 *);
+
+static const struct mfi_iop_ops mfi_iop_skinny = {
+ mfi_skinny_fw_state,
+ mfi_skinny_intr_ena,
+ mfi_skinny_intr,
+ mfi_skinny_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))
@@ -366,11 +378,17 @@ mfi_transition_firmware(struct mfi_softc *sc)
printf("%s: firmware fault\n", DEVNAME(sc));
return (1);
case MFI_STATE_WAIT_HANDSHAKE:
- mfi_write(sc, MFI_IDB, MFI_INIT_CLEAR_HANDSHAKE);
+ if (sc->sc_flags & MFI_IOP_SKINNY)
+ mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_CLEAR_HANDSHAKE);
+ else
+ mfi_write(sc, MFI_IDB, MFI_INIT_CLEAR_HANDSHAKE);
max_wait = 2;
break;
case MFI_STATE_OPERATIONAL:
- mfi_write(sc, MFI_IDB, MFI_INIT_READY);
+ if (sc->sc_flags & MFI_IOP_SKINNY)
+ mfi_write(sc, MFI_SKINNY_IDB, MFI_INIT_READY);
+ else
+ mfi_write(sc, MFI_IDB, MFI_INIT_READY);
max_wait = 10;
break;
case MFI_STATE_UNDEFINED:
@@ -646,6 +664,9 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop)
case MFI_IOP_GEN2:
sc->sc_iop = &mfi_iop_gen2;
break;
+ case MFI_IOP_SKINNY:
+ sc->sc_iop = &mfi_iop_skinny;
+ break;
default:
panic("%s: unknown iop %d", DEVNAME(sc), iop);
}
@@ -2170,3 +2191,38 @@ 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));
}
+
+u_int32_t
+mfi_skinny_fw_state(struct mfi_softc *sc)
+{
+ return (mfi_read(sc, MFI_OSP));
+}
+
+void
+mfi_skinny_intr_ena(struct mfi_softc *sc)
+{
+ mfi_write(sc, MFI_OMSK, ~0x00000001);
+}
+
+int
+mfi_skinny_intr(struct mfi_softc *sc)
+{
+ u_int32_t status;
+
+ status = mfi_read(sc, MFI_OSTS);
+ if (!ISSET(status, MFI_OSTS_SKINNY_INTR_VALID))
+ return (0);
+
+ /* write status back to acknowledge interrupt */
+ mfi_write(sc, MFI_OSTS, status);
+
+ return (1);
+}
+
+void
+mfi_skinny_post(struct mfi_softc *sc, struct mfi_ccb *ccb)
+{
+ mfi_write(sc, MFI_IQPL, 0x1 | ccb->ccb_pframe |
+ (ccb->ccb_extra_frames << 1));
+ mfi_write(sc, MFI_IQPH, 0x00000000);
+}
diff --git a/sys/dev/ic/mfireg.h b/sys/dev/ic/mfireg.h
index f7f19e82c0f..7a6a817ce35 100644
--- a/sys/dev/ic/mfireg.h
+++ b/sys/dev/ic/mfireg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfireg.h,v 1.29 2011/04/08 19:23:46 marco Exp $ */
+/* $OpenBSD: mfireg.h,v 1.30 2012/01/12 06:12:30 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -45,6 +45,14 @@
#define MFI_ODC 0xa0 /* outbound doorbell clr */
#define MFI_OSP 0xb0 /* outbound scratch pad */
+/*
+ * skinny specific changes
+*/
+#define MFI_SKINNY_IDB 0x00 /* Inbound doorbell is at 0x00 for skinny */
+#define MFI_IQPL 0x000000c0
+#define MFI_IQPH 0x000000c4
+#define MFI_OSTS_SKINNY_INTR_VALID 0x00000001
+
/* * firmware states */
#define MFI_STATE_MASK 0xf0000000
#define MFI_STATE_UNDEFINED 0x00000000
diff --git a/sys/dev/ic/mfivar.h b/sys/dev/ic/mfivar.h
index 2c9ccb3775d..ac4ceec60c3 100644
--- a/sys/dev/ic/mfivar.h
+++ b/sys/dev/ic/mfivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfivar.h,v 1.41 2011/04/09 20:23:31 marco Exp $ */
+/* $OpenBSD: mfivar.h,v 1.42 2012/01/12 06:12:30 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -95,7 +95,8 @@ SLIST_HEAD(mfi_ccb_list, mfi_ccb);
enum mfi_iop {
MFI_IOP_XSCALE,
MFI_IOP_PPC,
- MFI_IOP_GEN2
+ MFI_IOP_GEN2,
+ MFI_IOP_SKINNY
};
struct mfi_iop_ops {
@@ -114,6 +115,7 @@ struct mfi_softc {
const struct mfi_iop_ops *sc_iop;
int sc_64bit_dma;
+ int sc_flags;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
diff --git a/sys/dev/pci/mfi_pci.c b/sys/dev/pci/mfi_pci.c
index 2e12b7905a2..d30f731af6e 100644
--- a/sys/dev/pci/mfi_pci.c
+++ b/sys/dev/pci/mfi_pci.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mfi_pci.c,v 1.25 2011/07/20 20:15:23 marco Exp $ */
+/* $OpenBSD: mfi_pci.c,v 1.26 2012/01/12 06:12:30 dlg Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -105,6 +105,8 @@ struct mfi_pci_device {
MFI_IOP_GEN2, mfi_gen2_subtypes },
{ PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS2108_2,
MFI_IOP_GEN2, mfi_gen2_subtypes },
+ { PCI_VENDOR_SYMBIOS, PCI_PRODUCT_SYMBIOS_SAS2008_1,
+ MFI_IOP_SKINNY, NULL },
};
const struct mfi_pci_device *mfi_pci_find_device(struct pci_attach_args *);
@@ -153,7 +155,9 @@ mfi_pci_attach(struct device *parent, struct device *self, void *aux)
return;
}
- if (mpd->mpd_iop == MFI_IOP_GEN2)
+ sc->sc_flags = mpd->mpd_iop;
+
+ if (mpd->mpd_iop == MFI_IOP_GEN2 || mpd->mpd_iop == MFI_IOP_SKINNY)
regbar = MFI_BAR_GEN2;
else
regbar = MFI_BAR;