summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>1995-11-13 03:53:53 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>1995-11-13 03:53:53 +0000
commitbe6610d2f34f2369c6132c9aea7abe125de4448c (patch)
treefd76f3aea962540b09d8c099b326b80018e89940 /sys/arch
parent5c7a8b804cd7c4371a60d2319a767fbb86d4d6b5 (diff)
update to netbsd
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/amiga/amiga/amiga_init.c11
-rw-r--r--sys/arch/amiga/amiga/pmap.c17
-rw-r--r--sys/arch/amiga/amiga/sys_machdep.c6
-rw-r--r--sys/arch/amiga/amiga/trap.c6
-rw-r--r--sys/arch/amiga/conf/Makefile.amiga15
-rw-r--r--sys/arch/amiga/conf/files.amiga5
-rw-r--r--sys/arch/amiga/dev/grf_cv.c144
-rw-r--r--sys/arch/amiga/dev/grf_cvreg.h39
-rw-r--r--sys/arch/amiga/dev/grf_ul.c31
-rw-r--r--sys/arch/amiga/dev/grf_ultms.g (renamed from sys/arch/amiga/dev/grf_ul.gsp)0
-rw-r--r--sys/arch/amiga/dev/if_qn.c481
-rw-r--r--sys/arch/amiga/dev/if_qnreg.h8
12 files changed, 397 insertions, 366 deletions
diff --git a/sys/arch/amiga/amiga/amiga_init.c b/sys/arch/amiga/amiga/amiga_init.c
index 2d99fa05107..336da5a5b72 100644
--- a/sys/arch/amiga/amiga/amiga_init.c
+++ b/sys/arch/amiga/amiga/amiga_init.c
@@ -1,4 +1,4 @@
-/* $NetBSD: amiga_init.c,v 1.33 1995/10/05 12:40:48 chopps Exp $ */
+/* $NetBSD: amiga_init.c,v 1.33.2.1 1995/11/10 16:09:54 chopps Exp $ */
/*
* Copyright (c) 1994 Michael L. Hitch
@@ -63,6 +63,9 @@ extern u_int lowram;
extern u_int Sysptmap, Sysptsize, Sysseg, Umap, proc0paddr;
extern u_int Sysseg_pa;
extern u_int virtual_avail;
+#ifdef M68040
+extern int protostfree;
+#endif
extern char *esym;
@@ -346,7 +349,7 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags)
* Initialize level 2 descriptors (which immediately
* follow the level 1 table). We need:
* NPTEPG / SG4_LEV3SIZE
- * level 2 descriptors to map eachof the nptpages + 1
+ * level 2 descriptors to map each of the nptpages + 1
* pages of PTEs. Note that we set the "used" bit
* now to save the HW the expense of doing it.
*/
@@ -363,8 +366,10 @@ start_c(id, fphystart, fphysize, cphysize, esym_addr, flags)
* roundup(num, SG4_LEV2SIZE) / SG4_LEVEL2SIZE
* level 1 descriptors to map the 'num' level 2's.
*/
+ i = roundup(i, SG4_LEV2SIZE) / SG4_LEV2SIZE;
+ protostfree = (-1 << (i + 1)) /* & ~(-1 << MAXKL2SIZE) */;
sg = (u_int *) Sysseg_pa;
- esg = &sg[roundup(i, SG4_LEV2SIZE) / SG4_LEV2SIZE];
+ esg = &sg[i];
sg_proto = (u_int)&sg[SG4_LEV1SIZE] | SG_U | SG_RW |SG_V;
while (sg < esg) {
*sg++ = sg_proto;
diff --git a/sys/arch/amiga/amiga/pmap.c b/sys/arch/amiga/amiga/pmap.c
index 860f320f30f..60697284291 100644
--- a/sys/arch/amiga/amiga/pmap.c
+++ b/sys/arch/amiga/amiga/pmap.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap.c,v 1.27 1995/10/09 04:34:02 chopps Exp $ */
+/* $NetBSD: pmap.c,v 1.27.2.1 1995/11/10 16:10:00 chopps Exp $ */
/*
* Copyright (c) 1991 Regents of the University of California.
@@ -237,6 +237,7 @@ boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
char *pmap_attributes; /* reference and modify bits */
#ifdef M68040
static int pmap_ishift; /* segment table index shift */
+int protostfree; /* prototype (default) free ST map */
#endif
#ifdef MACHINE_NONCONTIG
@@ -363,7 +364,7 @@ pmap_bootstrap(firstaddr, loadaddr)
#ifdef M68040
if (mmutype == MMU_68040) {
pmap_ishift = SG4_SHIFT1;
- pmap_kernel()->pm_stfree = 0xfffffff8; /* XXXX */
+ pmap_kernel()->pm_stfree = protostfree;
} else
pmap_ishift = SG_ISHIFT;
#endif
@@ -574,6 +575,12 @@ pmap_init(phys_start, phys_end)
printf("pmap_init: pt_map [%x - %x)\n", addr, addr2);
#endif
+#ifdef M68040
+ if (mmutype == MMU_68040) {
+ protostfree = ~1 & ~(-1 << MAXUL2SIZE);
+ }
+#endif
+
/*
* Now it is safe to enable pv_table recording.
*/
@@ -734,7 +741,7 @@ pmap_pinit(pmap)
pmap->pm_stpa = Segtabzeropa;
#ifdef M68040
if (mmutype == MMU_68040)
- pmap->pm_stfree = 0x0000fffe; /* XXXX */
+ pmap->pm_stfree = protostfree;
#endif
pmap->pm_stchanged = TRUE;
pmap->pm_count = 1;
@@ -1011,7 +1018,7 @@ printf ("pmap_remove: PA %08x index %d\n", pa, pa_index(pa));
ptpmap->pm_stpa = Segtabzeropa;
#ifdef M68040
if (mmutype == MMU_68040)
- ptpmap->pm_stfree = 0x0000fffe; /* XXXX */
+ ptpmap->pm_stfree = protostfree;
#endif
ptpmap->pm_stchanged = TRUE;
/*
@@ -2046,7 +2053,7 @@ pmap_enter_ptpage(pmap, va)
pmap_kernel(), (vm_offset_t)pmap->pm_stab);
#ifdef M68040
if (mmutype == MMU_68040) {
- pmap->pm_stfree = 0x0000fffe; /* XXXX */
+ pmap->pm_stfree = protostfree;
}
#endif
pmap->pm_stchanged = TRUE;
diff --git a/sys/arch/amiga/amiga/sys_machdep.c b/sys/arch/amiga/amiga/sys_machdep.c
index a7f098b472e..bf4f9b66e4c 100644
--- a/sys/arch/amiga/amiga/sys_machdep.c
+++ b/sys/arch/amiga/amiga/sys_machdep.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_machdep.c,v 1.12 1995/10/09 04:34:05 chopps Exp $ */
+/* $NetBSD: sys_machdep.c,v 1.12.2.1 1995/11/10 16:13:41 chopps Exp $ */
/*
* Copyright (c) 1982, 1986 Regents of the University of California.
@@ -60,7 +60,7 @@ sys_vtrace(p, v, retval)
void *v;
register_t *retval;
{
- register struct vtrace_args /* {
+ register struct sys_vtrace_args /* {
syscallarg(int) request;
syscallarg(int) value;
} */ *uap = v;
@@ -276,7 +276,7 @@ sys_sysarch(p, v, retval)
void *v;
register_t *retval;
{
- struct sysarch_args /* {
+ struct sys_sysarch_args /* {
syscallarg(int) op;
syscallarg(char *) parms;
} */ *uap = v;
diff --git a/sys/arch/amiga/amiga/trap.c b/sys/arch/amiga/amiga/trap.c
index 90fd14b22a0..ee104684fde 100644
--- a/sys/arch/amiga/amiga/trap.c
+++ b/sys/arch/amiga/amiga/trap.c
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.42 1995/10/09 04:34:08 chopps Exp $ */
+/* $NetBSD: trap.c,v 1.42.2.1 1995/11/10 19:32:59 chopps Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -280,8 +280,10 @@ trapmmufault(type, code, v, fp, p, sticks)
/*
* Print out some data about the fault
*/
+#ifdef DEBUG_PAGE0
if (v < NBPG) /* XXX PAGE0 */
mmudebug |= 0x100; /* XXX PAGE0 */
+#endif
if (mmudebug && mmutype == MMU_68040) {
printf ("68040 access error: pc %x, code %x,"
" ea %x, fa %x\n", fp->f_pc, code, fp->f_fmt7.f_ea, v);
@@ -294,8 +296,10 @@ trapmmufault(type, code, v, fp, p, sticks)
Debugger(); /* XXX PAGE0 */
#endif /* XXX PAGE0 */
}
+#ifdef DEBUG_PAGE0
mmudebug &= ~0x100; /* XXX PAGE0 */
#endif
+#endif
if (p)
vm = p->p_vmspace;
diff --git a/sys/arch/amiga/conf/Makefile.amiga b/sys/arch/amiga/conf/Makefile.amiga
index f3820465088..b00139375aa 100644
--- a/sys/arch/amiga/conf/Makefile.amiga
+++ b/sys/arch/amiga/conf/Makefile.amiga
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.amiga,v 1.28 1995/10/09 15:23:25 chopps Exp $
+# $NetBSD: Makefile.amiga,v 1.28.2.1 1995/11/10 19:29:46 chopps Exp $
# @(#)Makefile.hp300 7.10 (Berkeley) 6/27/91
#
@@ -75,6 +75,12 @@ PROFILE_C= ${CC} -S -c ${COPTS} $<; \
NORMAL_S= ${CPP} ${COPTS} $< | ${AS} -o $@
NORMAL_S_C= ${CPP} ${COPTS} ${PARAM} $< | ${AS} -o $@
+.SUFFIXES: .o .g
+
+.g.o: ; echo This is a dummy rule and should not be executed.
+
+NORMAL_G= gspa < $< | gspahextoc > $*.c; ${CC} -c ${CFLAGS} ${PROF} $*.c
+
%OBJS
%CFILES
@@ -142,7 +148,7 @@ genassym:
${CC} -static ${INCLUDES} ${IDENT} ${PARAM} -Dmc68020 -Damiga \
-o genassym ${AMIGA}/amiga/genassym.c
-depend: assym.s param.c vnode_if.h grf_ultmscode.h
+depend: assym.s param.c vnode_if.h
mkdep ${COPTS} ${CFILES} ioconf.c param.c
mkdep -a -p ${INCLUDES} ${IDENT} ${PARAM} ${AMIGA}/amiga/genassym.c
@@ -169,9 +175,4 @@ param.o: param.c Makefile
vnode_if.c vnode_if.h: $S/kern/vnode_if.sh $S/kern/vnode_if.src
AWK="${AWK}" sh $S/kern/vnode_if.sh $S/kern/vnode_if.src
-grf_ultmscode.h: ${AMIGA}/dev/grf_ul.gsp
- gspa < ${AMIGA}/dev/grf_ul.gsp | gspahextoc > grf_ultmscode.h
-
-grf_ul.o: grf_ultmscode.h
-
%RULES
diff --git a/sys/arch/amiga/conf/files.amiga b/sys/arch/amiga/conf/files.amiga
index 35bc2520975..29471264bd3 100644
--- a/sys/arch/amiga/conf/files.amiga
+++ b/sys/arch/amiga/conf/files.amiga
@@ -1,4 +1,4 @@
-# $NetBSD: files.amiga,v 1.31.2.1 1995/10/20 11:01:01 chopps Exp $
+# $NetBSD: files.amiga,v 1.31.2.2 1995/11/10 19:29:49 chopps Exp $
# maxpartitions must be first item in files.${ARCH}.newconf
maxpartitions 16 # NOTE THAT AMIGA IS SPECIAL!
@@ -82,7 +82,8 @@ file arch/amiga/dev/grf_cv.c grfcv needs-flag
# A2410 grf
device grful at zbus: grfbus
file arch/amiga/dev/grf_ul.c grful needs-flag
-file arch/amiga/dev/ite_ul.c grful ite
+file arch/amiga/dev/ite_ul.c grful ite
+file arch/amiga/dev/grf_ultms.g grful
# retina ZIII grf
device grfrh at zbus: grfbus
diff --git a/sys/arch/amiga/dev/grf_cv.c b/sys/arch/amiga/dev/grf_cv.c
index 83480b8cb04..ec5a54aca7b 100644
--- a/sys/arch/amiga/dev/grf_cv.c
+++ b/sys/arch/amiga/dev/grf_cv.c
@@ -1,4 +1,4 @@
-/* $NetBSD: grf_cv.c,v 1.3.2.2 1995/10/21 15:15:41 chopps Exp $ */
+/* $NetBSD: grf_cv.c,v 1.3.2.3 1995/11/10 16:27:10 chopps Exp $ */
/*
* Copyright (c) 1995 Michael Teske
@@ -74,24 +74,26 @@
#include <amiga/dev/grf_cvreg.h>
#include <amiga/dev/zbusvar.h>
-int cv_mondefok __P((struct grfvideo_mode *));
-void cv_boardinit();
+int grfcvmatch __P((struct device *, struct cfdata *, void *));
+void grfcvattach __P((struct device *, struct device *, void *));
+int grfcvprint __P((void *, char *));
+
+static int cv_has_4mb __P((volatile char *));
static unsigned short compute_clock __P((unsigned long));
-int cv_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
-int cv_setvmode __P((struct grf_softc *, unsigned int));
-int cv_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
-int cv_toggle __P((struct grf_softc *,unsigned short));
-int cv_getcmap __P((struct grf_softc *, struct grf_colormap *));
-int cv_putcmap __P((struct grf_softc *, struct grf_colormap *));
-void cv_off __P((struct grf_softc *));
-int cv_blank __P((struct grf_softc *, int *));
-void cv_inittextmode __P((struct grf_softc *));
-
-int cv_ioctl __P((register struct grf_softc *gp, int cmd, void *data));
-void grfcvattach __P((struct device *, struct device *, void *));
-int grfcvprint __P((void *, char *));
-int grfcvmatch __P((struct device *, struct cfdata *, void *));
-void cv_memset __P((unsigned char *, unsigned char, int));
+void cv_boardinit __P((struct grf_softc *));
+int cv_getvmode __P((struct grf_softc *, struct grfvideo_mode *));
+int cv_setvmode __P((struct grf_softc *, unsigned int));
+int cv_blank __P((struct grf_softc *, int *));
+int cv_mode __P((register struct grf_softc *, int, void *, int, int));
+int cv_ioctl __P((register struct grf_softc *gp, int cmd, void *data));
+int cv_setmonitor __P((struct grf_softc *, struct grfvideo_mode *));
+int cv_getcmap __P((struct grf_softc *, struct grf_colormap *));
+int cv_putcmap __P((struct grf_softc *, struct grf_colormap *));
+int cv_toggle __P((struct grf_softc *));
+int cv_mondefok __P((struct grfvideo_mode *));
+int cv_load_mon __P((struct grf_softc *, struct grfcvtext_mode *));
+void cv_inittextmode __P((struct grf_softc *));
+void cv_memset __P((unsigned char *, unsigned char, int));
#ifdef CV64CONSOLE
extern void grfcv_iteinit __P((struct grf_softc *));
@@ -126,18 +128,15 @@ struct grfcvtext_mode cvconsole_mode = {
S3FONTX, S3FONTY, 80, 506/S3FONTY, S3FONT, 32, 255
};
-
/* Console colors */
unsigned char cvconscolors[3][3] = { /* background, foreground, hilite */
{0,0x40,0x50}, {152,152,152}, {255,255,255}
};
-unsigned char pass_toggle; /* passthru status tracker */
-
/* Board Address of CV64 */
-static void *cv_boardaddr;
+static volatile caddr_t cv_boardaddr;
static int cv_fbsize;
int
@@ -227,59 +226,36 @@ grfcvattach(pdp, dp, auxp)
struct device *pdp, *dp;
void *auxp;
{
- static struct grf_softc congrf;
struct zbus_args *zap;
struct grf_softc *gp;
- static char attachflag = 0;
zap = auxp;
printf("\n");
- /* make sure id's have matched */
- if (!cv_boardaddr)
- return;
+ gp = (struct grf_softc *)dp;
- /* do all that messy console/grf stuff */
- if (dp == NULL)
- gp = &congrf;
- else
- gp = (struct grf_softc *)dp;
-
- if (dp != NULL && congrf.g_regkva != 0) {
- /*
- * inited earlier, just copy (not device struct)
- */
- bcopy(&congrf.g_display, &gp->g_display,
- (char *)&gp[1] - (char *)&gp->g_display);
- } else {
- gp->g_regkva = (volatile caddr_t)cv_boardaddr + READ_OFFSET;
- gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
+ gp->g_regkva = (volatile caddr_t)cv_boardaddr + READ_OFFSET;
+ gp->g_fbkva = (volatile caddr_t)cv_boardaddr + 0x01400000;
- gp->g_unit = GRF_CV64_UNIT;
- gp->g_mode = cv_mode;
- gp->g_conpri = grfcv_cnprobe();
- gp->g_flags = GF_ALIVE;
+ gp->g_unit = GRF_CV64_UNIT;
+ gp->g_mode = cv_mode;
+ gp->g_conpri = grfcv_cnprobe();
+ gp->g_flags = GF_ALIVE;
- /* wakeup the board */
- cv_boardinit(gp);
+ /* wakeup the board */
+ cv_boardinit(gp);
#ifdef CV64CONSOLE
- grfcv_iteinit(gp);
- (void)cv_load_mon(gp, &cvconsole_mode);
+ grfcv_iteinit(gp);
+ (void)cv_load_mon(gp, &cvconsole_mode);
#endif
- }
/*
- * attach grf (once)
+ * attach grf
*/
- if (amiga_config_found(cfdata, &gp->g_device, gp, grfcvprint)) {
- attachflag = 1;
+ if (amiga_config_found(cfdata, &gp->g_device, gp, grfcvprint))
printf("grfcv: CyberVision64 with %dMB being used\n", cv_fbsize/0x100000);
- } else {
- if (!attachflag)
- printf("grfcv unattached!!\n");
- }
}
int
@@ -353,7 +329,7 @@ void
cv_boardinit(gp)
struct grf_softc *gp;
{
- unsigned char *ba = gp->g_regkva;
+ volatile caddr_t ba = gp->g_regkva;
unsigned char test;
unsigned int clockpar;
int i;
@@ -606,7 +582,7 @@ cv_setvmode(gp, mode)
unsigned mode;
{
if (!mode || (mode > monitor_def_max) ||
- monitor_def[mode-1].mode_num == 0)
+ monitor_def[mode - 1].mode_num == 0)
return (EINVAL);
monitor_current = monitor_def + (mode - 1);
@@ -614,25 +590,13 @@ cv_setvmode(gp, mode)
return (0);
}
-void
-cv_off(gp)
- struct grf_softc *gp;
-{
- char *ba = gp->g_regkva - READ_OFFSET;
-
- /* we'll put the pass-through on for cc ite and set Full Bandwidth
- * bit on just in case it didn't work...but then it doesn't matter
- * does it? =)
- */
- cvscreen(1, ba);
-}
int
cv_blank(gp, on)
struct grf_softc *gp;
int *on;
{
- char *ba = gp->g_regkva;
+ volatile caddr_t ba = gp->g_regkva;
gfx_on_off(*on ? 1 : 0, ba);
return (0);
@@ -660,7 +624,7 @@ cv_mode(gp, cmd, arg, a2, a3)
case GM_GRFOFF:
#ifndef CV64CONSOLE
- cv_off(gp);
+ (void)cv_toggle(gp);
#else
cv_load_mon(gp, &cvconsole_mode);
#endif
@@ -717,7 +681,7 @@ cv_ioctl (gp, cmd, data)
break;
case GRFTOGGLE:
- return (cv_toggle (gp, 0));
+ return (cv_toggle (gp));
case GRFIOCSETMON:
return (cv_setmonitor (gp, (struct grfvideo_mode *)data));
@@ -775,7 +739,7 @@ cv_getcmap(gfp, cmap)
struct grf_softc *gfp;
struct grf_colormap *cmap;
{
- volatile unsigned char *ba;
+ volatile caddr_t ba;
u_char red[256], green[256], blue[256], *rp, *gp, *bp;
short x;
int error;
@@ -814,7 +778,7 @@ cv_putcmap(gfp, cmap)
struct grf_softc *gfp;
struct grf_colormap *cmap;
{
- volatile unsigned char *ba;
+ volatile caddr_t ba;
u_char red[256], green[256], blue[256], *rp, *gp, *bp;
short x;
int error;
@@ -849,19 +813,14 @@ cv_putcmap(gfp, cmap)
int
-cv_toggle(gp,wopp)
+cv_toggle(gp)
struct grf_softc *gp;
- unsigned short wopp; /* don't need that one yet, ill */
{
- volatile unsigned char *ba;
+ volatile caddr_t ba;
- ba = gp->g_regkva - READ_OFFSET;
+ ba = gp->g_regkva;
+ cvscreen(1, ba - READ_OFFSET);
- if (pass_toggle) {
- cvscreen(0, ba);
- } else {
- cvscreen(1, ba);
- }
return (0);
}
@@ -908,8 +867,7 @@ cv_load_mon(gp, md)
{
struct grfvideo_mode *gv;
struct grfinfo *gi;
- volatile unsigned char *ba;
- volatile unsigned char *fb;
+ volatile caddr_t ba, fb;
unsigned short mnr;
unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS,
VSE, VT;
@@ -957,12 +915,12 @@ cv_load_mon(gp, md)
HBE = gv->hblank_stop;
HSS = gv->hsync_start;
HSE = gv->hsync_stop;
- HT = gv->htotal;
- VBS = gv->vblank_start;
+ HT = gv->htotal - 5;
+ VBS = gv->vblank_start - 1;
VSS = gv->vsync_start;
VSE = gv->vsync_stop;
VBE = gv->vblank_stop;
- VT = gv->vtotal;
+ VT = gv->vtotal - 2;
if (TEXT)
HDE = ((gv->disp_width + md->fx - 1) / md->fx) - 1;
@@ -1198,8 +1156,8 @@ cv_inittextmode(gp)
struct grf_softc *gp;
{
struct grfcvtext_mode *tm = (struct grfcvtext_mode *)gp->g_data;
- volatile unsigned char *ba = gp->g_regkva;
- unsigned char *fb = gp->g_fbkva;
+ volatile caddr_t ba = gp->g_regkva;
+ volatile caddr_t fb = gp->g_fbkva;
unsigned char *c, *f, y;
unsigned short z;
diff --git a/sys/arch/amiga/dev/grf_cvreg.h b/sys/arch/amiga/dev/grf_cvreg.h
index dbdd657a62d..a38dcbea6b9 100644
--- a/sys/arch/amiga/dev/grf_cvreg.h
+++ b/sys/arch/amiga/dev/grf_cvreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: grf_cvreg.h,v 1.1.2.1 1995/10/21 15:15:44 chopps Exp $ */
+/* $NetBSD: grf_cvreg.h,v 1.1.2.2 1995/11/10 16:27:13 chopps Exp $ */
/*
* Copyright (c) 1995 Michael Teske
@@ -57,11 +57,11 @@ struct grfcvtext_mode {
/* read VGA register */
-#define vgar(ba, reg) (*(((volatile unsigned char *)ba)+reg))
+#define vgar(ba, reg) (*(((volatile caddr_t)ba)+reg))
/* write VGA register */
#define vgaw(ba, reg, val) \
- *(((volatile unsigned char *)ba)+reg) = ((val) & 0xff)
+ *(((volatile caddr_t)ba)+reg) = ((val) & 0xff)
/*
* defines for the used register addresses (mw)
@@ -339,7 +339,7 @@ struct grfcvtext_mode {
static inline unsigned char
RAttr(ba, idx)
- volatile void *ba;
+ volatile caddr_t ba;
short idx;
{
@@ -350,7 +350,7 @@ RAttr(ba, idx)
static inline unsigned char
RSeq(ba, idx)
- volatile void *ba;
+ volatile caddr_t ba;
short idx;
{
vgaw(ba, SEQ_ADDRESS, idx);
@@ -359,7 +359,7 @@ RSeq(ba, idx)
static inline unsigned char
RCrt(ba, idx)
- volatile void *ba;
+ volatile caddr_t ba;
short idx;
{
vgaw(ba, CRT_ADDRESS, idx);
@@ -368,7 +368,7 @@ RCrt(ba, idx)
static inline unsigned char
RGfx(ba, idx)
- volatile void *ba;
+ volatile caddr_t ba;
short idx;
{
vgaw(ba, GCT_ADDRESS, idx);
@@ -379,10 +379,10 @@ RGfx(ba, idx)
static inline void
cv_write_port(bits, BoardAddr)
unsigned short bits;
- volatile unsigned char *BoardAddr;
+ volatile caddr_t BoardAddr;
{
volatile char *addr;
- static unsigned char CVPortBits=0; /* mirror port bits here */
+ static unsigned char CVPortBits = 0; /* mirror port bits here */
addr = BoardAddr + 0x40001;
if (bits & 0x8000)
@@ -409,8 +409,8 @@ cv_write_port(bits, BoardAddr)
static inline void
cvscreen(toggle, ba)
- char toggle;
- volatile unsigned char *ba;
+ char *toggle;
+ volatile caddr_t ba;
{
if (toggle)
@@ -423,23 +423,22 @@ cvscreen(toggle, ba)
/* ba= registerbase */
static inline void
gfx_on_off(toggle, ba)
- char toggle;
- volatile unsigned char *ba;
+ int toggle;
+ volatile caddr_t ba;
{
- unsigned char r;
+ int r;
toggle &= 0x1;
toggle = toggle << 5;
- r = RSeq(ba, 0x1);
- r &= 0xDF; /* Bit 5 auf 0!!! */
- WSeq(ba, 1, r | toggle);
+ r = RSeq(ba, SEQ_ID_CLOCKING_MODE);
+ r &= 0xdf; /* set Bit 5 to 0 */
+
+ WSeq(ba, SEQ_ID_CLOCKING_MODE, r | toggle);
}
-int cv_mode __P((register struct grf_softc *gp, int cmd, void *arg, int a2, int a3));
-int cv_load_mon __P((struct grf_softc *gp, struct grfcvtext_mode *gv));
-int grfcv_cnprobe __P((void));
#if 0
+int grfcv_cnprobe __P((void));
void grfcv_iteinit __P((struct grf_softc *gp));
#endif
diff --git a/sys/arch/amiga/dev/grf_ul.c b/sys/arch/amiga/dev/grf_ul.c
index 1ca64fdf12a..6e6c36401d7 100644
--- a/sys/arch/amiga/dev/grf_ul.c
+++ b/sys/arch/amiga/dev/grf_ul.c
@@ -1,4 +1,4 @@
-/* $NetBSD: grf_ul.c,v 1.7 1995/10/09 02:14:46 chopps Exp $ */
+/* $NetBSD: grf_ul.c,v 1.7.2.1 1995/11/10 19:29:54 chopps Exp $ */
#define UL_DEBUG
/*
@@ -53,7 +53,7 @@
#include <amiga/dev/grfvar.h>
#include <amiga/dev/grf_ulreg.h>
-#include <grf_ultmscode.h>
+extern u_int16_t tmscode[];
int ul_ioctl __P((struct grf_softc *, u_long, void *, dev_t));
int ul_getcmap __P((struct grf_softc *, struct grf_colormap *, dev_t));
@@ -81,12 +81,11 @@ struct grfvideo_mode ul_monitor_defs[] = {
/*
* Horizontal values are given in TMS units, that is, for the
* A2410 board, units of 16 pixels. The ioctl multiplies (when
- * exporting) or divides (when importing) them by 2 to conform to
- * the other grfs.
+ * exporting) or divides (when importing) them by 16 to conform to.
*
- * XXX This should have been in units of pixels, IMHO. If you change
- * this, you must also change amiga/stand/grfconfig/grfconfig.c,
- * grf_{rt,rh,cl}.c and egsgrfconfig (the latter to generate the
+ * XXX This used to be in units of 8 pixel times. We
+ * must also change amiga/stand/grfconfig/grfconfig.c,
+ * grf_{rt,rh,cl,cv}.c and egsgrfconfig (the latter to generate the
* horizontal timings in units of pixels instead of 8 pixels.
* You will also have to write warnings in BIG BOLD RED BLINKING
* LETTERS all over the docs, and still people will fry their monitors.
@@ -556,19 +555,11 @@ ul_getvmode (gp, vm)
vm->disp_height = md->disp_height;
vm->depth = md->depth;
- /* XXX should use 16 instead of 2, but others use 1 instead of 8 */
-
- /*
- * XXX another idea: maybe we should transform the timings to
- * have blank stop as point of reference (like other grfs) instead
- * of sync start?
- */
-
- vm->hblank_start = (md->hblank_start - md->hblank_stop) * 2;
- vm->hblank_stop = (md->htotal - 1) * 2;
- vm->hsync_start = (md->hsync_start - md->hblank_stop) * 2;
- vm->hsync_stop = (md->hsync_stop + md->htotal - md->hblank_stop) * 2;
- vm->htotal = md->htotal * 2;
+ vm->hblank_start = (md->hblank_start - md->hblank_stop) * 16;
+ vm->hblank_stop = (md->htotal - 1) * 16;
+ vm->hsync_start = (md->hsync_start - md->hblank_stop) * 16;
+ vm->hsync_stop = (md->hsync_stop + md->htotal - md->hblank_stop) * 16;
+ vm->htotal = md->htotal * 16;
vm->vblank_start = md->vblank_start - md->vblank_stop;
vm->vblank_stop = md->vtotal - 1;
diff --git a/sys/arch/amiga/dev/grf_ul.gsp b/sys/arch/amiga/dev/grf_ultms.g
index 502af7b3323..502af7b3323 100644
--- a/sys/arch/amiga/dev/grf_ul.gsp
+++ b/sys/arch/amiga/dev/grf_ultms.g
diff --git a/sys/arch/amiga/dev/if_qn.c b/sys/arch/amiga/dev/if_qn.c
index b4ad5e22efe..6f6de6be0fc 100644
--- a/sys/arch/amiga/dev/if_qn.c
+++ b/sys/arch/amiga/dev/if_qn.c
@@ -1,4 +1,4 @@
-/* $NetBSD: if_qn.c,v 1.1 1995/10/07 18:04:27 chopps Exp $ */
+/* $NetBSD: if_qn.c,v 1.1.2.1 1995/11/10 16:39:12 chopps Exp $ */
/*
* Copyright (c) 1995 Mika Kortelainen
@@ -35,7 +35,8 @@
* me with the necessary 'inside' information to write the driver.
*
* This is partly based on other code:
- * - if_ed.c: basic function structure for Ethernet driver
+ * - if_ed.c: basic function structure for Ethernet driver and now also
+ * qn_put() is done similarly, i.e. no extra packet buffers.
*
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
* adapters.
@@ -54,22 +55,27 @@
* Copyright (c) 1995 Michael L. Hitch
* All rights reserved.
*
+ * - if_fe.c: some ideas for error handling for qn_rint() which might
+ * have fixed those random lock ups, too.
+ *
+ * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
+ *
*
* TODO:
* - add multicast support
- * - try to find out what is the reason for random lock-ups happening
- * when (or after) getting data
*/
#include "qn.h"
#if NQN > 0
#define QN_DEBUG
+#define QN_DEBUG1_no /* hides some old tests */
#include "bpfilter.h"
/*
- * Fujitsu MB86950 Ethernet Controller (as used in QuickNet QN2000 Ethernet card)
+ * Fujitsu MB86950 Ethernet Controller (as used in the QuickNet QN2000
+ * Ethernet card)
*/
#include <sys/param.h>
@@ -108,10 +114,12 @@
#include <amiga/dev/if_qnreg.h>
-#define ETHER_MIN_LEN 64
-#define ETHER_MAX_LEN 1518
-#define ETHER_ADDR_LEN 6
-
+#define ETHER_MIN_LEN 60
+#define ETHER_MAX_LEN 1514
+#define ETHER_HDR_SIZE 14
+#define NIC_R_MASK (R_INT_PKT_RDY | R_INT_ALG_ERR |\
+ R_INT_CRC_ERR | R_INT_OVR_FLO)
+#define MAX_PACKETS 30 /* max number of packets read per interrupt */
/*
* Ethernet software status per interface
@@ -157,12 +165,17 @@ void qnreset __P((struct qn_softc *));
void qninit __P((struct qn_softc *));
void qnstop __P((struct qn_softc *));
static u_short qn_put __P((u_short volatile *, struct mbuf *));
+static void qn_rint __P((struct qn_softc *, u_short));
static void qn_flush __P((struct qn_softc *));
+#ifdef QN_DEBUG1
+static void qn_dump __P((struct qn_softc *));
+#endif
struct cfdriver qncd = {
NULL, "qn", qnmatch, qnattach, DV_IFNET, sizeof(struct qn_softc)
};
+
int
qnmatch(parent, match, aux)
struct device *parent;
@@ -261,20 +274,10 @@ qninit(sc)
{
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
u_short i;
- int s;
-
- s = splimp();
+ static retry = 0;
- /* Initialize NIC */
- *sc->nic_reset = DISABLE_DLC;
- *sc->nic_t_status = CLEAR_T_ERR;
- *sc->nic_t_mask = CLEAR_T_MASK;
- *sc->nic_r_status = CLEAR_R_ERR;
- *sc->nic_r_mask = R_INT_PKT_RDY;
- *sc->nic_t_mode = NO_LOOPBACK;
-
- /* Turn DMA off */
- *((u_short volatile *)(sc->sc_nic_base + NIC_BMPR4)) = (u_short)0x0000;
+ *sc->nic_r_mask = NIC_R_MASK;
+ *sc->nic_t_mode = NO_LOOPBACK;
if (sc->sc_arpcom.ac_if.if_flags & IFF_PROMISC) {
*sc->nic_r_mode = PROMISCUOUS_MODE;
@@ -284,27 +287,30 @@ qninit(sc)
/* Set physical ethernet address. */
for (i = 0; i < ETHER_ADDR_LEN; i++)
- *((u_short volatile *)(sc->sc_nic_base+QNET_HARDWARE_ADDRESS+2*i)) =
+ *((u_short volatile *)(sc->sc_nic_base+
+ QNET_HARDWARE_ADDRESS+2*i)) =
((((u_short)sc->sc_arpcom.ac_enaddr[i]) << 8) |
sc->sc_arpcom.ac_enaddr[i]);
- sc->transmit_pending = 0;
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
+ sc->transmit_pending = 0;
qn_flush(sc);
+ /* QuickNet magic. Done ONLY once, otherwise a lockup occurs. */
+ if (retry == 0) {
+ *((u_short volatile *)(sc->sc_nic_base + QNET_MAGIC)) = 0;
+ retry = 1;
+ }
+
/* Enable data link controller. */
- *((u_short volatile *)(sc->sc_nic_base + QNET_MAGIC)) = (u_short)0x0000;
*sc->nic_reset = ENABLE_DLC;
/* Attempt to start output, if any. */
qnstart(ifp);
-
- splx(s);
}
-
/*
* Device timeout/watchdog routine. Entered if the device neglects to
* generate an interrupt after a transmit has been started on it.
@@ -315,41 +321,35 @@ qnwatchdog(unit)
{
struct qn_softc *sc = qncd.cd_devs[unit];
- log(LOG_ERR, "%s: device timeout (watchdog)\n", sc->sc_dev.dv_xname);
+ log(LOG_INFO, "qn: device timeout (watchdog)\n");
++sc->sc_arpcom.ac_if.if_oerrors;
qnreset(sc);
}
-
/*
- * Flush card's buffer RAM
+ * Flush card's buffer RAM.
*/
static void
qn_flush(sc)
struct qn_softc *sc;
{
-#ifdef QN_DEBUG1
- int cnt = 0;
-#endif
+#if 1
/* Read data until bus read error (i.e. buffer empty). */
- while (!(*sc->nic_r_status & R_BUS_RD_ERR)) {
+ while (!(*sc->nic_r_status & R_BUS_RD_ERR))
(void)(*sc->nic_fifo);
-#ifdef QN_DEBUG1
- cnt++;
-#endif
- }
-#ifdef QN_DEBUG1
- log(LOG_INFO, "Flushed %d words\n", cnt);
+#else
+ /* Read data twice to clear some internal pipelines. */
+ (void)(*sc->nic_fifo);
+ (void)(*sc->nic_fifo);
#endif
/* Clear bus read error. */
*sc->nic_r_status = R_BUS_RD_ERR;
}
-
/*
- * Reset the interface...
+ * Reset the interface.
*
*/
void
@@ -364,9 +364,8 @@ qnreset(sc)
splx(s);
}
-
/*
- * Take interface offline
+ * Take interface offline.
*/
void
qnstop(sc)
@@ -374,15 +373,23 @@ qnstop(sc)
{
/* Stop the interface. */
- *sc->nic_reset = DISABLE_DLC;
+ *sc->nic_reset = DISABLE_DLC;
+ delay(200);
+ *sc->nic_t_status = CLEAR_T_ERR;
+ *sc->nic_t_mask = CLEAR_T_MASK;
+ *sc->nic_r_status = CLEAR_R_ERR;
+ *sc->nic_r_mask = CLEAR_R_MASK;
- *sc->nic_t_mask = CLEAR_T_MASK;
- *sc->nic_r_mask = CLEAR_R_MASK;
+ /* Turn DMA off */
+ *((u_short volatile *)(sc->sc_nic_base + NIC_BMPR4)) = 0;
+
+ /* Accept no packets. */
+ *sc->nic_r_mode = 0;
+ *sc->nic_t_mode = 0;
qn_flush(sc);
}
-
/*
* Start output on interface. Get another datagram to send
* off the interface queue, and copy it to the
@@ -398,10 +405,10 @@ qnstart(ifp)
struct qn_softc *sc = qncd.cd_devs[ifp->if_unit];
struct mbuf *m;
u_short len;
- int timout = 50000;
+ int timout = 60000;
+
- if ((sc->sc_arpcom.ac_if.if_flags & (IFF_RUNNING | IFF_OACTIVE)) !=
- IFF_RUNNING)
+ if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
return;
IF_DEQUEUE(&sc->sc_arpcom.ac_if.if_snd, m);
@@ -422,22 +429,26 @@ qnstart(ifp)
bpf_mtap(sc->sc_bpf, m);
#endif
len = qn_put(sc->nic_fifo, m);
+ m_freem(m);
/*
- * Really transmit the packet
+ * Really transmit the packet.
*/
- /* set packet length (byte-swapped) */
+ /* Set packet length (byte-swapped). */
len = ((len >> 8) & 0x0007) | TRANSMIT_START | ((len & 0x00ff) << 8);
*sc->nic_len = len;
- /* Wait for the packet to really leave */
- while (!(*sc->nic_t_status & T_TMT_OK) && --timout)
- ;
+ /* Wait for the packet to really leave. */
+ while (!(*sc->nic_t_status & T_TMT_OK) && --timout) {
+ if ((timout % 10000) == 0)
+ log(LOG_INFO, "qn: timout...\n");
+ }
+
if (timout == 0)
/* Maybe we should try to recover from this one? */
- /* But for now on, let's just fall thru and hope the best... */
- log(LOG_INFO, "qn:timout\n");
+ /* But now, let's just fall thru and hope the best... */
+ log(LOG_INFO, "qn: transmit timout (fatal?)\n");
sc->transmit_pending = 1;
*sc->nic_t_mask = INT_TMT_OK | INT_SIXTEEN_COL;
@@ -446,7 +457,6 @@ qnstart(ifp)
ifp->if_timer = 2;
}
-
/*
* Memory copy, copies word at a time
*/
@@ -472,7 +482,6 @@ word_copy_to_card(a, card, len)
*card = *a++;
}
-
/*
* Copy packet from mbuf to the board memory
*
@@ -485,53 +494,59 @@ qn_put(addr, m)
u_short volatile *addr;
struct mbuf *m;
{
- struct mbuf *mp;
- register u_short len, tlen;
- static u_short packet_buf[1536/2];
- register u_char *p;
+ u_char *data, savebyte[2];
+ int len, wantbyte;
+ u_short totlen;
+
+ totlen = wantbyte = 0;
+
+ for (; m != NULL; m = m->m_next) {
+ data = mtod(m, u_char *);
+ len = m->m_len;
+ totlen += len;
+ if (len > 0) {
+ /* Finish the last word. */
+ if (wantbyte) {
+ savebyte[1] = *data;
+ *addr = *((u_short *)savebyte);
+ data++;
+ len--;
+ wantbyte = 0;
+ }
+ /* Output contiguous words. */
+ if (len > 1) {
+ word_copy_to_card(data, addr, len);
+ data += len & ~1;
+ len &= 1;
+ }
+ /* Save last byte, if necessary. */
+ if (len == 1) {
+ savebyte[0] = *data;
+ wantbyte = 1;
+ }
+ }
+ }
- /*
- * If buffer is bzeroed, we might copy max(60, tlen) bytes and get
- * rid of extra zero fill-ins.
- */
- bzero(packet_buf, 1536);
+ if (wantbyte) {
+ savebyte[1] = 0;
+ *addr = *((u_short *)savebyte);
+ }
- /*
- * The whole packet in one mbuf?
- */
- if (m->m_next == NULL) {
- tlen = m->m_len;
- bcopy(mtod(m, u_char *), (u_char *)packet_buf, tlen);
- /*word_copy_to_card(mtod(m, u_short *), addr, tlen + 1);*/
- word_copy_to_card(packet_buf,
- addr,
- max(tlen + 1, ETHER_MIN_LEN-4));
- } else {
- /* No it wasn't, let's start copying */
- for (p = (u_char *)packet_buf, tlen = 0, mp = m;
- mp;
- mp = mp->m_next) {
- if ((len = mp->m_len) == 0)
- continue;
- tlen += len;
- bcopy(mtod(mp, u_char *), p, len);
- p += len;
- }
- /* word_copy_to_card(packet_buf, addr, tlen + 1); */
- word_copy_to_card(packet_buf,
- addr,
- max(tlen + 1, ETHER_MIN_LEN-4));
+ if(totlen < ETHER_MIN_LEN) {
+ /*
+ * Fill the rest of the packet with zeros.
+ * N.B.: This is required! Otherwise MB86950 fails.
+ */
+ for(len = totlen + 1; len < ETHER_MIN_LEN; len += 2)
+ *addr = (u_short)0x0000;
+ totlen = ETHER_MIN_LEN;
}
- m_freem(m);
- if (tlen < ETHER_MIN_LEN - 4)
- /* We have copied ETHER_MIN_LEN-4 bytes. */
- tlen = ETHER_MIN_LEN - 4;
- return (tlen);
+ return (totlen);
}
/*
- * Copy packet from board RAM
+ * Copy packet from board RAM.
*
* Trailers not supported.
*
@@ -543,15 +558,21 @@ qn_get_packet(sc, len)
{
register u_short volatile *nic_fifo_ptr = sc->nic_fifo;
struct ether_header *eh;
- struct mbuf *m, *dst, *head = 0;
+ struct mbuf *m, *dst, *head = NULL;
register u_short len1;
u_short amount;
/* Allocate header mbuf. */
MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == 0)
+ if (m == NULL)
goto bad;
+ /*
+ * Round len to even value.
+ */
+ if (len & 1)
+ len++;
+
m->m_pkthdr.rcvif = &sc->sc_arpcom.ac_if;
m->m_pkthdr.len = len;
m->m_len = 0;
@@ -571,10 +592,10 @@ qn_get_packet(sc, len)
amount = M_TRAILINGSPACE(m);
if (amount == 0) {
- /* allocate another mbuf */
+ /* Allocate another mbuf. */
dst = m;
MGET(m, M_DONTWAIT, MT_DATA);
- if (m == 0)
+ if (m == NULL)
goto bad;
if (len1 >= MINCLSIZE)
@@ -586,14 +607,12 @@ qn_get_packet(sc, len)
amount = M_TRAILINGSPACE(m);
}
- if (amount < len1) {
- if (amount & 1)
- log(LOG_INFO, "Room for odd-length packet\n");
+ if (amount < len1)
len1 = amount;
- }
+
word_copy_from_card(nic_fifo_ptr,
(u_short *)(mtod(m, caddr_t) + m->m_len),
- len1 + 1);
+ len1);
m->m_len += len1;
len -= len1;
}
@@ -624,94 +643,122 @@ qn_get_packet(sc, len)
return;
bad:
- if (head)
+ if (head) {
m_freem(head);
+ log(LOG_INFO, "qn_get_packet: mbuf alloc failed\n");
+ }
}
-
/*
* Ethernet interface receiver interrupt.
*/
static void
-qn_rint(sc)
+qn_rint(sc, rstat)
struct qn_softc *sc;
+ u_short rstat;
{
int i;
u_short len, status;
+ /* Clear the status register. */
+ *sc->nic_r_status = CLEAR_R_ERR;
+
/*
- * Read at most 25 packets per interrupt
+ * Was there some error?
+ * Some of them are senseless because they are masked off.
+ * XXX
*/
- for (i = 0; i < 25; i++) {
- if (*sc->nic_r_mode & RM_BUF_EMP) {
- /*
- * Buffer empty
- */
- if ((status = *sc->nic_r_status)) {
- /* It was some error: let's first clear
- * the register.
- */
- *sc->nic_r_status = CLEAR_R_ERR;
- if (status & 0x0101) {
+ if (rstat & 0x0101) {
#ifdef QN_DEBUG
- log(LOG_INFO, "Overflow\n");
+ log(LOG_INFO, "Overflow\n");
#endif
- ++sc->sc_arpcom.ac_if.if_ierrors;
- } else if (status & 0x0202) {
+ ++sc->sc_arpcom.ac_if.if_ierrors;
+ }
+ if (rstat & 0x0202) {
#ifdef QN_DEBUG
- log(LOG_INFO, "CRC Error\n");
+ log(LOG_INFO, "CRC Error\n");
#endif
- ++sc->sc_arpcom.ac_if.if_ierrors;
- } else if (status & 0x0404) {
+ ++sc->sc_arpcom.ac_if.if_ierrors;
+ }
+ if (rstat & 0x0404) {
#ifdef QN_DEBUG
- log(LOG_INFO, "Alignment error\n");
+ log(LOG_INFO, "Alignment error\n");
#endif
- ++sc->sc_arpcom.ac_if.if_ierrors;
- } else if (status & 0x0808) {
- /* Short packet (these may occur and are
- * no reason to worry about - or maybe
- * they are?).
- */
+ ++sc->sc_arpcom.ac_if.if_ierrors;
+ }
+ if (rstat & 0x0808) {
+ /* Short packet (these may occur and are
+ * no reason to worry about - or maybe
+ * they are?).
+ */
#ifdef QN_DEBUG
- log(LOG_INFO, "Short packet\n");
+ log(LOG_INFO, "Short packet\n");
#endif
- ++sc->sc_arpcom.ac_if.if_ierrors;
- /* qnreset(sc); */
- } else if (status & 0x4040) {
+ ++sc->sc_arpcom.ac_if.if_ierrors;
+ }
+ if (rstat & 0x4040) {
#ifdef QN_DEBUG
- log(LOG_INFO, "Bus read error\n");
+ log(LOG_INFO, "Bus read error\n");
#endif
- ++sc->sc_arpcom.ac_if.if_ierrors;
- } else {
- /* There are some registers which are
- * not meaningful when read, so don't
- * care...
- */
- }
- }
- return;
- } else {
- /* At least one valid packet. Clear the whole register. */
- *sc->nic_r_status = CLEAR_R_ERR;
+ ++sc->sc_arpcom.ac_if.if_ierrors;
+ qnreset(sc);
+ }
- /* Read one word of garbage. */
- (void)(*sc->nic_fifo);
+ /*
+ * Read at most MAX_PACKETS packets per interrupt
+ */
+ for (i = 0; i < MAX_PACKETS; i++) {
+ if (*sc->nic_r_mode & RM_BUF_EMP)
+ /* Buffer empty. */
+ break;
- /* Read packet length. */
- len = *sc->nic_fifo;
- len = ((len << 8) & 0xff00) | ((len >> 8) & 0x00ff);
+ /*
+ * Read the first word: upper byte contains useful
+ * information.
+ */
+ status = *sc->nic_fifo;
+ if ((status & 0x7000) != 0x2000) {
+ log(LOG_INFO, "qn: ERROR: status=%04x\n", status);
+ continue;
+ }
+
+ /*
+ * Read packet length (byte-swapped).
+ * CRC is stripped off by the NIC.
+ */
+ len = *sc->nic_fifo;
+ len = ((len << 8) & 0xff00) | ((len >> 8) & 0x00ff);
- /* Read the packet. */
- qn_get_packet(sc, len);
- ++sc->sc_arpcom.ac_if.if_ipackets;
+#ifdef QN_DEBUG
+ if (len > ETHER_MAX_LEN || len < ETHER_HDR_SIZE) {
+ log(LOG_WARNING,
+ "%s: received a %s packet? (%u bytes)\n",
+ sc->sc_dev.dv_xname,
+ len < ETHER_HDR_SIZE ? "partial" : "big", len);
+ ++sc->sc_arpcom.ac_if.if_ierrors;
+ continue;
}
+#endif
+#ifdef QN_DEBUG
+ if (len < ETHER_MIN_LEN)
+ log(LOG_WARNING,
+ "%s: received a short packet? (%u bytes)\n",
+ sc->sc_dev.dv_xname, len);
+#endif
+
+ /* Read the packet. */
+ qn_get_packet(sc, len);
+
+ ++sc->sc_arpcom.ac_if.if_ipackets;
}
- if (i == 25)
- log(LOG_INFO, "used all the 25 loops\n");
+#ifdef QN_DEBUG
+ /* This print just to see whether MAX_PACKETS is large enough. */
+ if (i == MAX_PACKETS)
+ log(LOG_INFO, "used all the %d loops\n", MAX_PACKETS);
+#endif
}
-
/*
* Our interrupt routine
*/
@@ -719,34 +766,36 @@ int
qnintr(sc)
struct qn_softc *sc;
{
- u_short tint, rint, tintmask, rintmask;
+ u_short tint, rint, tintmask;
+ char return_tintmask = 0;
/*
* If the driver has not been initialized, just return immediately.
* This also happens if there is no QuickNet board present.
*/
-
if (sc->sc_base == NULL)
return (0);
/* Get interrupt statuses and masks. */
- rint = *sc->nic_r_status;
- tint = *sc->nic_t_status;
- rintmask = *sc->nic_r_mask /* 0x8f8f */;
+ rint = (*sc->nic_r_status) & NIC_R_MASK;
tintmask = *sc->nic_t_mask;
- if (!(tint&tintmask) && !(rint&rintmask))
+ tint = (*sc->nic_t_status) & tintmask;
+ if (tint == 0 && rint == 0)
return (0);
- /* Disable receive interrupts so that we won't miss anything. */
+ /* Disable interrupts so that we won't miss anything. */
*sc->nic_r_mask = CLEAR_R_MASK;
+ *sc->nic_t_mask = CLEAR_T_MASK;
/*
* Handle transmitter interrupts. Some of them are not asked for
* but do happen, anyway.
*/
- if (tint) {
- *sc->nic_t_mask = CLEAR_T_MASK;
+
+ if (tint != 0) {
+ /* Clear transmit interrupt status. */
*sc->nic_t_status = CLEAR_T_ERR;
+
if (sc->transmit_pending && (tint & T_TMT_OK)) {
sc->transmit_pending = 0;
/*
@@ -761,55 +810,41 @@ qnintr(sc)
* 16 collision (i.e., packet lost).
*/
log(LOG_INFO, "qn: 16 collision - packet lost\n");
+#ifdef QN_DEBUG1
+ qn_dump(sc);
+#endif
sc->sc_arpcom.ac_if.if_oerrors++;
sc->sc_arpcom.ac_if.if_collisions += 16;
sc->transmit_pending = 0;
}
- if (tint & T_COL && !(tint & T_TMT_OK)) {
- /*
- * Normal collision
- */
- log(LOG_INFO, "qn:collision (shouldn't hurt)\n");
- sc->transmit_pending = 1;
- sc->sc_arpcom.ac_if.if_oerrors++;
- sc->sc_arpcom.ac_if.if_collisions++;
- }
-
- if (tint & BUS_WRITE_ERROR) {
- /* One bus write error occurs at start up, at least on my
- * card. So I don't care about this one.
- */
- sc->transmit_pending = 0;
- }
-
- if (tint & T_UNDERFLOW) {
- log(LOG_INFO, "qn:underflow\n");
- }
-
if (sc->transmit_pending) {
log(LOG_INFO, "qn:still pending...\n");
- /* Return transmission interrupt mask. */
- *sc->nic_t_mask = tintmask;
+
+ /* Must return transmission interrupt mask. */
+ return_tintmask = 1;
} else {
sc->sc_arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
/* Clear watchdog timer. */
sc->sc_arpcom.ac_if.if_timer = 0;
}
- }
+ } else
+ return_tintmask = 1;
/*
* Handle receiver interrupts.
*/
- if (rint & rintmask)
- qn_rint(sc);
-
- /* Set receive interrupt mask back. */
- *sc->nic_r_mask = rintmask;
+ if (rint != 0)
+ qn_rint(sc, rint);
if ((sc->sc_arpcom.ac_if.if_flags & IFF_OACTIVE) == 0)
qnstart(&sc->sc_arpcom.ac_if);
+ else if (return_tintmask == 1)
+ *sc->nic_t_mask = tintmask;
+
+ /* Set receive interrupt mask back. */
+ *sc->nic_r_mask = NIC_R_MASK;
return (1);
}
@@ -841,6 +876,7 @@ qnioctl(ifp, command, data)
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
+ qnstop(sc);
qninit(sc);
arp_ifinit(&sc->sc_arpcom, ifa);
break;
@@ -857,41 +893,46 @@ qnioctl(ifp, command, data)
bcopy(ina->x_host.c_host,
sc->sc_arpcom.ac_enaddr,
sizeof(sc->sc_arpcom.ac_enaddr));
+ qnstop(sc);
qninit(sc);
break;
}
#endif
default:
log(LOG_INFO, "qn:sa_family:default (not tested)\n");
+ qnstop(sc);
qninit(sc);
break;
}
break;
case SIOCSIFFLAGS:
- /*
- * If interface is marked down and it is running, then stop it.
- */
if ((ifp->if_flags & IFF_UP) == 0 &&
(ifp->if_flags & IFF_RUNNING) != 0) {
/*
* If interface is marked down and it is running, then
* stop it.
*/
+#ifdef QN_DEBUG1
+ qn_dump(sc);
+#endif
qnstop(sc);
ifp->if_flags &= ~IFF_RUNNING;
} else if ((ifp->if_flags & IFF_UP) != 0 &&
- (ifp->if_flags & IFF_RUNNING) == 0)
+ (ifp->if_flags & IFF_RUNNING) == 0) {
/*
* If interface is marked up and it is stopped, then
* start it.
*/
qninit(sc);
- else {
+ } else {
/*
* Something else... we won't do anything so we won't
* break anything (hope so).
*/
+#ifdef QN_DEBUG1
+ log(LOG_INFO, "Else branch...\n");
+#endif
}
break;
@@ -921,8 +962,28 @@ qnioctl(ifp, command, data)
error = EINVAL;
}
- (void)splx(s);
+ splx(s);
return (error);
}
+/*
+ * Dump some register information.
+ */
+#ifdef QN_DEBUG1
+static void
+qn_dump(sc)
+ struct qn_softc *sc;
+{
+
+ log(LOG_INFO, "t_status : %04x\n", *sc->nic_t_status);
+ log(LOG_INFO, "t_mask : %04x\n", *sc->nic_t_mask);
+ log(LOG_INFO, "t_mode : %04x\n", *sc->nic_t_mode);
+ log(LOG_INFO, "r_status : %04x\n", *sc->nic_r_status);
+ log(LOG_INFO, "r_mask : %04x\n", *sc->nic_r_mask);
+ log(LOG_INFO, "r_mode : %04x\n", *sc->nic_r_mode);
+ log(LOG_INFO, "pending : %02x\n", sc->transmit_pending);
+ log(LOG_INFO, "if_flags : %04x\n", sc->sc_arpcom.ac_if.if_flags);
+}
+#endif
+
#endif /* NQN > 0 */
diff --git a/sys/arch/amiga/dev/if_qnreg.h b/sys/arch/amiga/dev/if_qnreg.h
index 57f42866377..2094db7d925 100644
--- a/sys/arch/amiga/dev/if_qnreg.h
+++ b/sys/arch/amiga/dev/if_qnreg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: if_qnreg.h,v 1.1 1995/10/07 18:04:31 chopps Exp $ */
+/* $NetBSD: if_qnreg.h,v 1.1.2.1 1995/11/10 16:39:14 chopps Exp $ */
/*
* Copyright (c) 1995 Mika Kortelainen
@@ -94,6 +94,10 @@
#define CLEAR_R_ERR 0xcfcf /* Clear receive errors */
/* DLCR3 - Receive Interrupt Masks */
+#define R_INT_OVR_FLO 0x0101 /* Receive buf overflow */
+#define R_INT_CRC_ERR 0x0202 /* CRC error */
+#define R_INT_ALG_ERR 0x0404 /* Alignment error */
+#define R_INT_SRT_PKT 0x0808 /* Short packet */
#define R_INT_PKT_RDY 0x8080 /* Packet ready */
#define CLEAR_R_MASK 0x0000 /* Clear receive intr masks */
@@ -101,7 +105,7 @@
#define NO_LOOPBACK 0x0202 /* Loopback control */
/* DLCR5 - Receive Mode */
-/* Accept physical address, multicast group addresses
+/* Normal mode: accept physical address, multicast group addresses
* which match the 1st three bytes and broadcast address.
*/
#define NORMAL_MODE 0x0101