diff options
| author | dyoung <dyoung@NetBSD.org> | 2009-07-16 18:58:38 +0000 |
|---|---|---|
| committer | dyoung <dyoung@NetBSD.org> | 2009-07-16 18:58:38 +0000 |
| commit | bbc238f2cd2a03d9c3c4bf4f2e1c9c4d0977acf5 (patch) | |
| tree | 2d1098cc4c79a0c615bc364c5bf4143ecd5f94c6 /sys/dev | |
| parent | ebab3c38caf7117abd22c1c2f9e553e6e266bbe1 (diff) | |
Let us detach & re-attach children of mfi0. Detach mfi0 at shutdown.
Detachment may fail after freeing some but not all resources, so
take care not to re-release any resource during detachment.
Tested on a Dell PowerEdge 1950.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ic/mfi.c | 58 | ||||
| -rw-r--r-- | sys/dev/ic/mfivar.h | 5 | ||||
| -rw-r--r-- | sys/dev/pci/mfi_pci.c | 9 |
3 files changed, 56 insertions, 16 deletions
diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c index 38a69a0e1a7..3f6e0898ac5 100644 --- a/sys/dev/ic/mfi.c +++ b/sys/dev/ic/mfi.c @@ -1,4 +1,4 @@ -/* $NetBSD: mfi.c,v 1.26 2009/07/16 18:10:00 dyoung Exp $ */ +/* $NetBSD: mfi.c,v 1.27 2009/07/16 18:58:38 dyoung Exp $ */ /* $OpenBSD: mfi.c,v 1.66 2006/11/28 23:59:45 dlg Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.26 2009/07/16 18:10:00 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mfi.c,v 1.27 2009/07/16 18:58:38 dyoung Exp $"); #include "bio.h" @@ -70,7 +70,7 @@ static void mfi_put_ccb(struct mfi_ccb *); static int mfi_init_ccb(struct mfi_softc *); static struct mfi_mem *mfi_allocmem(struct mfi_softc *, size_t); -static void mfi_freemem(struct mfi_softc *, struct mfi_mem *); +static void mfi_freemem(struct mfi_softc *, struct mfi_mem **); static int mfi_transition_firmware(struct mfi_softc *); static int mfi_initialize_firmware(struct mfi_softc *); @@ -345,8 +345,15 @@ amfree: } static void -mfi_freemem(struct mfi_softc *sc, struct mfi_mem *mm) +mfi_freemem(struct mfi_softc *sc, struct mfi_mem **mmp) { + struct mfi_mem *mm = *mmp; + + if (mm == NULL) + return; + + *mmp = NULL; + DNPRINTF(MFI_D_MEM, "%s: mfi_freemem: %p\n", DEVNAME(sc), mm); bus_dmamap_unload(sc->sc_dmat, mm->am_map); @@ -629,6 +636,32 @@ mfiminphys(struct buf *bp) } int +mfi_rescan(device_t self, const char *ifattr, const int *locators) +{ + struct mfi_softc *sc = device_private(self); + + if (sc->sc_child != NULL) + return 0; + + sc->sc_child = config_found_sm_loc(self, ifattr, locators, &sc->sc_chan, + scsiprint, NULL); + + return 0; +} + +void +mfi_childdetached(device_t self, device_t child) +{ + struct mfi_softc *sc = device_private(self); + + KASSERT(self == sc->sc_dev); + KASSERT(child == sc->sc_child); + + if (child == sc->sc_child) + sc->sc_child = NULL; +} + +int mfi_detach(struct mfi_softc *sc, int flags) { int error; @@ -650,11 +683,11 @@ mfi_detach(struct mfi_softc *sc, int flags) if ((error = mfi_destroy_ccb(sc)) != 0) return error; - mfi_freemem(sc, sc->sc_sense); + mfi_freemem(sc, &sc->sc_sense); - mfi_freemem(sc, sc->sc_frames); + mfi_freemem(sc, &sc->sc_frames); - mfi_freemem(sc, sc->sc_pcq); + mfi_freemem(sc, &sc->sc_pcq); return 0; } @@ -779,7 +812,7 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop) chan->chan_ntargets = MFI_MAX_LD; chan->chan_id = MFI_MAX_LD; - (void)config_found(sc->sc_dev, &sc->sc_chan, scsiprint); + mfi_rescan(sc->sc_dev, "scsi", NULL); /* enable interrupts */ mfi_intr_enable(sc); @@ -793,11 +826,11 @@ mfi_attach(struct mfi_softc *sc, enum mfi_iop iop) return 0; noinit: - mfi_freemem(sc, sc->sc_sense); + mfi_freemem(sc, &sc->sc_sense); nosense: - mfi_freemem(sc, sc->sc_frames); + mfi_freemem(sc, &sc->sc_frames); noframe: - mfi_freemem(sc, sc->sc_pcq); + mfi_freemem(sc, &sc->sc_pcq); nopcq: return 1; } @@ -1940,7 +1973,10 @@ freeme: static int mfi_destroy_sensors(struct mfi_softc *sc) { + if (sc->sc_sme == NULL) + return 0; sysmon_envsys_unregister(sc->sc_sme); + sc->sc_sme = NULL; free(sc->sc_sensor, M_DEVBUF); return 0; } diff --git a/sys/dev/ic/mfivar.h b/sys/dev/ic/mfivar.h index c03c2a265c5..d5e246e8b8c 100644 --- a/sys/dev/ic/mfivar.h +++ b/sys/dev/ic/mfivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: mfivar.h,v 1.12 2009/07/16 18:10:00 dyoung Exp $ */ +/* $NetBSD: mfivar.h,v 1.13 2009/07/16 18:58:38 dyoung Exp $ */ /* $OpenBSD: mfivar.h,v 1.28 2006/08/31 18:18:46 marco Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> @@ -161,8 +161,11 @@ struct mfi_softc { struct sysmon_envsys *sc_sme; envsys_data_t *sc_sensor; + device_t sc_child; }; +int mfi_rescan(device_t, const char *, const int *); +void mfi_childdetached(device_t, device_t); int mfi_attach(struct mfi_softc *, enum mfi_iop); int mfi_detach(struct mfi_softc *, int); int mfi_intr(void *); diff --git a/sys/dev/pci/mfi_pci.c b/sys/dev/pci/mfi_pci.c index 5cc552b0d3f..c052d383c23 100644 --- a/sys/dev/pci/mfi_pci.c +++ b/sys/dev/pci/mfi_pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: mfi_pci.c,v 1.10 2009/07/16 18:10:00 dyoung Exp $ */ +/* $NetBSD: mfi_pci.c,v 1.11 2009/07/16 18:58:38 dyoung Exp $ */ /* $OpenBSD: mfi_pci.c,v 1.11 2006/08/06 04:40:08 brad Exp $ */ /* * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> @@ -17,7 +17,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mfi_pci.c,v 1.10 2009/07/16 18:10:00 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mfi_pci.c,v 1.11 2009/07/16 18:58:38 dyoung Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -50,8 +50,9 @@ 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_NEW(mfi_pci, sizeof(struct mfi_pci_softc), - mfi_pci_match, mfi_pci_attach, mfi_pci_detach, NULL); +CFATTACH_DECL3_NEW(mfi_pci, sizeof(struct mfi_pci_softc), + mfi_pci_match, mfi_pci_attach, mfi_pci_detach, NULL, mfi_rescan, + mfi_childdetached, DVF_DETACH_SHUTDOWN); struct mfi_pci_subtype { pcireg_t st_vendor; |
