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