From bade6e5e6b0eb47c91fd01ee753821f9bb8bcf0c Mon Sep 17 00:00:00 2001 From: Bill Paul Date: Thu, 23 Nov 2000 00:28:43 +0000 Subject: [PATCH] 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. --- sys/pci/if_pcn.c | 33 +++++++++++++++++++++++++++++++-- sys/pci/if_pcnreg.h | 2 +- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/sys/pci/if_pcn.c b/sys/pci/if_pcn.c index 216e17ca967..aa9549e1147 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); diff --git a/sys/pci/if_pcnreg.h b/sys/pci/if_pcnreg.h index 026c0ea9300..db7c1a3d4e3 100644 --- a/sys/pci/if_pcnreg.h +++ b/sys/pci/if_pcnreg.h @@ -247,7 +247,7 @@ #define PCN_BCR_SSTYLE 0x14 #define PCN_BCR_PCILAT 0x16 #define PCN_BCR_PCISUBVENID 0x17 -#define PCN_BCR_PCISUNSYSID 0x18 +#define PCN_BCR_PCISUBSYSID 0x18 #define PCN_BCR_SRAMSIZE 0x19 #define PCN_BCR_SRAMBOUND 0x1A #define PCN_BCR_SRAMCTL 0x1B