summaryrefslogtreecommitdiff
path: root/sys/dev/ic
diff options
context:
space:
mode:
authordyoung <dyoung@NetBSD.org>2009-07-16 18:58:38 +0000
committerdyoung <dyoung@NetBSD.org>2009-07-16 18:58:38 +0000
commitbbc238f2cd2a03d9c3c4bf4f2e1c9c4d0977acf5 (patch)
tree2d1098cc4c79a0c615bc364c5bf4143ecd5f94c6 /sys/dev/ic
parentebab3c38caf7117abd22c1c2f9e553e6e266bbe1 (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/ic')
-rw-r--r--sys/dev/ic/mfi.c58
-rw-r--r--sys/dev/ic/mfivar.h5
2 files changed, 51 insertions, 12 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 *);