⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_dp.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 2 页
字号:
		m = m0;		dpstat.nohdr++;	}	if (len < 2)		goto out;	if (len > DP_MTU) {		error = EINVAL;		goto out;	}	dppdma[2*unit].p_mem = cp = dp->dp_obuf;	while (m) {		struct mbuf *n;		bcopy(mtod(m, caddr_t), (caddr_t)cp, m->m_len);		cp += m->m_len;		MFREE(m, n); m = n;	}	dppdma[2*unit].p_end = cp - 1;	dp->dp_if.if_flags |= IFF_OACTIVE;	dp->dp_ostate = DPS_ACTIVE;	dp->dp_if.if_collisions--;	dp->dp_olen = len;	if (dp_log) {		register u_char *p = (u_char *)dp->dp_obuf;		log(LOG_DEBUG, "dpoutput(%d):%x %x %x %x %x\n",			len, p[0], p[1], p[2], p[3], p[4]);	}	addr->dpsar = DP_SSLM | DP_IDLE;	addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;	addr->dpclr = DP_XIE | DP_XE | dp_ilb;	addr->dptdsr = DP_XSM;out:	return (error);}/* * Receive done or error interrupt */dprint(unit, pdma, addr)register struct pdma *pdma;register struct dpdevice *addr;{	register struct dp_softc *dp = &dp_softc[unit];	short rdsr = addr->dprdsr, rcsr = pdma->p_arg;	dpstat.rint++;	splx(dp->dp_ipl);	if (rdsr & DP_RGA) {		/* DP_ATA = 0, DP_CHRM = 0, DP_SSLM = 1, (enable aborts),			    CRC = CCIIT, initially all ones, 2nd addr = 0 */		addr->dpsar = DP_SSLM | DP_IDLE;		addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;		dpstat.rga++;		return;	}	if (rdsr & DP_RSM) { /* Received Start of Message */		dpstat.rsm++;		pdma->p_mem = dp->dp_ibuf;		if (rcsr & DP_RDR) {		    dp->dp_ibuf[0] = rdsr & DP_RBUF;		    pdma->p_mem++;		}		dp->dp_flags &= ~DPF_FLUSH;		return;	}	if (rdsr & DP_REM) { /* Received End of Message */		dpstat.rem++;		if (rcsr & DP_RDR) {		    *(pdma->p_mem++) = rdsr;		    dpstat.remchr++;		}		dp->dp_ilen = pdma->p_mem - dp->dp_ibuf;		if (rdsr & DP_REC || dp->dp_flags & DPF_FLUSH) {			dp->dp_if.if_ierrors++;		} else			dpinput(&dp->dp_if, dp->dp_ilen, dp->dp_ibuf);		pdma->p_mem = pdma->p_end;		dp->dp_flags &= ~ DPF_FLUSH;		return;	}	if (rdsr & DP_ROVR) {		dpstat.rovr++;		dp->dp_flags |= DPF_FLUSH;		return;	}	if (rcsr & DP_MSC) {		dpstat.mchange++;		if (0 == (rcsr & DP_DSR)) {			log(LOG_DEBUG, "dp%d: lost modem\n", unit);			/*dpdown(unit);*/		}		return;	}	dp->dp_flags |= DPF_FLUSH;	if (pdma->p_mem != pdma->p_end)		log(LOG_DEBUG, "dp%d: unexplained receiver interrupt\n", unit);}/* * Transmit complete or error interrupt */dpxint(unit, pdma, addr)register struct pdma *pdma;register struct dpdevice *addr;{	register struct dp_softc *dp = &dp_softc[unit];	int s;	splx(dp->dp_ipl);	dpstat.xint++;	if (addr->dptdsr & DP_XERR) {		log(LOG_DEBUG, "if_dp%d: data late\n", unit);	restart:		pdma->p_mem = dp->dp_obuf;		addr->dptdsr = DP_XSM;		dp->dp_if.if_oerrors++;		return;	}	switch (dp->dp_ostate) {	case DPS_ACTIVE:		if (pdma->p_mem != pdma->p_end) {			log(LOG_DEBUG, "if_dp%d: misc error in dpxint\n", unit);			goto restart;		}		addr->dpsar = DP_IDLE|DP_SSLM;		addr->dpclr = DP_XE | DP_XIE | dp_ilb;		addr->dptdsr = DP_XEM | (0xff & pdma->p_mem[0]);		addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR | DP_RTS;		dp->dp_ostate = DPS_XEM;		break;	case DPS_XEM:		dpstat.xem++;		dp->dp_if.if_opackets++;		dp->dp_ostate = DPS_IDLE;		dp->dp_if.if_flags &= ~IFF_OACTIVE;		if (dp->dp_if.if_snd.ifq_len)			dpstart(&dp->dp_if);		else {			addr->dpsar = DP_IDLE|DP_SSLM;			addr->dpclr = DP_XE | dp_ilb;			addr->dptdsr = DP_XSM;			addr->dprcsr = DP_RIE | DP_MIE | DP_RE | DP_DTR|DP_RTS;		}		break;	default:		log(LOG_DEBUG, "if_dp%d: impossible state in dpxint\n");	}}dpinput(ifp, len, buffer)register struct ifnet *ifp;caddr_t buffer;{	register struct ifqueue *inq;	register struct mbuf *m;	extern struct ifqueue hdintrq, ipintrq;	int isr;	extern struct mbuf *m_devget();	ifp->if_ipackets++;	if (dp_log) {		register u_char *p = (u_char *)buffer;		log(LOG_DEBUG, "dpinput(%d):%x %x %x %x %x\n",			len, p[0], p[1], p[2], p[3], p[4]);	}	    {	register struct ifaddr *ifa = ifp->if_addrlist;	register u_char *cp = (u_char *)buffer;	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)		if (ifa->ifa_addr->sa_family != AF_LINK)			break;	if (cp[0] == 0xff && cp[1] == 0x3) {		/* This is a UI HDLC Packet, so we'll assume PPP		   protocol.  for now, IP only. */		buffer += 4;		len -= 4;		inq = &ipintrq;		isr = NETISR_IP;	} else {		inq = &hdintrq;		isr = NETISR_CCITT;	}    }	if (len <= 0)		return;	m = m_devget(buffer, len , 0, ifp, 0);	if (m == 0)		return;	if(IF_QFULL(inq)) {		IF_DROP(inq);		m_freem(m);	} else {		IF_ENQUEUE(inq, m);		schednetisr(isr);	}}/* * Process an ioctl request. */dpioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t data;{	register struct ifaddr *ifa = (struct ifaddr *)data;	int s = splimp(), error = 0;	struct dp_softc *dp = &dp_softc[ifp->if_unit];	dpstat.ioctl++;	switch (cmd) {	case SIOCSIFCONF_X25:		ifp->if_flags |= IFF_UP;		error = hd_ctlinput(PRC_IFUP, ifa->ifa_addr);		if (error == 0)			dpinit(ifp->if_unit);		break;	case SIOCSIFADDR:		ifa->ifa_rtrequest = x25_rtrequest;		break;	case SIOCSIFFLAGS:		if ((ifp->if_flags & IFF_UP) == 0 &&		    (ifp->if_flags & IFF_RUNNING))			dpdown(ifp->if_unit);		else if (ifp->if_flags & IFF_UP &&		    (ifp->if_flags & IFF_RUNNING) == 0)			dpinit(ifp->if_unit);		break;	default:		error = EINVAL;	}	splx(s);	return (error);}/* * Reset a device and mark down. * Flush output queue and drop queue limit. */dpdown(unit)int unit;{	register struct dp_softc *dp = &dp_softc[unit];	register struct dpdevice *addr = dp->dp_addr;	dpstat.down++;	if_qflush(&dp->dp_if.if_snd);	dp->dp_flags = 0;	dp->dp_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);	addr->dpclr = DP_CLR;	DELAY(1000);	addr->dpsar = 0;	addr->dprcsr = 0;}/* * Watchdog timeout to see that transmitted packets don't * lose interrupts.  The device has to be online (the first * transmission may block until the other side comes up). */dptimeout(unit)	int unit;{	register struct dp_softc *dp;	/* currently not armed */	dpstat.timeout++;	dp = &dp_softc[unit];	if (dp->dp_if.if_flags & IFF_OACTIVE) {		dpstart(&dp->dp_if);	}}/* * For debugging loopback activity. */static char pppheader[4] = { -1, 3, 0, 0x21 };int dp_louts;dptestoutput(ifp, m, dst, rt)register struct ifnet *ifp;register struct mbuf *m;struct sockaddr *dst;struct rtentry *rt;{	/*	 * Queue message on interface, and start output if interface	 * not yet active.	 */	int s = splimp(), error = 0;	dp_louts++;	M_PREPEND(m, sizeof pppheader, M_DONTWAIT);	if (m == 0) {		splx(s);		return ENOBUFS;	}	bcopy(pppheader, mtod(m, caddr_t), sizeof pppheader);	if (IF_QFULL(&ifp->if_snd)) {		IF_DROP(&ifp->if_snd);	    /* printf("%s%d: HDLC says OK to send but queue full, may hang\n",			ifp->if_name, ifp->if_unit);*/		m_freem(m);		error = ENOBUFS;	} else {		IF_ENQUEUE(&ifp->if_snd, m);		if ((ifp->if_flags & IFF_OACTIVE) == 0)			(*ifp->if_start)(ifp);	}	splx(s);	return (error);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -