diff options
-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 d742117..1aff68b 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 d742117..1aff68b 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 4b378be..c0eef44 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 0000000..46a36b3 --- /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> |