Subject: Changes to .../dev/ic/am7990*
To: None <tech-kern@NetBSD.ORG>
From: Leo Weppelman <leo@wau.mis.ah.nl>
List: tech-kern
Date: 03/07/1997 22:02:39
I have some changes I like to commit to the generic am7990 code living
in .../dev/ic/ . The changes are necessary (I think) to produce a
properly working frontend for the atari VME Lance cards. The changes
are small and without any side effects that I could see (I'm unable
to try it out however).

1. An extra sc_isr field to am7990_softc.

    On the atari, the card is usually hard-wired to irq-5. Without
changes this would force splnet() to become >= tty-hardware-interrupt.
This would break the serial driver throughput. So, I've broken the lance
interrupt handler into 2 pieces. The hardware-interrupt function
fetches the CSR0 register value, saves it into 'sc_isr' and turns off
the card interrupt (INEA-bit). The latter is necessary because the
card keeps interrupting until the interrupt is really served. Thereafter
the hw-interrupt schedules a software interrupt, that just calls
the am7990_intr() function. This function is changed to 'or' in the
'sc_isr' bits in the copy of CSR0 it uses.
On ports that don't use this 2-level sceme, the or-ed in value is
always zero.

2. Changed semantics of sc_rbufaddr/sc_tbufaddr - am7990_softc

    These fields no longer contain an offset to the first read (or
write) buffer. They are changed to hold an array of offsets to
those buffers. The virtue is that the buffers are no longer required
to be contiguous. This is a big win because someone decided that
the (Riebl) cards available on the atari have their config area in
the middle of the RAM-space. With the array of offsets, I am able
to drape the buffers around this config area.

I'm not aware of breaking anything with these changes. If someone
thinks otherwise or thinks it can be done better, please let me
know.

Leo.


--- am7990.c.org	Thu Mar  6 22:48:27 1997
+++ am7990.c	Thu Mar  6 22:50:49 1997
@@ -143,7 +143,7 @@
 am7990_config(sc)
 	struct am7990_softc *sc;
 {
-	int mem;
+	int mem, i;
 
 	/* Make sure the chip is stopped. */
 	am7990_stop(sc);
@@ -200,6 +200,8 @@
 	sc->sc_sh = shutdownhook_establish(am7990_shutdown, sc);
 	if (sc->sc_sh == NULL)
 		panic("am7990_config: can't establish shutdownhook");
+	sc->sc_rbufaddr = malloc(sc->sc_nrbuf * sizeof(int), M_DEVBUF,M_WAITOK);
+	sc->sc_tbufaddr = malloc(sc->sc_ntbuf * sizeof(int), M_DEVBUF,M_WAITOK);
 
 	mem = 0;
 	sc->sc_initaddr = mem;
@@ -208,10 +210,10 @@
 	mem += sizeof(struct lermd) * sc->sc_nrbuf;
 	sc->sc_tmdaddr = mem;
 	mem += sizeof(struct letmd) * sc->sc_ntbuf;
-	sc->sc_rbufaddr = mem;
-	mem += LEBLEN * sc->sc_nrbuf;
-	sc->sc_tbufaddr = mem;
-	mem += LEBLEN * sc->sc_ntbuf;
+	for (i = 0; i < sc->sc_nrbuf; i++, mem += LEBLEN)
+		sc->sc_rbufaddr[i] = mem;
+	for (i = 0; i < sc->sc_ntbuf; i++, mem += LEBLEN)
+		sc->sc_tbufaddr[i] = mem;
 #ifdef notyet
 	if (mem > ...)
 		panic(...);
@@ -677,7 +679,8 @@
 	register struct am7990_softc *sc = arg;
 	register u_int16_t isr;
 
-	isr = (*sc->sc_rdcsr)(sc, LE_CSR0);
+	isr = (*sc->sc_rdcsr)(sc, LE_CSR0) | sc->sc_isr;
+	sc->sc_isr = 0;
 #ifdef LEDEBUG
 	if (sc->sc_debug)
 		printf("%s: am7990_intr entering with isr=%04x\n",
--- am7990reg.h.org	Thu Mar  6 22:48:29 1997
+++ am7990reg.h	Thu Mar  6 22:48:28 1997
@@ -91,8 +91,8 @@
 #define	LE_INITADDR(sc)		(sc->sc_initaddr)
 #define	LE_RMDADDR(sc, bix)	(sc->sc_rmdaddr + sizeof(struct lermd) * (bix))
 #define	LE_TMDADDR(sc, bix)	(sc->sc_tmdaddr + sizeof(struct letmd) * (bix))
-#define	LE_RBUFADDR(sc, bix)	(sc->sc_rbufaddr + LEBLEN * (bix))
-#define	LE_TBUFADDR(sc, bix)	(sc->sc_tbufaddr + LEBLEN * (bix))
+#define	LE_RBUFADDR(sc, bix)	(sc->sc_rbufaddr[bix])
+#define	LE_TBUFADDR(sc, bix)	(sc->sc_tbufaddr[bix])
 
 /* register addresses */
 #define	LE_CSR0		0x0000		/* Control and status register */
--- am7990var.h.org	Thu Mar  6 22:48:38 1997
+++ am7990var.h	Fri Mar  7 22:25:08 1997
@@ -89,7 +89,7 @@
 	void	*sc_sh;		/* shutdownhook cookie */
 
 	u_int16_t sc_conf3;	/* CSR3 value */
-	u_int16_t sc_pad1;	/* be nice to m68k ports */
+	u_int16_t sc_isr;	/* Value of csr0 at time of interrupt */
 
 	void	*sc_mem;	/* base address of RAM -- CPU's view */
 	u_long	sc_addr;	/* base address of RAM -- LANCE's view */
@@ -104,8 +104,8 @@
 	int	sc_initaddr;
 	int	sc_rmdaddr;
 	int	sc_tmdaddr;
-	int	sc_rbufaddr;
-	int	sc_tbufaddr;
+	int	*sc_rbufaddr;
+	int	*sc_tbufaddr;
 
 #ifdef LEDEBUG
 	int	sc_debug;