diff options
author | Joerg Wunsch <joerg@FreeBSD.org> | 2001-06-29 07:36:29 +0000 |
---|---|---|
committer | Joerg Wunsch <joerg@FreeBSD.org> | 2001-06-29 07:36:29 +0000 |
commit | e219897a2ac55202020d8467356d94641d0510b3 (patch) | |
tree | 26b185d25159dd387d41c613bab5c3e274d8978f /sys | |
parent | cb082ac476b0c0ff562c15115d7355e7d49f1562 (diff) | |
download | src-e219897a2ac55202020d8467356d94641d0510b3.tar.gz src-e219897a2ac55202020d8467356d94641d0510b3.zip |
First stab at fixing resource deallocation, and implementing fdc(4) as
a KLD. Still doesn't work well except in the PCMCIA case (now if only
pccardd(8) could load and unload drivers dynamically...). Mainly, it
tries to find fdc0 on the PCI bus for whatever obscure reasons, but i
need someone who understands driver(9) to fix this. However, it's at least
already better than before, and i'm tired of maintaining too many private
changes in my tree, given the large patches bde submitted. :)
Idea of a KLD triggered by: Michael Reifenberger <root@nihil.plaut.de>
Notes
Notes:
svn path=/head/; revision=78953
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/fdc/fdc.c | 34 | ||||
-rw-r--r-- | sys/isa/fd.c | 34 | ||||
-rw-r--r-- | sys/modules/Makefile | 2 | ||||
-rw-r--r-- | sys/modules/fdc/Makefile | 29 |
4 files changed, 78 insertions, 21 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index d74211714975..1aff68bf14c3 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -179,6 +179,8 @@ struct fd_data { struct callout_handle toffhandle; struct callout_handle tohandle; struct devstat device_stats; + eventhandler_tag clonetag; + dev_t masterdev; device_t dev; fdu_t fdu; }; @@ -506,7 +508,7 @@ static int fdc_alloc_resources(struct fdc_data *fdc) { device_t dev; - int ispnp, ispcmcia; + int ispnp, ispcmcia, nports; dev = fdc->fdc_dev; ispnp = (fdc->flags & FDC_ISPNP) != 0; @@ -525,12 +527,13 @@ fdc_alloc_resources(struct fdc_data *fdc) * uses the register with offset 6 for pseudo-DMA, and the * one with offset 7 as control register. */ + nports = ispcmcia ? 8 : (ispnp ? 1 : 6); fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &fdc->rid_ioport, 0ul, ~0ul, - ispcmcia ? 8 : (ispnp ? 1 : 6), - RF_ACTIVE); + nports, RF_ACTIVE); if (fdc->res_ioport == 0) { - device_printf(dev, "cannot reserve I/O port range\n"); + device_printf(dev, "cannot reserve I/O port range (%d ports)\n", + nports); return ENXIO; } fdc->portt = rman_get_bustag(fdc->res_ioport); @@ -578,7 +581,7 @@ fdc_alloc_resources(struct fdc_data *fdc) 0ul, ~0ul, 1, RF_ACTIVE); if (fdc->res_ctl == 0) { device_printf(dev, - "cannot reserve control I/O port range\n"); + "cannot reserve control I/O port range (control port)\n"); return ENXIO; } fdc->ctlt = rman_get_bustag(fdc->res_ctl); @@ -769,8 +772,10 @@ out: return (error); } +#endif /* NCARD > 0 */ + static int -fdc_pccard_detach(device_t dev) +fdc_detach(device_t dev) { struct fdc_data *fdc; int error; @@ -781,6 +786,12 @@ fdc_pccard_detach(device_t dev) if ((error = bus_generic_detach(dev))) return (error); + /* reset controller, turn motor off */ + fdout_wr(fdc, 0); + + if ((fdc->flags & FDC_NODMA) == 0) + isa_dma_release(fdc->dmachan); + if ((fdc->flags & FDC_ATTACHED) == 0) { device_printf(dev, "already unloaded\n"); return (0); @@ -794,8 +805,6 @@ fdc_pccard_detach(device_t dev) return (0); } -#endif /* NCARD > 0 */ - /* * Add a child device to the fdc controller. It will then be probed etc. */ @@ -886,7 +895,7 @@ static device_method_t fdc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fdc_probe), DEVMETHOD(device_attach, fdc_attach), - DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_detach, fdc_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), @@ -913,7 +922,7 @@ static device_method_t fdc_pccard_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fdc_pccard_probe), DEVMETHOD(device_attach, fdc_attach), - DEVMETHOD(device_detach, fdc_pccard_detach), + DEVMETHOD(device_detach, fdc_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), @@ -1162,6 +1171,11 @@ fd_detach(device_t dev) struct fd_data *fd; fd = device_get_softc(dev); + devstat_remove_entry(&fd->device_stats); + destroy_dev(fd->masterdev); + cdevsw_remove(&fd_cdevsw); + /* XXX need to destroy cloned devs as well */ + EVENTHANDLER_DEREGISTER(dev_clone, fd->clonetag); untimeout(fd_turnoff, fd, fd->toffhandle); return (0); diff --git a/sys/isa/fd.c b/sys/isa/fd.c index d74211714975..1aff68bf14c3 100644 --- a/sys/isa/fd.c +++ b/sys/isa/fd.c @@ -179,6 +179,8 @@ struct fd_data { struct callout_handle toffhandle; struct callout_handle tohandle; struct devstat device_stats; + eventhandler_tag clonetag; + dev_t masterdev; device_t dev; fdu_t fdu; }; @@ -506,7 +508,7 @@ static int fdc_alloc_resources(struct fdc_data *fdc) { device_t dev; - int ispnp, ispcmcia; + int ispnp, ispcmcia, nports; dev = fdc->fdc_dev; ispnp = (fdc->flags & FDC_ISPNP) != 0; @@ -525,12 +527,13 @@ fdc_alloc_resources(struct fdc_data *fdc) * uses the register with offset 6 for pseudo-DMA, and the * one with offset 7 as control register. */ + nports = ispcmcia ? 8 : (ispnp ? 1 : 6); fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &fdc->rid_ioport, 0ul, ~0ul, - ispcmcia ? 8 : (ispnp ? 1 : 6), - RF_ACTIVE); + nports, RF_ACTIVE); if (fdc->res_ioport == 0) { - device_printf(dev, "cannot reserve I/O port range\n"); + device_printf(dev, "cannot reserve I/O port range (%d ports)\n", + nports); return ENXIO; } fdc->portt = rman_get_bustag(fdc->res_ioport); @@ -578,7 +581,7 @@ fdc_alloc_resources(struct fdc_data *fdc) 0ul, ~0ul, 1, RF_ACTIVE); if (fdc->res_ctl == 0) { device_printf(dev, - "cannot reserve control I/O port range\n"); + "cannot reserve control I/O port range (control port)\n"); return ENXIO; } fdc->ctlt = rman_get_bustag(fdc->res_ctl); @@ -769,8 +772,10 @@ out: return (error); } +#endif /* NCARD > 0 */ + static int -fdc_pccard_detach(device_t dev) +fdc_detach(device_t dev) { struct fdc_data *fdc; int error; @@ -781,6 +786,12 @@ fdc_pccard_detach(device_t dev) if ((error = bus_generic_detach(dev))) return (error); + /* reset controller, turn motor off */ + fdout_wr(fdc, 0); + + if ((fdc->flags & FDC_NODMA) == 0) + isa_dma_release(fdc->dmachan); + if ((fdc->flags & FDC_ATTACHED) == 0) { device_printf(dev, "already unloaded\n"); return (0); @@ -794,8 +805,6 @@ fdc_pccard_detach(device_t dev) return (0); } -#endif /* NCARD > 0 */ - /* * Add a child device to the fdc controller. It will then be probed etc. */ @@ -886,7 +895,7 @@ static device_method_t fdc_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fdc_probe), DEVMETHOD(device_attach, fdc_attach), - DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_detach, fdc_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), @@ -913,7 +922,7 @@ static device_method_t fdc_pccard_methods[] = { /* Device interface */ DEVMETHOD(device_probe, fdc_pccard_probe), DEVMETHOD(device_attach, fdc_attach), - DEVMETHOD(device_detach, fdc_pccard_detach), + DEVMETHOD(device_detach, fdc_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, bus_generic_suspend), DEVMETHOD(device_resume, bus_generic_resume), @@ -1162,6 +1171,11 @@ fd_detach(device_t dev) struct fd_data *fd; fd = device_get_softc(dev); + devstat_remove_entry(&fd->device_stats); + destroy_dev(fd->masterdev); + cdevsw_remove(&fd_cdevsw); + /* XXX need to destroy cloned devs as well */ + EVENTHANDLER_DEREGISTER(dev_clone, fd->clonetag); untimeout(fd_turnoff, fd, fd->toffhandle); return (0); diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 4b378be8d0db..c0eef44c4255 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -7,7 +7,7 @@ _random= random .endif SUBDIR= 3dfx accf_data accf_http agp aha amr an aue \ - cam ccd cd9660 coda cue dc de digi ed fdescfs fs fxp if_disc if_ef \ + cam ccd cd9660 coda cue dc de digi ed fdescfs fdc fs fxp if_disc if_ef \ if_ppp if_sl if_tap if_tun ip6fw ipfilter ipfw ispfw joy kue lge \ libmchain linux lnc md mii mlx msdosfs ncp netgraph nfs nge ntfs \ nullfs nwfs pcn portalfs procfs ${_random} \ diff --git a/sys/modules/fdc/Makefile b/sys/modules/fdc/Makefile new file mode 100644 index 000000000000..46a36b3704d0 --- /dev/null +++ b/sys/modules/fdc/Makefile @@ -0,0 +1,29 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../isa + +KMOD= fdc +SRCS= fd.c \ + opt_fdc.h card.h \ + bus_if.h card_if.h device_if.h isa_if.h +NOMAN= + +FDC_DEBUG= 1 # 0/1 +FDC_PCCARD= 0 # 0/1 whether pccard support (i. e. Y-E DATA PCMCIA + # fdc) is desired + +CLEANFILES= card.h + +opt_fdc.h: + touch ${.TARGET} +.if ${FDC_DEBUG} > 0 + echo "#define FDC_DEBUG 1" >> ${.TARGET} +.endif + +card.h: + touch ${.TARGET} +.if ${FDC_PCCARD} > 0 + echo "#define NCARD 1" >> ${.TARGET} +.endif + +.include <bsd.kmod.mk> |