summaryrefslogtreecommitdiffstats
path: root/sys/dev/cardbus/cardbus_cis.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2003-02-17 23:47:31 +0000
committerscottl <scottl@FreeBSD.org>2003-02-17 23:47:31 +0000
commit0b8c31403a46f0a8b7a922c3f1fb90a0afc5a980 (patch)
tree3fe353412b6d8e8319aee45fd120701828bb94db /sys/dev/cardbus/cardbus_cis.c
parent082ad05a9b09c9435c82cbd90169d5a3b32812ac (diff)
downloadFreeBSD-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/cardbus/cardbus_cis.c')
-rw-r--r--sys/dev/cardbus/cardbus_cis.c26
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);
}
OpenPOWER on IntegriCloud