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);
 	}
 }

Reply via email to