summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/fdc/fdc_isa.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/dev/fdc/fdc_isa.c b/sys/dev/fdc/fdc_isa.c
index b912771..0833fed 100644
--- a/sys/dev/fdc/fdc_isa.c
+++ b/sys/dev/fdc/fdc_isa.c
@@ -81,6 +81,7 @@ fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
* 5: 0x3f2-0x3f5 # implies 0x3f7 too.
* 6: 0x3f2-0x3f3,0x3f4-0x3f5,0x3f7 # becoming common
* 7: 0x3f2-0x3f3,0x3f4-0x3f5 # rare
+ * 8: 0x3f0-0x3f1,0x3f2-0x3f3,0x3f4-0x3f5,0x3f7
*
* The following code is generic for any value of 0x3fx :-)
*/
@@ -90,6 +91,7 @@ fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
* worlds, this is 4 or 6 ports. In others, well, that's
* why this function is so complicated.
*/
+again_ioport:
fdc->res_ioport = bus_alloc_resource(dev, SYS_RES_IOPORT,
&fdc->rid_ioport, 0ul, ~0ul, nports, RF_ACTIVE);
if (fdc->res_ioport == 0) {
@@ -97,19 +99,27 @@ fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
nports);
return (ENXIO);
}
+ if ((rman_get_start(fdc->res_ioport) & 0x7) == 0 &&
+ rman_get_size(fdc->res_ioport) == 2) {
+ /* Case 8 */
+ bus_release_resource(dev, SYS_RES_IOPORT, fdc->rid_ioport,
+ fdc->res_ioport);
+ fdc->rid_ioport++;
+ goto again_ioport;
+ }
fdc->portt = rman_get_bustag(fdc->res_ioport);
fdc->porth = rman_get_bushandle(fdc->res_ioport);
/*
- * Handle cases 4-7 above
+ * Handle cases 4-8 above
*/
fdc->port_off = -(fdc->porth & 0x7);
/*
- * Deal with case 6 and 7: FDSTS and FDSATA are in rid 1.
+ * Deal with case 6, 7, and 8: FDSTS and FDSATA are in rid 1.
*/
if (rman_get_size(fdc->res_ioport) == 2) {
- fdc->rid_sts = 1;
+ fdc->rid_sts = fdc->rid_ioport + 1;
fdc->res_sts = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
&fdc->rid_sts, RF_ACTIVE);
if (fdc->res_sts == NULL) {
@@ -117,7 +127,6 @@ fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
fdc_release_resources(fdc);
return (ENXIO);
}
- fdc->rid_ctl++;
fdc->sts_off = -4;
fdc->stst = rman_get_bustag(fdc->res_sts);
fdc->stsh = rman_get_bushandle(fdc->res_sts);
@@ -133,6 +142,7 @@ fdc_isa_alloc_resources(device_t dev, struct fdc_data *fdc)
* fake it from the ioports resource. XXX IS THIS THE RIGHT THING
* TO DO, OR SHOULD WE CREATE A NEW RID? (I think we need a new rid)
*/
+ fdc->rid_ctl = fdc->rid_sts + 1;
fdc->res_ctl = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
&fdc->rid_ctl, RF_ACTIVE);
if (fdc->res_ctl == NULL) {
OpenPOWER on IntegriCloud