diff options
author | scottl <scottl@FreeBSD.org> | 2003-02-17 23:47:31 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2003-02-17 23:47:31 +0000 |
commit | 0b8c31403a46f0a8b7a922c3f1fb90a0afc5a980 (patch) | |
tree | 3fe353412b6d8e8319aee45fd120701828bb94db /sys/dev | |
parent | 082ad05a9b09c9435c82cbd90169d5a3b32812ac (diff) | |
download | FreeBSD-src-0b8c31403a46f0a8b7a922c3f1fb90a0afc5a980.zip FreeBSD-src-0b8c31403a46f0a8b7a922c3f1fb90a0afc5a980.tar.gz |
Sanity check the BAR length reported by the CIS with the BAR length that
is encoded in the PCI BAR. The latter is more reliable.
This allows the sio/modem function of the Xircom RealPort ethernet+modem
card to work. Note that there still seem to be issues with sio_pci not
releasing resources on detach.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/cardbus/cardbus_cis.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/sys/dev/cardbus/cardbus_cis.c b/sys/dev/cardbus/cardbus_cis.c index 204749f..2b8e2b2 100644 --- a/sys/dev/cardbus/cardbus_cis.c +++ b/sys/dev/cardbus/cardbus_cis.c @@ -393,7 +393,7 @@ decode_tuple_bar(device_t cbdev, device_t child, int id, struct cardbus_devinfo *dinfo = device_get_ivars(child); int type; uint8_t reg; - uint32_t bar; + uint32_t bar, pci_bar; if (len != 6) { device_printf(cbdev, "CIS BAR length not 6 (%d)\n", len); @@ -416,16 +416,33 @@ decode_tuple_bar(device_t cbdev, device_t child, int id, /* XXX Should we try to map in Option ROMs? */ return (0); } - + + /* Convert from BAR type to BAR offset */ bar = CARDBUS_BASE0_REG + (bar - 1) * 4; if (type == SYS_RES_MEMORY) { - if (bar & TPL_BAR_REG_PREFETCHABLE) + if (reg & TPL_BAR_REG_PREFETCHABLE) dinfo->mprefetchable |= BARBIT(bar); - if (bar & TPL_BAR_REG_BELOW1MB) + if (reg & TPL_BAR_REG_BELOW1MB) dinfo->mbelow1mb |= BARBIT(bar); } + /* + * Sanity check the BAR length reported in the CIS with the length + * encoded in the PCI BAR. The latter seems to be more reliable. + * XXX - This probably belongs elsewhere. + */ + pci_write_config(child, bar, 0xffffffff, 4); + pci_bar = pci_read_config(child, bar, 4); + if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) { + if (type == SYS_RES_MEMORY) { + pci_bar &= ~0xf; + } else { + pci_bar &= ~0x3; + } + len = 1 << (ffs(pci_bar) - 1); + } + DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n", (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len, (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ? @@ -439,6 +456,7 @@ decode_tuple_bar(device_t cbdev, device_t child, int id, * device drivers will know which type of BARs can be used. */ pci_enable_io(child, type); + return (0); } |