Module Name:    src
Committed By:   jakllsch
Date:           Sat Nov  6 00:29:09 UTC 2010

Modified Files:
        src/sys/dev/pci: pciide.c pciide_common.c pciidevar.h

Log Message:
Rework pciide(4) detachment to take the legacy interrupt mapping into
consideration and avoid future code duplication.

Ports wanting to enable detachment of controllers with compatibility-mapped
channels will need to supply a pciide_machdep_compat_intr_disestablish()
function.


To generate a diff of this commit:
cvs rdiff -u -r1.218 -r1.219 src/sys/dev/pci/pciide.c
cvs rdiff -u -r1.45 -r1.46 src/sys/dev/pci/pciide_common.c
cvs rdiff -u -r1.41 -r1.42 src/sys/dev/pci/pciidevar.h

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/pci/pciide.c
diff -u src/sys/dev/pci/pciide.c:1.218 src/sys/dev/pci/pciide.c:1.219
--- src/sys/dev/pci/pciide.c:1.218	Fri Nov  5 19:50:18 2010
+++ src/sys/dev/pci/pciide.c	Sat Nov  6 00:29:09 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pciide.c,v 1.218 2010/11/05 19:50:18 jakllsch Exp $	*/
+/*	$NetBSD: pciide.c,v 1.219 2010/11/06 00:29:09 jakllsch Exp $	*/
 
 
 /*
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.218 2010/11/05 19:50:18 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pciide.c,v 1.219 2010/11/06 00:29:09 jakllsch Exp $");
 
 #include <sys/param.h>
 
@@ -80,7 +80,6 @@
 
 static int	pciide_match(device_t, cfdata_t, void *);
 static void	pciide_attach(device_t, device_t, void *);
-static int	pciide_detach(device_t, int);
 
 CFATTACH_DECL_NEW(pciide, sizeof(struct pciide_softc),
     pciide_match, pciide_attach, pciide_detach, NULL);
@@ -113,19 +112,3 @@
 
 	pciide_common_attach(sc, pa, NULL);
 }
-
-static int
-pciide_detach(device_t self, int flags)
-{
-	struct pciide_softc *sc = device_private(self);
-	int ret;
-
-	ret = pciide_common_detach(sc, flags);
-
-	if (ret != 0)
-		return ret;
-
-	pci_intr_disestablish(sc->sc_pc, sc->sc_pci_ih);
-
-	return ret;
-}

Index: src/sys/dev/pci/pciide_common.c
diff -u src/sys/dev/pci/pciide_common.c:1.45 src/sys/dev/pci/pciide_common.c:1.46
--- src/sys/dev/pci/pciide_common.c:1.45	Fri Nov  5 19:48:43 2010
+++ src/sys/dev/pci/pciide_common.c	Sat Nov  6 00:29:09 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pciide_common.c,v 1.45 2010/11/05 19:48:43 jakllsch Exp $	*/
+/*	$NetBSD: pciide_common.c,v 1.46 2010/11/06 00:29:09 jakllsch Exp $	*/
 
 
 /*
@@ -70,7 +70,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.45 2010/11/05 19:48:43 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pciide_common.c,v 1.46 2010/11/06 00:29:09 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -222,6 +222,42 @@
 	return 0;
 }
 
+int
+pciide_detach(device_t self, int flags)
+{
+	struct pciide_softc *sc = device_private(self);
+	struct pciide_channel *cp;
+	int channel;
+#ifndef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_DISESTABLISH
+	bool has_compat_chan;
+
+	has_compat_chan = false;
+	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
+	     channel++) {
+		cp = &sc->pciide_channels[channel];
+		if (cp->compat != 0) {
+			has_compat_chan = true;
+		}
+	}
+
+	if (has_compat_chan != false)
+		return EBUSY;
+#endif
+
+	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
+	     channel++) {
+		cp = &sc->pciide_channels[channel];
+		if (cp->compat != 0)
+			if (cp->ih != NULL)
+			       pciide_unmap_compat_intr(sc->sc_pc, cp, channel);
+	}
+
+	if (sc->sc_pci_ih != NULL)
+		pci_intr_disestablish(sc->sc_pc, sc->sc_pci_ih);
+
+	return pciide_common_detach(sc, flags);
+}
+
 /* tell whether the chip is enabled or not */
 int
 pciide_chipen(struct pciide_softc *sc, struct pci_attach_args *pa)
@@ -888,6 +924,17 @@
 }
 
 void
+pciide_unmap_compat_intr(pci_chipset_tag_t pc, struct pciide_channel *cp, int compatchan)
+{
+#ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_DISESTABLISH
+	struct pciide_softc *sc = CHAN_TO_PCIIDE(&cp->ata_channel);
+
+	pciide_machdep_compat_intr_disestablish(sc->sc_wdcdev.sc_atac.atac_dev,
+	    sc->sc_pc, compatchan, cp->ih);
+#endif
+}
+
+void
 default_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
 {
 	struct pciide_channel *cp;

Index: src/sys/dev/pci/pciidevar.h
diff -u src/sys/dev/pci/pciidevar.h:1.41 src/sys/dev/pci/pciidevar.h:1.42
--- src/sys/dev/pci/pciidevar.h:1.41	Fri Nov  5 18:07:24 2010
+++ src/sys/dev/pci/pciidevar.h	Sat Nov  6 00:29:09 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pciidevar.h,v 1.41 2010/11/05 18:07:24 jakllsch Exp $	*/
+/*	$NetBSD: pciidevar.h,v 1.42 2010/11/06 00:29:09 jakllsch Exp $	*/
 
 /*
  * Copyright (c) 1998 Christopher G. Demetriou.  All rights reserved.
@@ -222,12 +222,17 @@
 void	*pciide_machdep_compat_intr_establish(device_t,
 	    struct pci_attach_args *, int, int (*)(void *), void *);
 #endif
+#ifdef __HAVE_PCIIDE_MACHDEP_COMPAT_INTR_DISESTABLISH
+void	pciide_machdep_compat_intr_disestablish(device_t,
+	    pci_chipset_tag_t, int,  void *);
+#endif
 
 const struct pciide_product_desc* pciide_lookup_product
 	(u_int32_t, const struct pciide_product_desc *);
 void	pciide_common_attach(struct pciide_softc *, struct pci_attach_args *,
 		const struct pciide_product_desc *);
 int	pciide_common_detach(struct pciide_softc *, int);
+int	pciide_detach(device_t, int);
 
 int	pciide_chipen(struct pciide_softc *, struct pci_attach_args *);
 void	pciide_mapregs_compat(struct pci_attach_args *,
@@ -241,6 +246,8 @@
 	    struct pciide_channel *, pcireg_t, int (*pci_intr)(void *));
 void	pciide_map_compat_intr(struct pci_attach_args *,
 	    struct pciide_channel *, int);
+void	pciide_unmap_compat_intr(pci_chipset_tag_t,
+	    struct pciide_channel *, int);
 int	pciide_compat_intr(void *);
 int	pciide_pci_intr(void *);
 

Reply via email to