summaryrefslogtreecommitdiffstats
path: root/sys/dev/fdc/fdc_isa.c
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2005-03-10 18:09:25 +0000
committerimp <imp@FreeBSD.org>2005-03-10 18:09:25 +0000
commitd0ffad32b585c4e46b0814f34d9469d7bbb374b3 (patch)
tree216e079508b6b4579a927e5cffeed3e2b9a67044 /sys/dev/fdc/fdc_isa.c
parenta72c7b81ca4991121fc5d76704efa9902b35aa71 (diff)
downloadFreeBSD-src-d0ffad32b585c4e46b0814f34d9469d7bbb374b3.zip
FreeBSD-src-d0ffad32b585c4e46b0814f34d9469d7bbb374b3.tar.gz
Fix a couple of problems with the probe code when used with pnpbios
resources. When allocating 6 ports for a 4 port range isa code returns an error. I'm not sure yet why this is the case, but suspect it is just a non-regularity in how the resource allocation code works which should be corrected. Use 1 as the ports size in this case. However, in the hints case, we have to specify the length, so use 6 in that case. I believe that this is also acpi friendly. Also, complain when we can't allocate FDOUT register space. Right now we silently fail when we can't. This failure is referred to above. When there's no resource for FDCTL, go ahead and allocate one by hand. Many PNPBIOS tables don't list this resource, and our hints mechanism also doesn't cover that range. If we can't allocate it, whine, but fake up something. Before, we were always bogusly faking it and no one noticed the sham (save the original author who has now fixed his private shame).
Diffstat (limited to 'sys/dev/fdc/fdc_isa.c')
-rw-r--r--sys/dev/fdc/fdc_isa.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/sys/dev/fdc/fdc_isa.c b/sys/dev/fdc/fdc_isa.c
index cb4d317..b52da52 100644
--- a/sys/dev/fdc/fdc_isa.c
+++ b/sys/dev/fdc/fdc_isa.c
@@ -78,18 +78,19 @@ int
fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
{
struct resource *res;
- int nports = 6;
- int i, j, rid, newrid;
+ int i, j, rid, newrid, nport;
+ u_long port;
fdc->fdc_dev = dev;
rid = 0;
for (i = 0; i < FDC_MAXREG; i++)
fdc->resio[i] = NULL;
+ nport = isa_get_logicalid(dev) ? 1 : 6;
for (rid = 0; ; rid++) {
newrid = rid;
res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid,
- 0ul, ~0ul, nports, RF_ACTIVE);
+ 0ul, ~0ul, nport, RF_ACTIVE);
if (res == NULL)
break;
/*
@@ -106,15 +107,28 @@ fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
fdc->ioh[i + j] = rman_get_bushandle(res);
}
}
- if (fdc->resio[2] == NULL)
+ if (fdc->resio[2] == NULL) {
+ device_printf(dev, "No FDOUT register!\n");
return (ENXIO);
+ }
fdc->iot = rman_get_bustag(fdc->resio[2]);
if (fdc->resio[7] == NULL) {
- /* XXX allocate */
- fdc->resio[7] = fdc->resio[2];
- fdc->ridio[7] = fdc->ridio[2];
- fdc->ioff[7] = fdc->ioff[2] + 5;
- fdc->ioh[7] = fdc->ioh[2];
+ port = (rman_get_start(fdc->resio[2]) & ~0x7) + 7;
+ newrid = rid;
+ res = bus_alloc_resource(dev, SYS_RES_IOPORT, &newrid, port,
+ port, 1, RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "Faking up FDCTL\n");
+ fdc->resio[7] = fdc->resio[2];
+ fdc->ridio[7] = fdc->ridio[2];
+ fdc->ioff[7] = fdc->ioff[2] + 5;
+ fdc->ioh[7] = fdc->ioh[2];
+ } else {
+ fdc->resio[7] = res;
+ fdc->ridio[7] = newrid;
+ fdc->ioff[7] = rman_get_start(res) & 7;
+ fdc->ioh[7] = rman_get_bushandle(res);
+ }
}
fdc->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &fdc->rid_irq,
OpenPOWER on IntegriCloud