Index: arch/atari/atari/autoconf.c =================================================================== RCS file: /cvsroot/src/sys/arch/atari/atari/autoconf.c,v retrieving revision 1.54 diff -u -r1.54 autoconf.c --- arch/atari/atari/autoconf.c 3 Dec 2007 15:33:21 -0000 1.54 +++ arch/atari/atari/autoconf.c 29 Mar 2010 16:02:24 -0000 @@ -299,6 +299,7 @@ config_found(dp, __UNCONST("nvr") , simple_devprint); config_found(dp, __UNCONST("lpt") , simple_devprint); config_found(dp, __UNCONST("wdc") , simple_devprint); + config_found(dp, __UNCONST("ne") , simple_devprint); config_found(dp, __UNCONST("isab") , simple_devprint); config_found(dp, __UNCONST("pcib") , simple_devprint); config_found(dp, __UNCONST("avmebus") , simple_devprint); Index: arch/atari/conf/ATARITT =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/ATARITT,v retrieving revision 1.86.4.4 diff -u -r1.86.4.4 ATARITT --- arch/atari/conf/ATARITT 12 Mar 2009 23:33:48 -0000 1.86.4.4 +++ arch/atari/conf/ATARITT 29 Mar 2010 16:02:24 -0000 @@ -106,10 +106,12 @@ ite2 at grfcc2 # 3rd tty lp0 at mainbus0 # centronics printer ser0 at mainbus0 # UART on first 68901 (ttyB0) +ne0 at mainbus0 # EtherNEC on Atari ROM cartridge slot avmebus0 at mainbus0 # VME bus vme0 at avmebus0 le0 at vme0 irq 5 # Lance ethernet (Riebl/PAM). le0 at vme0 irq 4 # Lance ethernet (BVME410). +we0 at vme0 irq 4 # SMC Elite Ultra via SMC_TT VME-ISA bridge et0 at vme0 # Crazy Dots II scsibus* at scsi? # SCSI bus sd* at scsibus? target ? lun ? # SCSI disk drives Index: arch/atari/conf/FALCON =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/FALCON,v retrieving revision 1.84.4.4 diff -u -r1.84.4.4 FALCON --- arch/atari/conf/FALCON 12 Mar 2009 23:33:48 -0000 1.84.4.4 +++ arch/atari/conf/FALCON 29 Mar 2010 16:02:24 -0000 @@ -108,6 +108,7 @@ ite2 at grfcc2 # 3rd tty lp0 at mainbus0 # centronics printer ser0 at mainbus0 # UART on first 68901 (ttyB0) +ne0 at mainbus0 # EtherNEC on Atari ROM cartridge slot wdc0 at mainbus0 # IDE-bus atabus* at wdc? channel ? wd* at atabus? drive ? Index: arch/atari/conf/GENERIC.in =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/GENERIC.in,v retrieving revision 1.73.4.5 diff -u -r1.73.4.5 GENERIC.in --- arch/atari/conf/GENERIC.in 12 Mar 2009 23:32:35 -0000 1.73.4.5 +++ arch/atari/conf/GENERIC.in 29 Mar 2010 16:02:24 -0000 @@ -345,12 +345,14 @@ ite2 at grfcc2 # 3rd tty lp0 at mainbus0 # centronics printer ser0 at mainbus0 # UART on first 68901 (ttyB0) +ne0 at mainbus0 # EtherNEC on Atari ROM cartridge slot #if defined(TT030_KERNEL) avmebus0 at mainbus0 # VME bus vme0 at avmebus0 le0 at vme0 irq 5 # Lance ethernet (Riebl/PAM). le0 at vme0 irq 4 # Lance ethernet (BVME410). +we0 at vme0 irq 4 # SMC Elite Ultra via SMC_TT VME-ISA bridge et0 at vme0 # Crazy Dots II #endif /* TT030_KERNEL */ #endif /* SMALL030_KERNEL */ Index: arch/atari/conf/HADES =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/HADES,v retrieving revision 1.76.4.4 diff -u -r1.76.4.4 HADES --- arch/atari/conf/HADES 12 Mar 2009 23:33:48 -0000 1.76.4.4 +++ arch/atari/conf/HADES 29 Mar 2010 16:02:25 -0000 @@ -112,6 +112,7 @@ nvr0 at mainbus0 # nvram driver lp0 at mainbus0 # centronics printer ser0 at mainbus0 # UART on first 68901 (ttyB0) +ne0 at mainbus0 # EtherNEC on Atari ROM cartridge slot grfbus0 at mainbus0 # bitmapped display's grfet0 at grfbus0 # et4000/et6000/et6100 consoles ite0 at grfet0 Index: arch/atari/conf/HADES.in =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/HADES.in,v retrieving revision 1.8.88.1 diff -u -r1.8.88.1 HADES.in --- arch/atari/conf/HADES.in 26 Jan 2009 03:07:52 -0000 1.8.88.1 +++ arch/atari/conf/HADES.in 29 Mar 2010 16:02:25 -0000 @@ -21,6 +21,7 @@ nvr0 at mainbus0 # nvram driver lp0 at mainbus0 # centronics printer ser0 at mainbus0 # UART on first 68901 (ttyB0) +ne0 at mainbus0 # EtherNEC on Atari ROM cartridge slot grfbus0 at mainbus0 # bitmapped display's grfet0 at grfbus0 # et4000/et6000/et6100 consoles ite0 at grfet0 Index: arch/atari/conf/MILAN-ISAIDE =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/MILAN-ISAIDE,v retrieving revision 1.53.4.4 diff -u -r1.53.4.4 MILAN-ISAIDE --- arch/atari/conf/MILAN-ISAIDE 12 Mar 2009 23:33:48 -0000 1.53.4.4 +++ arch/atari/conf/MILAN-ISAIDE 29 Mar 2010 16:02:25 -0000 @@ -113,6 +113,7 @@ pci0 at pcib0 nvr0 at mainbus0 # nvram driver ser0 at mainbus0 +ne0 at mainbus0 # EtherNEC fdcisa0 at isa? port 0x3f0 irq 6 drq 2 # standard PC floppy contr. fdisa0 at fdcisa0 drive 0 wdc0 at isa? port 0x1f0 irq 14 flags 0x04 # 1st IDE controller Index: arch/atari/conf/MILAN-PCIIDE =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/MILAN-PCIIDE,v retrieving revision 1.57.4.4 diff -u -r1.57.4.4 MILAN-PCIIDE --- arch/atari/conf/MILAN-PCIIDE 12 Mar 2009 23:33:48 -0000 1.57.4.4 +++ arch/atari/conf/MILAN-PCIIDE 29 Mar 2010 16:02:25 -0000 @@ -113,6 +113,7 @@ pci0 at pcib0 nvr0 at mainbus0 # nvram driver ser0 at mainbus0 +ne0 at mainbus0 # EtherNEC fdcisa0 at isa? port 0x3f0 irq 6 drq 2 # standard PC floppy contr. fdisa0 at fdcisa0 drive 0 pciide* at pci? dev ? function ? flags 0x0000 # GENERIC pciide driver Index: arch/atari/conf/MILAN.in =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/MILAN.in,v retrieving revision 1.21.70.1 diff -u -r1.21.70.1 MILAN.in --- arch/atari/conf/MILAN.in 26 Jan 2009 03:07:52 -0000 1.21.70.1 +++ arch/atari/conf/MILAN.in 29 Mar 2010 16:02:25 -0000 @@ -45,6 +45,7 @@ pci0 at pcib0 nvr0 at mainbus0 # nvram driver ser0 at mainbus0 +ne0 at mainbus0 # EtherNEC fdcisa0 at isa? port 0x3f0 irq 6 drq 2 # standard PC floppy contr. fdisa0 at fdcisa0 drive 0 Index: arch/atari/conf/files.atari =================================================================== RCS file: /cvsroot/src/sys/arch/atari/conf/files.atari,v retrieving revision 1.112.20.1 diff -u -r1.112.20.1 files.atari --- arch/atari/conf/files.atari 8 Jan 2009 22:45:30 -0000 1.112.20.1 +++ arch/atari/conf/files.atari 29 Mar 2010 16:02:25 -0000 @@ -91,6 +91,10 @@ attach le at vme with le_vme: le24 file arch/atari/vme/if_le_vme.c le_vme +# SMC Elite Ultra (8216) with SMC_TT VME-ISA bridge +attach we at vme with we_vme +file arch/atari/vme/if_we_vme.c we_vme + # Circad Leonardo 24-bit true color video device leo attach leo at vme @@ -178,6 +182,10 @@ attach wdc at mainbus with wdc_mb: mbdma file arch/atari/dev/wdc_mb.c wdc_mb +# EtherNEC on Atari ROM cartridge slot +attach ne at mainbus with ne_mb: rtl80x9 +file arch/atari/dev/if_ne_mb.c ne_mb + # ISA Plug 'n Play devices file arch/atari/isa/isapnp_machdep.c isapnp Index: arch/atari/vme/if_le_vme.c =================================================================== RCS file: /cvsroot/src/sys/arch/atari/vme/if_le_vme.c,v retrieving revision 1.24 diff -u -r1.24 if_le_vme.c --- arch/atari/vme/if_le_vme.c 28 Jun 2008 05:26:33 -0000 1.24 +++ arch/atari/vme/if_le_vme.c 29 Mar 2010 16:02:25 -0000 @@ -125,7 +125,7 @@ } lestd[] = { { 0xfe00fff0, 0xfe010000, IRQUNK, 16, 64*1024, LE_OLD_RIEBL|LE_NEW_RIEBL }, /* Riebl */ - { 0xffcffff0, 0xffcf0000, 5, 16, 64*1024, + { 0xfecffff0, 0xfecf0000, 5, 16, 64*1024, LE_PAM }, /* PAM */ { 0xfecffff0, 0xfecf0000, 5, 16, 64*1024, LE_ROTHRON }, /* Rhotron */ Index: arch/atari/vme/if_levar.h =================================================================== RCS file: /cvsroot/src/sys/arch/atari/vme/if_levar.h,v retrieving revision 1.6 diff -u -r1.6 if_levar.h --- arch/atari/vme/if_levar.h 28 Apr 2008 20:23:15 -0000 1.6 +++ arch/atari/vme/if_levar.h 29 Mar 2010 16:02:25 -0000 @@ -64,11 +64,11 @@ /* * Board Type: */ -#define LE_PAM 0x00 #define LE_OLD_RIEBL 0x01 #define LE_NEW_RIEBL 0x02 #define LE_BVME410 0x04 #define LE_ROTHRON 0x08 +#define LE_PAM 0x10 /* * Determine type of RIEBL card by magic Index: arch/x68k/dev/if_ne_intio.c =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/dev/if_ne_intio.c,v retrieving revision 1.11 diff -u -r1.11 if_ne_intio.c --- arch/x68k/dev/if_ne_intio.c 12 Mar 2008 15:07:48 -0000 1.11 +++ arch/x68k/dev/if_ne_intio.c 29 Mar 2010 16:02:31 -0000 @@ -75,8 +75,6 @@ #include #include #include -#include -#include #include @@ -189,21 +187,10 @@ case NE2000_TYPE_NE2000: typestr = "NE2000"; - /* - * Check for a Realtek 8019. - */ - bus_space_write_1(iot, ioh, ED_P0_CR, - ED_CR_PAGE_0 | ED_CR_STP); - if (bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID0) == - RTL0_8019ID0 && - bus_space_read_1(iot, ioh, NERTL_RTL0_8019ID1) == - RTL0_8019ID1) { - typestr = "NE2000 (RTL8019)"; - dsc->sc_mediachange = rtl80x9_mediachange; - dsc->sc_mediastatus = rtl80x9_mediastatus; - dsc->init_card = rtl80x9_init_card; - dsc->sc_media_init = rtl80x9_media_init; - } + break; + + case NE2000_TYPE_RTL8019: + typestr = "NE2000 (RTL8019)"; break; default: Index: arch/x68k/dev/if_ne_neptune.c =================================================================== RCS file: /cvsroot/src/sys/arch/x68k/dev/if_ne_neptune.c,v retrieving revision 1.16 diff -u -r1.16 if_ne_neptune.c --- arch/x68k/dev/if_ne_neptune.c 9 May 2008 10:09:27 -0000 1.16 +++ arch/x68k/dev/if_ne_neptune.c 29 Mar 2010 16:02:31 -0000 @@ -78,9 +78,6 @@ #include #include -#include -#include - #include static int ne_neptune_match(device_t, cfdata_t, void *); @@ -172,21 +169,10 @@ case NE2000_TYPE_NE2000: typestr = "NE2000"; - /* - * Check for a Realtek 8019. - */ - bus_space_write_1(nict, nich, ED_P0_CR, - ED_CR_PAGE_0 | ED_CR_STP); - if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) == - RTL0_8019ID0 && - bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) == - RTL0_8019ID1) { - typestr = "NE2000 (RTL8019)"; - dsc->sc_mediachange = rtl80x9_mediachange; - dsc->sc_mediastatus = rtl80x9_mediastatus; - dsc->init_card = rtl80x9_init_card; - dsc->sc_media_init = rtl80x9_media_init; - } + break; + + case NE2000_TYPE_RTL8019: + typestr = "NE2000 (RTL8019)"; break; default: Index: conf/files =================================================================== RCS file: /cvsroot/src/sys/conf/files,v retrieving revision 1.924.4.1 diff -u -r1.924.4.1 files --- conf/files 15 Mar 2009 19:43:48 -0000 1.924.4.1 +++ conf/files 29 Mar 2010 16:02:32 -0000 @@ -883,7 +883,7 @@ # Realtek 8019/8029 NE2000-compatible network interface subroutines # define rtl80x9 -file dev/ic/rtl80x9.c rtl80x9 +file dev/ic/rtl80x9.c rtl80x9 needs-flag # Realtek 8129/8139 Ethernet controllers # Index: dev/ic/dp8390.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/dp8390.c,v retrieving revision 1.68 diff -u -r1.68 dp8390.c --- dev/ic/dp8390.c 12 Mar 2008 14:31:11 -0000 1.68 +++ dev/ic/dp8390.c 29 Mar 2010 16:02:33 -0000 @@ -118,7 +118,8 @@ sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT; sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT); - sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT); + sc->mem_ring = sc->mem_start + + ((sc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); sc->mem_end = sc->mem_start + sc->mem_size; /* Now zero memory and verify that it is clear. */ @@ -1354,7 +1355,8 @@ sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT; sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE; sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT); - sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT); + sc->mem_ring = sc->mem_start + + ((sc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); sc->mem_end = sc->mem_start + sc->mem_size; dp8390_stop(sc); Index: dev/ic/ne2000.c =================================================================== RCS file: /cvsroot/src/sys/dev/ic/ne2000.c,v retrieving revision 1.59 diff -u -r1.59 ne2000.c --- dev/ic/ne2000.c 28 Apr 2008 20:23:50 -0000 1.59 +++ dev/ic/ne2000.c 29 Mar 2010 16:02:34 -0000 @@ -52,6 +52,8 @@ #include "opt_ipkdb.h" +#include "rtl80x9.h" + #include #include #include @@ -85,6 +87,9 @@ #include #include +#include +#include + #include int ne2000_write_mbuf(struct dp8390_softc *, struct mbuf *, int); @@ -98,14 +103,17 @@ void ne2000_readmem(bus_space_tag_t, bus_space_handle_t, bus_space_tag_t, bus_space_handle_t, int, u_int8_t *, size_t, int); +#ifdef NE2000_DETECT_8BIT +static bool ne2000_detect_8bit(bus_space_tag_t, bus_space_handle_t, + bus_space_tag_t, bus_space_handle_t); +#endif + #define ASIC_BARRIER(asict, asich) \ bus_space_barrier((asict), (asich), 0, 0x10, \ BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE) int -ne2000_attach(nsc, myea) - struct ne2000_softc *nsc; - u_int8_t *myea; +ne2000_attach(struct ne2000_softc *nsc, u_int8_t *myea) { struct dp8390_softc *dsc = &nsc->sc_dp8390; bus_space_tag_t nict = dsc->sc_regt; @@ -113,7 +121,7 @@ bus_space_tag_t asict = nsc->sc_asict; bus_space_handle_t asich = nsc->sc_asich; u_int8_t romdata[16]; - int memsize, i, useword; + int memstart, memsize, i, useword; /* * Detect it again unless caller specified it; this gives us @@ -132,23 +140,46 @@ aprint_error_dev(dsc->sc_dev, "where did the card go?\n"); return (1); case NE2000_TYPE_NE1000: + memstart = 8192; memsize = 8192; useword = 0; break; case NE2000_TYPE_NE2000: case NE2000_TYPE_AX88190: /* XXX really? */ case NE2000_TYPE_AX88790: - memsize = 8192 * 2; +#if NRTL80X9 > 0 + case NE2000_TYPE_RTL8019: +#endif + memstart = 16384; + memsize = 16384; useword = 1; + if ( +#ifdef NE2000_DETECT_8BIT + ne2000_detect_8bit(nict, nich, asict, asich) || +#endif + (nsc->sc_quirk & NE2000_QUIRK_8BIT) != 0) { + /* in 8 bit mode, only 8KB memory can be used */ + memsize = 8192; + useword = 0; + } break; case NE2000_TYPE_DL10019: case NE2000_TYPE_DL10022: + memstart = 8192 * 3; memsize = 8192 * 3; useword = 1; break; } nsc->sc_useword = useword; +#if NRTL80X9 > 0 + if (nsc->sc_type == NE2000_TYPE_RTL8019) { + dsc->init_card = rtl80x9_init_card; + dsc->sc_media_init = rtl80x9_media_init; + dsc->sc_mediachange = rtl80x9_mediachange; + dsc->sc_mediastatus = rtl80x9_mediastatus; + } +#endif dsc->cr_proto = ED_CR_RD2; if (nsc->sc_type == NE2000_TYPE_AX88190 || @@ -180,16 +211,14 @@ /* * NIC memory doens't start at zero on an NE board. * The start address is tied to the bus width. - * (It happens to be computed the same way as mem size.) */ - dsc->mem_start = memsize; - #ifdef GWETHER { - int x, mstart = 0; + int x; int8_t pbuf0[ED_PAGE_SIZE], pbuf[ED_PAGE_SIZE], tbuf[ED_PAGE_SIZE]; + memstart = 0; for (i = 0; i < ED_PAGE_SIZE; i++) pbuf0[i] = 0; @@ -209,14 +238,14 @@ x << ED_PAGE_SHIFT, tbuf, ED_PAGE_SIZE, useword); if (memcmp(pbuf, tbuf, ED_PAGE_SIZE) == 0) { - mstart = x << ED_PAGE_SHIFT; + memstart = x << ED_PAGE_SHIFT; memsize = ED_PAGE_SIZE; break; } } } - if (mstart == 0) { + if (memstart == 0) { aprint_error_dev(&dsc->sc_dev, "cannot find start of RAM\n"); return (1); } @@ -245,11 +274,10 @@ } printf("%s: RAM start 0x%x, size %d\n", - device_xname(&dsc->sc_dev), mstart, memsize); - - dsc->mem_start = mstart; + device_xname(&dsc->sc_dev), memstart, memsize); } #endif /* GWETHER */ + dsc->mem_start = memstart; dsc->mem_size = memsize; @@ -263,17 +291,20 @@ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA); NIC_BARRIER(nict, nich); /* Select word transfer. */ - bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_WTS); + bus_space_write_1(nict, nich, ED_P0_DCR, + useword ? ED_DCR_WTS : 0); NIC_BARRIER(nict, nich); ne2000_readmem(nict, nich, asict, asich, AX88190_NODEID_OFFSET, dsc->sc_enaddr, ETHER_ADDR_LEN, useword); } else { + bool ne1000 = (nsc->sc_type == NE2000_TYPE_NE1000); + ne2000_readmem(nict, nich, asict, asich, 0, romdata, sizeof(romdata), useword); for (i = 0; i < ETHER_ADDR_LEN; i++) dsc->sc_enaddr[i] = - romdata[i * (useword ? 2 : 1)]; + romdata[i * (ne1000 ? 1 : 2)]; } } else memcpy(dsc->sc_enaddr, myea, sizeof(dsc->sc_enaddr)); @@ -291,13 +322,6 @@ return (1); } - /* - * We need to compute mem_ring a bit differently; override the - * value set up in dp8390_config(). - */ - dsc->mem_ring = - dsc->mem_start + ((dsc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); - return (0); } @@ -305,15 +329,12 @@ * Detect an NE-2000 or compatible. Returns a model code. */ int -ne2000_detect(nict, nich, asict, asich) - bus_space_tag_t nict; - bus_space_handle_t nich; - bus_space_tag_t asict; - bus_space_handle_t asich; +ne2000_detect(bus_space_tag_t nict, bus_space_handle_t nich, bus_space_tag_t asict, bus_space_handle_t asich) { static u_int8_t test_pattern[32] = "THIS is A memory TEST pattern"; u_int8_t test_buffer[32], tmp; int i, rv = NE2000_TYPE_UNKNOWN; + int useword; /* Reset the board. */ #ifdef GWETHER @@ -428,50 +449,102 @@ ne2000_readmem(nict, nich, asict, asich, 8192, test_buffer, sizeof(test_buffer), 0); - if (memcmp(test_pattern, test_buffer, sizeof(test_pattern))) { - /* not an NE1000 - try NE2000 */ - bus_space_write_1(nict, nich, ED_P0_DCR, - ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS); - bus_space_write_1(nict, nich, ED_P0_PSTART, - 16384 >> ED_PAGE_SHIFT); - bus_space_write_1(nict, nich, ED_P0_PSTOP, - 32768 >> ED_PAGE_SHIFT); - - /* - * Write the test pattern in word mode. If this also fails, - * then we don't know what this board is. - */ - ne2000_writemem(nict, nich, asict, asich, test_pattern, 16384, - sizeof(test_pattern), 1, 0); - ne2000_readmem(nict, nich, asict, asich, 16384, test_buffer, - sizeof(test_buffer), 1); - - if (memcmp(test_pattern, test_buffer, sizeof(test_pattern))) - goto out; /* not an NE2000 either */ - - rv = NE2000_TYPE_NE2000; - } else { + if (memcmp(test_pattern, test_buffer, sizeof(test_pattern)) == 0) { /* We're an NE1000. */ rv = NE2000_TYPE_NE1000; + goto out; } + /* not an NE1000 - try NE2000 */ + + /* try 16 bit mode first */ + useword = 1; + +#ifdef NE2000_DETECT_8BIT + /* + * Check bus type in EEPROM first because some NE2000 compatible wedges + * on 16 bit DMA access if the chip is configured in 8 bit mode. + */ + if (ne2000_detect_8bit(nict, nich, asict, asich)) + useword = 0; +#endif + again: + bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS | + (useword ? ED_DCR_WTS : 0)); + bus_space_write_1(nict, nich, ED_P0_PSTART, 16384 >> ED_PAGE_SHIFT); + bus_space_write_1(nict, nich, ED_P0_PSTOP, + (16384 + (useword ? 16384 : 8192)) >> ED_PAGE_SHIFT); + + /* + * Write the test pattern in word mode. If this also fails, + * then we don't know what this board is. + */ + ne2000_writemem(nict, nich, asict, asich, test_pattern, 16384, + sizeof(test_pattern), useword, 1); + ne2000_readmem(nict, nich, asict, asich, 16384, test_buffer, + sizeof(test_buffer), useword); + + if (memcmp(test_pattern, test_buffer, sizeof(test_pattern)) != 0) { + if (useword == 1) { + /* try 8 bit mode */ + useword = 0; + goto again; + } + return NE2000_TYPE_UNKNOWN; /* not an NE2000 either */ + } + + rv = NE2000_TYPE_NE2000; + +#if NRTL80X9 > 0 + /* Check for a Realtek RTL8019. */ + if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) == RTL0_8019ID0 && + bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) == RTL0_8019ID1) + rv = NE2000_TYPE_RTL8019; +#endif + + out: /* Clear any pending interrupts that might have occurred above. */ NIC_BARRIER(nict, nich); bus_space_write_1(nict, nich, ED_P0_ISR, 0xff); - out: return (rv); } +#ifdef NE2000_DETECT_8BIT +static bool +ne2000_detect_8bit(bus_space_tag_t nict, bus_space_handle_t nich, + bus_space_tag_t asict, bus_space_handle_t asich) +{ + bool is8bit; + uint8_t romdata[32]; + + is8bit = false; + + /* Set DCR for 8 bit DMA. */ + bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS); + /* Read PROM area. */ + ne2000_readmem(nict, nich, asict, asich, 0, romdata, + sizeof(romdata), 0); + if (romdata[28] == 'B' && romdata[30] == 'B') { + /* 'B' (0x42) in 8 bit mode, 'W' (0x57) in 16 bit mode */ + is8bit = true; + } + if (!is8bit) { + /* not in 8 bit mode; put back DCR setting for 16 bit DMA */ + bus_space_write_1(nict, nich, ED_P0_DCR, + ED_DCR_FT1 | ED_DCR_LS | ED_DCR_WTS); + } + + return is8bit; +} +#endif + /* * Write an mbuf chain to the destination NIC memory address using programmed * I/O. */ int -ne2000_write_mbuf(sc, m, buf) - struct dp8390_softc *sc; - struct mbuf *m; - int buf; +ne2000_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf) { struct ne2000_softc *nsc = (struct ne2000_softc *)sc; bus_space_tag_t nict = sc->sc_regt; @@ -519,8 +592,8 @@ * so that case requires some extra code to patch over odd-length * mbufs. */ - if (nsc->sc_type == NE2000_TYPE_NE1000) { - /* NE1000s are easy. */ + if (nsc->sc_useword == 0) { + /* byte ops are easy. */ for (; m != 0; m = m->m_next) { if (m->m_len) { bus_space_write_multi_1(asict, asich, @@ -534,7 +607,7 @@ NE2000_ASIC_DATA, 0); } } else { - /* NE2000s are a bit trickier. */ + /* word ops are a bit trickier. */ u_int8_t *data, savebyte[2]; int l, leftover; #ifdef DIAGNOSTIC @@ -647,11 +720,7 @@ * ring-wrap. */ int -ne2000_ring_copy(sc, src, dstv, amount) - struct dp8390_softc *sc; - int src; - void *dstv; - u_short amount; +ne2000_ring_copy(struct dp8390_softc *sc, int src, void *dstv, u_short amount) { char *dst = dstv; struct ne2000_softc *nsc = (struct ne2000_softc *)sc; @@ -682,10 +751,7 @@ } void -ne2000_read_hdr(sc, buf, hdr) - struct dp8390_softc *sc; - int buf; - struct dp8390_ring *hdr; +ne2000_read_hdr(struct dp8390_softc *sc, int buf, struct dp8390_ring *hdr) { struct ne2000_softc *nsc = (struct ne2000_softc *)sc; @@ -711,15 +777,7 @@ * rounded up to a word - ok as long as mbufs are word sized. */ void -ne2000_readmem(nict, nich, asict, asich, src, dst, amount, useword) - bus_space_tag_t nict; - bus_space_handle_t nich; - bus_space_tag_t asict; - bus_space_handle_t asich; - int src; - u_int8_t *dst; - size_t amount; - int useword; +ne2000_readmem(bus_space_tag_t nict, bus_space_handle_t nich, bus_space_tag_t asict, bus_space_handle_t asich, int src, u_int8_t *dst, size_t amount, int useword) { /* Select page 0 registers. */ @@ -729,8 +787,7 @@ NIC_BARRIER(nict, nich); /* Round up to a word. */ - if (amount & 1) - ++amount; + amount = roundup2(amount, sizeof(uint16_t)); /* Set up DMA byte count. */ bus_space_write_1(nict, nich, ED_P0_RBCR0, amount); @@ -758,16 +815,7 @@ * used in the probe routine to test the memory. 'len' must be even. */ void -ne2000_writemem(nict, nich, asict, asich, src, dst, len, useword, quiet) - bus_space_tag_t nict; - bus_space_handle_t nich; - bus_space_tag_t asict; - bus_space_handle_t asich; - u_int8_t *src; - int dst; - size_t len; - int useword; - int quiet; +ne2000_writemem(bus_space_tag_t nict, bus_space_handle_t nich, bus_space_tag_t asict, bus_space_handle_t asich, u_int8_t *src, int dst, size_t len, int useword, int quiet) { int maxwait = 100; /* about 120us */ @@ -820,9 +868,7 @@ } int -ne2000_detach(sc, flags) - struct ne2000_softc *sc; - int flags; +ne2000_detach(struct ne2000_softc *sc, int flags) { return (dp8390_detach(&sc->sc_dp8390, flags)); @@ -833,13 +879,14 @@ * This code is essentially the same as ne2000_attach above. */ int -ne2000_ipkdb_attach(kip) - struct ipkdb_if *kip; +ne2000_ipkdb_attach(struct ipkdb_if *kip) { struct ne2000_softc *np = kip->port; struct dp8390_softc *dp = &np->sc_dp8390; bus_space_tag_t nict = dp->sc_regt; bus_space_handle_t nich = dp->sc_regh; + bus_space_tag_t asict = np->sc_asict; + bus_space_handle_t asich = np->sc_asich; int i, useword; #ifdef GWETHER @@ -847,59 +894,84 @@ return -1; #endif - if (np->sc_type == 0) - np->sc_type = ne2000_detect(nict, nich, - np->sc_asict, np->sc_asich); - if (np->sc_type == 0) + if (np->sc_type == NE2000_TYPE_UNKNOWN) + np->sc_type = ne2000_detect(nict, nich, asict, asich); + if (np->sc_type == NE2000_TYPE_UNKNOWN) return -1; - useword = np->sc_useword; - - dp->cr_proto = ED_CR_RD2; - dp->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0); - dp->rcr_proto = 0; - - dp->test_mem = ne2000_test_mem; - dp->ring_copy = ne2000_ring_copy; - dp->write_mbuf = ne2000_write_mbuf; - dp->read_hdr = ne2000_read_hdr; - - for (i = 0; i < 16; i++) - dp->sc_reg_map[i] = i; - switch (np->sc_type) { case NE2000_TYPE_NE1000: - dp->mem_start = dp->mem_size = 8192; + dp->mem_start = 8192; + dp->mem_size = 8192; + useword = 0; kip->name = "ne1000"; break; case NE2000_TYPE_NE2000: - dp->mem_start = dp->mem_size = 8192 * 2; - kip->name = "ne2000"; + case NE2000_TYPE_AX88190: + case NE2000_TYPE_AX88790: +#if NRTL80X9 > 0 + case NE2000_TYPE_RTL8019: +#endif + dp->mem_start = 16384; + dp->mem_size = 16384; + useword = 1; + if ( +#ifdef NE2000_DETECT_8BIT + ne2000_detect_8bit(nict, nich, asict, asich) || +#endif + (np->sc_quirk & NE2000_QUIRK_8BIT) != 0) { + /* in 8 bit mode, only 8KB memory can be used */ + dp->mem_size = 8192; + useword = 0; + } + kip->name = + (np->sc_type == NE2000_TYPE_AX88190 || + np->sc_type == NE2000_TYPE_AX88790) ? + "ax88190" : "ne2000"; break; case NE2000_TYPE_DL10019: case NE2000_TYPE_DL10022: - dp->mem_start = dp->mem_size = 8192 * 3; + dp->mem_start = 8192 * 3; + dp->mem_size = 8192 * 3; + useword = 1; kip->name = (np->sc_type == NE2000_TYPE_DL10019) ? "dl10022" : "dl10019"; break; - case NE2000_TYPE_AX88190: - case NE2000_TYPE_AX88790: - dp->rcr_proto = ED_RCR_INTT; - dp->sc_flags |= DP8390_DO_AX88190_WORKAROUND; - dp->mem_start = dp->mem_size = 8192 * 2; - kip->name = "ax88190"; - break; default: return -1; break; } + np->sc_useword = useword; +#if NRTL80X9 > 0 + if (np->sc_type == NE2000_TYPE_RTL8019) { + dp->init_card = rtl80x9_init_card; + dp->sc_media_init = rtl80x9_media_init; + dp->sc_mediachange = rtl80x9_mediachange; + dp->sc_mediastatus = rtl80x9_mediastatus; + } +#endif + + dp->cr_proto = ED_CR_RD2; + if (np->sc_type == NE2000_TYPE_AX88190 || + np->sc_type == NE2000_TYPE_AX88790) { + dp->rcr_proto = ED_RCR_INTT; + dp->sc_flags |= DP8390_DO_AX88190_WORKAROUND; + } else + dp->rcr_proto = 0; + dp->dcr_reg = ED_DCR_FT1 | ED_DCR_LS | (useword ? ED_DCR_WTS : 0); + + dp->test_mem = ne2000_test_mem; + dp->ring_copy = ne2000_ring_copy; + dp->write_mbuf = ne2000_write_mbuf; + dp->read_hdr = ne2000_read_hdr; + + for (i = 0; i < 16; i++) + dp->sc_reg_map[i] = i; + if (dp8390_ipkdb_attach(kip)) return -1; - dp->mem_ring = dp->mem_start - + ((dp->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); - if (!(kip->flags & IPKDB_MYHW)) { char romdata[16]; @@ -912,15 +984,19 @@ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA); NIC_BARRIER(nict, nich); /* Select word transfer */ - bus_space_write_1(nict, nich, ED_P0_DCR, ED_DCR_WTS); - ne2000_readmem(nict, nich, np->sc_asict, np->sc_asich, + bus_space_write_1(nict, nich, ED_P0_DCR, + useword ? ED_DCR_WTS : 0); + ne2000_readmem(nict, nich, asict, asich, AX88190_NODEID_OFFSET, kip->myenetaddr, ETHER_ADDR_LEN, useword); } else { - ne2000_readmem(nict, nich, np->sc_asict, np->sc_asich, + bool ne1000 = (np->sc_type == NE2000_TYPE_NE1000); + + ne2000_readmem(nict, nich, asict, asich, 0, romdata, sizeof romdata, useword); for (i = 0; i < ETHER_ADDR_LEN; i++) - kip->myenetaddr[i] = romdata[i << useword]; + kip->myenetaddr[i] = + romdata[i * (ne1000 ? 1 : 2)]; } kip->flags |= IPKDB_MYHW; Index: dev/ic/ne2000var.h =================================================================== RCS file: /cvsroot/src/sys/dev/ic/ne2000var.h,v retrieving revision 1.19 diff -u -r1.19 ne2000var.h --- dev/ic/ne2000var.h 28 Apr 2008 20:23:50 -0000 1.19 +++ dev/ic/ne2000var.h 29 Mar 2010 16:02:34 -0000 @@ -46,9 +46,12 @@ NE2000_TYPE_DL10019, NE2000_TYPE_DL10022, NE2000_TYPE_AX88190, - NE2000_TYPE_AX88790 + NE2000_TYPE_AX88790, + NE2000_TYPE_RTL8019 } sc_type; int sc_useword; + u_int sc_quirk; /* quirks passed from attachments */ +#define NE2000_QUIRK_8BIT 0x0001 /* force 8bit mode even on NE2000 */ }; int ne2000_attach(struct ne2000_softc *, u_int8_t *); Index: dev/isa/if_ne_isa.c =================================================================== RCS file: /cvsroot/src/sys/dev/isa/if_ne_isa.c,v retrieving revision 1.26 diff -u -r1.26 if_ne_isa.c --- dev/isa/if_ne_isa.c 28 Apr 2008 20:23:52 -0000 1.26 +++ dev/isa/if_ne_isa.c 29 Mar 2010 16:02:34 -0000 @@ -57,9 +57,6 @@ #include #include -#include -#include - #include int ne_isa_match(device_t, cfdata_t, void *); @@ -178,21 +175,10 @@ case NE2000_TYPE_NE2000: typestr = "NE2000"; - /* - * Check for a Realtek 8019. - */ - bus_space_write_1(nict, nich, ED_P0_CR, - ED_CR_PAGE_0 | ED_CR_STP); - if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) == - RTL0_8019ID0 && - bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) == - RTL0_8019ID1) { - typestr = "NE2000 (RTL8019)"; - dsc->sc_mediachange = rtl80x9_mediachange; - dsc->sc_mediastatus = rtl80x9_mediastatus; - dsc->init_card = rtl80x9_init_card; - dsc->sc_media_init = rtl80x9_media_init; - } + break; + + case NE2000_TYPE_RTL8019: + typestr = "NE2000 (RTL8019)"; break; default: Index: dev/isapnp/if_ne_isapnp.c =================================================================== RCS file: /cvsroot/src/sys/dev/isapnp/if_ne_isapnp.c,v retrieving revision 1.26 diff -u -r1.26 if_ne_isapnp.c --- dev/isapnp/if_ne_isapnp.c 28 Apr 2008 20:23:53 -0000 1.26 +++ dev/isapnp/if_ne_isapnp.c 29 Mar 2010 16:02:34 -0000 @@ -57,9 +57,6 @@ #include #include -#include -#include - #include #include @@ -142,21 +139,10 @@ case NE2000_TYPE_NE2000: typestr = "NE2000"; - /* - * Check for a Realtek 8019. - */ - bus_space_write_1(nict, nich, ED_P0_CR, - ED_CR_PAGE_0 | ED_CR_STP); - if (bus_space_read_1(nict, nich, NERTL_RTL0_8019ID0) == - RTL0_8019ID0 && - bus_space_read_1(nict, nich, NERTL_RTL0_8019ID1) == - RTL0_8019ID1) { - typestr = "NE2000 (RTL8019)"; - dsc->sc_mediachange = rtl80x9_mediachange; - dsc->sc_mediastatus = rtl80x9_mediastatus; - dsc->init_card = rtl80x9_init_card; - dsc->sc_media_init = rtl80x9_media_init; - } + break; + + case NE2000_TYPE_RTL8019: + typestr = "NE2000 (RTL8019)"; break; default: --- /dev/null 2010-03-30 00:32:18.000000000 +0900 +++ arch/atari/dev/if_ne_mb.c 2010-03-30 00:53:19.000000000 +0900 @@ -0,0 +1,458 @@ +/* $NetBSD$ */ + +/* + * Copyright (c) 2010 Izumi Tsutsui. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Device driver for the EtherNEC, + * NE2000 in 8bit mode over Atari ROM cartridge slot. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +/* + * EtherNEC specific address configuration + */ + +/* I/O read ops are through /ROM4 area (0xFA0000) */ +#define AD_CART_ROM4 (AD_CART + 0x00000) +#define ETHERNEC_READ_PORT AD_CART_ROM4 + +/* I/O write ops are through /ROM3 area (0xFB0000) */ +#define AD_CART_ROM3 (AD_CART + 0x10000) +#define ETHERNEC_WRITE_PORT AD_CART_ROM3 + +/* CPU address lines A13-A9 are connected to ISA A4-A0 */ +#define ETHERNEC_PORT_STRIDE 9 + +/* Using A8-A1 lines to specify write data (no A0 but UDS/LDS on m68k) */ +#define ETHERNEC_WR_ADDR_SHIFT 1 + +/* interrupt polling per HZ */ +#define ETHERNEC_TICK 1 + +static int ne_mb_probe(device_t, cfdata_t, void *); +static void ne_mb_attach(device_t, device_t, void *); + +static void ne_mb_poll(void *); + +static bus_space_tag_t ethernec_init_bus_space_tag(bus_space_tag_t); + +static int ethernec_bus_space_peek_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t); +static uint8_t ethernec_bus_space_read_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t); +static void ethernec_bus_space_write_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, uint8_t); +static void ethernec_bus_space_read_multi_1(bus_space_tag_t, + bus_space_handle_t, bus_size_t, uint8_t *, bus_size_t); +static void ethernec_bus_space_read_multi_2(bus_space_tag_t, + bus_space_handle_t, bus_size_t, uint16_t *, bus_size_t); +static void ethernec_bus_space_write_multi_1(bus_space_tag_t, + bus_space_handle_t, bus_size_t, const uint8_t *, bus_size_t); +static void ethernec_bus_space_write_multi_2(bus_space_tag_t, + bus_space_handle_t, bus_size_t, const uint16_t *, bus_size_t); +static void ethernec_bus_space_unimpl(void); + +struct ne_mb_softc { + struct ne2000_softc sc_ne2000; /* MI ne2000 softc */ + + struct atari_bus_space sc_bs; + struct callout sc_poll; +}; + +CFATTACH_DECL_NEW(ne_mb, sizeof(struct ne_mb_softc), + ne_mb_probe, ne_mb_attach, NULL, NULL); + +static int +ne_mb_probe(device_t parent, cfdata_t cf, void *aux) +{ + static bool ne_matched = false; + struct atari_bus_space bs; + bus_space_tag_t iot, asict; + bus_space_handle_t ioh, iowh, asich; + int netype, rv; + + rv = 0; + + if (!atari_realconfig) + goto out; + if (strcmp("ne", aux) || ne_matched) + goto out; + + iot = ethernec_init_bus_space_tag(&bs); + + /* map I/O space for read ops */ + if (bus_space_map(iot, ETHERNEC_READ_PORT, + NE2000_NPORTS << ETHERNEC_PORT_STRIDE, 0, &ioh) != 0) + goto out; + + /* map I/O space for write ops */ + if (bus_space_map(iot, ETHERNEC_WRITE_PORT, + NE2000_NPORTS << ETHERNEC_PORT_STRIDE, 0, &iowh) != 0) + goto out1; + + /* XXX abuse stride for offset of write ports from read ones */ + iot->stride = + (vaddr_t)bus_space_vaddr(iot, iowh) - + (vaddr_t)bus_space_vaddr(iot, ioh); + + /* check if register regions are vaild */ + if (bus_space_peek_1(iot, ioh, 0) == 0) + goto out2; + + asict = iot; + if (bus_space_subregion(iot, ioh, + NE2000_ASIC_OFFSET << ETHERNEC_PORT_STRIDE, + NE2000_ASIC_NPORTS << ETHERNEC_PORT_STRIDE, &asich)) + goto out2; + + /* Look for an NE2000 compatible card */ + netype = ne2000_detect(iot, ioh, asict, asich); + switch (netype) { + /* XXX should we reject non RTL8019 varilants? */ + case NE2000_TYPE_NE1000: + case NE2000_TYPE_NE2000: + case NE2000_TYPE_RTL8019: + ne_matched = true; + rv = 1; + break; + default: + break; + } + + out2: + bus_space_unmap(iot, iowh, NE2000_NPORTS << ETHERNEC_PORT_STRIDE); + out1: + bus_space_unmap(iot, ioh, NE2000_NPORTS << ETHERNEC_PORT_STRIDE); + out: + return rv; +} + +static void +ne_mb_attach(device_t parent, device_t self, void *aux) +{ + struct ne_mb_softc *sc = device_private(self); + struct ne2000_softc *nsc = &sc->sc_ne2000; + struct dp8390_softc *dsc = &nsc->sc_dp8390; + bus_space_tag_t iot, asict; + bus_space_handle_t ioh, iowh, asich; + const char *typestr; + int netype; + + dsc->sc_dev = self; + aprint_normal(": EtherNEC on Atari ROM cartridge slot\n"); + + iot = ethernec_init_bus_space_tag(&sc->sc_bs); + + /* map I/O space for read ops */ + if (bus_space_map(iot, ETHERNEC_READ_PORT, + NE2000_NPORTS << ETHERNEC_PORT_STRIDE, 0, &ioh) != 0) + goto out; + + /* map I/O space for write ops */ + if (bus_space_map(iot, ETHERNEC_WRITE_PORT, + NE2000_NPORTS << ETHERNEC_PORT_STRIDE, 0, &iowh) != 0) + goto out1; + + /* XXX abuse stride */ + iot->stride = + (vaddr_t)bus_space_vaddr(iot, iowh) - + (vaddr_t)bus_space_vaddr(iot, ioh); + + asict = iot; + if (bus_space_subregion(iot, ioh, + NE2000_ASIC_OFFSET << ETHERNEC_PORT_STRIDE, + NE2000_ASIC_NPORTS << ETHERNEC_PORT_STRIDE, &asich)) + goto out2; + + dsc->sc_regt = iot; + dsc->sc_regh = ioh; + + nsc->sc_asict = asict; + nsc->sc_asich = asich; + + /* EtherNEC uses 8-bit data bus */ + nsc->sc_quirk = NE2000_QUIRK_8BIT; + + /* + * detect it again, so we can print some information about + * the interface. + * XXX: Should we accept only RTL8019? + */ + netype = ne2000_detect(iot, ioh, asict, asich); + switch (netype) { + case NE2000_TYPE_NE1000: + typestr = "NE1000"; + break; + + case NE2000_TYPE_NE2000: + typestr = "NE2000"; + break; + + case NE2000_TYPE_RTL8019: + typestr = "NE2000 (RTL8019)"; + break; + + default: + aprint_error_dev(self, "where did the card go?!\n"); + goto out2; + } + + aprint_normal_dev(self, "%s Ethernet (8-bit)\n", typestr); + + /* this interface is always enabled */ + dsc->sc_enabled = 1; + + /* call MI ne2000 attach function */ + ne2000_attach(nsc, NULL); + + /* emulate interrupts by callout(9) */ + aprint_normal_dev(self, "using %d Hz polling\n", hz / ETHERNEC_TICK); + callout_init(&sc->sc_poll, 0); + callout_reset(&sc->sc_poll, ETHERNEC_TICK, ne_mb_poll, sc); + + return; + + out2: + bus_space_unmap(iot, iowh, NE2000_NPORTS << ETHERNEC_PORT_STRIDE); + out1: + bus_space_unmap(iot, ioh, NE2000_NPORTS << ETHERNEC_PORT_STRIDE); + out: + return; +} + +static void +ne_mb_poll(void *arg) +{ + struct ne_mb_softc *sc; + struct ne2000_softc *nsc; + struct dp8390_softc *dsc; + int s; + + sc = arg; + nsc = &sc->sc_ne2000; + dsc = &nsc->sc_dp8390; + + s = splnet(); + (void)dp8390_intr(dsc); + splx(s); + + callout_reset(&sc->sc_poll, ETHERNEC_TICK, ne_mb_poll, sc); +} + +/* + * bus_space(9) functions for EtherNEC + * + * XXX: should these belong to an independent cartridge slot bus? + */ +static bus_space_tag_t +ethernec_init_bus_space_tag(bus_space_tag_t en_t) +{ + + if (en_t == NULL) + return NULL; + + memset(en_t, 0, sizeof(*en_t)); + + /* XXX: implement functions used by MI ne2000 and dp8390 only */ + en_t->abs_p_1 = ethernec_bus_space_peek_1; + en_t->abs_p_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_p_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_p_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_r_1 = ethernec_bus_space_read_1; + en_t->abs_r_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_r_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_r_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rs_1 = ethernec_bus_space_read_1; + en_t->abs_rs_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rs_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rs_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rm_1 = ethernec_bus_space_read_multi_1; + en_t->abs_rm_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rm_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rm_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rms_1 = ethernec_bus_space_read_multi_1; + en_t->abs_rms_2 = ethernec_bus_space_read_multi_2; /* XXX dummy */ + en_t->abs_rms_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rms_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rr_1 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rr_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rr_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rr_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rrs_1 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rrs_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rrs_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_rrs_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_w_1 = ethernec_bus_space_write_1; + en_t->abs_w_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_w_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_w_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_ws_1 = ethernec_bus_space_write_1; + en_t->abs_ws_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_ws_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_ws_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wm_1 = ethernec_bus_space_write_multi_1; + en_t->abs_wm_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wm_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wm_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wms_1 = ethernec_bus_space_write_multi_1; + en_t->abs_wms_2 = ethernec_bus_space_write_multi_2; /* XXX dummy */ + en_t->abs_wms_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wms_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wr_1 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wr_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wr_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wr_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wrs_1 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wrs_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wrs_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_wrs_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sm_1 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sm_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sm_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sm_8 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sr_1 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sr_2 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sr_4 = (void *)ethernec_bus_space_unimpl; + en_t->abs_sr_8 = (void *)ethernec_bus_space_unimpl; + + return en_t; +} + +static void +ethernec_bus_space_unimpl(void) +{ + + panic("%s: unimplemented EtherNEC bus_space(9) function called", + __func__); +} + +static int +ethernec_bus_space_peek_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg) +{ + uint8_t *va; + + va = (uint8_t *)(bh + (reg << ETHERNEC_PORT_STRIDE)); + + return !badbaddr(va, sizeof(uint8_t)); +} + +static uint8_t +ethernec_bus_space_read_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg) +{ + volatile uint8_t *ba; + + ba = (volatile uint8_t *)(bh + (reg << ETHERNEC_PORT_STRIDE)); + + return *ba; +} + +static void +ethernec_bus_space_write_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg, uint8_t val) +{ + volatile uint8_t *wport; + + /* + * Write ops are done by read against write region (ROM3) address. + * 8-bit write data is specified via lower address bits. + */ + wport = (volatile uint8_t *)bh + + bt->stride + (reg << ETHERNEC_PORT_STRIDE); + wport += (u_int)val << ETHERNEC_WR_ADDR_SHIFT; + + (void)*wport; +} + +static void +ethernec_bus_space_read_multi_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg, uint8_t *a, bus_size_t c) +{ + volatile uint8_t *ba; + + ba = (volatile uint8_t *)(bh + (reg << ETHERNEC_PORT_STRIDE)); + for (; c != 0; c--) + *a++ = *ba; +} + +static void +ethernec_bus_space_read_multi_2(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg, uint16_t *a, bus_size_t c) +{ + + /* XXX: dummy function for probe ops in ne2000_detect() */ +} + +static void +ethernec_bus_space_write_multi_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg, const uint8_t *a, bus_size_t c) +{ + volatile uint8_t *ba, *wport; + u_int val; + + ba = (volatile uint8_t *)(bh + + bt->stride + (reg << ETHERNEC_PORT_STRIDE)); + + for (; c != 0; c--) { + val = *a++; + wport = ba + (val << ETHERNEC_WR_ADDR_SHIFT); + (void)*wport; + } +} + +static void +ethernec_bus_space_write_multi_2(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg, const uint16_t *a, bus_size_t c) +{ + + /* XXX: dummy function for probe ops in ne2000_detect() */ +} --- /dev/null 2010-03-30 00:32:18.000000000 +0900 +++ arch/atari/vme/if_we_vme.c 2010-03-17 22:31:32.000000000 +0900 @@ -0,0 +1,453 @@ +/* $NetBSD: if_we_vme.c,v 1.2 2010/03/16 18:50:14 tsutsui Exp $ */ + +/*- + * Copyright (c) 1997, 1998, 2010 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Device driver for National Semiconductor DS8390/WD83C690 based ethernet + * adapters. + * + * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. + * + * Copyright (C) 1993, David Greenman. This software may be used, modified, + * copied, distributed, and sold, in both source and binary form provided that + * the above copyright and these terms are retained. Under no circumstances is + * the author responsible for the proper functioning of this software, nor does + * the author assume any responsibility for damages incurred with its use. + */ + +/* + * Device driver for the SMC Elite Ultra (8216) with SMC_TT VME-ISA bridge. + * Based on: + * NetBSD: if_we_isa.c,v 1.20 2008/04/28 20:23:52 martin Exp + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: if_we_vme.c,v 1.2 2010/03/16 18:50:14 tsutsui Exp $"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +/* #define WE_DEBUG */ +#ifdef WE_DEBUG +#define DPRINTF(x) printf x +#else +#define DPRINTF(x) /**/ +#endif + +/* VME space mapped by SMC_TT VME-ISA bridge */ +#define SMCTT_MEM_BASE 0xFE000000 /* base for shared memory space */ +#define SMCTT_IOE_BASE 0xFE200000 /* base for I/O ports at even address */ +#define SMCTT_IOO_BASE 0xFE300000 /* base for I/O ports at odd address */ + +#define SMCTT_IO_OFFSET (SMCTT_IOO_BASE - SMCTT_IOE_BASE) + +/* default SMC8216 settings for SMC_TT specified by a jumper switch at No.2 */ +#define SMCTT_MEM_ADDR 0xD0000 +#define SMCTT_IO_ADDR 0x280 + +/* SMC_TT uses IRQ4 on VME, IRQ3 on ISA, and interrupt vector 0xAA */ +#define SMCTT_VME_IRQ 4 +#define SMCTT_ISA_IRQ 3 +#define SMCTT_VECTOR 0xAA + +static int we_vme_probe(device_t, cfdata_t , void *); +static void we_vme_attach(device_t, device_t, void *); + +static uint8_t smctt_bus_space_read_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t); +static void smctt_bus_space_write_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t, uint8_t); +static int smctt_bus_space_peek_1(bus_space_tag_t, bus_space_handle_t, + bus_size_t); + +struct we_vme_softc { + struct we_softc sc_we; + struct atari_bus_space sc_bs; +}; + +CFATTACH_DECL_NEW(we_vme, sizeof(struct we_vme_softc), + we_vme_probe, we_vme_attach, NULL, NULL); + +static const int we_790_irq[] = { + -1, 9, 3, 5, 7, 10, 11, 15, +}; + +static int +we_vme_probe(device_t parent, cfdata_t cf, void *aux) +{ + struct vme_attach_args *va = aux; + struct atari_bus_space t; + bus_space_tag_t asict, memt; + bus_space_handle_t asich, asich1, memh; + bus_size_t memsize; + bool asich_valid, asich1_valid, memh_valid; + int i, rv; + uint8_t sum, reg, type, hwr; + + rv = 0; + asich_valid = false; + asich1_valid = false; + memh_valid = false; + + if (va->va_iobase != IOBASEUNK && + va->va_iobase != SMCTT_IOE_BASE + SMCTT_IO_ADDR) + return 0; + if (va->va_maddr != IOBASEUNK && + va->va_maddr != SMCTT_MEM_BASE + SMCTT_MEM_ADDR) + return 0; + if (va->va_irq != IRQUNK && + va->va_irq != SMCTT_VME_IRQ) + return 0; + + /* SMC_TT has a bit weird I/O address mappings */ + asict = beb_alloc_bus_space_tag(&t); + /* XXX setup only simple byte functions used in MI we(4) driver */ + asict->abs_r_1 = smctt_bus_space_read_1; + asict->abs_w_1 = smctt_bus_space_write_1; + asict->abs_p_1 = smctt_bus_space_peek_1; + + /* + * Only 16 bit accesses are allowed for memory space on SMC_TT, + * but MI we(4) uses them on 16 bit mode. + */ + memt = va->va_memt; + + /* Attempt to map the device. */ + if (bus_space_map(asict, SMCTT_IOE_BASE + SMCTT_IO_ADDR, WE_NPORTS, + 0, &asich) != 0) { + DPRINTF(("%s: failed to map even I/O space", __func__)); + goto out; + } + asich_valid = true; + + if (bus_space_map(asict, SMCTT_IOO_BASE + SMCTT_IO_ADDR, WE_NPORTS, + 0, &asich1) != 0) { + DPRINTF(("%s: failed to map odd I/O space", __func__)); + goto out; + } + asich1_valid = true; + + /* XXX abuse stride for offset of odd ports from even ones */ + asict->stride = + (vaddr_t)bus_space_vaddr(asict, asich1) - + (vaddr_t)bus_space_vaddr(asict, asich); + + /* check if register regions are valid */ + if (bus_space_peek_1(asict, asich, WE_PROM + 0) == 0 || + bus_space_peek_1(asict, asich, WE_PROM + 1) == 0) + goto out; + + /* + * Attempt to do a checksum over the station address PROM. + * If it fails, it's probably not an SMC_TT board. + */ + DPRINTF(("%s: WE_PROM: ", __func__)); + sum = 0; + for (i = 0; i < 8; i++) { + reg = bus_space_read_1(asict, asich, WE_PROM + i); + DPRINTF(("%02x ", reg)); + sum += reg; + } + DPRINTF(("\n")); + DPRINTF(("%s: WE_ROM_SUM: 0x%02x\n", __func__, sum)); + + if (sum != WE_ROM_CHECKSUM_TOTAL) + goto out; + + /* + * Reset the card to force it into a known state. + */ + bus_space_write_1(asict, asich, WE_MSR, WE_MSR_RST); + delay(100); + + bus_space_write_1(asict, asich, WE_MSR, + bus_space_read_1(asict, asich, WE_MSR) & ~WE_MSR_RST); + + /* Wait in case the card is reading it's EEPROM. */ + delay(5000); + + /* + * Check card type. + */ + type = bus_space_read_1(asict, asich, WE_CARD_ID); + /* Assume SMT_TT has only 8216 */ + if (type != WE_TYPE_SMC8216C && type != WE_TYPE_SMC8216T) + goto out; + + hwr = bus_space_read_1(asict, asich, WE790_HWR); + bus_space_write_1(asict, asich, WE790_HWR, hwr | WE790_HWR_SWH); + switch (bus_space_read_1(asict, asich, WE790_RAR) & WE790_RAR_SZ64) { + case WE790_RAR_SZ64: + memsize = 65536; + break; + case WE790_RAR_SZ32: + memsize = 32768; + break; + case WE790_RAR_SZ16: + memsize = 16384; + break; + case WE790_RAR_SZ8: + memsize = 8192; + break; + default: + memsize = 16384; + break; + } + bus_space_write_1(asict, asich, WE790_HWR, hwr); + + /* Attempt to map the memory space. */ + if (bus_space_map(memt, SMCTT_MEM_BASE + SMCTT_MEM_ADDR, memsize, + 0, &memh) != 0) { + DPRINTF(("%s: failed to map shared memory", __func__)); + goto out; + } + memh_valid = true; + + /* check if memory region is valid */ + if (bus_space_peek_2(memt, memh, 0) == 0) + goto out; + + /* + * Check the assigned interrupt number from the card. + */ + + /* Assemble together the encoded interrupt number. */ + hwr = bus_space_read_1(asict, asich, WE790_HWR); + bus_space_write_1(asict, asich, WE790_HWR, hwr | WE790_HWR_SWH); + + reg = bus_space_read_1(asict, asich, WE790_GCR); + i = ((reg & WE790_GCR_IR2) >> 4) | + ((reg & (WE790_GCR_IR1|WE790_GCR_IR0)) >> 2); + bus_space_write_1(asict, asich, WE790_HWR, hwr & ~WE790_HWR_SWH); + + if (we_790_irq[i] != SMCTT_ISA_IRQ) { + DPRINTF(("%s: wrong IRQ (%d); check jumper settings\n", + __func__, we_790_irq[i])); + goto out; + } + + /* So, we say we've found it! */ + va->va_iobase = SMCTT_IOE_BASE + SMCTT_IO_ADDR; + va->va_iosize = WE_NPORTS; + va->va_maddr = SMCTT_MEM_BASE + SMCTT_MEM_ADDR; + va->va_msize = memsize; + va->va_irq = SMCTT_VME_IRQ; + + rv = 1; + + out: + if (asich_valid) + bus_space_unmap(asict, asich, WE_NPORTS); + if (asich1_valid) + bus_space_unmap(asict, asich1, WE_NPORTS); + if (memh_valid) + bus_space_unmap(memt, memh, memsize); + return rv; +} + +void +we_vme_attach(device_t parent, device_t self, void *aux) +{ + struct we_vme_softc *wvsc = device_private(self); + struct we_softc *wsc = &wvsc->sc_we; + struct dp8390_softc *sc = &wsc->sc_dp8390; + struct vme_attach_args *va = aux; + bus_space_tag_t nict, asict, memt; + bus_space_handle_t nich, asich, asich1, memh; + const char *typestr; + + aprint_normal("\n"); + + sc->sc_dev = self; + + /* See comments in the above probe function */ + asict = beb_alloc_bus_space_tag(&wvsc->sc_bs); + asict->abs_r_1 = smctt_bus_space_read_1; + asict->abs_w_1 = smctt_bus_space_write_1; + nict = asict; + + memt = va->va_memt; + + /* Map the device. */ + if (bus_space_map(asict, va->va_iobase, WE_NPORTS, 0, &asich) != 0) { + aprint_error_dev(self, "can't map even I/O space\n"); + return; + } + if (bus_space_map(asict, va->va_iobase + SMCTT_IO_OFFSET, WE_NPORTS, + 0, &asich1) != 0) { + aprint_error_dev(self, "can't map odd I/O space\n"); + goto out; + } + asict->stride = + (vaddr_t)bus_space_vaddr(asict, asich1) - + (vaddr_t)bus_space_vaddr(asict, asich); + + if (bus_space_subregion(asict, asich, WE_NIC_OFFSET, WE_NIC_NPORTS, + &nich) != 0) { + aprint_error_dev(self, "can't subregion I/O space\n"); + goto out1; + } + + /* Map memory space. */ + if (bus_space_map(memt, va->va_maddr, va->va_msize, 0, &memh) != 0) { + aprint_error_dev(self, "can't map shared memory\n"); + goto out1; + } + + wsc->sc_asict = asict; + wsc->sc_asich = asich; + + sc->sc_regt = nict; + sc->sc_regh = nich; + + sc->sc_buft = memt; + sc->sc_bufh = memh; + + wsc->sc_maddr = va->va_maddr & 0xfffff; + sc->mem_size = va->va_msize; + + /* Interface is always enabled. */ + sc->sc_enabled = 1; + + /* SMC_TT assumes SMC8216 */ + sc->is790 = 1; + + /* SMC_TT supports only 16 bit access for shared memory */ + wsc->sc_flags |= WE_16BIT_ENABLE; + + /* Appeal the Atari spirit :-) */ + typestr = "SMC8216 with SMC_TT VME-ISA bridge"; + + if (we_config(self, wsc, typestr) != 0) + goto out2; + + /* + * Enable the configured interrupt. + */ + bus_space_write_1(asict, asich, WE790_ICR, + bus_space_read_1(asict, asich, WE790_ICR) | WE790_ICR_EIL); + + /* Establish interrupt handler. */ + wsc->sc_ih = intr_establish(SMCTT_VECTOR - 64, USER_VEC, 0, + (hw_ifun_t)dp8390_intr, sc); + if (wsc->sc_ih == NULL) { + aprint_error_dev(self, "can't establish interrupt\n"); + goto out2; + } + /* + * Unmask the VME interrupt we're on. + */ + if ((machineid & ATARI_TT) != 0) + SCU->vme_mask |= 1 << va->va_irq; + + return; + + out2: + bus_space_unmap(memt, memh, va->va_msize); + out1: + bus_space_unmap(asict, asich1, WE_NPORTS); + out: + bus_space_unmap(asict, asich, WE_NPORTS); +} + +static uint8_t +smctt_bus_space_read_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg) +{ + uint8_t rv; + + if ((reg & 0x01) != 0) { + /* odd address space */ + rv = *(volatile uint8_t *)(bh + bt->stride + (reg & ~0x01)); + } else { + /* even address space */ + rv = *(volatile uint8_t *)(bh + reg); + } + + return rv; +} + +static void +smctt_bus_space_write_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg, uint8_t val) +{ + + if ((reg & 0x01) != 0) { + /* odd address space */ + *(volatile uint8_t *)(bh + bt->stride + (reg & ~0x01)) = val; + } else { + /* even address space */ + *(volatile uint8_t *)(bh + reg) = val; + } +} + +static int +smctt_bus_space_peek_1(bus_space_tag_t bt, bus_space_handle_t bh, + bus_size_t reg) +{ + uint8_t *va; + + if ((reg & 0x01) != 0) { + /* odd address space */ + va = (uint8_t *)(bh + bt->stride + (reg & ~0x01)); + } else { + /* even address space */ + va = (uint8_t *)(bh + reg); + } + + return !badbaddr(va, sizeof(uint8_t)); +}