PERFORCE change 29719 for review
John Baldwin
jhb at FreeBSD.org
Fri Apr 25 13:31:41 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=29719
Change 29719 by jhb at 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 = ⊤
-
- /* 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) <<<
More information about the p4-projects
mailing list