mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-04 12:52:15 +00:00
When checking the device code in the probe routine, leave the chip in
16-bit mode. Technically, pcn_probe() is destructive because once the chip goes into 32-bit mode, the only way to get it out again is a hardware reset. And once the device is in 32-bit mode, the lnc driver won't be able to talk to it. So if pcn_probe() is called before the lnc probe routine, and pcn_probe() rejects the chip as one it doesn't support, the lnc driver will be SOL. I don't like this. I think it's a design flaw that you can't switch the chip out of 32-bit mode once it's selected. The only 'right' solution is for the pcn driver to support all of the PCI devices in 32-bit mode, however I don't have samples of all the PCnet series cards for testing.
This commit is contained in:
parent
810888e2f8
commit
da6e4b77bb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=68837
@ -110,6 +110,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 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));
|
||||
@ -203,6 +204,14 @@ static u_int32_t pcn_csr_read(sc, reg)
|
||||
return(CSR_READ_4(sc, PCN_IO32_RDP));
|
||||
}
|
||||
|
||||
static u_int16_t pcn_csr_read16(sc, reg)
|
||||
struct pcn_softc *sc;
|
||||
int reg;
|
||||
{
|
||||
CSR_WRITE_2(sc, PCN_IO16_RAP, reg);
|
||||
return(CSR_READ_2(sc, PCN_IO16_RDP));
|
||||
}
|
||||
|
||||
static void pcn_csr_write(sc, reg, val)
|
||||
struct pcn_softc *sc;
|
||||
int reg;
|
||||
@ -401,10 +410,20 @@ static int pcn_probe(dev)
|
||||
mtx_init(&sc->pcn_mtx,
|
||||
device_get_nameunit(dev), MTX_DEF);
|
||||
PCN_LOCK(sc);
|
||||
pcn_reset(sc);
|
||||
chip_id = pcn_csr_read(sc, PCN_CSR_CHIPID1);
|
||||
/*
|
||||
* Note: we can *NOT* put the chip into
|
||||
* 32-bit mode yet. The lnc driver will only
|
||||
* work in 16-bit mode, and once the chip
|
||||
* goes into 32-bit mode, the only way to
|
||||
* get it out again is with a hardware reset.
|
||||
* So if pcn_probe() is called before the
|
||||
* 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.
|
||||
*/
|
||||
chip_id = pcn_csr_read16(sc, PCN_CSR_CHIPID1);
|
||||
chip_id <<= 16;
|
||||
chip_id |= pcn_csr_read(sc, PCN_CSR_CHIPID0);
|
||||
chip_id |= pcn_csr_read16(sc, PCN_CSR_CHIPID0);
|
||||
bus_release_resource(dev, PCN_RES,
|
||||
PCN_RID, sc->pcn_res);
|
||||
PCN_UNLOCK(sc);
|
||||
|
Loading…
Reference in New Issue
Block a user