diff options
author | Warner Losh <imp@FreeBSD.org> | 2008-08-09 07:41:18 +0000 |
---|---|---|
committer | Warner Losh <imp@FreeBSD.org> | 2008-08-09 07:41:18 +0000 |
commit | 1b146a73eef1b4933ecd86222f80394ce9ce8a0d (patch) | |
tree | 6f62846a304bdc31934978bbbc2982b63b669e59 /sys/dev/pccbb | |
parent | d606fed62481d24fa7dfcb2171b81cfa589a413e (diff) | |
download | src-1b146a73eef1b4933ecd86222f80394ce9ce8a0d.tar.gz src-1b146a73eef1b4933ecd86222f80394ce9ce8a0d.zip |
After some intial testing, there are even slower cards than the ones
that I have. Wait up to 1.1s for the card to become ready. Document
what the standards say, and use that to justify the behavior in the
code: PCI standard says that a card must respond to configuration
cycles within 2^25 cycles after reset goes high, which is
approximately 1s. Therefore, give cards a little break and wait for
up to 1.1s for VENDOR to become valid. Only look at the vendor part
of the ID, since only it can't be 0xffff (although in practice
vendor/device will always be != 0xfffffffff). Include detailed
pointers to standards so epople understand why we're doing what we're
doing and why it just might be OK. Make it clear in the timeout
message that it is just a warning, sinc we try to soldier on as best
we can anyway.
This should eliminate an error message that r181453 produced on
certain Atheros cards.
Notes
Notes:
svn path=/head/; revision=181458
Diffstat (limited to 'sys/dev/pccbb')
-rw-r--r-- | sys/dev/pccbb/pccbb.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index f5a3b74c15c6..cfbbfba6fea8 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -934,31 +934,42 @@ cbb_cardbus_reset(device_t brdev, int on) int delay, count; /* - * 20ms is necessary for most bridges. For some reason, the Ricoh - * RF5C47x bridges need 400ms. + * Asserting reset for 20ms is necessary for most bridges. For some + * reason, the Ricoh RF5C47x bridges need it asserted for 400ms. */ delay = sc->chipset == CB_RF5C47X ? 400 : 20; - PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, |CBBM_BRIDGECTRL_RESET, 2); - pause("cbbP3", hz * delay / 1000); - /* If a card exists and we're turning it on, unreset it! */ + /* + * If a card exists and we're turning it on, take it out of reset. + */ if (on && CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) { - PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, - &~CBBM_BRIDGECTRL_RESET, 2); /* - * Wait up to .5s for the vendor of device 0.0 to become - * != 0xffffffff + * After clearing reset, wait up to 1.1s for the vendor of + * device 0.0 to become != 0xffff. The PCMCIA PC Card Host + * System Specification says that when powering up the card, + * the PCI Spec v2.1 must be followed. In PCI spec v2.2 Table + * 4-6, Trhfa (Reset High to first Config Access) is at most + * 2^25 clocks, or just over 1s. Secont 2.2.1 states any card + * not ready to participate in bus transactions must tristate + * its outputs. Therefore, any access to its configuration + * registers must be ignored. In that state, the vendor will + * read 0xffff. Section 6.2.1 states a vendor id of 0xffff is + * invalid, so this can never match a real card. Print a + * warning if it never returns a real id. The PCMCIA PC Card + * Electrical Spec Section 5.2.7.1 implies only device 0. */ + PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, + &~CBBM_BRIDGECTRL_RESET, 2); b = pcib_get_bus(brdev); - count = 25; + count = 1100 / 20; do { pause("cbbP4", hz * 2 / 100); - } while (PCIB_READ_CONFIG(brdev, b, 0, 0, PCIR_DEVVENDOR, 4) == - 0xfffffffful && --count >= 0); + } while (PCIB_READ_CONFIG(brdev, b, 0, 0, PCIR_DEVVENDOR, 2) == + 0xfffful && --count >= 0); if (count < 0) - device_printf(brdev, "Timeout on reset\n"); + device_printf(brdev, "Warning: Bus reset timeout\n"); } } |