I'm working on converting the 'ie' driver to newbus. I've rewritten the code that identifies the cards and am in need of wider testing since I've only got a lone Intel EtherExpress 16. I have a non-invasive test 'driver' that just looks for the cards and figures out the resources they are using. Please do the following if you own/use an Intel EtherExpress 16 or a 3Com 3C507 Etherlink 16 and are running -CURRENT: - save the attachment if_ie_isa.c to src/sys/dev/ie - save the attachment ie_test.patch to /tmp/ - cd /sys && patch < /tmp/ie_test.patch - edit your kernel config file and add the following line: device ie_test0 - config and build your kernel - boot verbose and look for 'if_ie' in the messages. - compare the reported values with the values your card actually uses. - report success or failure to me. Thanks! -- | Matthew N. Dodd | '78 Datsun 280Z | '75 Volvo 164E | FreeBSD/NetBSD | | [EMAIL PROTECTED] | 2 x '84 Volvo 245DL | ix86,sparc,pmax | | http://www.jurai.net/~winter | This Space For Rent | ISO8802.5 4ever |
Index: conf/files =================================================================== RCS file: /cvs/src/sys/conf/files,v retrieving revision 1.342 diff -u -r1.342 files --- conf/files 2000/03/20 14:08:37 1.342 +++ conf/files 2000/03/25 03:29:40 @@ -168,6 +173,7 @@ dev/hfa/fore_transmit.c optional hfa dev/hfa/fore_vcm.c optional hfa dev/ie/if_ie.c optional ie isa +dev/ie/if_ie_isa.c optional ie_test isa dev/ida/ida.c optional ida dev/ida/ida_disk.c optional ida dev/ida/ida_eisa.c optional ida eisa
#include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> #include <sys/bus.h> #include <machine/bus_pio.h> #include <machine/bus.h> #include <machine/resource.h> #include <sys/rman.h> #include <machine/clock.h> #include <isa/isavar.h> #include <isa/pnpvar.h> #include <i386/isa/elink.h> #include <dev/ie/if_ie507.h> #include <dev/ie/if_iee16.h> static void ie_isa_3C507_identify (driver_t *, device_t); static int ie_3C507_port_check (u_int32_t); static void ie_isa_ee16_identify (driver_t *, device_t); static u_int16_t ie_ee16_hw_read_eeprom (u_int32_t port, int loc); #define IE_3C507_IOBASE_LOW 0x200 #define IE_3C507_IOBASE_HIGH 0x3e0 #define IE_3C507_IOSIZE 16 #define IE_3C507_IRQ_MASK 0x0f #define IE_3C507_MADDR_HIGH 0x20 #define IE_3C507_MADDR_MASK 0x1c #define IE_3C507_MADDR_BASE 0xc0000 #define IE_3C507_MADDR_SHIFT 12 #define IE_3C507_MSIZE_MASK 3 #define IE_3C507_MSIZE_SHIFT 14 /* * 3Com 3C507 Etherlink 16 */ static void ie_isa_3C507_identify (driver_t *driver, device_t parent) { char * desc = "3Com 3C507 Etherlink 16"; u_int32_t port; u_int32_t maddr; u_int32_t msize; u_int8_t irq; u_int8_t data; /* Reset and put card in CONFIG state without changing address. */ elink_reset(); outb(ELINK_ID_PORT, 0); elink_idseq(ELINK_507_POLY); elink_idseq(ELINK_507_POLY); outb(ELINK_ID_PORT, 0xff); for (port = IE_3C507_IOBASE_LOW; port <= IE_3C507_IOBASE_HIGH; port += IE_3C507_IOSIZE) { if (ie_3C507_port_check(port)) { if (bootverbose) { #if 0 device_printf(parent, "if_ie: (3C507) not found at port %#x\n", port); #endif } continue; } outb(port + IE507_CTRL, EL_CTRL_NRST); data = inb(port + IE507_IRQ); irq = data & IE_3C507_IRQ_MASK; data = inb(port + IE507_MADDR); if (data & IE_3C507_MADDR_HIGH) { if (bootverbose) { device_printf(parent, "if_ef: can't map 3C507 RAM in high memory\n"); } continue; } maddr = IE_3C507_MADDR_BASE + ((data & IE_3C507_MADDR_MASK) << IE_3C507_MADDR_SHIFT); msize = ((data & IE_3C507_MSIZE_MASK) + 1) << IE_3C507_MSIZE_SHIFT; outb(port + IE507_CTRL, EL_CTRL_NORMAL); /* Clear the interrupt latch just in case. */ outb(port + IE507_ICTRL, 1); #if 0 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ie", -1); device_set_desc_copy(child, desc); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); bus_set_resource(child, SYS_RES_IOPORT, 0, port, IE_3C507_IOSIZE); bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize); #endif if (bootverbose) { device_printf(parent, "if_ie: <%s> at port %#x-%#x irq %d iomem %#lx-%#lx (%dKB)\n", desc, port, (port + IE_3C507_IOSIZE) - 1, irq, (u_long)maddr, (u_long)(maddr + msize) - 1, (msize / 1024)); } } /* go to RUN state */ outb(ELINK_ID_PORT, 0x00); elink_idseq(ELINK_507_POLY); outb(ELINK_ID_PORT, 0x00); return; } static int ie_3C507_port_check (u_int32_t port) { u_char * signature = "*3COM*"; int i; for (i = 0; i < 6; i++) if (inb(port + i) != signature[i]) return (ENXIO); return (0); } #define IE_EE16_ID_PORT 0x0f #define IE_EE16_ID 0xbaba #define IE_EE16_EEPROM_CONFIG1 0x00 #define IE_EE16_EEPROM_IRQ_MASK 0xe000 #define IE_EE16_EEPROM_IRQ_SHIFT 13 #define IE_EE16_EEPROM_MEMCFG 0x06 #define IE_EE16_IOSIZE 16 /* * Intel EtherExpress 16 * * TODO: * Test for 8/16 bit mode. * Test for invalid mem sizes. */ static void ie_isa_ee16_identify (driver_t *driver, device_t parent) { char * desc = "Intel EtherExpress 16"; u_int16_t ports[] = { 0x300, 0x310, 0x320, 0x330, 0x340, 0x350, 0x360, 0x370, 0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270, 0 }; u_int16_t irqs[] = { 0, 0x09, 0x03, 0x04, 0x05, 0x0a, 0x0b, 0 }; u_int32_t port; u_int32_t maddr; u_int32_t msize; u_int8_t irq; u_int8_t data; u_int16_t data1; int i, j; for (i = 0; ports[i] != 0; i++) { u_int16_t board_id; board_id = 0; port = ports[i]; for (j = 0; j < 4; j++) { data = inb(port + IE_EE16_ID_PORT); board_id |= ((data >> 4) << ((data & 0x03) << 2)); } if (board_id != IE_EE16_ID) { #if 0 device_printf(parent, "if_ie: (EE16) not found at port %#x\n", port); #endif continue; } /* reset any ee16 at the current iobase */ outb(port + IEE16_ECTRL, IEE16_RESET_ASIC); outb(port + IEE16_ECTRL, 0); DELAY(240); data1 = ie_ee16_hw_read_eeprom(port, IE_EE16_EEPROM_CONFIG1); irq = irqs[((data1 & IE_EE16_EEPROM_IRQ_MASK) >> IE_EE16_EEPROM_IRQ_SHIFT)]; data1 = ie_ee16_hw_read_eeprom(port, IE_EE16_EEPROM_MEMCFG); maddr = 0xc0000 + ((ffs(data1 & 0x00ff) - 1) * 0x4000); msize = (fls((data1 & 0x00ff) >> (ffs(data1 & 0x00ff) - 1))) * 0x4000; #if 0 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ie", -1); device_set_desc_copy(child, desc); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); bus_set_resource(child, SYS_RES_IOPORT, 0, port, IE_EE16_IOSIZE); bus_set_resource(child, SYS_RES_MEMORY, 0, maddr, msize); #endif if (bootverbose) { device_printf(parent, "if_ie: <%s> at port %#x-%#x irq %d iomem %#lx-%#lx (%dKB)\n", desc, port, (port + IE_EE16_IOSIZE) - 1, irq, (u_long)maddr, (u_long)(maddr + msize) - 1, (msize / 1024)); } } return; } static void ie_ee16_hw_eeprom_clock (u_int32_t port, int state) { u_int8_t ectrl; ectrl = inb(port + IEE16_ECTRL); ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK); if (state) { ectrl |= IEE16_ECTRL_EESK; } outb(port + IEE16_ECTRL, ectrl); DELAY(9); /* EESK must be stable for 8.38 uSec */ } static void ie_ee16_hw_eeprom_out (u_int32_t port, u_int16_t edata, int count) { u_int8_t ectrl; int i; ectrl = inb(port + IEE16_ECTRL); ectrl &= ~IEE16_RESET_ASIC; for (i = count - 1; i >= 0; i--) { ectrl &= ~IEE16_ECTRL_EEDI; if (edata & (1 << i)) { ectrl |= IEE16_ECTRL_EEDI; } outb(port + IEE16_ECTRL, ectrl); DELAY(1); /* eeprom data must be setup for 0.4 uSec */ ie_ee16_hw_eeprom_clock(port, 1); ie_ee16_hw_eeprom_clock(port, 0); } ectrl &= ~IEE16_ECTRL_EEDI; outb(port + IEE16_ECTRL, ectrl); DELAY(1); /* eeprom data must be held for 0.4 uSec */ return; } static u_int16_t ie_ee16_hw_eeprom_in (u_int32_t port) { u_int8_t ectrl; u_int16_t edata; int i; ectrl = inb(port + IEE16_ECTRL); ectrl &= ~IEE16_RESET_ASIC; for (edata = 0, i = 0; i < 16; i++) { edata = edata << 1; ie_ee16_hw_eeprom_clock(port, 1); ectrl = inb(port + IEE16_ECTRL); if (ectrl & IEE16_ECTRL_EEDO) { edata |= 1; } ie_ee16_hw_eeprom_clock(port, 0); } return (edata); } static u_int16_t ie_ee16_hw_read_eeprom (u_int32_t port, int loc) { u_int8_t ectrl; u_int16_t edata; ectrl = inb(port + IEE16_ECTRL); ectrl &= IEE16_ECTRL_MASK; ectrl |= IEE16_ECTRL_EECS; outb(port + IEE16_ECTRL, ectrl); ie_ee16_hw_eeprom_out(port, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1); ie_ee16_hw_eeprom_out(port, loc, IEE16_EEPROM_ADDR_SIZE); edata = ie_ee16_hw_eeprom_in(port); ectrl = inb(port + IEE16_ECTRL); ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS); outb(port + IEE16_ECTRL, ectrl); ie_ee16_hw_eeprom_clock(port, 1); ie_ee16_hw_eeprom_clock(port, 0); return (edata); } static devclass_t ie_devclass; static device_method_t ie_isa_3C507_methods[] = { DEVMETHOD(device_identify, ie_isa_3C507_identify), { 0, 0 } }; static driver_t ie_isa_3C507_driver = { "ie", ie_isa_3C507_methods, 1 /* sizeof(struct ie_softc) */, }; DRIVER_MODULE(ie_3C507, isa, ie_isa_3C507_driver, ie_devclass, 0, 0); static device_method_t ie_isa_ee16_methods[] = { DEVMETHOD(device_identify, ie_isa_ee16_identify), { 0, 0 } }; static driver_t ie_isa_ee16_driver = { "ie", ie_isa_ee16_methods, 1 /* sizeof(struct ie_softc) */, }; DRIVER_MODULE(ie_ee16, isa, ie_isa_ee16_driver, ie_devclass, 0, 0);