Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 25 Apr 2003 13:31:36 -0700 (PDT)
From:      John Baldwin <jhb@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 29719 for review
Message-ID:  <200304252031.h3PKVaUZ099428@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=29719

Change 29719 by jhb@jhb_laptop on 2003/04/25 13:31:22

	IFC @29718 (proc locking).

Affected files ...

.. //depot/projects/smpng/sys/alpha/alpha/sys_machdep.c#15 integrate
.. //depot/projects/smpng/sys/alpha/osf1/osf1_misc.c#21 integrate
.. //depot/projects/smpng/sys/alpha/osf1/osf1_signal.c#18 integrate
.. //depot/projects/smpng/sys/compat/linux/linux_signal.c#12 integrate
.. //depot/projects/smpng/sys/dev/en/midway.c#10 integrate
.. //depot/projects/smpng/sys/dev/en/midwayreg.h#2 integrate
.. //depot/projects/smpng/sys/dev/en/midwayvar.h#4 integrate
.. //depot/projects/smpng/sys/geom/bde/g_bde_work.c#7 integrate
.. //depot/projects/smpng/sys/i386/i386/sys_machdep.c#27 integrate
.. //depot/projects/smpng/sys/ia64/ia64/sys_machdep.c#4 integrate
.. //depot/projects/smpng/sys/kern/kern_ktrace.c#30 integrate
.. //depot/projects/smpng/sys/kern/kern_prot.c#68 integrate
.. //depot/projects/smpng/sys/kern/kern_sig.c#63 integrate
.. //depot/projects/smpng/sys/kern/sys_process.c#28 integrate
.. //depot/projects/smpng/sys/modules/Makefile#50 integrate
.. //depot/projects/smpng/sys/modules/en/Makefile#1 branch
.. //depot/projects/smpng/sys/pci/if_en_pci.c#4 integrate
.. //depot/projects/smpng/sys/powerpc/powerpc/sys_machdep.c#4 integrate
.. //depot/projects/smpng/sys/sparc64/sparc64/sys_machdep.c#9 integrate
.. //depot/projects/smpng/sys/vm/vm_glue.c#25 integrate
.. //depot/user/jhb/proc/kern/kern_sig.c#66 edit

Differences ...

==== //depot/projects/smpng/sys/alpha/alpha/sys_machdep.c#15 (text+ko) ====

@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	from: @(#)sys_machdep.c	5.5 (Berkeley) 1/19/91
- * $FreeBSD: src/sys/alpha/alpha/sys_machdep.c,v 1.23 2003/04/18 18:06:32 jhb Exp $
+ * $FreeBSD: src/sys/alpha/alpha/sys_machdep.c,v 1.24 2003/04/25 20:04:02 jhb Exp $
  *
  */
 
@@ -77,7 +77,7 @@
 	struct thread *td;
 	register struct sysarch_args *uap;
 {
-	int error = 0;
+	int error;
 
 	switch(uap->op) {
 	case ALPHA_SETHAE:

==== //depot/projects/smpng/sys/alpha/osf1/osf1_misc.c#21 (text+ko) ====

@@ -29,7 +29,7 @@
 
 /*
  * Additional Copyright (c) 1999 by Andrew Gallatin
- * $FreeBSD: src/sys/alpha/osf1/osf1_misc.c,v 1.40 2003/02/19 05:46:56 imp Exp $
+ * $FreeBSD: src/sys/alpha/osf1/osf1_misc.c,v 1.41 2003/04/25 19:51:41 jhb Exp $
  */
 
 
@@ -1781,6 +1781,9 @@
 }
 
 
+/*
+ * MPSAFE
+ */
 int
 osf1_sysinfo(td, uap)
 	struct thread *td;
@@ -1804,8 +1807,10 @@
 		len = uap->count;
 		name[0] = CTL_KERN;
 		name[1] = KERN_HOSTNAME;
+		mtx_lock(&Giant);
 		retval = userland_sysctl(td, name, 2, uap->buf, &len,
 					1, 0, 0, &bytes);
+		mtx_unlock(&Giant);
 		td->td_retval[0] =  bytes;
 		return(retval);
 		break;

==== //depot/projects/smpng/sys/alpha/osf1/osf1_signal.c#18 (text+ko) ====

@@ -30,7 +30,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/alpha/osf1/osf1_signal.c,v 1.30 2003/04/22 18:23:47 jhb Exp $
+ * $FreeBSD: src/sys/alpha/osf1/osf1_signal.c,v 1.31 2003/04/25 19:52:30 jhb Exp $
  */
 
 #include "opt_compat.h"
@@ -572,6 +572,7 @@
 
 	p = td->td_proc;
 	scp = uap->sigcntxp;
+	mtx_lock(&Giant);
 	if (useracc((caddr_t)scp, sizeof (*scp), VM_PROT_READ) == 0 ) {
 		uprintf("uac fails\n");
 		uprintf("scp: %p\n", scp);
@@ -581,8 +582,11 @@
 	 * We grab it all at once for speed.
 	 */
 	if (useracc((caddr_t)scp, sizeof (*scp), VM_PROT_READ) == 0 ||
-	    copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc))
+	    copyin((caddr_t)scp, (caddr_t)&ksc, sizeof ksc)) {
+		mtx_unlock(&Giant);
 		return (EFAULT);
+	}
+	mtx_unlock(&Giant);
 
 	/*
 	 * Restore the user-supplied information.

==== //depot/projects/smpng/sys/compat/linux/linux_signal.c#12 (text+ko) ====

@@ -25,7 +25,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/compat/linux/linux_signal.c,v 1.42 2003/04/22 18:23:47 jhb Exp $
+ * $FreeBSD: src/sys/compat/linux/linux_signal.c,v 1.43 2003/04/25 19:26:18 jhb Exp $
  */
 
 #include <sys/param.h>
@@ -233,14 +233,25 @@
 
 	td->td_retval[0] = 0;
 
+	switch (how) {
+	case LINUX_SIG_BLOCK:
+		how = SIG_BLOCK;
+		break;
+	case LINUX_SIG_UNBLOCK:
+		how = SIG_UNBLOCK;
+		break;
+	case LINUX_SIG_SETMASK:
+		how = SIG_SETMASK;
+		break;
+	default:
+		return (EINVAL);
+	}
 	if (new != NULL) {
 		linux_to_bsd_sigset(new, &nmask);
 		nmaskp = &nmask;
 	} else
 		nmaskp = NULL;
-
-	/* Linux sigprocmask flag values are one less than FreeBSD values. */
-	error = kern_sigprocmask(td, how + 1, nmaskp, &omask, 0);
+	error = kern_sigprocmask(td, how, nmaskp, &omask, 0);
 	if (error != 0 && old != NULL)
 		bsd_to_linux_sigset(&omask, old);
 

==== //depot/projects/smpng/sys/dev/en/midway.c#10 (text+ko) ====

@@ -32,7 +32,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/en/midway.c,v 1.36 2003/03/12 10:28:26 kjc Exp $
+ * $FreeBSD: src/sys/dev/en/midway.c,v 1.37 2003/04/25 16:14:03 harti Exp $
  */
 
 /*
@@ -49,25 +49,11 @@
  *   generally helpful.
  */
 
-#undef	EN_DEBUG
-#undef	EN_DEBUG_RANGE		/* check ranges on en_read/en_write's? */
-#define	EN_MBUF_OPT		/* try and put more stuff in mbuf? */
 #define	EN_DIAG
-#define	EN_STAT
-#ifndef EN_DMA
-#define EN_DMA		1	/* use dma? */
-#endif
-#define EN_NOTXDMA	0	/* hook to disable tx dma only */
-#define EN_NORXDMA	0	/* hook to disable rx dma only */
 #define EN_DDBHOOK	1	/* compile in ddb functions */
-#if defined(MIDWAY_ADPONLY)
-#define EN_ENIDMAFIX	0	/* no ENI cards to worry about */
-#else
-#define EN_ENIDMAFIX	1	/* avoid byte DMA on the ENI card (see below) */
-#endif
 
 /*
- * note on EN_ENIDMAFIX: the byte aligner on the ENI version of the card
+ * Note on EN_ENIDMAFIX: the byte aligner on the ENI version of the card
  * appears to be broken.   it works just fine if there is no load... however
  * when the card is loaded the data get corrupted.   to see this, one only
  * has to use "telnet" over ATM.   do the following command in "telnet":
@@ -91,48 +77,68 @@
 #if defined(DIAGNOSTIC) && !defined(EN_DIAG)
 #define EN_DIAG			/* link in with master DIAG option */
 #endif
-#ifdef EN_STAT
+
 #define EN_COUNT(X) (X)++
-#else
-#define EN_COUNT(X) /* nothing */
-#endif
 
 #ifdef EN_DEBUG
+
 #undef	EN_DDBHOOK
 #define	EN_DDBHOOK	1
-#define STATIC /* nothing */
-#define INLINE /* nothing */
+
+/*
+ * This macro removes almost all the EN_DEBUG conditionals in the code that make
+ * to code a good deal less readable.
+ */
+#define DBG(SC, FL, PRINT) do {						\
+	if ((SC)->debug & DBG_##FL) {					\
+		if_printf(&(SC)->enif, "%s: "#FL": ", __func__);	\
+		printf PRINT;						\
+		printf("\n");						\
+	}								\
+    } while (0)
+
+enum {
+	DBG_INIT	= 0x0001,	/* debug attach/detach */
+	DBG_TX		= 0x0002,	/* debug transmitting */
+	DBG_SERV	= 0x0004,	/* debug service interrupts */
+	DBG_IOCTL	= 0x0008,	/* debug ioctls */
+	DBG_VC		= 0x0010,	/* debug VC handling */
+	DBG_INTR	= 0x0020,	/* debug interrupts */
+	DBG_DMA		= 0x0040,	/* debug DMA probing */
+	DBG_IPACKETS	= 0x0080,	/* print input packets */
+	DBG_REG		= 0x0100,	/* print all register access */
+	DBG_LOCK	= 0x0200,	/* debug locking */
+};
+
 #else /* EN_DEBUG */
-#define STATIC static
-#define INLINE __inline
+
+#define DBG(SC, FL, PRINT) do { } while (0)
+
 #endif /* EN_DEBUG */
 
-#ifdef __FreeBSD__
 #include "opt_inet.h"
 #include "opt_natm.h"
 #include "opt_ddb.h"
-/* enable DDBHOOK when DDB is available */
+
+#ifdef DDB
 #undef	EN_DDBHOOK
-#ifdef DDB
 #define	EN_DDBHOOK	1
 #endif
-#endif
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/queue.h>
-#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__)
-#include <sys/device.h>
-#endif
 #include <sys/sockio.h>
+#include <sys/socket.h>
 #include <sys/mbuf.h>
-#include <sys/socket.h>
+#include <sys/endian.h>
+#include <sys/sbuf.h>
+#include <sys/stdint.h>
+#include <vm/uma.h>
 
 #include <net/if.h>
 #include <net/if_atm.h>
 
-#include <vm/vm.h>
-
 #if defined(INET) || defined(INET6)
 #include <netinet/in.h>
 #include <netinet/if_atm.h>
@@ -142,115 +148,45 @@
 #include <netnatm/natm.h>
 #endif
 
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#include <machine/bus.h>
-#include <dev/ic/midwayreg.h>
-#include <dev/ic/midwayvar.h>
-#elif defined(__FreeBSD__)
 #include <sys/bus.h>
 #include <machine/bus.h>
 #include <sys/rman.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+#include <sys/malloc.h>
 #include <machine/resource.h>
 #include <dev/en/midwayreg.h>
 #include <dev/en/midwayvar.h>
-#include <vm/pmap.h>			/* for vtophys proto */
 
-#ifndef IFF_NOTRAILERS
-#define IFF_NOTRAILERS 0
-#endif
-
-#endif	/* __FreeBSD__ */
-
-#if defined(__alpha__)
-/* XXX XXX NEED REAL DMA MAPPING SUPPORT XXX XXX */
-#undef vtophys
-#define	vtophys(va)	alpha_XXX_dmamap((vm_offset_t)(va))
-#endif
-
-#ifdef __FreeBSD__
-#define NBPF 1
-#else
-#include "bpf.h"
-#endif
-#if NBPF > 0
 #include <net/bpf.h>
-#ifdef __FreeBSD__
-#define BPFATTACH(ifp, dlt, hlen)	bpfattach((ifp), (dlt), (hlen))
-#else
-#define BPFATTACH(ifp, dlt, hlen)	bpfattach(&(ifp)->if_bpf, (ifp), (dlt), (hlen))
-#define BPF_MTAP(ifp, m)		bpf_mtap((ifp)->if_bpf, (m))
-#endif
-#endif /* NBPF > 0 */
 
 /*
  * params
  */
-
 #ifndef EN_TXHIWAT
-#define EN_TXHIWAT	(64*1024)	/* max 64 KB waiting to be DMAd out */
+#define EN_TXHIWAT	(64 * 1024)	/* max 64 KB waiting to be DMAd out */
 #endif
 
-#ifndef EN_MINDMA
-#define EN_MINDMA	32	/* don't DMA anything less than this (bytes) */
-#endif
-
-#define RX_NONE		0xffff	/* recv VC not in use */
-
-#define EN_OBHDR	ATM_PH_DRIVER7  /* TBD in first mbuf ! */
-#define EN_OBTRL	ATM_PH_DRIVER8  /* PDU trailier in last mbuf ! */
+#define RX_NONE		0xffff		/* recv VC not in use */
 
 #define ENOTHER_FREE	0x01		/* free rxslot */
 #define ENOTHER_DRAIN	0x02		/* almost free (drain DRQ dma) */
-#define ENOTHER_RAW	0x04		/* 'raw' access  (aka boodi mode) */
 #define ENOTHER_SWSL	0x08		/* in software service list */
 
-static int en_dma = EN_DMA;		/* use DMA (switch off for dbg) */
-
-#ifndef __FreeBSD__
-/*
- * autoconfig attachments
- */
+SYSCTL_NODE(_hw, OID_AUTO, en, CTLFLAG_RW, 0, "ENI 155p");
 
-struct cfdriver en_cd = {
-    0, "en", DV_IFNET,
-};
-#endif
-
 /*
- * local structures
- */
-
-/*
- * params to en_txlaunch() function
- */
-
-struct en_launch {
-  u_int32_t tbd1;		/* TBD 1 */
-  u_int32_t tbd2;		/* TBD 2 */
-  u_int32_t pdu1;		/* PDU 1 (aal5) */
-  int nodma;			/* don't use DMA */
-  int need;			/* total space we need (pad out if less data) */
-  int mlen;			/* length of mbuf (for dtq) */
-  struct mbuf *t;		/* data */
-  u_int32_t aal;		/* aal code */
-  u_int32_t atm_vci;		/* vci */
-  u_int8_t atm_flags;		/* flags */
-};
-
-
-/*
- * dma table (index by # of words)
+ * dma tables
  *
- * plan A: use WMAYBE (obsolete)
- * plan B: avoid WMAYBE
+ * The plan is indexed by the number of words to transfer.
+ * The maximum index is 15 for 60 words.
  */
-
 struct en_dmatab {
-  u_int8_t bcode;		/* code */
-  u_int8_t divshift;		/* byte divisor */
+	uint8_t bcode;		/* code */
+	uint8_t divshift;	/* byte divisor */
 };
 
-static struct en_dmatab en_dma_planB[] = {
+static const struct en_dmatab en_dmaplan[] = {
   { 0, 0 },		/* 0 */		{ MIDDMA_WORD, 2},	/* 1 */
   { MIDDMA_2WORD, 3},	/* 2 */		{ MIDDMA_WORD, 2},	/* 3 */
   { MIDDMA_4WORD, 4},	/* 4 */		{ MIDDMA_WORD, 2},	/* 5 */
@@ -259,2882 +195,2733 @@
   { MIDDMA_2WORD, 3},	/* 10 */	{ MIDDMA_WORD, 2},	/* 11 */
   { MIDDMA_4WORD, 4},	/* 12 */	{ MIDDMA_WORD, 2},	/* 13 */
   { MIDDMA_2WORD, 3},	/* 14 */	{ MIDDMA_WORD, 2},	/* 15 */
-  { MIDDMA_16WORD, 6},  /* 16 */
+  { MIDDMA_16WORD,6},	/* 16 */
 };
 
-static struct en_dmatab *en_dmaplan = en_dma_planB;
-
 /*
  * prototypes
  */
-
-STATIC INLINE	int en_b2sz(int) __attribute__ ((unused));
 #ifdef EN_DDBHOOK
-		int en_dump(int,int);
-		int en_dumpmem(int,int,int);
+int en_dump(int unit, int level);
+int en_dumpmem(int,int,int);
 #endif
-STATIC		void en_dmaprobe(struct en_softc *);
-STATIC		int en_dmaprobe_doit(struct en_softc *, u_int8_t *, 
-		    u_int8_t *, int);
-STATIC INLINE	int en_dqneed(struct en_softc *, caddr_t, u_int,
-		    u_int) __attribute__ ((unused));
-STATIC		void en_init(struct en_softc *);
-STATIC		int en_ioctl(struct ifnet *, EN_IOCTL_CMDT, caddr_t);
-STATIC INLINE	int en_k2sz(int) __attribute__ ((unused));
-STATIC		void en_loadvc(struct en_softc *, int);
-STATIC		int en_mfix(struct en_softc *, struct mbuf **, struct mbuf *);
-STATIC INLINE	struct mbuf *en_mget(struct en_softc *, u_int,
-		    u_int *) __attribute__ ((unused));
-STATIC INLINE	u_int32_t en_read(struct en_softc *,
-		    u_int32_t) __attribute__ ((unused));
-STATIC		int en_rxctl(struct en_softc *, struct atm_pseudoioctl *, int);
-STATIC		void en_txdma(struct en_softc *, int);
-STATIC		void en_txlaunch(struct en_softc *, int,
-		    struct en_launch *);
-STATIC		void en_service(struct en_softc *);
-STATIC		void en_start(struct ifnet *);
-STATIC INLINE	int en_sz2b(int) __attribute__ ((unused));
-STATIC INLINE	void en_write(struct en_softc *, u_int32_t,
-		    u_int32_t) __attribute__ ((unused));
 
-/*
- * macros/inline
- */
+#define EN_LOCK(SC)	do {				\
+	DBG(SC, LOCK, ("ENLOCK %d\n", __LINE__));	\
+	mtx_lock(&sc->en_mtx);				\
+    } while (0)
+#define EN_UNLOCK(SC)	do {				\
+	DBG(SC, LOCK, ("ENUNLOCK %d\n", __LINE__));	\
+	mtx_unlock(&sc->en_mtx);			\
+    } while (0)
 
 /*
- * raw read/write macros
+ * While a transmit mbuf is waiting to get transmit DMA resources we
+ * need to keep some information with it. We don't want to allocate
+ * additional memory for this so we stuff it into free fields in the
+ * mbuf packet header. Neither the checksum fields nor the rcvif field are used
+ * so use these.
  */
+#define TX_AAL5		0x1	/* transmit AAL5 PDU */
+#define TX_HAS_TBD	0x2	/* TBD did fit into mbuf */
+#define TX_HAS_PAD	0x4	/* padding did fit into mbuf */
+#define TX_HAS_PDU	0x8	/* PDU trailer did fit into mbuf */
 
-#define EN_READDAT(SC,R) en_read(SC,R)
-#define EN_WRITEDAT(SC,R,V) en_write(SC,R,V)
+#define MBUF_SET_TX(M, VCI, FLAGS, DATALEN, PAD, MAP) do {		\
+	(M)->m_pkthdr.csum_data = (VCI) | ((FLAGS) << MID_VCI_BITS);	\
+	(M)->m_pkthdr.csum_flags = ((DATALEN) & 0xffff) |		\
+	    ((PAD & 0x3f) << 16);					\
+	(M)->m_pkthdr.rcvif = (void *)(MAP);				\
+    } while (0)
 
-/*
- * cooked read/write macros
- */
+#define MBUF_GET_TX(M, VCI, FLAGS, DATALEN, PAD, MAP) do {		\
+	(VCI) = (M)->m_pkthdr.csum_data & ((1 << MID_VCI_BITS) - 1);	\
+	(FLAGS) = ((M)->m_pkthdr.csum_data >> MID_VCI_BITS) & 0xf;	\
+	(DATALEN) = (M)->m_pkthdr.csum_flags & 0xffff;			\
+	(PAD) = ((M)->m_pkthdr.csum_flags >> 16) & 0x3f;		\
+	(MAP) = (void *)((M)->m_pkthdr.rcvif);				\
+    } while (0)
 
-#define EN_READ(SC,R) (u_int32_t)ntohl(en_read(SC,R))
-#define EN_WRITE(SC,R,V) en_write(SC,R, htonl(V))
 
-#define EN_WRAPADD(START,STOP,CUR,VAL) { \
-	(CUR) = (CUR) + (VAL); \
-	if ((CUR) >= (STOP)) \
-		(CUR) = (START) + ((CUR) - (STOP)); \
-	}
+#define EN_WRAPADD(START, STOP, CUR, VAL) do {			\
+	(CUR) = (CUR) + (VAL);					\
+	if ((CUR) >= (STOP))					\
+		(CUR) = (START) + ((CUR) - (STOP));		\
+    } while (0)
 
-#define WORD_IDX(START, X) (((X) - (START)) / sizeof(u_int32_t))
+#define WORD_IDX(START, X) (((X) - (START)) / sizeof(uint32_t))
 
-/* we store sc->dtq and sc->drq data in the following format... */
-#define EN_DQ_MK(SLOT,LEN) (((SLOT) << 20)|(LEN)|(0x80000))
-					/* the 0x80000 ensures we != 0 */
-#define EN_DQ_SLOT(X) ((X) >> 20)
-#define EN_DQ_LEN(X) ((X) & 0x3ffff)
-
-/* format of DTQ/DRQ word 1 differs between ENI and ADP */
-#if defined(MIDWAY_ENIONLY)
-
-#define MID_MK_TXQ(SC,CNT,CHAN,END,BCODE) \
-	EN_WRITE((SC), (SC)->dtq_us, \
-		MID_MK_TXQ_ENI((CNT), (CHAN), (END), (BCODE))); 
-
-#define MID_MK_RXQ(SC,CNT,VCI,END,BCODE) \
-	EN_WRITE((SC), (SC)->drq_us, \
-		MID_MK_RXQ_ENI((CNT), (VCI), (END), (BCODE))); 
-
-#elif defined(MIDWAY_ADPONLY)
-
-#define MID_MK_TXQ(SC,CNT,CHAN,END,JK) \
-	EN_WRITE((SC), (SC)->dtq_us, \
-		MID_MK_TXQ_ADP((CNT), (CHAN), (END), (JK))); 
-
-#define MID_MK_RXQ(SC,CNT,VCI,END,JK) \
-	EN_WRITE((SC), (SC)->drq_us, \
-		MID_MK_RXQ_ADP((CNT), (VCI), (END), (JK))); 
-
-#else
-
-#define MID_MK_TXQ(SC,CNT,CHAN,END,JK_OR_BCODE) { \
-	if ((SC)->is_adaptec) \
-	  EN_WRITE((SC), (SC)->dtq_us, \
-		  MID_MK_TXQ_ADP((CNT), (CHAN), (END), (JK_OR_BCODE))); \
-	else \
-	  EN_WRITE((SC), (SC)->dtq_us, \
-		  MID_MK_TXQ_ENI((CNT), (CHAN), (END), (JK_OR_BCODE))); \
-	}
+#define SETQ_END(SC, VAL) ((SC)->is_adaptec ?			\
+	((VAL) | (MID_DMA_END >> 4)) :				\
+	((VAL) | (MID_DMA_END)))
 
-#define MID_MK_RXQ(SC,CNT,VCI,END,JK_OR_BCODE) { \
-	if ((SC)->is_adaptec) \
-	  EN_WRITE((SC), (SC)->drq_us, \
-		  MID_MK_RXQ_ADP((CNT), (VCI), (END), (JK_OR_BCODE))); \
-	else \
-	  EN_WRITE((SC), (SC)->drq_us, \
-		   MID_MK_RXQ_ENI((CNT), (VCI), (END), (JK_OR_BCODE))); \
-	}
-
-#endif
-
-/* add an item to the DTQ */
-#define EN_DTQADD(SC,CNT,CHAN,JK_OR_BCODE,ADDR,LEN,END) { \
-	if (END) \
-	  (SC)->dtq[MID_DTQ_A2REG((SC)->dtq_us)] = EN_DQ_MK(CHAN,LEN); \
-	MID_MK_TXQ(SC,CNT,CHAN,END,JK_OR_BCODE); \
-	(SC)->dtq_us += 4; \
-	EN_WRITE((SC), (SC)->dtq_us, (ADDR)); \
-	EN_WRAPADD(MID_DTQOFF, MID_DTQEND, (SC)->dtq_us, 4); \
-	(SC)->dtq_free--; \
-	if (END) \
-	  EN_WRITE((SC), MID_DMA_WRTX, MID_DTQ_A2REG((SC)->dtq_us)); \
-}
-
-/* DRQ add macro */
-#define EN_DRQADD(SC,CNT,VCI,JK_OR_BCODE,ADDR,LEN,SLOT,END) { \
-	if (END) \
-	  (SC)->drq[MID_DRQ_A2REG((SC)->drq_us)] = EN_DQ_MK(SLOT,LEN); \
-	MID_MK_RXQ(SC,CNT,VCI,END,JK_OR_BCODE); \
-	(SC)->drq_us += 4; \
-	EN_WRITE((SC), (SC)->drq_us, (ADDR)); \
-	EN_WRAPADD(MID_DRQOFF, MID_DRQEND, (SC)->drq_us, 4); \
-	(SC)->drq_free--; \
-	if (END) \
-	  EN_WRITE((SC), MID_DMA_WRRX, MID_DRQ_A2REG((SC)->drq_us)); \
-}
-
 /*
- * the driver code
+ * The dtq and drq members are set for each END entry in the corresponding
+ * card queue entry. It is used to find out, when a buffer has been
+ * finished DMAing and can be freed.
  *
- * the code is arranged in a specific way:
- * [1] short/inline functions
- * [2] autoconfig stuff
- * [3] ioctl stuff
- * [4] reset -> init -> trasmit -> intr -> receive functions
- *
+ * We store sc->dtq and sc->drq data in the following format...
+ * the 0x80000 ensures we != 0
  */
+#define EN_DQ_MK(SLOT, LEN)	(((SLOT) << 20) | (LEN) | (0x80000))
+#define EN_DQ_SLOT(X)		((X) >> 20)
+#define EN_DQ_LEN(X)		((X) & 0x3ffff)
 
 /***********************************************************************/
 
 /*
- * en_read: read a word from the card.   this is the only function
- * that reads from the card.
+ * en_read{x}: read a word from the card. These are the only functions
+ * that read from the card.
  */
+static __inline uint32_t
+en_readx(struct en_softc *sc, uint32_t r)
+{
+	uint32_t v;
 
-STATIC INLINE u_int32_t en_read(sc, r)
+#ifdef EN_DIAG
+	if (r > MID_MAXOFF || (r % 4))
+		panic("en_read out of range, r=0x%x", r);
+#endif
+	v = bus_space_read_4(sc->en_memt, sc->en_base, r);
+	return (v);
+}
 
-struct en_softc *sc;
-u_int32_t r;
-
+static __inline uint32_t
+en_read(struct en_softc *sc, uint32_t r)
 {
+	uint32_t v;
 
-#ifdef EN_DEBUG_RANGE
-  if (r > MID_MAXOFF || (r % 4))
-    panic("en_read out of range, r=0x%x", r);
+#ifdef EN_DIAG
+	if (r > MID_MAXOFF || (r % 4))
+		panic("en_read out of range, r=0x%x", r);
 #endif
-
-  return(bus_space_read_4(sc->en_memt, sc->en_base, r));
+	v = bus_space_read_4(sc->en_memt, sc->en_base, r);
+	DBG(sc, REG, ("en_read(%#x) -> %08x", r, v));
+	return (v);
 }
 
 /*
- * en_write: write a word to the card.   this is the only function that
+ * en_write: write a word to the card. This is the only function that
  * writes to the card.
  */
-
-STATIC INLINE void en_write(sc, r, v)
-
-struct en_softc *sc;
-u_int32_t r, v;
-
+static __inline void
+en_write(struct en_softc *sc, uint32_t r, uint32_t v)
 {
-#ifdef EN_DEBUG_RANGE
-  if (r > MID_MAXOFF || (r % 4))
-    panic("en_write out of range, r=0x%x", r);
+#ifdef EN_DIAG
+	if (r > MID_MAXOFF || (r % 4))
+		panic("en_write out of range, r=0x%x", r);
 #endif
-
-  bus_space_write_4(sc->en_memt, sc->en_base, r, v);
+	DBG(sc, REG, ("en_write(%#x) <- %08x", r, v));
+	bus_space_write_4(sc->en_memt, sc->en_base, r, v);
 }
 
 /*
  * en_k2sz: convert KBytes to a size parameter (a log2)
  */
-
-STATIC INLINE int en_k2sz(k)
-
-int k;
-
+static __inline int
+en_k2sz(int k)
 {
-  switch(k) {
-    case 1:   return(0);
-    case 2:   return(1);
-    case 4:   return(2);
-    case 8:   return(3);
-    case 16:  return(4);
-    case 32:  return(5);
-    case 64:  return(6);
-    case 128: return(7);
-    default: panic("en_k2sz");
-  }
-  return(0);
+	switch(k) {
+	  case 1:   return (0);
+	  case 2:   return (1);
+	  case 4:   return (2);
+	  case 8:   return (3);
+	  case 16:  return (4);
+	  case 32:  return (5);
+	  case 64:  return (6);
+	  case 128: return (7);
+	  default:
+		panic("en_k2sz");
+	}
+	return (0);
 }
 #define en_log2(X) en_k2sz(X)
 
-
 /*
  * en_b2sz: convert a DMA burst code to its byte size
  */
-
-STATIC INLINE int en_b2sz(b)
-
-int b;
-
+static __inline int
+en_b2sz(int b)
 {
-  switch (b) {
-    case MIDDMA_WORD:   return(1*4);
-    case MIDDMA_2WMAYBE:
-    case MIDDMA_2WORD:  return(2*4);
-    case MIDDMA_4WMAYBE:
-    case MIDDMA_4WORD:  return(4*4);
-    case MIDDMA_8WMAYBE:
-    case MIDDMA_8WORD:  return(8*4);
-    case MIDDMA_16WMAYBE:
-    case MIDDMA_16WORD: return(16*4);
-    default: panic("en_b2sz");
-  }
-  return(0);
+	switch (b) {
+	  case MIDDMA_WORD:   return (1*4);
+	  case MIDDMA_2WMAYBE:
+	  case MIDDMA_2WORD:  return (2*4);
+	  case MIDDMA_4WMAYBE:
+	  case MIDDMA_4WORD:  return (4*4);
+	  case MIDDMA_8WMAYBE:
+	  case MIDDMA_8WORD:  return (8*4);
+	  case MIDDMA_16WMAYBE:
+	  case MIDDMA_16WORD: return (16*4);
+	  default:
+		panic("en_b2sz");
+	}
+	return (0);
 }
 
-
 /*
  * en_sz2b: convert a burst size (bytes) to DMA burst code
  */
-
-STATIC INLINE int en_sz2b(sz)
-
-int sz;
-
+static __inline int
+en_sz2b(int sz)
 {
-  switch (sz) {
-    case 1*4:  return(MIDDMA_WORD);
-    case 2*4:  return(MIDDMA_2WORD);
-    case 4*4:  return(MIDDMA_4WORD);
-    case 8*4:  return(MIDDMA_8WORD);
-    case 16*4: return(MIDDMA_16WORD);
-    default: panic("en_sz2b");
-  }
-  return(0);
+	switch (sz) {
+	  case 1*4:  return (MIDDMA_WORD);
+	  case 2*4:  return (MIDDMA_2WORD);
+	  case 4*4:  return (MIDDMA_4WORD);
+	  case 8*4:  return (MIDDMA_8WORD);
+	  case 16*4: return (MIDDMA_16WORD);
+	  default:
+		panic("en_sz2b");
+	}
+	return(0);
 }
 
-
+#ifdef EN_DEBUG
 /*
- * en_dqneed: calculate number of DTQ/DRQ's needed for a buffer
+ * Dump a packet
  */
-
-STATIC INLINE int en_dqneed(sc, data, len, tx)
-
-struct en_softc *sc;
-caddr_t data;
-u_int len, tx;
-
+static void
+en_dump_packet(struct en_softc *sc, struct mbuf *m)
 {
-  int result, needalign, sz;
+	int plen = m->m_pkthdr.len;
+	u_int pos = 0;
+	u_int totlen = 0;
+	int len;
+	u_char *ptr;
 
-#if !defined(MIDWAY_ENIONLY)
-#if !defined(MIDWAY_ADPONLY)
-    if (sc->is_adaptec)
-#endif /* !MIDWAY_ADPONLY */
-      return(1);	/* adaptec can DMA anything in one go */
+	if_printf(&sc->enif, "packet len=%d", plen);
+	while (m != NULL) {
+		totlen += m->m_len;
+		ptr = mtod(m, u_char *);
+		for (len = 0; len < m->m_len; len++, pos++, ptr++) {
+			if (pos % 16 == 8)
+				printf(" ");
+			if (pos % 16 == 0)
+				printf("\n");
+			printf(" %02x", *ptr);
+		}
+		m = m->m_next;
+	}
+	printf("\n");
+	if (totlen != plen);
+		printf("sum of m_len=%u\n", totlen);
+}
 #endif
-    
-#if !defined(MIDWAY_ADPONLY)
-    result = 0;
-    if (len < EN_MINDMA) {
-      if (!tx)			/* XXX: conservative */
-        return(1);		/* will copy/DMA_JK */
-    }
 
-    if (tx) {			/* byte burst? */
-      needalign = (((uintptr_t) (void *) data) % sizeof(u_int32_t));
-      if (needalign) {
-        result++;
-        sz = min(len, sizeof(u_int32_t) - needalign);
-        len -= sz;
-        data += sz;
-      }
-    }
+/*********************************************************************/
+/*
+ * DMA maps
+ */
 
-    if (sc->alburst && len) {
-      needalign = (((uintptr_t) (void *) data) & sc->bestburstmask);
-      if (needalign) {
-	result++;		/* alburst */
-        sz = min(len, sc->bestburstlen - needalign);
-        len -= sz;
-      }
-    }
+/*
+ * Map constructor for a MAP.
+ *
+ * This is called each time when a map is allocated
+ * from the pool and about to be returned to the user. Here we actually
+ * allocate the map if there isn't one. The problem is that we may fail
+ * to allocate the DMA map yet have no means to signal this error. Therefor
+ * when allocating a map, the call must check that there is a map. An
+ * additional problem is, that i386 maps will be NULL, yet are ok and must
+ * be freed so let's use a flag to signal allocation.
+ *
+ * Caveat: we have no way to know that we are called from an interrupt context
+ * here. We rely on the fact, that bus_dmamap_create uses M_NOWAIT in all
+ * its allocations.
+ *
+ * LOCK: any, not needed
+ */
+static void
+en_map_ctor(void *mem, int size, void *arg)
+{
+	struct en_softc *sc = arg;
+	struct en_map *map = mem;
+	int err;
 
-    if (len >= sc->bestburstlen) {
-      sz = len / sc->bestburstlen;
-      sz = sz * sc->bestburstlen;
-      len -= sz;
-      result++;			/* best shot */
-    }
-    
-    if (len) {
-      result++;			/* clean up */
-      if (tx && (len % sizeof(u_int32_t)) != 0)
-        result++;		/* byte cleanup */
-    }
+	if (map->sc == NULL)
+		map->sc = sc;
 
-    return(result);
-#endif	/* !MIDWAY_ADPONLY */
+	if (!(map->flags & ENMAP_ALLOC)) {
+		err = bus_dmamap_create(sc->txtag, 0, &map->map);
+		if (err != 0)
+			if_printf(&sc->enif, "cannot create DMA map %d\n", err);
+		else
+			map->flags |= ENMAP_ALLOC;
+	}
+	map->flags &= ~ENMAP_LOADED;
 }
 
-
 /*
- * en_mget: get an mbuf chain that can hold totlen bytes and return it
- * (for recv)   [based on am7990_get from if_le and ieget from if_ie]
- * after this call the sum of all the m_len's in the chain will be totlen.
+ * Map destructor.
+ *
+ * Called when a map is disposed into the zone. If the map is loaded, unload
+ * it.
+ *
+ * LOCK: any, not needed
  */
+static void
+en_map_dtor(void *mem, int size, void *arg)
+{
+	struct en_map *map = mem;
 
-STATIC INLINE struct mbuf *en_mget(sc, totlen, drqneed)
+	if (map->flags & ENMAP_LOADED) {
+		bus_dmamap_unload(map->sc->txtag, map->map);
+		map->flags &= ~ENMAP_LOADED;
+	}
+}
 
-struct en_softc *sc;
-u_int totlen, *drqneed;
-
+/*
+ * Map finializer.
+ *
+ * This is called each time a map is returned from the zone to the system.
+ * Get rid of the dmamap here.
+ *
+ * LOCK: any, not needed
+ */
+static void
+en_map_fini(void *mem, int size)
 {
-  struct mbuf *m;
-  struct mbuf *top, **mp;
-  *drqneed = 0;
+	struct en_map *map = mem;
 
-  MGETHDR(m, M_DONTWAIT, MT_DATA);
-  if (m == NULL)
-    return(NULL);
-  m->m_pkthdr.rcvif = &sc->enif;
-  m->m_pkthdr.len = totlen;
-  m->m_len = MHLEN;
-  top = NULL;
-  mp = &top;
-  
-  /* if (top != NULL) then we've already got 1 mbuf on the chain */
-  while (totlen > 0) {
-    if (top) {
-      MGET(m, M_DONTWAIT, MT_DATA);
-      if (!m) {
-	m_freem(top);	
-	return(NULL);	/* out of mbufs */
-      }
-      m->m_len = MLEN;
-    }
-    if (totlen >= MINCLSIZE) {
-      MCLGET(m, M_DONTWAIT);
-      if ((m->m_flags & M_EXT) == 0) {
-	m_free(m);
-	m_freem(top);
-	return(NULL);	  /* out of mbuf clusters */
-      }
-      m->m_len = MCLBYTES;
-    }
-    m->m_len = min(totlen, m->m_len);
-    totlen -= m->m_len;
-    *mp = m;

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304252031.h3PKVaUZ099428>