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

📄 if_dmv.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
			}			if ((sc->sc_flag & (DMV_ALLOC | DMV_BMAPPED)) == (DMV_ALLOC | DMV_BMAPPED) && ( sc->sc_flag & DMV_RESTART) == 0 ) {				sc->sc_flag |= DMV_RESTART;				dmvrestart(sc->sc_if.if_unit);			}			break;		case DMV_PRC_BUF:			printdmverr("dmv%d: buffer too small\n", sc->sc_if.if_unit);			sc->sc_if.if_ierrors++;			sc->sc_dmvcs.if_dstate = IFS_HALTING;			sc->sc_if.if_flags &= ~IFF_UP;			dmv_issue_ctl( sc, DMV_TRIB_POINT, 0, DMV_CNTL_RQHALT );			break;		case DMV_ERR_RXTHRES:			printdmverr("dmv%d: receive threshold reported\n", sc->sc_if.if_unit);			sc->sc_if.if_oerrors++;			sc->sc_dmvcs.if_dstate = IFS_HALTING;			sc->sc_if.if_flags &= ~IFF_UP;			dmv_issue_ctl( sc, DMV_TRIB_POINT, 0, DMV_CNTL_RQHALT );			break;		case DMV_ERR_TXTHRES:			printdmverr("dmv%d: transmit threshold reached\n", sc->sc_if.if_unit);			goto dmv_rsp_cntl_txtimeo;		case DMV_ERR_SETHRES:			printdmverr("dmv%d: select threshold reached\n", sc->sc_if.if_unit);			goto dmv_rsp_cntl_txtimeo;		case DMV_ERR_BABBLE:			printdmverr("dmv%d: babbling tributary reported\n", sc->sc_if.if_unit);			goto dmv_rsp_cntl_txtimeo;		case DMV_ERR_STREAM:			printdmverr("dmv%d: streaming tributary reported\n", sc->sc_if.if_unit);		dmv_rsp_cntl_txtimeo:			sc->sc_timeo++;			sc->sc_dmvcs.if_dstate = IFS_HALTING;			sc->sc_if.if_flags &= ~IFF_UP;			dmv_issue_ctl( sc, DMV_TRIB_POINT, 0, DMV_CNTL_RQHALT );			break;			case DMV_EVT_RXMNT_RU:			printf("dmv%d: MOP mode entered while DDCMP was running\n", sc->sc_if.if_unit);			sc->sc_dmvcs.if_dstate = IFS_ENTEREDMOP;			sc->sc_if.if_flags &= ~IFF_UP;			dmv_issue_ctl( sc, DMV_TRIB_POINT, 0, DMV_CNTL_RQHALT );			break;		case DMV_EVT_RXMNT_HA:			printf("dmv%d: MOP mode entered while device was halted\n", sc->sc_if.if_unit);			sc->sc_dmvcs.if_dstate = IFS_ENTEREDMOP;			sc->sc_dmvcs.if_ustate = IFS_USROFF;			if ( sc->sc_if.if_addr.sa_family != AF_UNSPEC ) {				if ((pr=iffamily_to_proto(sc->sc_if.if_addr.sa_family)) && pr->pr_ifstate ) 					(*pr->pr_ifstate)(&sc->sc_if, sc->sc_dmvcs.if_dstate, &sc->sc_dmvcs); 			}			sc->sc_dmvcs.if_dstate = IFS_HALTING;			sc->sc_if.if_flags &= ~IFF_UP;			dmv_issue_ctl( sc, DMV_TRIB_POINT, 0, DMV_CNTL_RQHALT );			break;		case DMV_EVT_RXSTRT_MA:			break;		case DMV_EVT_RXSTRT_RU:			printf("dmv%d: received start while DDCMP running\n", sc->sc_if.if_unit);			sc->sc_dmvcs.if_dstate = IFS_HALTING;			break;		case DMV_EVT_DDCMPRUN:			/*			 * Inform owner that device is up.			 */			printd("dmv%d: device is up\n", sc->sc_if.if_unit);			sc->sc_if.if_flags |= IFF_UP;			sc->sc_dmvcs.if_dstate = IFS_RUNNING;			sc->sc_dmverrmsg = 0;			if ( sc->sc_if.if_addr.sa_family != AF_UNSPEC ) {				if ((pr=iffamily_to_proto(sc->sc_if.if_addr.sa_family)) && pr->pr_ifstate ) 					(*pr->pr_ifstate)(&sc->sc_if, sc->sc_dmvcs.if_dstate, &sc->sc_dmvcs); 			}			break;		case DMV_PRC_NXM:			printf("dmv%d: non existent memory reported\n", sc->sc_if.if_unit);			goto dmv_rsp_cntl_harderr;		case DMV_EVT_QOVF:			printf("dmv%d: device queue overflow reported\n", sc->sc_if.if_unit);			goto dmv_rsp_cntl_harderr;		case DMV_PRC_INVMODE:			printf("dmv%d: device mode being overridden with an invalid value\n", sc->sc_if.if_unit);			break;		default:			printd("dmv%d: procedure error (0%o) reported\n", sc->sc_if.if_unit, rsp->qp_ctl);		dmv_rsp_cntl_harderr:			if ((sc->sc_flag & (DMV_ALLOC | DMV_BMAPPED)) == (DMV_ALLOC | DMV_BMAPPED) && ( sc->sc_flag & DMV_RESTART) == 0 ) {				sc->sc_flag |= DMV_RESTART;				sc->sc_if.if_flags &= ~IFF_UP;				sc->sc_dmvcs.if_dstate = IFS_HALTING;				dmvrestart(sc->sc_if.if_unit);			}			break;	}	return;}/* * DMV counter formatter routine. * This routine stores the counter information in the softc structure. */dmv_format_tgss(sc, rsp)register struct dmv_softc *sc;register struct dmv_command *rsp;{	switch ( rsp->qp_ctl & KEY_MASK )	{		case DMV_KEY_SELINT:			sc->sc_errctrs.ctr_ddcmp.dst_select = (rsp->qp_data > 0377 ) ? 0377 : rsp->qp_cntlo;			sc->sc_ctrmask |= DMV_MSK_SELINT;			break;		case DMV_KEY_DEOUT:			sc->sc_errctrs.ctr_ddcmp.dst_outbound = rsp->qp_cntlo;			sc->sc_errctrs.ctr_ddcmp.dst_outbound_bm = rsp->qp_cnthi & 0x7;			sc->sc_ctrmask |= DMV_MSK_DEOUT;			break;		case DMV_KEY_DEIN:			sc->sc_errctrs.ctr_ddcmp.dst_inbound = rsp->qp_cntlo;			sc->sc_errctrs.ctr_ddcmp.dst_inbound_bm = rsp->qp_cnthi & 0x7;			sc->sc_ctrmask |= DMV_MSK_DEIN;			break;		case DMV_KEY_LBERR:			sc->sc_errctrs.ctr_ddcmp.dst_localbuf = rsp->qp_cntlo;			sc->sc_errctrs.ctr_ddcmp.dst_localbuf_bm = rsp->qp_cnthi & 0x3;			sc->sc_ctrmask |= DMV_MSK_LBERR;			break;		case DMV_KEY_RBERR:		/* also defined as DMV_KEY_RSERR */			if ( rsp->qp_trib ) {				sc->sc_errctrs.ctr_ddcmp.dst_remotebuf = rsp->qp_cntlo;				sc->sc_errctrs.ctr_ddcmp.dst_remotebuf_bm = rsp->qp_cnthi & 0x3;				sc->sc_ctrmask |= DMV_MSK_RBERR;			} else {				sc->sc_errctrs.ctr_ddcmp.dst_remotesta = rsp->qp_cntlo;				sc->sc_errctrs.ctr_ddcmp.dst_remotesta_bm = rsp->qp_cnthi & 0xf;				sc->sc_ctrmask |= DMV_MSK_RSERR;			}			break;		case DMV_KEY_SELTO:		/* also defined as DMV_KEY_LSERR */			if ( rsp->qp_trib ) {				sc->sc_errctrs.ctr_ddcmp.dst_selecttmo = rsp->qp_cntlo;				sc->sc_errctrs.ctr_ddcmp.dst_selecttmo_bm = rsp->qp_cnthi & 0x3;				sc->sc_ctrmask |= DMV_MSK_SELTO;			} else {				sc->sc_errctrs.ctr_ddcmp.dst_localsta = rsp->qp_cntlo;				sc->sc_errctrs.ctr_ddcmp.dst_localsta_bm = rsp->qp_cnthi & 0xf;				sc->sc_ctrmask |= DMV_MSK_LSERR;			}			break;		case DMV_KEY_REPTO:			sc->sc_errctrs.ctr_ddcmp.dst_localtmo = rsp->qp_cntlo;			sc->sc_errctrs.ctr_ddcmp.dst_remotetmo = rsp->qp_cnthi;			sc->sc_ctrmask |= DMV_MSK_REPTO;			break;		default:			printd("dmv%d: unexpected information response\n", sc->sc_if.if_unit);			break;	}	if ( sc->sc_ctrmask == DMV_MSK_CMPLT )	{		struct ifnet *ifp = &sc->sc_if;		int unit = ifp->if_unit;		struct protosw *pr;		if (!dmv_instack[unit])			wakeup((caddr_t) &sc->sc_ctrmask);		else		{			/*			 * get counter command was from timer routine			 * call ifiotctl to pass the counter info			 */			if ((pr=iffamily_to_proto(ifp->if_addr.sa_family)) && 			     pr->pr_ifioctl)				(*pr->pr_ifioctl)(ifp, SIOCRDZCTRS, &sc->sc_errctrs.ctr_ddcmp);			dmv_instack[unit] = 0;		 	sc->sc_ctrmask = 0;			sc->sc_ztime = time.tv_sec;			sc->sc_errctrs.ctr_ddcmp.dst_bytercvd = 0;			sc->sc_errctrs.ctr_ddcmp.dst_bytesent = 0;			sc->sc_errctrs.ctr_ddcmp.dst_blockrcvd = 0;			sc->sc_errctrs.ctr_ddcmp.dst_blocksent = 0;		}	}	return;}/* * DMV state routine * This routine either halts the DMV or sets it up to operate * in a particular mode. */dmvstate(ifp, sc, ui)        register struct ifnet *ifp;        register struct dmv_softc *sc;        register struct uba_device *ui;{	ifp->if_addr.sa_family = sc->sc_dmvcs.if_family; 	if ( sc->sc_dmvcs.if_dstate == IFS_ENTEREDMOP ) {		sc->sc_dmvcs.if_dstate = IFS_HALTING;		sc->sc_dmvcs.if_ustate = IFS_USRON;	} else if ( sc->sc_dmvcs.if_ustate == IFS_USROFF ) {		sc->sc_dmvcs.if_mode = ui->ui_flags;		sc->sc_dmvcs.if_dstate = IFS_HALTED;	} else {		    sc->sc_dmvcs.if_dstate = IFS_STARTING;	}}/* * DMV output routine. * Encapsulate a packet of type family for the dmv. * Use trailer local net encapsulation if enough data in first * packet leaves a multiple of 512 bytes of data in remainder. */dmvoutput(ifp, m0, dst)        register struct ifnet *ifp;        register struct mbuf *m0;        struct sockaddr *dst;{	register struct dmv_softc *sc = &dmv_softc[ifp->if_unit];        int type, error, s;        register struct mbuf *m = m0;	register struct dmv_header *dh;	register int off;	struct protosw *pr;        struct ifqueue *inq;	/*	 * check to make sure device state is currently on	 */	if ( (sc->sc_dmvcs.if_dstate == IFS_HALTING) || (sc->sc_dmvcs.if_dstate == IFS_HALTED) )	{		error = ENETDOWN;		goto bad;	}	/*	 * check for device ownership if if_nomuxhdr is asserted!	 */	if ( (sc->sc_dmvcs.if_nomuxhdr) && (ifp->if_addr.sa_family != dst->sa_family) )	{		error = EADDRINUSE;		goto bad;	}	switch (dst->sa_family) {#ifdef	INET	case AF_INET:		off = ntohs((u_short)mtod(m, struct ip *)->ip_len) - m->m_len;		if ((ifp->if_flags & IFF_NOTRAILERS) == 0)		if (off > 0 && (off & 0x1ff) == 0 &&		    m->m_off >= MMINOFF + 2 * sizeof (u_short)) {			type = DMV_TRAILER + (off>>9);			m->m_off -= 2 * sizeof (u_short);			m->m_len += 2 * sizeof (u_short);			*mtod(m, u_short *) = htons((u_short)DMV_IPTYPE);			*(mtod(m, u_short *) + 1) = htons((u_short)m->m_len);			goto gottrailertype;		}		type = DMV_IPTYPE;		off = 0;		goto gottype;#endif	case AF_UNSPEC:		dh = (struct dmv_header *)dst->sa_data;		type = dh->dmv_type;		goto gottype;	default:		if ((pr=iffamily_to_proto(ifp->if_addr.sa_family)) && pr->pr_ifoutput) 			(*pr->pr_ifoutput)(ifp, m, dst, &type, NULL);		else {			printf("dmv%d: can't handle af%d\n", ifp->if_unit,				dst->sa_family);			error = EAFNOSUPPORT;			goto bad;		}		goto gottype;        }gottrailertype:	/*	 * Packet to be sent as a trailer; move first packet	 * (control information) to end of chain.	 */	while (m->m_next)		m = m->m_next;	m->m_next = m0;	m = m0->m_next;	m0->m_next = 0;	m0 = m;gottype:	/*	 * Add local header only if if_nomuxhdr is NOT asserted!	 * (there is space for a uba on a vax to step on)	 */	if ( ! sc->sc_dmvcs.if_nomuxhdr ) {		if (m->m_off > MMAXOFF ||		    MMINOFF + sizeof(struct dmv_header) > m->m_off) {			m = m_get(M_DONTWAIT, MT_DATA);			if (m == 0) {				error = ENOBUFS;				goto bad;			}			m->m_next = m0;			m->m_off = MMINOFF;			m->m_len = sizeof (struct dmv_header);		} else {			m->m_off -= sizeof (struct dmv_header);			m->m_len += sizeof (struct dmv_header);		}		dh = mtod(m, struct dmv_header *);		dh->dmv_type = htons((u_short)type);	}	/*	 * Queue message on interface, and start output if interface	 * not yet active.	 */	s = splimp();        if (IF_QFULL(&ifp->if_snd)) {                IF_DROP(&ifp->if_snd);                m_freem(m);                splx(s);                return (ENOBUFS);        }        IF_ENQUEUE(&ifp->if_snd, m);        dmvstart(ifp->if_unit);        splx(s);        return(0);bad:	m_freem(m0);	return(error);}/* * Process an ioctl request. */dmvioctl(ifp, cmd, data)        register struct ifnet *ifp;        int cmd;        caddr_t data;{        int s = splimp(), error = 0;	int arg;	register struct dmv_softc *sc = &dmv_softc[ifp->if_unit];	register struct uba_device *ui = dmvinfo[ifp->if_unit];        switch (cmd) {	case SIOCSTATE:		/*		 * read and/or set current ownership and state of device.		 */		{			register struct ifstate *dmvstate = (struct ifstate *) data;			register struct protosw *pr;			register struct ifaddr *ifa;			for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)				if ((ifa->ifa_addr.sa_family && ifa->ifa_dstaddr.sa_family) || ifa->ifa_addr.sa_family == AF_OSI)					break;			if (ifa == (struct ifaddr *) 0)				return(ENETDOWN);			if ( ! dmvsuser() ) 				return(EACCES);			/*			 * If currently owned by another family, request			 * ownership from that family.			 */			if (ifp->if_addr.sa_family && (ifp->if_addr.sa_family != dmvstate->if_family)) {				if ((pr=iffamily_to_proto(ifp->if_addr.sa_family)) && pr->pr_ifstate) 				{					if (! (*pr->pr_ifstate)(ifp, IFS_OWNREQ, dmvstate)) 						return(EBUSY);					else						dmvstate->if_next_family = ifp->if_addr.sa_family;				}				else					return(EBUSY);			}			/*			 * check validity of ioctl request			 */			if ( !( dmvstate->if_wrstate | dmvstate->if_rdstate | dmvstate->if_xferctl ) )				return(EINVAL);			/*			 * set line ownership			 */			if ( dmvstate->if_wrstate ) {				u_char save_state = sc->sc_dmvcs.if_dstate;				ifp->if_addr.sa_family = dmvstate->if_family;				sc->sc_dmvcs = *dmvstate;				sc->sc_dmvcs.if_dstate = save_state;				sc->sc_dmvcs.if_wrstate = ~IFS_WRSTATE;				sc->sc_dmvcs.if_rdstate = ~IFS_RDSTATE;				sc->sc_dmvcs.if_xferctl = ~IFS_XFERCTL;			}			/*			 * current owner can transfer control to another family			 */			if ( dmvstate->if_xferctl && dmvstate->if_wrstate ) {				ifp->if_addr.sa_family = (sc->sc_dmvcs.if_family = sc->sc_dmvcs.if_next_family);				sc->sc_dmvcs.if_next_family = ifp->if_addr.sa_family;			}			if ( dmvstate->if_wrstate ) {				/*				 * If stopping line, restart device to force dtr drop				 * Else if currently running, stop device ( to be started again				 * later).  Otherwise, start protocol up.				 */								if ( dmvstate->if_ustate == IFS_USROFF && 				     (sc->sc_flag & (DMV_ALLOC | DMV_BMAPPED)) == (DMV_ALLOC | DMV_BMAPPED) && 				     ( sc->sc_flag & DMV_RESTART) == 0 ) {					sc->sc_flag |= DMV_RESTART;					sc->sc_if.if_flags &= ~IFF_UP;					sc->sc_dmvcs.if_dstate = IFS_HALTING;					dmvrestart(sc->sc_if.if_unit);				}				else if (sc->sc_dmvcs.if_dstate != IFS_HALTED && sc->sc_dmvcs.if_dstate != IFS_HALTING) {					ifp->if_flags &= ~IFF_UP;					sc->sc_dmvcs.if_dstate = IFS_HALTING;					dmv_issue_ctl( sc, DMV_TRIB_POINT, 0, DMV_CNTL_RQHALT );				} else {					dmvinit(ifp->if_unit);				}			}			/*			 * pass back current state if requested.			 */			if ( dmvstate->if_rdstate ) {				bcopy(&sc->sc_dmvcs, dmvstate, sizeof(struct ifstate));			}		break;		}	case SIOCENABLBACK:	/*	 * place device in loopback	 */		if ( ! dmvsuser() ) 			return(EACCES);		printf("dmv%d: internal loopback enable requested\n", ifp->if_unit);		ifp->if_flags |= IFF_LOOPBACK;

⌨️ 快捷键说明

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