From owner-p4-projects@FreeBSD.ORG Fri Apr 25 13:31:41 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4B07737B404; Fri, 25 Apr 2003 13:31:40 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id ED18837B401 for ; Fri, 25 Apr 2003 13:31:39 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id E757B43FDF for ; Fri, 25 Apr 2003 13:31:38 -0700 (PDT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h3PKVc0U099457 for ; Fri, 25 Apr 2003 13:31:38 -0700 (PDT) (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h3PKVaUZ099428 for perforce@freebsd.org; Fri, 25 Apr 2003 13:31:36 -0700 (PDT) Date: Fri, 25 Apr 2003 13:31:36 -0700 (PDT) Message-Id: <200304252031.h3PKVaUZ099428@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Subject: PERFORCE change 29719 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Apr 2003 20:31:41 -0000 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 @@ -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 #include #include -#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) -#include -#endif #include +#include #include -#include +#include +#include +#include +#include #include #include -#include - #if defined(INET) || defined(INET6) #include #include @@ -142,115 +148,45 @@ #include #endif -#if defined(__NetBSD__) || defined(__OpenBSD__) -#include -#include -#include -#elif defined(__FreeBSD__) #include #include #include +#include +#include +#include #include #include #include -#include /* 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 -#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) <<<