summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/fdc/fdc.c34
-rw-r--r--sys/isa/fd.c34
-rw-r--r--sys/modules/Makefile2
-rw-r--r--sys/modules/fdc/Makefile29
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>
OpenPOWER on IntegriCloud