aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/pccbb
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2008-08-09 07:41:18 +0000
committerWarner Losh <imp@FreeBSD.org>2008-08-09 07:41:18 +0000
commit1b146a73eef1b4933ecd86222f80394ce9ce8a0d (patch)
tree6f62846a304bdc31934978bbbc2982b63b669e59 /sys/dev/pccbb
parentd606fed62481d24fa7dfcb2171b81cfa589a413e (diff)
downloadsrc-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.c37
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");
}
}