Move the fdc_alloc_resources function into the bus front end.
This commit is contained in:
parent
386ecc28e7
commit
dc6ea865f7
@ -259,10 +259,6 @@ struct fd_data {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef PC98
|
||||
static bus_addr_t fdc_iat[] = {0, 2, 4};
|
||||
#endif
|
||||
|
||||
struct fdc_ivars {
|
||||
int fdunit;
|
||||
int fdtype;
|
||||
@ -759,199 +755,6 @@ static void pc98_fd_check_type(struct fd_data *fd)
|
||||
}
|
||||
#endif /* PC98 */
|
||||
|
||||
int
|
||||
fdc_alloc_resources(struct fdc_data *fdc)
|
||||
{
|
||||
device_t dev;
|
||||
#ifdef PC98
|
||||
int rid;
|
||||
#else
|
||||
int ispnp, ispcmcia, nports;
|
||||
#endif
|
||||
|
||||
dev = fdc->fdc_dev;
|
||||
#ifndef PC98
|
||||
ispnp = (fdc->flags & FDC_ISPNP) != 0;
|
||||
ispcmcia = (fdc->flags & FDC_ISPCMCIA) != 0;
|
||||
#endif
|
||||
fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
|
||||
fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
|
||||
#ifndef PC98
|
||||
fdc->rid_ctl = 1;
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
fdc->res_ioport = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ioport, fdc_iat,
|
||||
3, RF_ACTIVE);
|
||||
if (fdc->res_ioport == 0) {
|
||||
device_printf(dev, "cannot reserve I/O port range\n");
|
||||
return ENXIO;
|
||||
}
|
||||
isa_load_resourcev(fdc->res_ioport, fdc_iat, 3);
|
||||
#else
|
||||
/*
|
||||
* On standard ISA, we don't just use an 8 port range
|
||||
* (e.g. 0x3f0-0x3f7) since that covers an IDE control
|
||||
* register at 0x3f6.
|
||||
*
|
||||
* Isn't PC hardware wonderful.
|
||||
*
|
||||
* The Y-E Data PCMCIA FDC doesn't have this problem, it
|
||||
* uses the register with offset 6 for pseudo-DMA, and the
|
||||
* one with offset 7 as control register.
|
||||
*/
|
||||
nports = ispcmcia ? 8 : (ispnp ? 1 : 6);
|
||||
|
||||
/*
|
||||
* Some ACPI BIOSen have _CRS objects for the floppy device that
|
||||
* split the I/O port resource into several resources. We detect
|
||||
* this case by checking if there are more than 2 IOPORT resources.
|
||||
* If so, we use the resource with the smallest start address as
|
||||
* the port RID and the largest start address as the control RID.
|
||||
*/
|
||||
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 2) != 0) {
|
||||
u_long min_start, max_start, tmp;
|
||||
int i;
|
||||
|
||||
/* Find the min/max start addresses and their RIDs. */
|
||||
max_start = 0ul;
|
||||
min_start = ~0ul;
|
||||
for (i = 0; bus_get_resource_count(dev, SYS_RES_IOPORT, i) > 0;
|
||||
i++) {
|
||||
tmp = bus_get_resource_start(dev, SYS_RES_IOPORT, i);
|
||||
KASSERT(tmp != 0, ("bogus resource"));
|
||||
if (tmp < min_start) {
|
||||
min_start = tmp;
|
||||
fdc->rid_ioport = i;
|
||||
}
|
||||
if (tmp > max_start) {
|
||||
max_start = tmp;
|
||||
fdc->rid_ctl = i;
|
||||
}
|
||||
}
|
||||
if (min_start + 7 != max_start) {
|
||||
device_printf(dev, "I/O to control range incorrect\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ioport, 0ul, ~0ul,
|
||||
nports, RF_ACTIVE);
|
||||
if (fdc->res_ioport == 0) {
|
||||
device_printf(dev, "cannot reserve I/O port range (%d ports)\n",
|
||||
nports);
|
||||
return ENXIO;
|
||||
}
|
||||
#endif
|
||||
fdc->portt = rman_get_bustag(fdc->res_ioport);
|
||||
fdc->porth = rman_get_bushandle(fdc->res_ioport);
|
||||
|
||||
#ifdef PC98
|
||||
rid = 3;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, IO_FDPORT, 1);
|
||||
fdc->res_fdsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdsiot = rman_get_bustag(fdc->res_fdsio);
|
||||
fdc->sc_fdsioh = rman_get_bushandle(fdc->res_fdsio);
|
||||
|
||||
rid = 4;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4be, 1);
|
||||
fdc->res_fdemsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdemsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdemsiot = rman_get_bustag(fdc->res_fdemsio);
|
||||
fdc->sc_fdemsioh = rman_get_bushandle(fdc->res_fdemsio);
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
if (!ispcmcia) {
|
||||
/*
|
||||
* Some BIOSen report the device at 0x3f2-0x3f5,0x3f7
|
||||
* and some at 0x3f0-0x3f5,0x3f7. We detect the former
|
||||
* by checking the size and adjust the port address
|
||||
* accordingly.
|
||||
*/
|
||||
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 4)
|
||||
fdc->port_off = -2;
|
||||
|
||||
/*
|
||||
* Register the control port range as rid 1 if it
|
||||
* isn't there already. Most PnP BIOSen will have
|
||||
* already done this but non-PnP configurations don't.
|
||||
*
|
||||
* And some (!!) report 0x3f2-0x3f5 and completely
|
||||
* leave out the control register! It seems that some
|
||||
* non-antique controller chips have a different
|
||||
* method of programming the transfer speed which
|
||||
* doesn't require the control register, but it's
|
||||
* mighty bogus as the chip still responds to the
|
||||
* address for the control register.
|
||||
*/
|
||||
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 1) == 0) {
|
||||
u_long ctlstart;
|
||||
|
||||
/* Find the control port, usually 0x3f7 */
|
||||
ctlstart = rman_get_start(fdc->res_ioport) +
|
||||
fdc->port_off + 7;
|
||||
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, 1, ctlstart, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now (finally!) allocate the control port.
|
||||
*/
|
||||
fdc->res_ctl = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ctl, RF_ACTIVE);
|
||||
if (fdc->res_ctl == 0) {
|
||||
device_printf(dev,
|
||||
"cannot reserve control I/O port range (control port)\n");
|
||||
return ENXIO;
|
||||
}
|
||||
fdc->ctlt = rman_get_bustag(fdc->res_ctl);
|
||||
fdc->ctlh = rman_get_bushandle(fdc->res_ctl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
|
||||
RF_ACTIVE);
|
||||
#else
|
||||
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
|
||||
RF_ACTIVE | RF_SHAREABLE);
|
||||
#endif
|
||||
if (fdc->res_irq == 0) {
|
||||
device_printf(dev, "cannot reserve interrupt line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
if ((fdc->flags & FDC_NODMA) == 0) {
|
||||
#ifdef PC98
|
||||
fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
|
||||
&fdc->rid_drq, RF_ACTIVE);
|
||||
if (fdc->res_drq == 0) {
|
||||
device_printf(dev, "cannot reserve DMA request line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
fdc->dmachan = rman_get_start(fdc->res_drq);
|
||||
#else
|
||||
fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
|
||||
&fdc->rid_drq, RF_ACTIVE | RF_SHAREABLE);
|
||||
if (fdc->res_drq == 0) {
|
||||
device_printf(dev, "cannot reserve DMA request line\n");
|
||||
fdc->flags |= FDC_NODMA;
|
||||
} else
|
||||
fdc->dmachan = rman_get_start(fdc->res_drq);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
fdc_release_resources(struct fdc_data *fdc)
|
||||
{
|
||||
@ -1126,15 +929,10 @@ fdc_attach(device_t dev)
|
||||
{
|
||||
struct fdc_data *fdc;
|
||||
const char *name, *dname;
|
||||
int i, error, dunit;
|
||||
int i, dunit, error;
|
||||
|
||||
fdc = device_get_softc(dev);
|
||||
fdc->fdc_dev = dev;
|
||||
error = fdc_alloc_resources(fdc);
|
||||
if (error) {
|
||||
device_printf(dev, "cannot re-acquire resources\n");
|
||||
return error;
|
||||
}
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
|
||||
INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
|
||||
&fdc->fdc_intr);
|
||||
|
@ -45,6 +45,69 @@ __FBSDID("$FreeBSD$");
|
||||
#include <isa/isavar.h>
|
||||
#include <pc98/pc98/pc98.h>
|
||||
|
||||
static bus_addr_t fdc_iat[] = {0, 2, 4};
|
||||
|
||||
static int
|
||||
fdc_cbus_alloc_resources(device_t dev, struct fdc_data *fdc)
|
||||
{
|
||||
int rid;
|
||||
|
||||
fdc->fdc_dev = dev;
|
||||
fdc->rid_ioport = 0;
|
||||
fdc->rid_irq = 0;
|
||||
fdc->rid_drq = 0;
|
||||
fdc->res_irq = 0;
|
||||
fdc->res_drq = 0;
|
||||
|
||||
fdc->res_ioport = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ioport, fdc_iat,
|
||||
3, RF_ACTIVE);
|
||||
if (fdc->res_ioport == 0) {
|
||||
device_printf(dev, "cannot reserve I/O port range\n");
|
||||
return ENXIO;
|
||||
}
|
||||
isa_load_resourcev(fdc->res_ioport, fdc_iat, 3);
|
||||
fdc->portt = rman_get_bustag(fdc->res_ioport);
|
||||
fdc->porth = rman_get_bushandle(fdc->res_ioport);
|
||||
|
||||
rid = 3;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, IO_FDPORT, 1);
|
||||
fdc->res_fdsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdsiot = rman_get_bustag(fdc->res_fdsio);
|
||||
fdc->sc_fdsioh = rman_get_bushandle(fdc->res_fdsio);
|
||||
|
||||
rid = 4;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4be, 1);
|
||||
fdc->res_fdemsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdemsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdemsiot = rman_get_bustag(fdc->res_fdemsio);
|
||||
fdc->sc_fdemsioh = rman_get_bushandle(fdc->res_fdemsio);
|
||||
|
||||
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_irq == 0) {
|
||||
device_printf(dev, "cannot reserve interrupt line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
if ((fdc->flags & FDC_NODMA) == 0) {
|
||||
fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
|
||||
&fdc->rid_drq, RF_ACTIVE);
|
||||
if (fdc->res_drq == 0) {
|
||||
device_printf(dev, "cannot reserve DMA request line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
fdc->dmachan = rman_get_start(fdc->res_drq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
fdc_cbus_probe(device_t dev)
|
||||
{
|
||||
@ -52,14 +115,13 @@ fdc_cbus_probe(device_t dev)
|
||||
struct fdc_data *fdc;
|
||||
|
||||
fdc = device_get_softc(dev);
|
||||
fdc->fdc_dev = dev;
|
||||
|
||||
/* Check pnp ids */
|
||||
if (isa_get_vendorid(dev))
|
||||
return (ENXIO);
|
||||
|
||||
/* Attempt to allocate our resources for the duration of the probe */
|
||||
error = fdc_alloc_resources(fdc);
|
||||
error = fdc_cbus_alloc_resources(dev, fdc);
|
||||
if (!error)
|
||||
error = fdc_initial_reset(fdc);
|
||||
|
||||
@ -67,10 +129,27 @@ fdc_cbus_probe(device_t dev)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
fdc_cbus_attach(device_t dev)
|
||||
{
|
||||
int error;
|
||||
struct fdc_data *fdc;
|
||||
|
||||
fdc = device_get_softc(dev);
|
||||
|
||||
if ((error = fdc_cbus_alloc_resources(dev, fdc)) != 0 ||
|
||||
(error = fdc_attach(dev)) != 0) {
|
||||
fdc_release_resources(fdc);
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t fdc_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, fdc_cbus_probe),
|
||||
DEVMETHOD(device_attach, fdc_attach),
|
||||
DEVMETHOD(device_attach, fdc_cbus_attach),
|
||||
DEVMETHOD(device_detach, fdc_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
|
@ -259,10 +259,6 @@ struct fd_data {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef PC98
|
||||
static bus_addr_t fdc_iat[] = {0, 2, 4};
|
||||
#endif
|
||||
|
||||
struct fdc_ivars {
|
||||
int fdunit;
|
||||
int fdtype;
|
||||
@ -759,199 +755,6 @@ static void pc98_fd_check_type(struct fd_data *fd)
|
||||
}
|
||||
#endif /* PC98 */
|
||||
|
||||
int
|
||||
fdc_alloc_resources(struct fdc_data *fdc)
|
||||
{
|
||||
device_t dev;
|
||||
#ifdef PC98
|
||||
int rid;
|
||||
#else
|
||||
int ispnp, ispcmcia, nports;
|
||||
#endif
|
||||
|
||||
dev = fdc->fdc_dev;
|
||||
#ifndef PC98
|
||||
ispnp = (fdc->flags & FDC_ISPNP) != 0;
|
||||
ispcmcia = (fdc->flags & FDC_ISPCMCIA) != 0;
|
||||
#endif
|
||||
fdc->rid_ioport = fdc->rid_irq = fdc->rid_drq = 0;
|
||||
fdc->res_ioport = fdc->res_irq = fdc->res_drq = 0;
|
||||
#ifndef PC98
|
||||
fdc->rid_ctl = 1;
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
fdc->res_ioport = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ioport, fdc_iat,
|
||||
3, RF_ACTIVE);
|
||||
if (fdc->res_ioport == 0) {
|
||||
device_printf(dev, "cannot reserve I/O port range\n");
|
||||
return ENXIO;
|
||||
}
|
||||
isa_load_resourcev(fdc->res_ioport, fdc_iat, 3);
|
||||
#else
|
||||
/*
|
||||
* On standard ISA, we don't just use an 8 port range
|
||||
* (e.g. 0x3f0-0x3f7) since that covers an IDE control
|
||||
* register at 0x3f6.
|
||||
*
|
||||
* Isn't PC hardware wonderful.
|
||||
*
|
||||
* The Y-E Data PCMCIA FDC doesn't have this problem, it
|
||||
* uses the register with offset 6 for pseudo-DMA, and the
|
||||
* one with offset 7 as control register.
|
||||
*/
|
||||
nports = ispcmcia ? 8 : (ispnp ? 1 : 6);
|
||||
|
||||
/*
|
||||
* Some ACPI BIOSen have _CRS objects for the floppy device that
|
||||
* split the I/O port resource into several resources. We detect
|
||||
* this case by checking if there are more than 2 IOPORT resources.
|
||||
* If so, we use the resource with the smallest start address as
|
||||
* the port RID and the largest start address as the control RID.
|
||||
*/
|
||||
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 2) != 0) {
|
||||
u_long min_start, max_start, tmp;
|
||||
int i;
|
||||
|
||||
/* Find the min/max start addresses and their RIDs. */
|
||||
max_start = 0ul;
|
||||
min_start = ~0ul;
|
||||
for (i = 0; bus_get_resource_count(dev, SYS_RES_IOPORT, i) > 0;
|
||||
i++) {
|
||||
tmp = bus_get_resource_start(dev, SYS_RES_IOPORT, i);
|
||||
KASSERT(tmp != 0, ("bogus resource"));
|
||||
if (tmp < min_start) {
|
||||
min_start = tmp;
|
||||
fdc->rid_ioport = i;
|
||||
}
|
||||
if (tmp > max_start) {
|
||||
max_start = tmp;
|
||||
fdc->rid_ctl = i;
|
||||
}
|
||||
}
|
||||
if (min_start + 7 != max_start) {
|
||||
device_printf(dev, "I/O to control range incorrect\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ioport, 0ul, ~0ul,
|
||||
nports, RF_ACTIVE);
|
||||
if (fdc->res_ioport == 0) {
|
||||
device_printf(dev, "cannot reserve I/O port range (%d ports)\n",
|
||||
nports);
|
||||
return ENXIO;
|
||||
}
|
||||
#endif
|
||||
fdc->portt = rman_get_bustag(fdc->res_ioport);
|
||||
fdc->porth = rman_get_bushandle(fdc->res_ioport);
|
||||
|
||||
#ifdef PC98
|
||||
rid = 3;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, IO_FDPORT, 1);
|
||||
fdc->res_fdsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdsiot = rman_get_bustag(fdc->res_fdsio);
|
||||
fdc->sc_fdsioh = rman_get_bushandle(fdc->res_fdsio);
|
||||
|
||||
rid = 4;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4be, 1);
|
||||
fdc->res_fdemsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdemsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdemsiot = rman_get_bustag(fdc->res_fdemsio);
|
||||
fdc->sc_fdemsioh = rman_get_bushandle(fdc->res_fdemsio);
|
||||
#endif
|
||||
|
||||
#ifndef PC98
|
||||
if (!ispcmcia) {
|
||||
/*
|
||||
* Some BIOSen report the device at 0x3f2-0x3f5,0x3f7
|
||||
* and some at 0x3f0-0x3f5,0x3f7. We detect the former
|
||||
* by checking the size and adjust the port address
|
||||
* accordingly.
|
||||
*/
|
||||
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 0) == 4)
|
||||
fdc->port_off = -2;
|
||||
|
||||
/*
|
||||
* Register the control port range as rid 1 if it
|
||||
* isn't there already. Most PnP BIOSen will have
|
||||
* already done this but non-PnP configurations don't.
|
||||
*
|
||||
* And some (!!) report 0x3f2-0x3f5 and completely
|
||||
* leave out the control register! It seems that some
|
||||
* non-antique controller chips have a different
|
||||
* method of programming the transfer speed which
|
||||
* doesn't require the control register, but it's
|
||||
* mighty bogus as the chip still responds to the
|
||||
* address for the control register.
|
||||
*/
|
||||
if (bus_get_resource_count(dev, SYS_RES_IOPORT, 1) == 0) {
|
||||
u_long ctlstart;
|
||||
|
||||
/* Find the control port, usually 0x3f7 */
|
||||
ctlstart = rman_get_start(fdc->res_ioport) +
|
||||
fdc->port_off + 7;
|
||||
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, 1, ctlstart, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now (finally!) allocate the control port.
|
||||
*/
|
||||
fdc->res_ctl = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ctl, RF_ACTIVE);
|
||||
if (fdc->res_ctl == 0) {
|
||||
device_printf(dev,
|
||||
"cannot reserve control I/O port range (control port)\n");
|
||||
return ENXIO;
|
||||
}
|
||||
fdc->ctlt = rman_get_bustag(fdc->res_ctl);
|
||||
fdc->ctlh = rman_get_bushandle(fdc->res_ctl);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PC98
|
||||
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
|
||||
RF_ACTIVE);
|
||||
#else
|
||||
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
|
||||
RF_ACTIVE | RF_SHAREABLE);
|
||||
#endif
|
||||
if (fdc->res_irq == 0) {
|
||||
device_printf(dev, "cannot reserve interrupt line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
if ((fdc->flags & FDC_NODMA) == 0) {
|
||||
#ifdef PC98
|
||||
fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
|
||||
&fdc->rid_drq, RF_ACTIVE);
|
||||
if (fdc->res_drq == 0) {
|
||||
device_printf(dev, "cannot reserve DMA request line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
fdc->dmachan = rman_get_start(fdc->res_drq);
|
||||
#else
|
||||
fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
|
||||
&fdc->rid_drq, RF_ACTIVE | RF_SHAREABLE);
|
||||
if (fdc->res_drq == 0) {
|
||||
device_printf(dev, "cannot reserve DMA request line\n");
|
||||
fdc->flags |= FDC_NODMA;
|
||||
} else
|
||||
fdc->dmachan = rman_get_start(fdc->res_drq);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
fdc_release_resources(struct fdc_data *fdc)
|
||||
{
|
||||
@ -1126,15 +929,10 @@ fdc_attach(device_t dev)
|
||||
{
|
||||
struct fdc_data *fdc;
|
||||
const char *name, *dname;
|
||||
int i, error, dunit;
|
||||
int i, dunit, error;
|
||||
|
||||
fdc = device_get_softc(dev);
|
||||
fdc->fdc_dev = dev;
|
||||
error = fdc_alloc_resources(fdc);
|
||||
if (error) {
|
||||
device_printf(dev, "cannot re-acquire resources\n");
|
||||
return error;
|
||||
}
|
||||
error = BUS_SETUP_INTR(device_get_parent(dev), dev, fdc->res_irq,
|
||||
INTR_TYPE_BIO | INTR_ENTROPY, fdc_intr, fdc,
|
||||
&fdc->fdc_intr);
|
||||
|
@ -45,6 +45,69 @@ __FBSDID("$FreeBSD$");
|
||||
#include <isa/isavar.h>
|
||||
#include <pc98/pc98/pc98.h>
|
||||
|
||||
static bus_addr_t fdc_iat[] = {0, 2, 4};
|
||||
|
||||
static int
|
||||
fdc_cbus_alloc_resources(device_t dev, struct fdc_data *fdc)
|
||||
{
|
||||
int rid;
|
||||
|
||||
fdc->fdc_dev = dev;
|
||||
fdc->rid_ioport = 0;
|
||||
fdc->rid_irq = 0;
|
||||
fdc->rid_drq = 0;
|
||||
fdc->res_irq = 0;
|
||||
fdc->res_drq = 0;
|
||||
|
||||
fdc->res_ioport = isa_alloc_resourcev(dev, SYS_RES_IOPORT,
|
||||
&fdc->rid_ioport, fdc_iat,
|
||||
3, RF_ACTIVE);
|
||||
if (fdc->res_ioport == 0) {
|
||||
device_printf(dev, "cannot reserve I/O port range\n");
|
||||
return ENXIO;
|
||||
}
|
||||
isa_load_resourcev(fdc->res_ioport, fdc_iat, 3);
|
||||
fdc->portt = rman_get_bustag(fdc->res_ioport);
|
||||
fdc->porth = rman_get_bushandle(fdc->res_ioport);
|
||||
|
||||
rid = 3;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, IO_FDPORT, 1);
|
||||
fdc->res_fdsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdsiot = rman_get_bustag(fdc->res_fdsio);
|
||||
fdc->sc_fdsioh = rman_get_bushandle(fdc->res_fdsio);
|
||||
|
||||
rid = 4;
|
||||
bus_set_resource(dev, SYS_RES_IOPORT, rid, 0x4be, 1);
|
||||
fdc->res_fdemsio = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_fdemsio == 0)
|
||||
return ENXIO;
|
||||
fdc->sc_fdemsiot = rman_get_bustag(fdc->res_fdemsio);
|
||||
fdc->sc_fdemsioh = rman_get_bushandle(fdc->res_fdemsio);
|
||||
|
||||
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
|
||||
RF_ACTIVE);
|
||||
if (fdc->res_irq == 0) {
|
||||
device_printf(dev, "cannot reserve interrupt line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
if ((fdc->flags & FDC_NODMA) == 0) {
|
||||
fdc->res_drq = bus_alloc_resource_any(dev, SYS_RES_DRQ,
|
||||
&fdc->rid_drq, RF_ACTIVE);
|
||||
if (fdc->res_drq == 0) {
|
||||
device_printf(dev, "cannot reserve DMA request line\n");
|
||||
return ENXIO;
|
||||
}
|
||||
fdc->dmachan = rman_get_start(fdc->res_drq);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
fdc_cbus_probe(device_t dev)
|
||||
{
|
||||
@ -52,14 +115,13 @@ fdc_cbus_probe(device_t dev)
|
||||
struct fdc_data *fdc;
|
||||
|
||||
fdc = device_get_softc(dev);
|
||||
fdc->fdc_dev = dev;
|
||||
|
||||
/* Check pnp ids */
|
||||
if (isa_get_vendorid(dev))
|
||||
return (ENXIO);
|
||||
|
||||
/* Attempt to allocate our resources for the duration of the probe */
|
||||
error = fdc_alloc_resources(fdc);
|
||||
error = fdc_cbus_alloc_resources(dev, fdc);
|
||||
if (!error)
|
||||
error = fdc_initial_reset(fdc);
|
||||
|
||||
@ -67,10 +129,27 @@ fdc_cbus_probe(device_t dev)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
fdc_cbus_attach(device_t dev)
|
||||
{
|
||||
int error;
|
||||
struct fdc_data *fdc;
|
||||
|
||||
fdc = device_get_softc(dev);
|
||||
|
||||
if ((error = fdc_cbus_alloc_resources(dev, fdc)) != 0 ||
|
||||
(error = fdc_attach(dev)) != 0) {
|
||||
fdc_release_resources(fdc);
|
||||
return (error);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static device_method_t fdc_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, fdc_cbus_probe),
|
||||
DEVMETHOD(device_attach, fdc_attach),
|
||||
DEVMETHOD(device_attach, fdc_cbus_attach),
|
||||
DEVMETHOD(device_detach, fdc_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
||||
|
Loading…
Reference in New Issue
Block a user