diff options
-rw-r--r-- | sys/dev/ic/mfi.c | 62 | ||||
-rw-r--r-- | sys/dev/ic/mfireg.h | 10 | ||||
-rw-r--r-- | sys/dev/ic/mfivar.h | 6 | ||||
-rw-r--r-- | sys/dev/pci/mfi_pci.c | 8 |
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; |