summaryrefslogtreecommitdiffstats
path: root/sys/pci/if_pcn.c
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2000-11-23 00:28:43 +0000
committerwpaul <wpaul@FreeBSD.org>2000-11-23 00:28:43 +0000
commitf246e2cfe8f32b4402f7d81b0ee0a6a99ec3ee69 (patch)
tree3088b5ad7be4d941531b418efac8432efac2e896 /sys/pci/if_pcn.c
parent4d12edec9a904acc2ec81e4a273f2447b687792e (diff)
downloadFreeBSD-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.c33
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);
OpenPOWER on IntegriCloud