diff options
author | wpaul <wpaul@FreeBSD.org> | 2000-11-23 00:28:43 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2000-11-23 00:28:43 +0000 |
commit | f246e2cfe8f32b4402f7d81b0ee0a6a99ec3ee69 (patch) | |
tree | 3088b5ad7be4d941531b418efac8432efac2e896 /sys/pci/if_pcn.c | |
parent | 4d12edec9a904acc2ec81e4a273f2447b687792e (diff) | |
download | FreeBSD-src-f246e2cfe8f32b4402f7d81b0ee0a6a99ec3ee69.zip FreeBSD-src-f246e2cfe8f32b4402f7d81b0ee0a6a99ec3ee69.tar.gz |
Update the probe some more to deal with 16/32 bit issues. If the chip
is already in 32-bit mode, we need to be able to detect this and still
read the chip ID code. Detecting 32-bit mode is actually a little
tricky, since we want to avoid turning it on accidentally. The easiest
way to do it is to just try and read the PCI subsystem ID from the
bus control registers using 16-bit accesses and compare that with the
value read from PCI config space. If they match, then we know we're in
16-bit mode, otherwise we assume 32-bit mode.
Diffstat (limited to 'sys/pci/if_pcn.c')
-rw-r--r-- | sys/pci/if_pcn.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/sys/pci/if_pcn.c b/sys/pci/if_pcn.c index 216e17c..aa9549e 100644 --- a/sys/pci/if_pcn.c +++ b/sys/pci/if_pcn.c @@ -111,6 +111,7 @@ static struct pcn_type pcn_devs[] = { static u_int32_t pcn_csr_read __P((struct pcn_softc *, int)); static u_int16_t pcn_csr_read16 __P((struct pcn_softc *, int)); +static u_int16_t pcn_bcr_read16 __P((struct pcn_softc *, int)); static void pcn_csr_write __P((struct pcn_softc *, int, int)); static u_int32_t pcn_bcr_read __P((struct pcn_softc *, int)); static void pcn_bcr_write __P((struct pcn_softc *, int, int)); @@ -229,6 +230,14 @@ static u_int32_t pcn_bcr_read(sc, reg) return(CSR_READ_4(sc, PCN_IO32_BDP)); } +static u_int16_t pcn_bcr_read16(sc, reg) + struct pcn_softc *sc; + int reg; +{ + CSR_WRITE_2(sc, PCN_IO16_RAP, reg); + return(CSR_READ_2(sc, PCN_IO16_BDP)); +} + static void pcn_bcr_write(sc, reg, val) struct pcn_softc *sc; int reg; @@ -420,10 +429,30 @@ static int pcn_probe(dev) * lnc driver's probe routine, the chip will * be locked into 32-bit operation and the lnc * driver will be unable to attach to it. + * Note II: if the chip happens to already + * be in 32-bit mode, we still need to check + * the chip ID, but first we have to detect + * 32-bit mode using only 16-bit operations. + * The safest way to do this is to read the + * PCI subsystem ID from BCR23/24 and compare + * that with the value read from PCI config + * space. */ - chip_id = pcn_csr_read16(sc, PCN_CSR_CHIPID1); + chip_id = pcn_bcr_read16(sc, PCN_BCR_PCISUBSYSID); chip_id <<= 16; - chip_id |= pcn_csr_read16(sc, PCN_CSR_CHIPID0); + chip_id |= pcn_bcr_read16(sc, PCN_BCR_PCISUBVENID); + if (chip_id == pci_read_config(dev, + PCIR_SUBVEND_0, 4)) { + /* We're in 16-bit mode. */ + chip_id = pcn_csr_read16(sc, PCN_CSR_CHIPID1); + chip_id <<= 16; + chip_id |= pcn_csr_read16(sc, PCN_CSR_CHIPID0); + } else { + /* We're in 32-bit mode. */ + chip_id = pcn_csr_read(sc, PCN_CSR_CHIPID1); + chip_id <<= 16; + chip_id |= pcn_csr_read(sc, PCN_CSR_CHIPID0); + } bus_release_resource(dev, PCN_RES, PCN_RID, sc->pcn_res); PCN_UNLOCK(sc); |