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>
This commit is contained in:
parent
cb082ac476
commit
e219897a2a
@ -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 @@ fdc_pccard_probe(device_t dev)
|
||||
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);
|
||||
|
34
sys/isa/fd.c
34
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 @@ fdc_pccard_probe(device_t dev)
|
||||
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);
|
||||
|
@ -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} \
|
||||
|
29
sys/modules/fdc/Makefile
Normal file
29
sys/modules/fdc/Makefile
Normal file
@ -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>
|
Loading…
Reference in New Issue
Block a user