Module Name: src Committed By: dyoung Date: Tue Aug 18 16:52:43 UTC 2009
Modified Files: src/sys/dev/isa: isa.c isadma.c isadmavar.h Log Message: Let us safely detach the ISA bus and devices attaching to the ISA bus: 1 Add isadetach() for detaching the ISA bus, and add some helper routines that release resources held for ISA DMA. 2 In isachilddetached(), forget references to child devices. While I am here, change ISA_DMA_DRQ_ISFREE(...) == 0 to the simpler expression, !ISA_DMA_DRQ_ISFREE(...). To generate a diff of this commit: cvs rdiff -u -r1.135 -r1.136 src/sys/dev/isa/isa.c cvs rdiff -u -r1.61 -r1.62 src/sys/dev/isa/isadma.c cvs rdiff -u -r1.24 -r1.25 src/sys/dev/isa/isadmavar.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/isa/isa.c diff -u src/sys/dev/isa/isa.c:1.135 src/sys/dev/isa/isa.c:1.136 --- src/sys/dev/isa/isa.c:1.135 Tue Apr 7 21:48:46 2009 +++ src/sys/dev/isa/isa.c Tue Aug 18 16:52:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: isa.c,v 1.135 2009/04/07 21:48:46 dyoung Exp $ */ +/* $NetBSD: isa.c,v 1.136 2009/08/18 16:52:42 dyoung Exp $ */ /*- * Copyright (c) 1998, 2001, 2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: isa.c,v 1.135 2009/04/07 21:48:46 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: isa.c,v 1.136 2009/08/18 16:52:42 dyoung Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -56,12 +56,13 @@ int isamatch(device_t, cfdata_t, void *); void isaattach(device_t, device_t, void *); +int isadetach(device_t, int); int isarescan(device_t, const char *, const int *); void isachilddetached(device_t, device_t); int isaprint(void *, const char *); CFATTACH_DECL2_NEW(isa, sizeof(struct isa_softc), - isamatch, isaattach, NULL, NULL, isarescan, isachilddetached); + isamatch, isaattach, isadetach, NULL, isarescan, isachilddetached); void isa_attach_knowndevs(struct isa_softc *); void isa_free_knowndevs(struct isa_softc *); @@ -138,6 +139,27 @@ } int +isadetach(device_t self, int flags) +{ + struct isa_softc *sc = device_private(self); + int rc; + + if ((rc = config_detach_children(self, flags)) != 0) + return rc; + + pmf_device_deregister(self); + + isa_free_knowndevs(sc); + +#if NISADMA > 0 + isa_dmadestroy(sc->sc_ic); +#endif + isa_detach_hook(self); + + return 0; +} + +int isarescan(device_t self, const char *ifattr, const int *locators) { int locs[ISACF_NLOCS]; @@ -162,7 +184,13 @@ void isachilddetached(device_t self, device_t child) { - /* nothing to do */ + struct isa_knowndev *ik; + struct isa_softc *sc = device_private(self); + + TAILQ_FOREACH(ik, &sc->sc_knowndevs, ik_list) { + if (ik->ik_claimed == child) + ik->ik_claimed = NULL; + } } void Index: src/sys/dev/isa/isadma.c diff -u src/sys/dev/isa/isadma.c:1.61 src/sys/dev/isa/isadma.c:1.62 --- src/sys/dev/isa/isadma.c:1.61 Tue May 12 09:10:15 2009 +++ src/sys/dev/isa/isadma.c Tue Aug 18 16:52:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: isadma.c,v 1.61 2009/05/12 09:10:15 cegger Exp $ */ +/* $NetBSD: isadma.c,v 1.62 2009/08/18 16:52:42 dyoung Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: isadma.c,v 1.61 2009/05/12 09:10:15 cegger Exp $"); +__KERNEL_RCSID(0, "$NetBSD: isadma.c,v 1.62 2009/08/18 16:52:42 dyoung Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -201,6 +201,24 @@ } } +void +_isa_dmadestroy(struct isa_dma_state *ids) +{ + if (!ids->ids_initialized) + return; + + _isa_dmacascade_stop(ids, 4); + + /* + * Unmap the registers used by the ISA DMA controller. + */ + bus_space_unmap(ids->ids_bst, ids->ids_dmapgh, 0xf); + bus_space_unmap(ids->ids_bst, ids->ids_dma2h, DMA2_IOSIZE); + bus_space_unmap(ids->ids_bst, ids->ids_dma1h, DMA1_IOSIZE); + + ids->ids_initialized = 0; +} + /* * _isa_dmacascade(): program 8237 DMA controller channel to accept * external dma control by a board. @@ -215,7 +233,7 @@ return (EINVAL); } - if (ISA_DMA_DRQ_ISFREE(ids, chan) == 0) { + if (!ISA_DMA_DRQ_ISFREE(ids, chan)) { printf("%s: DRQ %d is not free\n", device_xname(ids->ids_dev), chan); return (EAGAIN); @@ -235,10 +253,32 @@ return (0); } +/* + * _isa_dmacascade_stop(): turn off cascading on the 8237 DMA controller channel + * external dma control by a board. + */ +int +_isa_dmacascade_stop(struct isa_dma_state *ids, int chan) +{ + if (chan < 0 || chan > 7) { + printf("%s: bogus drq %d\n", device_xname(ids->ids_dev), chan); + return EINVAL; + } + + if (ISA_DMA_DRQ_ISFREE(ids, chan)) + return 0; + + _isa_dmamask(ids, chan); + + ISA_DMA_DRQ_FREE(ids, chan); + + return 0; +} + int _isa_drq_alloc(struct isa_dma_state *ids, int chan) { - if (ISA_DMA_DRQ_ISFREE(ids, chan) == 0) + if (!ISA_DMA_DRQ_ISFREE(ids, chan)) return EBUSY; ISA_DMA_DRQ_ALLOC(ids, chan); return 0; Index: src/sys/dev/isa/isadmavar.h diff -u src/sys/dev/isa/isadmavar.h:1.24 src/sys/dev/isa/isadmavar.h:1.25 --- src/sys/dev/isa/isadmavar.h:1.24 Tue May 12 09:10:15 2009 +++ src/sys/dev/isa/isadmavar.h Tue Aug 18 16:52:42 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: isadmavar.h,v 1.24 2009/05/12 09:10:15 cegger Exp $ */ +/* $NetBSD: isadmavar.h,v 1.25 2009/08/18 16:52:42 dyoung Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -97,7 +97,10 @@ void _isa_dmainit(struct isa_dma_state *, bus_space_tag_t, bus_dma_tag_t, device_t); +void _isa_dmadestroy(struct isa_dma_state *); + int _isa_dmacascade(struct isa_dma_state *, int); +int _isa_dmacascade_stop(struct isa_dma_state *, int); bus_size_t _isa_dmamaxsize(struct isa_dma_state *, int);