summaryrefslogtreecommitdiffstats
path: root/sys/isa
diff options
context:
space:
mode:
Diffstat (limited to 'sys/isa')
-rw-r--r--sys/isa/fd.c34
1 files changed, 24 insertions, 10 deletions
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);
OpenPOWER on IntegriCloud