diff options
author | wpaul <wpaul@FreeBSD.org> | 2003-06-29 01:38:57 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2003-06-29 01:38:57 +0000 |
commit | 86478848415c822dedbc00f5682f3dc469fe4df0 (patch) | |
tree | aa92195d1d42273bccc31c205c5d66281a00e162 /sys | |
parent | 5c2c3d8274e19784e2f06dad02f05176255b525c (diff) | |
download | FreeBSD-src-86478848415c822dedbc00f5682f3dc469fe4df0.zip FreeBSD-src-86478848415c822dedbc00f5682f3dc469fe4df0.tar.gz |
Modify the xl_reset() routine slightly so that, if we're using memory
mapped I/O mode, we pause for .1 seconds after issuing the reset command
before trying to poll the 'command busy' bit in the status register.
With my 3c575C cardbus NIC, my Sony Picturebook locks up when it tries
to read the status register immediately after the reset. This appears
to be a problem only with certain NICs on certain hardware, but the
added delay should not hurt cards that already work.
This bug seems to have been brought to light by the fact that the xl
driver now defaults to memory mapped I/O mode instead of programmed
I/O mode like it used to. With PIO mode, the delay isn't needed and
everything works (which is why this NIC worked with 5.0-RELEASE but
not 5.1). I suspect that what's happening is that when the chip is
reset, it takes a little while for the memory-mapped decoding logic
to recover. Trying to access the chip's registers during this period
causes an error condition of some kind that wedges the system.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/pci/if_xl.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/pci/if_xl.c b/sys/pci/if_xl.c index 2b65aad..b4a43fc 100644 --- a/sys/pci/if_xl.c +++ b/sys/pci/if_xl.c @@ -1079,6 +1079,16 @@ xl_reset(sc) ((sc->xl_flags & XL_FLAG_WEIRDRESET) ? XL_RESETOPT_DISADVFD:0)); + /* + * If we're using memory mapped register mode, pause briefly + * after issuing the reset command before trying to access any + * other registers. With my 3c575C cardbus card, failing to do + * this results in the system locking up while trying to poll + * the command busy bit in the status register. + */ + if (sc->xl_flags & XL_FLAG_USE_MMIO) + DELAY(100000); + for (i = 0; i < XL_TIMEOUT; i++) { DELAY(10); if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY)) |