Module Name:    src
Committed By:   tsutsui
Date:           Sun Jan 13 14:10:55 UTC 2013

Modified Files:
        src/sys/arch/luna68k/stand/boot: Makefile conf.c devopen.c init_main.c
            ioconf.c locore.S samachdep.h version
Added Files:
        src/sys/arch/luna68k/stand/boot: getsecs.c if_le.c lance.c lance.h

Log Message:
Add netboot support.
Based on ews4800mips, mvme68k, and x68k standalone drivers.
Also bump version.

Tested on LUNA-I.

XXX: We really need proper documents about libsa APIs.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/luna68k/stand/boot/Makefile
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/luna68k/stand/boot/conf.c \
    src/sys/arch/luna68k/stand/boot/devopen.c \
    src/sys/arch/luna68k/stand/boot/ioconf.c \
    src/sys/arch/luna68k/stand/boot/version
cvs rdiff -u -r0 -r1.1 src/sys/arch/luna68k/stand/boot/getsecs.c \
    src/sys/arch/luna68k/stand/boot/if_le.c \
    src/sys/arch/luna68k/stand/boot/lance.c \
    src/sys/arch/luna68k/stand/boot/lance.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/luna68k/stand/boot/init_main.c \
    src/sys/arch/luna68k/stand/boot/samachdep.h
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/luna68k/stand/boot/locore.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/luna68k/stand/boot/Makefile
diff -u src/sys/arch/luna68k/stand/boot/Makefile:1.4 src/sys/arch/luna68k/stand/boot/Makefile:1.5
--- src/sys/arch/luna68k/stand/boot/Makefile:1.4	Thu Jan 10 15:51:32 2013
+++ src/sys/arch/luna68k/stand/boot/Makefile	Sun Jan 13 14:10:55 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.4 2013/01/10 15:51:32 tsutsui Exp $
+#	$NetBSD: Makefile,v 1.5 2013/01/13 14:10:55 tsutsui Exp $
 #	@(#)Makefile	8.2 (Berkeley) 8/15/93
 
 NOMAN= # defined
@@ -7,16 +7,18 @@ NOMAN= # defined
 .include <bsd.sys.mk>
 
 S= ${.CURDIR}/../../../..
+LIBSADIR=	${S}/lib/libsa
 
 CPPFLAGS+=	-nostdinc -D_STANDALONE
 CPPFLAGS+=	-I${.CURDIR} -I${.OBJDIR} -I${S} -I${S}/arch
 
 CPPFLAGS+=	-DSUPPORT_DISK
 #CPPFLAGS+=	-DSUPPORT_TAPE
-#CPPFLAGS+=	-DSUPPORT_ETHERNET
-#CPPFLAGS+=	-DSUPPORT_DHCP -DSUPPORT_BOOTP
+CPPFLAGS+=	-DSUPPORT_ETHERNET
+CPPFLAGS+=	-DSUPPORT_DHCP -DSUPPORT_BOOTP
 #CPPFLAGS+=	-DBOOTP_DEBUG -DNETIF_DEBUG -DETHER_DEBUG -DNFS_DEBUG
 #CPPFLAGS+=	-DRPC_DEBUG -DRARP_DEBUG -DNET_DEBUG -DDEBUG -DPARANOID
+CPPFLAGS+=	-DLIBSA_PRINTF_WIDTH_SUPPORT
 
 CFLAGS=		-Os -msoft-float
 CFLAGS+=	-ffreestanding
@@ -45,6 +47,11 @@ SRCS+=	disklabel.c
 #SRCS+=	fsdump.c
 SRCS+=	ufs_disksubr.c
 
+# netboot support
+SRCS+=	if_le.c lance.c getsecs.c
+.PATH: ${LIBSADIR}
+SRCS+=	dev_net.c
+
 PROG=   boot
 
 NEWVERSWHAT=	"${PROG}"

Index: src/sys/arch/luna68k/stand/boot/conf.c
diff -u src/sys/arch/luna68k/stand/boot/conf.c:1.1 src/sys/arch/luna68k/stand/boot/conf.c:1.2
--- src/sys/arch/luna68k/stand/boot/conf.c:1.1	Sat Jan  5 17:44:24 2013
+++ src/sys/arch/luna68k/stand/boot/conf.c	Sun Jan 13 14:10:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: conf.c,v 1.1 2013/01/05 17:44:24 tsutsui Exp $	*/
+/*	$NetBSD: conf.c,v 1.2 2013/01/13 14:10:55 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1990, 1993
@@ -39,6 +39,7 @@
 #include <netinet/in_systm.h>
 
 #include <lib/libsa/stand.h>
+#include <lib/libsa/dev_net.h>
 #include <lib/libsa/nfs.h>
 #include <lib/libsa/ufs.h>
 
@@ -56,6 +57,10 @@
 #define	netstrategy	xxstrategy
 #define	netopen		xxopen
 #define	netclose	xxclose
+#else
+#define	netstrategy	net_strategy
+#define	netopen		net_open
+#define	netclose	net_close
 #endif
 #define	netioctl	noioctl
 
@@ -76,8 +81,9 @@ struct devsw devsw[] = {
 int	ndevs = __arraycount(devsw);
 
 #ifdef SUPPORT_ETHERNET
+extern struct netif_driver le_netif_driver;
 struct netif_driver *netif_drivers[] = {
-	&le_driver,
+	&le_netif_driver,
 };
 int	n_netif_drivers = __arraycount(netif_drivers);
 #endif
Index: src/sys/arch/luna68k/stand/boot/devopen.c
diff -u src/sys/arch/luna68k/stand/boot/devopen.c:1.1 src/sys/arch/luna68k/stand/boot/devopen.c:1.2
--- src/sys/arch/luna68k/stand/boot/devopen.c:1.1	Sat Jan  5 17:44:24 2013
+++ src/sys/arch/luna68k/stand/boot/devopen.c	Sun Jan 13 14:10:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: devopen.c,v 1.1 2013/01/05 17:44:24 tsutsui Exp $	*/
+/*	$NetBSD: devopen.c,v 1.2 2013/01/13 14:10:55 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1992 OMRON Corporation.
@@ -101,6 +101,13 @@ devopen(struct open_file *f, const char 
 	}
 
 	file_system[0] = file_system_ufs[0];
+#ifdef SUPPORT_ETHERNET
+	if (strcmp(dp->dv_name, "le") == 0) {
+		/* XXX mixing local fs_ops on netboot could be troublesome */
+		file_system[0] = file_system_nfs[0];
+	}
+#endif
+
 	f->f_dev = dp;
 
 	return 0;
Index: src/sys/arch/luna68k/stand/boot/ioconf.c
diff -u src/sys/arch/luna68k/stand/boot/ioconf.c:1.1 src/sys/arch/luna68k/stand/boot/ioconf.c:1.2
--- src/sys/arch/luna68k/stand/boot/ioconf.c:1.1	Sat Jan  5 17:44:24 2013
+++ src/sys/arch/luna68k/stand/boot/ioconf.c	Sun Jan 13 14:10:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ioconf.c,v 1.1 2013/01/05 17:44:24 tsutsui Exp $	*/
+/*	$NetBSD: ioconf.c,v 1.2 2013/01/13 14:10:55 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1992 OMRON Corporation.
@@ -80,6 +80,7 @@
 
 extern struct driver scdriver;
 extern struct driver sddriver;
+extern struct driver ledriver;
 extern struct driver stdriver;
 
 struct hp_ctlr hp_cinit[] = {
@@ -92,6 +93,7 @@ struct hp_device hp_dinit[] = {
 /*driver,	cdriver,	unit,	ctlr,	slave,	addr,	dk,	flags*/
 { &sddriver,	&scdriver,	0,	0,	6,	C 0x0,	1,	0x0 },
 { &sddriver,	&scdriver,	1,	0,	5,	C 0x0,	1,	0x0 },
+{ &ledriver,	NULL,		0,	0,	0,	C 0x0,	0,	0x0 },
 #ifdef notyet
 { &stdriver,	&scdriver,	0,	0,	4,	C 0x0,	0,	0x0 },
 #endif
Index: src/sys/arch/luna68k/stand/boot/version
diff -u src/sys/arch/luna68k/stand/boot/version:1.1 src/sys/arch/luna68k/stand/boot/version:1.2
--- src/sys/arch/luna68k/stand/boot/version:1.1	Sat Jan  5 17:44:24 2013
+++ src/sys/arch/luna68k/stand/boot/version	Sun Jan 13 14:10:55 2013
@@ -1,7 +1,8 @@
-$NetBSD: version,v 1.1 2013/01/05 17:44:24 tsutsui Exp $
+$NetBSD: version,v 1.2 2013/01/13 14:10:55 tsutsui Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
 is taken as the current.
 
 1.0:	Initial revision, based on 4.4BSD-Lite2/luna68k and NetBSD/hp300
+1.1:	Add netboot support.

Index: src/sys/arch/luna68k/stand/boot/init_main.c
diff -u src/sys/arch/luna68k/stand/boot/init_main.c:1.2 src/sys/arch/luna68k/stand/boot/init_main.c:1.3
--- src/sys/arch/luna68k/stand/boot/init_main.c:1.2	Sat Jan 12 07:11:59 2013
+++ src/sys/arch/luna68k/stand/boot/init_main.c	Sun Jan 13 14:10:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: init_main.c,v 1.2 2013/01/12 07:11:59 tsutsui Exp $	*/
+/*	$NetBSD: init_main.c,v 1.3 2013/01/13 14:10:55 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1992 OMRON Corporation.
@@ -78,6 +78,9 @@
 #include <luna68k/stand/boot/romvec.h>
 #include <luna68k/stand/boot/status.h>
 #include <lib/libsa/loadfile.h>
+#ifdef SUPPORT_ETHERNET
+#include <lib/libsa/dev_net.h>
+#endif
 
 static int get_plane_numbers(void);
 static int reorder_dipsw(int);
@@ -149,6 +152,10 @@ main(void)
 	 * IO configuration
 	 */
 
+#ifdef SUPPORT_ETHERNET
+	try_bootp = 1;
+#endif
+
 	find_devs();
 	configure();
 	printf("\n");
Index: src/sys/arch/luna68k/stand/boot/samachdep.h
diff -u src/sys/arch/luna68k/stand/boot/samachdep.h:1.2 src/sys/arch/luna68k/stand/boot/samachdep.h:1.3
--- src/sys/arch/luna68k/stand/boot/samachdep.h:1.2	Sat Jan 12 07:11:59 2013
+++ src/sys/arch/luna68k/stand/boot/samachdep.h	Sun Jan 13 14:10:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: samachdep.h,v 1.2 2013/01/12 07:11:59 tsutsui Exp $	*/
+/*	$NetBSD: samachdep.h,v 1.3 2013/01/13 14:10:55 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1982, 1990, 1993
@@ -107,6 +107,9 @@ int fsrestore(int, char **);
 /* getline.c */
 int getline(char *, char *);
 
+/* if_le.c */
+int leinit(void *);
+
 /* init_main.c */
 extern int nplane;
 extern int machtype;
@@ -114,6 +117,16 @@ extern int machtype;
 /* kbd.c */
 int kbd_decode(u_char);
 
+/* lance.c */
+void *lance_attach(int, void *, void *, uint8_t *);
+void *lance_cookie(int);
+uint8_t *lance_eaddr(void *);
+bool lance_init(void *);
+int lance_get(void *, void *, size_t);
+bool lance_put(void *, void *, size_t);
+bool lance_end(void *); 
+int lance_intr(void);
+
 /* locore.S */
 extern	u_int bootdev;
 extern int dipsw1, dipsw2;

Index: src/sys/arch/luna68k/stand/boot/locore.S
diff -u src/sys/arch/luna68k/stand/boot/locore.S:1.3 src/sys/arch/luna68k/stand/boot/locore.S:1.4
--- src/sys/arch/luna68k/stand/boot/locore.S:1.3	Sat Jan 12 07:11:59 2013
+++ src/sys/arch/luna68k/stand/boot/locore.S	Sun Jan 13 14:10:55 2013
@@ -516,6 +516,7 @@ ENTRY_NOPROFILE(lev2intr)
 ENTRY_NOPROFILE(lev3intr)
 	clrw	%sp@-
 	moveml	#0xC0C0,%sp@-
+	jbsr	_C_LABEL(lance_intr)
 	moveml	%sp@+,#0x0303
 	addql	#2,%sp
 	jra	_ASM_LABEL(rei)

Added files:

Index: src/sys/arch/luna68k/stand/boot/getsecs.c
diff -u /dev/null src/sys/arch/luna68k/stand/boot/getsecs.c:1.1
--- /dev/null	Sun Jan 13 14:10:56 2013
+++ src/sys/arch/luna68k/stand/boot/getsecs.c	Sun Jan 13 14:10:55 2013
@@ -0,0 +1,65 @@
+/*	$NetBSD: getsecs.c,v 1.1 2013/01/13 14:10:55 tsutsui Exp $	*/
+
+/*-
+ * Copyright (c) 2004 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * 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.
+ */
+
+#include <machine/cpu.h>
+
+#include <lib/libkern/libkern.h>
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+
+#include <luna68k/dev/timekeeper.h>
+#include <luna68k/stand/boot/samachdep.h>
+
+satime_t
+getsecs(void)
+{
+	volatile uint8_t *mclock;
+	u_int t;
+
+	mclock = (volatile uint8_t *)0x45000000;
+
+	if (machtype == LUNA_I) {
+		mclock += 2040;
+		mclock[MK_CSR] |= MK_CSR_READ;
+		t =  bcdtobin(mclock[MK_SEC]);
+		t += bcdtobin(mclock[MK_MIN]) * 60;
+		t += bcdtobin(mclock[MK_HOUR]) * 60 * 60;
+		mclock[MK_CSR] &= ~MK_CSR_READ;
+	} else {
+		while (mclock[MC_REGA] & MC_REGA_UIP)
+			continue;
+		t =  mclock[MC_SEC];
+		t += mclock[MC_MIN] * 60;
+		t += mclock[MC_HOUR] * 60 * 60;
+	}
+
+	return (satime_t)t;
+}
Index: src/sys/arch/luna68k/stand/boot/if_le.c
diff -u /dev/null src/sys/arch/luna68k/stand/boot/if_le.c:1.1
--- /dev/null	Sun Jan 13 14:10:56 2013
+++ src/sys/arch/luna68k/stand/boot/if_le.c	Sun Jan 13 14:10:55 2013
@@ -0,0 +1,290 @@
+/* $NetBSD: if_le.c,v 1.1 2013/01/13 14:10:55 tsutsui Exp $ */
+
+/*
+ * Copyright (c) 2013 Izumi Tsutsui.  All rights reserved.
+ * Copyright (c) 2003 Tetsuya Isaki. 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.
+ */
+/*
+ * Copyright (c) 1982, 1990, 1993
+ *      The Regents of the University of California.  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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: hp300/dev/if_le.c      7.16 (Berkeley) 3/11/93
+ *
+ *      @(#)if_le.c     8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/cpu.h>
+
+#include <net/if.h>
+#include <net/if_ether.h>
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/net.h>
+#include <lib/libsa/netif.h>
+
+#include <luna68k/stand/boot/samachdep.h>
+#include <luna68k/stand/boot/device.h>
+
+/* libsa netif_driver glue functions */
+static int  le_match(struct netif *, void *);
+static int  le_probe(struct netif *, void *);
+static void le_init(struct iodesc *, void *);
+static int  le_get(struct iodesc *, void *, size_t, saseconds_t);
+static int  le_put(struct iodesc *, void *, size_t);
+static void le_end(struct netif *);
+
+static void myetheraddr(uint8_t *);
+
+/* luna68k driver glue stuff */
+struct driver ledriver = {
+	leinit,
+	"le",
+	NULL
+};
+
+/* libsa netif glue stuff */
+struct netif_stats le_stats;
+struct netif_dif le_ifs[] = {
+	{ 0, 1, &le_stats, 0, 0, },
+};
+
+struct netif_driver le_netif_driver = {
+	"le",
+	le_match,
+	le_probe,
+	le_init,
+	le_get,
+	le_put,
+	le_end,
+	le_ifs,
+	__arraycount(le_ifs),
+};
+
+#ifdef DEBUG
+int debug;
+#endif
+
+int
+leinit(void *arg)
+{
+	struct hp_device *hd = arg;
+	void *cookie;
+	void *reg, *mem;
+	uint8_t eaddr[6];
+
+	reg = hd->hp_addr;
+	mem = (void *)0x71010000;	/* XXX */
+
+	myetheraddr(eaddr);
+
+	cookie = lance_attach(hd->hp_unit, reg, mem, eaddr);
+	if (cookie == NULL)
+		return 0;
+
+	printf("%s%d: Am7990 LANCE Ethernet, mem at 0x%x\n",
+	    hd->hp_driver->d_name, hd->hp_unit, (uint32_t)mem);
+	printf("%s%d: Ethernet address = %s\n",
+	    hd->hp_driver->d_name, hd->hp_unit,
+	    ether_sprintf(eaddr));
+
+	return 1;
+}
+
+static int
+le_match(struct netif *nif, void *machdep_hint)
+{
+	void *cookie;
+	uint8_t *eaddr;
+
+	/* XXX should check nif_unit and unit number in machdep_hint path */
+
+	cookie = lance_cookie(nif->nif_unit);
+	if (cookie == NULL)
+		return 0;
+
+	eaddr = lance_eaddr(cookie);
+	if (eaddr == NULL)
+		return 0;
+
+	return 1;
+}
+
+static int
+le_probe(struct netif *nif, void *machdep_hint)
+{
+
+	/* XXX what should be checked? */
+
+	return 0;
+}
+
+static void
+le_init(struct iodesc *desc, void *machdep_hint)
+{
+	struct netif *nif = desc->io_netif;
+	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
+	void *cookie;
+	uint8_t *eaddr;
+
+#ifdef DEBUG
+	printf("%s\n", __func__);
+#endif
+
+	cookie = lance_cookie(nif->nif_unit);
+	eaddr = lance_eaddr(cookie);
+
+	lance_init(cookie);
+
+	/* fill glue stuff */
+	dif->dif_private = cookie;
+	memcpy(desc->myea, eaddr, 6);
+}
+
+static int
+le_get(struct iodesc *desc, void *pkt, size_t maxlen, saseconds_t timeout)
+{
+	struct netif *nif = desc->io_netif;
+	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
+	void *cookie = dif->dif_private;
+	int len = -1;
+	saseconds_t t;
+
+	t = getsecs() + timeout;
+	while (getsecs() < t) {
+		len = lance_get(cookie, pkt, len);
+		if (len > 0)
+			break;
+	}
+
+	return len;
+}
+
+static int
+le_put(struct iodesc *desc, void *pkt, size_t len)
+{
+	struct netif *nif = desc->io_netif;
+	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
+	void *cookie = dif->dif_private;
+#ifdef DEBUG
+ 	struct ether_header *eh;
+ 
+ 	eh = pkt;
+ 	printf("dst:  %s\n", ether_sprintf(eh->ether_dhost));
+ 	printf("src:  %s\n", ether_sprintf(eh->ether_shost));
+ 	printf("type: 0x%x\n", eh->ether_type & 0xffff);
+#endif
+ 
+	return lance_put(cookie, pkt, len) ? len : -1;
+}
+
+static void
+le_end(struct netif *nif)
+{
+	struct netif_dif *dif = &nif->nif_driver->netif_ifs[nif->nif_unit];
+	void *cookie = dif->dif_private;
+
+#ifdef DEBUG
+	printf("%s\n", __func__);
+#endif
+	lance_end(cookie);
+}
+
+static void
+myetheraddr(uint8_t *ether)
+{
+	unsigned int i, loc;
+	uint8_t *ea;
+	volatile struct { uint32_t ctl; } *ds1220;
+
+	switch (machtype) {
+	case LUNA_I:
+		ea = (uint8_t *)0x4101FFE0;
+		for (i = 0; i < ETHER_ADDR_LEN; i++) {
+			int u, l;
+
+			u = ea[0];
+			u = (u < 'A') ? u & 0xf : u - 'A' + 10;
+			l = ea[1];
+			l = (l < 'A') ? l & 0xf : l - 'A' + 10;
+                
+			ether[i] = l | (u << 4);
+			ea += 2;
+		}
+		break;
+	case LUNA_II:
+		ds1220 = (void *)0xF1000004;
+		loc = 12;
+		for (i = 0; i < ETHER_ADDR_LEN; i++) {
+			unsigned int u, l, hex;
+
+			ds1220->ctl = (loc) << 16;
+			u = 0xf0 & (ds1220->ctl >> 12);
+			ds1220->ctl = (loc + 1) << 16;
+			l = 0x0f & (ds1220->ctl >> 16);
+			hex = (u < '9') ? l : l + 9;
+
+			ds1220->ctl = (loc + 2) << 16;
+			u = 0xf0 & (ds1220->ctl >> 12);
+			ds1220->ctl = (loc + 3) << 16;
+			l = 0x0f & (ds1220->ctl >> 16);
+
+			ether[i] = ((u < '9') ? l : l + 9) | (hex << 4);
+			loc += 4;
+		}
+		break;
+	default:
+		ether[0] = 0x00; ether[1] = 0x00; ether[2] = 0x0a;
+		ether[3] = 0xDE; ether[4] = 0xAD; ether[5] = 0x00;
+		break;
+	}
+}
Index: src/sys/arch/luna68k/stand/boot/lance.c
diff -u /dev/null src/sys/arch/luna68k/stand/boot/lance.c:1.1
--- /dev/null	Sun Jan 13 14:10:56 2013
+++ src/sys/arch/luna68k/stand/boot/lance.c	Sun Jan 13 14:10:55 2013
@@ -0,0 +1,375 @@
+/*	$NetBSD: lance.c,v 1.1 2013/01/13 14:10:55 tsutsui Exp $	*/
+
+/*
+ * Copyright (c) 2013 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.
+ */
+/*-
+ * Copyright (c) 2004 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by UCHIYAMA Yasushi.
+ *
+ * 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.
+ */
+
+/*
+ * LANCE driver for LUNA
+ * based on sys/arch/ews4800mips/stand/common/lance.c
+ */
+
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include <dev/ic/am7990reg.h>
+#include <dev/ic/lancereg.h>
+
+#include <luna68k/stand/boot/samachdep.h>
+#include <luna68k/stand/boot/lance.h>
+
+static void lance_setup(struct le_softc *);
+static bool lance_set_initblock(struct le_softc *);
+static bool lance_do_initialize(struct le_softc *);
+
+#define NLE	1	/* XXX for now */
+static struct le_softc lesc[NLE];
+
+void *
+lance_attach(int unit, void *reg, void *mem, uint8_t *eaddr)
+{
+	struct le_softc *sc;
+
+	if (unit >= NLE) {
+		printf("%s: invalid unit number\n", __func__);
+		return NULL;
+	}
+	sc = &lesc[unit];
+
+	if (sc->sc_reg != NULL) {
+		printf("%s: unit %d is already attached\n", __func__, unit);
+		return NULL;
+	}
+	sc->sc_reg = reg;
+	sc->sc_mem = mem;
+	memcpy(sc->sc_enaddr, eaddr, 6);
+
+	return sc;
+}
+
+void *
+lance_cookie(int unit)
+{
+	struct le_softc *sc;
+
+	if (unit >= NLE)
+		return NULL;
+
+	sc = &lesc[unit];
+
+	if (sc->sc_reg == NULL)
+		return NULL;
+
+	return sc;
+}
+
+uint8_t *
+lance_eaddr(void *cookie)
+{
+	struct le_softc *sc = cookie;
+
+	if (sc == NULL || sc->sc_reg == NULL)
+		return NULL;
+
+	return sc->sc_enaddr;
+}
+
+bool
+lance_init(void *cookie)
+{
+	struct le_softc *sc = cookie;
+
+	lance_setup(sc);
+
+	if (!lance_set_initblock(sc))
+		return false;
+
+	if (!lance_do_initialize(sc))
+		return false;
+
+	return true;
+}
+
+int
+lance_get(void *cookie, void *data, size_t maxlen)
+{
+	struct le_softc *sc = cookie;
+	struct lereg *lereg = sc->sc_reg;
+	struct lemem *lemem = sc->sc_mem;
+	struct lermd_v *rmd;
+	uint16_t csr;
+	int len = -1;
+
+	lereg->ler_rap = LE_CSR0;
+	if ((lereg->ler_rdp & LE_C0_RINT) != 0)
+		lereg->ler_rdp = LE_C0_RINT;
+	rmd = &lemem->lem_rmd[sc->sc_currmd];
+	if ((rmd->rmd1_bits & LE_R1_OWN) != 0)
+		return -1;
+	
+	csr = lereg->ler_rdp;
+#if 0
+	if ((csr & LE_C0_ERR) != 0)
+		printf("%s: RX poll error (CSR=0x%x)\n", __func__, csr);
+#endif
+	if ((rmd->rmd1_bits & LE_R1_ERR) != 0) {
+		printf("%s: RX error (rmd status=0x%x)\n", __func__,
+		    rmd->rmd1_bits);
+		goto out;
+	}
+
+	len = rmd->rmd3;
+	if (len < LEMINSIZE + 4 || len > LEMTU) {
+		printf("%s: RX error (bad length %d)\n", __func__, len);
+		goto out;
+	}
+	len -= 4;
+	memcpy(data, (void *)lemem->lem_rbuf[sc->sc_currmd], min(len, maxlen));
+
+ out:
+	rmd->rmd2 = -LEMTU;
+	rmd->rmd1_bits = LE_R1_OWN;	/* return to LANCE */
+	sc->sc_currmd = LE_NEXTRMD(sc->sc_currmd);
+
+	return len;
+}
+
+bool
+lance_put(void *cookie, void *data, size_t len)
+{
+	struct le_softc *sc = cookie;
+	struct lereg *lereg = sc->sc_reg;
+	struct lemem *lemem = sc->sc_mem;
+	struct letmd_v *tmd;
+	uint16_t stat;
+	int timeout;
+
+	lereg->ler_rap = LE_CSR0;
+	stat = lereg->ler_rdp;
+	lereg->ler_rdp =
+	    stat & (LE_C0_BABL | LE_C0_CERR | LE_C0_MISS | LE_C0_TINT);
+#if 0
+	if (stat & (LE_C0_BABL | LE_C0_CERR | LE_C0_MISS | LE_C0_MERR))
+		printf("%s: TX error before xmit csr0=0x%x\n",
+		    __func__, stat);
+#endif
+
+	/* setup TX descriptor */
+	tmd = &lemem->lem_tmd[sc->sc_curtmd];
+	while (tmd->tmd1_bits & LE_T1_OWN)
+		continue;
+	tmd->tmd1_bits = LE_T1_STP | LE_T1_ENP;
+	memcpy((void *)lemem->lem_tbuf[sc->sc_curtmd], data, len);
+	tmd->tmd2 = -max(len, LEMINSIZE);
+	tmd->tmd3 = 0;
+
+	/* start TX */
+	tmd->tmd1_bits |= LE_T1_OWN;
+	lereg->ler_rap = LE_CSR0;
+	lereg->ler_rdp = LE_C0_TDMD;
+
+	/* check TX complete */
+	timeout = 0;
+	do {
+		lereg->ler_rap = LE_CSR0;
+		stat = lereg->ler_rdp;
+#if 0
+		if (stat & LE_C0_ERR) {
+			printf("%s: TX error (CSR0=%x)\n", __func__, stat);
+			if (stat & LE_C0_CERR) {
+				lereg->ler_rdp = LE_C0_CERR;
+			}
+		}
+#endif
+		if (timeout++ > 1000) {
+			printf("%s: TX timeout (CSR0=%x)\n", __func__, stat);
+			return false;
+		}
+	} while ((stat & LE_C0_TINT) == 0);
+
+	lereg->ler_rdp = LE_C0_TINT;
+
+	sc->sc_curtmd = LE_NEXTTMD(sc->sc_curtmd);
+
+	return true;
+}
+
+bool
+lance_end(void *cookie)
+{
+	struct le_softc *sc = cookie;
+	struct lereg *lereg = sc->sc_reg;
+
+	lereg->ler_rap = LE_CSR0;
+	lereg->ler_rdp = LE_C0_STOP;
+
+	return true;
+}
+
+/* XXX */
+int
+lance_intr(void)
+{
+
+	return 1;
+}
+
+static bool
+lance_set_initblock(struct le_softc *sc)
+{
+	struct lereg *lereg = sc->sc_reg;
+	uint32_t addr = (uint32_t)sc->sc_mem;
+
+	lereg->ler_rap = LE_CSR0;
+	lereg->ler_rdp = LE_C0_STOP;	/* disable all external activity */
+	DELAY(100);
+
+	/* Set the correct byte swapping mode */
+	lereg->ler_rap = LE_CSR3;
+	lereg->ler_rdp = LE_C3_BSWP;
+
+	/* Low address of init block */
+	lereg->ler_rap = LE_CSR1;
+	lereg->ler_rdp = addr & 0xfffe;
+
+	/* High address of init block */
+	lereg->ler_rap = LE_CSR2;
+	lereg->ler_rdp = (addr >> 16) & 0x00ff;
+	DELAY(100);
+
+	return true;
+}
+
+static bool
+lance_do_initialize(struct le_softc *sc)
+{
+	struct lereg *lereg = sc->sc_reg;
+	uint16_t reg;
+	int timeout;
+
+	sc->sc_curtmd = 0;
+	sc->sc_currmd = 0;
+
+	/* Initialze LANCE */
+	lereg->ler_rap = LE_CSR0;
+	lereg->ler_rdp = LE_C0_INIT;
+
+	/* Wait interrupt */
+	timeout = 1000000;
+	do {
+		lereg->ler_rap = LE_CSR0;
+		reg = lereg->ler_rdp;
+		if (--timeout == 0) {
+			printf("le: init timeout (CSR=0x%x)\n", reg);
+			return false;
+		}
+		DELAY(1);
+	} while ((reg & LE_C0_IDON) == 0);
+		
+	lereg->ler_rap = LE_CSR0;
+	lereg->ler_rdp = LE_C0_STRT | LE_C0_IDON;
+
+	return true;
+}
+
+static void
+lance_setup(struct le_softc *sc)
+{
+	struct lereg *lereg = sc->sc_reg;
+	struct lemem *lemem = sc->sc_mem;
+	uint32_t addr;
+	int i;
+
+	/* make sure to stop LANCE chip before setup memory */
+	lereg->ler_rap = LE_CSR0;
+	lereg->ler_rdp = LE_C0_STOP;
+
+	memset(lemem, 0, sizeof *lemem);
+
+	/* Init block */
+	lemem->lem_mode = LE_MODE_NORMAL;
+	lemem->lem_padr[0] = (sc->sc_enaddr[1] << 8) | sc->sc_enaddr[0];
+	lemem->lem_padr[1] = (sc->sc_enaddr[3] << 8) | sc->sc_enaddr[2];
+	lemem->lem_padr[2] = (sc->sc_enaddr[5] << 8) | sc->sc_enaddr[4];
+	/* Logical address filter */
+	for (i = 0; i < 4; i++)
+		lemem->lem_ladrf[i] = 0x0000;
+
+	/* Location of Rx descriptor ring */
+	addr = (uint32_t)lemem->lem_rmd;
+	lemem->lem_rdra = addr & 0xffff;
+	lemem->lem_rlen = LE_RLEN | ((addr >> 16) & 0xff);
+
+	/* Location of Tx descriptor ring */
+	addr = (uint32_t)lemem->lem_tmd;
+	lemem->lem_tdra = addr & 0xffff;
+	lemem->lem_tlen = LE_TLEN | ((addr >> 16) & 0xff);
+
+	/* Rx descriptor */
+	for (i = 0; i < LERBUF; i++) {
+		addr = (uint32_t)lemem->lem_rbuf[i];
+		lemem->lem_rmd[i].rmd0 = addr & 0xffff;
+		lemem->lem_rmd[i].rmd1_hadr = (addr >> 16) & 0xff;
+		lemem->lem_rmd[i].rmd1_bits = LE_R1_OWN;
+		lemem->lem_rmd[i].rmd2 = LE_XMD2_ONES | -LEMTU;
+		lemem->lem_rmd[i].rmd3 = 0;
+	}
+
+	/* Tx descriptor */
+	for (i = 0; i < LETBUF; i++) {
+		addr = (uint32_t)lemem->lem_tbuf[i];
+		lemem->lem_tmd[i].tmd0 = addr & 0xffff;
+		lemem->lem_tmd[i].tmd1_hadr = (addr >> 16) & 0xff;
+		lemem->lem_tmd[i].tmd1_bits = 0;
+		lemem->lem_tmd[i].tmd2 = LE_XMD2_ONES | 0;
+		lemem->lem_tmd[i].tmd3 = 0;
+	}
+}
Index: src/sys/arch/luna68k/stand/boot/lance.h
diff -u /dev/null src/sys/arch/luna68k/stand/boot/lance.h:1.1
--- /dev/null	Sun Jan 13 14:10:56 2013
+++ src/sys/arch/luna68k/stand/boot/lance.h	Sun Jan 13 14:10:55 2013
@@ -0,0 +1,105 @@
+/*	$NetBSD: lance.h,v 1.1 2013/01/13 14:10:55 tsutsui Exp $ */
+
+/*-
+ * Copyright (c) 1982, 1992, 1993
+ *	The Regents of the University of California.  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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)if_lereg.h	8.2 (Berkeley) 10/30/93
+ */
+
+#define	LEMTU		1518
+#define	LEMINSIZE	60	/* should be 64 if mode DTCR is set */
+#define	LERBUF		8
+#define	LERBUFLOG2	3
+#define	LE_RLEN		(LERBUFLOG2 << 13)
+#define	LE_NEXTRMD(x)	(((x) + 1) & (LERBUF - 1))
+#define	LETBUF		1
+#define	LETBUFLOG2	0
+#define	LE_TLEN		(LETBUFLOG2 << 13)
+#define	LE_NEXTTMD(x)	(((x) + 1) & (LETBUF - 1))
+
+/* Local Area Network Controller for Ethernet (LANCE) registers */
+struct lereg {
+	volatile uint16_t	ler_rdp;	/* register data port */
+	volatile uint16_t	ler_rap;	/* register address port */
+};
+
+/*
+ * lance memory
+ */
+
+/* receive message descriptors. bits/hadr are byte order dependent. */
+struct	lermd_v {
+	volatile uint16_t rmd0;		/* low address of packet */
+#if BYTE_ORDER == BIG_ENDIAN
+	volatile uint8_t  rmd1_bits;	/* descriptor bits */
+	volatile uint8_t  rmd1_hadr;	/* high address of packet */
+#else
+	volatile uint8_t  rmd1_hadr;	/* high address of packet */
+	volatile uint8_t  rmd1_bits;	/* descriptor bits */
+#endif
+	volatile int16_t  rmd2;		/* buffer byte count */
+	volatile uint16_t rmd3;		/* message byte count */
+};
+
+/* transmit message descriptors */
+struct	letmd_v {
+	volatile uint16_t tmd0;		/* low address of packet */
+#if BYTE_ORDER == BIG_ENDIAN
+	volatile uint8_t  tmd1_bits;	/* descriptor bits */
+	volatile uint8_t  tmd1_hadr;	/* high address of packet */
+#else
+	volatile uint8_t  tmd1_hadr;	/* high address of packet */
+	volatile uint8_t  tmd1_bits;	/* descriptor bits */
+#endif
+	volatile int16_t  tmd2;		/* buffer byte count */
+	volatile uint16_t tmd3;		/* transmit error bits */
+};
+
+struct lemem {
+	/* initialization block */
+	volatile uint16_t	lem_mode;	/* mode */
+	volatile uint16_t	lem_padr[3];	/* physical address */
+	volatile uint16_t	lem_ladrf[4];	/* logical address filter */
+	volatile uint16_t	lem_rdra;	/* receive descriptor addr */
+	volatile uint16_t	lem_rlen;	/* rda high and ring size */
+	volatile uint16_t	lem_tdra;	/* transmit descriptor addr */
+	volatile uint16_t	lem_tlen;	/* tda high and ring size */
+	uint16_t		lem_pad0[4];
+	struct lermd_v		lem_rmd[LERBUF];
+	struct letmd_v		lem_tmd[LETBUF];
+	volatile uint8_t	lem_rbuf[LERBUF][LEMTU];
+	volatile uint8_t	lem_tbuf[LETBUF][LEMTU];
+};
+
+struct le_softc {
+	struct lereg *sc_reg;
+	struct lemem *sc_mem;
+	uint8_t sc_enaddr[6];
+	int sc_curtmd;
+	int sc_currmd;
+};

Reply via email to