DF-5175 / fix.diff
--- a/sys/dev/disk/nata/ata-card.c +++ b/sys/dev/disk/nata/ata-card.c @@ -89,6 +89,18 @@ ATA_IOSIZE, RF_ACTIVE))) return (ENXIO); + /* + * The pccard bus hands back the CIS-declared I/O window verbatim, so its + * size is card-controlled. Make sure it actually covers the primary + * register block (offsets 0..7) wired below before we use it. + */ + if (rman_get_size(io) < ATA_IOSIZE) { + device_printf(dev, "CIS io window too small (%ju ports)\n", + (uintmax_t)rman_get_size(io)); + bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io); + return (ENXIO); + } + /* setup the resource vectors */ for (i = ATA_DATA; i <= ATA_COMMAND; i++) { ch->r_io[i].res = io; @@ -99,10 +111,11 @@ /* * if we got more than the default ATA_IOSIZE ports, this is a device * where ctlio is located at offset 14 into "normal" io space. + * Only trust that layout when the window really covers offset 14. */ - if (rman_get_size(io) > ATA_IOSIZE) { + if (rman_get_size(io) >= ATA_PCCARD_CTLOFFSET + ATA_CTLIOSIZE) { ch->r_io[ATA_CONTROL].res = io; - ch->r_io[ATA_CONTROL].offset = 14; + ch->r_io[ATA_CONTROL].offset = ATA_PCCARD_CTLOFFSET; } else { rid = ATA_CTLADDR_RID; |