diff options
author | mdodd <mdodd@FreeBSD.org> | 1999-12-06 08:31:47 +0000 |
---|---|---|
committer | mdodd <mdodd@FreeBSD.org> | 1999-12-06 08:31:47 +0000 |
commit | 4c8ffdfc97267cfaa58e15077345d48104b67bc8 (patch) | |
tree | b5d2a151d0e73620647f71e7414dce82a7164b0e /sys/dev/ep | |
parent | f57de250e017306d4d0e84625cda4cc11417f0f6 (diff) | |
download | FreeBSD-src-4c8ffdfc97267cfaa58e15077345d48104b67bc8.zip FreeBSD-src-4c8ffdfc97267cfaa58e15077345d48104b67bc8.tar.gz |
Correctly implement the non-PnP enumeration of ISA board.
We now correctly skip boards that have PnP support enabled, or are in
test mode. The 3c509s support a number of combinations of device
probing, as per the databook.
- ISA only
- PnP only
- ISA or PnP
We will allow cards that can be dealt with by PnP to be attached by the
PnP enumerator.
This fixes the bogus detection of boards at weird ioports.
Diffstat (limited to 'sys/dev/ep')
-rw-r--r-- | sys/dev/ep/if_ep_isa.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/sys/dev/ep/if_ep_isa.c b/sys/dev/ep/if_ep_isa.c index 537f5d2..28f4fd4 100644 --- a/sys/dev/ep/if_ep_isa.c +++ b/sys/dev/ep/if_ep_isa.c @@ -138,7 +138,7 @@ ep_isa_identify (driver_t *driver, device_t parent) int i; int j; const char * desc; - u_int32_t data; + u_int16_t data; u_int32_t irq; u_int32_t ioport; u_int32_t isa_id; @@ -146,7 +146,6 @@ ep_isa_identify (driver_t *driver, device_t parent) outb(ELINK_ID_PORT, 0); outb(ELINK_ID_PORT, 0); - elink_idseq(ELINK_509_POLY); elink_reset(); @@ -156,7 +155,8 @@ ep_isa_identify (driver_t *driver, device_t parent) outb(ELINK_ID_PORT, 0); outb(ELINK_ID_PORT, 0); - elink_idseq(0xCF); + elink_idseq(ELINK_509_POLY); + DELAY(400); /* For the first probe, clear all * board's tag registers. @@ -169,6 +169,17 @@ ep_isa_identify (driver_t *driver, device_t parent) outb(ELINK_ID_PORT, 0xd8); } + /* Get out of loop if we're out of cards. */ + data = get_eeprom_data(ELINK_ID_PORT, EEPROM_MFG_ID); + if (data != MFG_ID) { + break; + } + + /* resolve contention using the Ethernet address */ + for (j = 0; j < 3; j++) { + (void)get_eeprom_data(ELINK_ID_PORT, j); + } + /* * Construct an 'isa_id' in 'EISA' * format. @@ -188,11 +199,6 @@ ep_isa_identify (driver_t *driver, device_t parent) break; } - /* resolve contention using the Ethernet address */ - for (j = 0; j < 3; j++) { - get_eeprom_data(ELINK_ID_PORT, j); - } - /* Retreive IRQ */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_RESOURCE_CFG); irq = (data >> 12); @@ -200,22 +206,38 @@ ep_isa_identify (driver_t *driver, device_t parent) /* Retreive IOPORT */ data = get_eeprom_data(ELINK_ID_PORT, EEPROM_ADDR_CFG); #ifdef PC98 - ioport = ((data * 0x100) + 0x40d0); + ioport = (((data & 0x1f) * 0x100) + 0x40d0); #else - ioport = ((data << 4) + 0x200); + ioport = (((data & 0x1f) << 4) + 0x200); #endif + /* Test for an adapter with PnP support. */ + data = get_eeprom_data(ELINK_ID_PORT, EEPROM_CAP); + if (data == CAP_ISA) { + data = get_eeprom_data(ELINK_ID_PORT, EEPROM_INT_CONFIG_1); + if (data & ICW1_IAS_PNP) { + if (bootverbose) { + device_printf(parent, "if_ep: Adapter at 0x%03x in PnP mode!\n", + ioport); + } + /* Set the adaptor tag so that the next card can be found. */ + outb(ELINK_ID_PORT, tag--); + continue; + } + } + /* Set the adaptor tag so that the next card can be found. */ outb(ELINK_ID_PORT, tag--); /* Activate the adaptor at the EEPROM location. */ - outb(ELINK_ID_PORT, ((ioport >> 4) | 0xe0)); + outb(ELINK_ID_PORT, ACTIVATE_ADAPTER_TO_CONFIG); - /* Test for an adapter in PnP mode */ + /* Test for an adapter in TEST mode. */ + outw(ioport + EP_COMMAND, WINDOW_SELECT | 0); data = inw(ioport + EP_W0_EEPROM_COMMAND); if (data & EEPROM_TST_MODE) { - device_printf(parent, "if_ep: Adapter at 0x%03x in PnP mode!\n", - ioport); + device_printf(parent, "if_ep: Adapter at 0x%03x in TEST mode! Erase pencil mark.\n", + ioport); continue; } |