Module Name: src Committed By: dyoung Date: Thu Jul 16 01:01:47 UTC 2009
Modified Files: src/sys/dev/ic: mfi.c mfivar.h src/sys/dev/pci: mfi_pci.c Log Message: Add a rudimentary detachment hook for mfi(4). To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/sys/dev/ic/mfi.c cvs rdiff -u -r1.10 -r1.11 src/sys/dev/ic/mfivar.h cvs rdiff -u -r1.8 -r1.9 src/sys/dev/pci/mfi_pci.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/mfi.c diff -u src/sys/dev/ic/mfi.c:1.23 src/sys/dev/ic/mfi.c:1.24 --- src/sys/dev/ic/mfi.c:1.23 Tue May 12 14:25:17 2009 +++ src/sys/dev/ic/mfi.c Thu Jul 16 01:01:47 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: mfi.c,v 1.23 2009/05/12 14:25:17 cegger Exp $ */ +/* $NetBSD: mfi.c,v 1.24 2009/07/16 01:01:47 dyoung Exp $ */ /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.23 2009/05/12 14:25:17 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.24 2009/07/16 01:01:47 dyoung Exp $"); #include "bio.h" @@ -104,17 +104,20 @@ struct bioc_setstate *); static int mfi_bio_hs(struct mfi_softc *, int, int, void *); static int mfi_create_sensors(struct mfi_softc *); +static int mfi_destroy_sensors(struct mfi_softc *); static void mfi_sensor_refresh(struct sysmon_envsys *, envsys_data_t *); #endif /* NBIO > 0 */ static uint32_t mfi_xscale_fw_state(struct mfi_softc *sc); static void mfi_xscale_intr_ena(struct mfi_softc *sc); +static void mfi_xscale_intr_dis(struct mfi_softc *sc); static int mfi_xscale_intr(struct mfi_softc *sc); static void mfi_xscale_post(struct mfi_softc *sc, struct mfi_ccb *ccb); static const struct mfi_iop_ops mfi_iop_xscale = { mfi_xscale_fw_state, + mfi_xscale_intr_dis, mfi_xscale_intr_ena, mfi_xscale_intr, mfi_xscale_post @@ -122,11 +125,13 @@ static uint32_t mfi_ppc_fw_state(struct mfi_softc *sc); static void mfi_ppc_intr_ena(struct mfi_softc *sc); +static void mfi_ppc_intr_dis(struct mfi_softc *sc); static int mfi_ppc_intr(struct mfi_softc *sc); static void mfi_ppc_post(struct mfi_softc *sc, struct mfi_ccb *ccb); static const struct mfi_iop_ops mfi_iop_ppc = { mfi_ppc_fw_state, + mfi_ppc_intr_dis, mfi_ppc_intr_ena, mfi_ppc_intr, mfi_ppc_post @@ -134,6 +139,7 @@ #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_intr_disable(_s) ((_s)->sc_iop->mio_intr_dis(_s)) #define mfi_my_intr(_s) ((_s)->sc_iop->mio_intr(_s)) #define mfi_post(_s, _c) ((_s)->sc_iop->mio_post((_s), (_c))) @@ -180,6 +186,28 @@ } static int +mfi_destroy_ccb(struct mfi_softc *sc) +{ + struct mfi_ccb *ccb; + uint32_t i; + + DNPRINTF(MFI_D_CCB, "%s: mfi_init_ccb\n", DEVNAME(sc)); + + + for (i = 0; (ccb = mfi_get_ccb(sc)) != NULL; i++) { + /* create a dma map for transfer */ + bus_dmamap_destroy(sc->sc_dmat, ccb->ccb_dmamap); + } + + if (i < sc->sc_max_cmds) + return EBUSY; + + free(sc->sc_ccb, M_DEVBUF); + + return 0; +} + +static int mfi_init_ccb(struct mfi_softc *sc) { struct mfi_ccb *ccb; @@ -601,6 +629,37 @@ } int +mfi_detach(struct mfi_softc *sc, int flags) +{ + int error; + + DNPRINTF(MFI_D_MISC, "%s: mfi_detach\n", DEVNAME(sc)); + +#if NBIO > 0 + mfi_destroy_sensors(sc); + bio_unregister(&sc->sc_dev); +#endif /* NBIO > 0 */ + + mfi_intr_disable(sc); + + if ((error = config_detach_children(&sc->sc_dev, flags)) != 0) + return error; + + /* TBD: shutdown firmware */ + + if ((error = mfi_destroy_ccb(sc)) != 0) + return error; + + mfi_freemem(sc, sc->sc_sense); + + mfi_freemem(sc, sc->sc_frames); + + mfi_freemem(sc, sc->sc_pcq); + + return 0; +} + +int mfi_attach(struct mfi_softc *sc, enum mfi_iop iop) { struct scsipi_adapter *adapt = &sc->sc_adapt; @@ -1879,6 +1938,14 @@ } static int +mfi_destroy_sensors(struct mfi_softc *sc) +{ + sysmon_envsys_unregister(sc->sc_sme); + free(sc->sc_sensor, M_DEVBUF); + return 0; +} + +static int mfi_create_sensors(struct mfi_softc *sc) { int i; @@ -1976,6 +2043,12 @@ } static void +mfi_xscale_intr_dis(struct mfi_softc *sc) +{ + mfi_write(sc, MFI_OMSK, 0); +} + +static void mfi_xscale_intr_ena(struct mfi_softc *sc) { mfi_write(sc, MFI_OMSK, MFI_ENABLE_INTR); @@ -2016,6 +2089,14 @@ } static void +mfi_ppc_intr_dis(struct mfi_softc *sc) +{ + /* Taking a wild guess --dyoung */ + mfi_write(sc, MFI_OMSK, ~(uint32_t)0x0); + mfi_write(sc, MFI_ODC, 0xffffffff); +} + +static void mfi_ppc_intr_ena(struct mfi_softc *sc) { mfi_write(sc, MFI_ODC, 0xffffffff); Index: src/sys/dev/ic/mfivar.h diff -u src/sys/dev/ic/mfivar.h:1.10 src/sys/dev/ic/mfivar.h:1.11 --- src/sys/dev/ic/mfivar.h:1.10 Tue Jun 24 10:09:24 2008 +++ src/sys/dev/ic/mfivar.h Thu Jul 16 01:01:47 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: mfivar.h,v 1.10 2008/06/24 10:09:24 gmcgarry Exp $ */ +/* $NetBSD: mfivar.h,v 1.11 2009/07/16 01:01:47 dyoung Exp $ */ /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us> @@ -103,6 +103,7 @@ struct mfi_iop_ops { uint32_t (*mio_fw_state)(struct mfi_softc *); + void (*mio_intr_dis)(struct mfi_softc *); void (*mio_intr_ena)(struct mfi_softc *); int (*mio_intr)(struct mfi_softc *); void (*mio_post)(struct mfi_softc *, struct mfi_ccb *); @@ -122,6 +123,7 @@ bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; bus_dma_tag_t sc_dmat; + bus_size_t sc_size; /* save some useful information for logical drives that is missing * in sc_ld_list @@ -161,5 +163,6 @@ }; -int mfi_attach(struct mfi_softc *sc, enum mfi_iop); +int mfi_attach(struct mfi_softc *, enum mfi_iop); +int mfi_detach(struct mfi_softc *, int); int mfi_intr(void *); Index: src/sys/dev/pci/mfi_pci.c diff -u src/sys/dev/pci/mfi_pci.c:1.8 src/sys/dev/pci/mfi_pci.c:1.9 --- src/sys/dev/pci/mfi_pci.c:1.8 Tue May 12 08:23:01 2009 +++ src/sys/dev/pci/mfi_pci.c Thu Jul 16 01:01:46 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: mfi_pci.c,v 1.8 2009/05/12 08:23:01 cegger Exp $ */ +/* $NetBSD: mfi_pci.c,v 1.9 2009/07/16 01:01:46 dyoung Exp $ */ /* $OpenBSD: mfi_pci.c,v 1.11 2006/08/06 04:40:08 brad Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <ma...@peereboom.us> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mfi_pci.c,v 1.8 2009/05/12 08:23:01 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mfi_pci.c,v 1.9 2009/07/16 01:01:46 dyoung Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -40,12 +40,18 @@ #define MFI_BAR 0x10 #define MFI_PCI_MEMSIZE 0x2000 /* 8k */ +struct mfi_pci_softc { + struct mfi_softc psc_sc; + pci_chipset_tag_t psc_pc; +}; + const struct mfi_pci_device *mfi_pci_find_device(struct pci_attach_args *); int mfi_pci_match(device_t, cfdata_t, void *); void mfi_pci_attach(device_t, device_t, void *); +int mfi_pci_detach(device_t, int); -CFATTACH_DECL(mfi_pci, sizeof(struct mfi_softc), - mfi_pci_match, mfi_pci_attach, NULL, NULL); +CFATTACH_DECL(mfi_pci, sizeof(struct mfi_pci_softc), + mfi_pci_match, mfi_pci_attach, mfi_pci_detach, NULL); struct mfi_pci_subtype { pcireg_t st_vendor; @@ -117,24 +123,42 @@ return (mfi_pci_find_device(aux) != NULL) ? 1 : 0; } +int +mfi_pci_detach(device_t self, int flags) +{ + struct mfi_pci_softc *psc = device_private(self); + struct mfi_softc *sc = &psc->psc_sc; + int error; + + if ((error = mfi_detach(sc, flags)) != 0) + return error; + + /* xxx */ + pci_intr_disestablish(psc->psc_pc, sc->sc_ih); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); + return 0; +} + void mfi_pci_attach(device_t parent, device_t self, void *aux) { - struct mfi_softc *sc = device_private(self); + struct mfi_pci_softc *psc = device_private(self); + struct mfi_softc *sc = &psc->psc_sc; struct pci_attach_args *pa = aux; const struct mfi_pci_device *mpd; const struct mfi_pci_subtype *st; const char *intrstr; pci_intr_handle_t ih; - bus_size_t size; pcireg_t csr; const char *subtype = NULL; uint32_t subsysid; + psc->psc_pc = pa->pa_pc; + csr = pci_mapreg_type(pa->pa_pc, pa->pa_tag, MFI_BAR); csr |= PCI_MAPREG_MEM_TYPE_32BIT; if (pci_mapreg_map(pa, MFI_BAR, csr, 0, - &sc->sc_iot, &sc->sc_ioh, NULL, &size)) { + &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_size)) { aprint_error(": can't map controller pci space\n"); return; } @@ -143,7 +167,7 @@ if (pci_intr_map(pa, &ih)) { aprint_error(": can't map interrupt\n"); - bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); return; } intrstr = pci_intr_string(pa->pa_pc, ih); @@ -153,7 +177,7 @@ if (intrstr) aprint_error(" at %s", intrstr); aprint_error("\n"); - bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); return; } @@ -180,6 +204,6 @@ aprint_error("%s: can't attach", DEVNAME(sc)); pci_intr_disestablish(pa->pa_pc, sc->sc_ih); sc->sc_ih = NULL; - bus_space_unmap(sc->sc_iot, sc->sc_ioh, size); + bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); } }