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:
Joerg Wunsch 2001-06-29 07:36:29 +00:00
parent cb082ac476
commit e219897a2a
4 changed files with 78 additions and 21 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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
View 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>