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

📄 if_hy.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (is->hy_ifuba.ifu_flags & UBA_NEEDBDP)			UBAPURGE(is->hy_ifuba.ifu_uba,			    is->hy_ifuba.ifu_r.ifrw_bdp);		hym = (struct hym_hdr *) (is->hy_ifuba.ifu_r.ifrw_addr);		len = (0xffff & (addr->hyd_wcr - is->hy_lastwcr)) << 1;		if (len > MPSIZE) {			printf("hy%d: RECVD MP > MPSIZE (%d)\n",			    ui->ui_unit, len);			is->hy_state = IDLE;#ifdef DEBUG			hy_debug_flag = 1;			printD("hy%d: csr = 0x%b, bar = 0x%x, wcr = 0x%x\n",				ui->ui_unit, addr->hyd_csr, HY_CSR_BITS,				addr->hyd_bar, addr->hyd_wcr);#endif		}		hym->hym_mplen = len;#ifdef DEBUG		printD("hy%d: recvd mp, len = %d, data = ", ui->ui_unit, len);		if (hy_debug_flag)			hyprintdata((char *)hym, len + HYM_SWLEN);#endif		if (hym->hym_ctl & H_ASSOC) {			is->hy_state = RECVDATASENT;			is->hy_retry = 0;			hystart(ui, HYF_INPUTDATA,			    (int)(HYMTU + sizeof (struct hy_hdr) - len),			    (int)(HYM_SWLEN + is->hy_ifuba.ifu_r.ifrw_info + len));		} else {			hyrecvdata(ui, hym, (int)len + HYM_SWLEN);			is->hy_state = IDLE;		}		break;	}	case RECVDATASENT: {		register struct hym_hdr *hym;		register unsigned len;		if (is->hy_ifuba.ifu_flags & UBA_NEEDBDP)			UBAPURGE(is->hy_ifuba.ifu_uba,			    is->hy_ifuba.ifu_r.ifrw_bdp);		hym = (struct hym_hdr *) (is->hy_ifuba.ifu_r.ifrw_addr);		len = (0xffff & (addr->hyd_wcr - is->hy_lastwcr)) << 1;#ifdef DEBUG		printD("hy%d: recvd assoc data, len = %d, data = ",			ui->ui_unit, len);		if (hy_debug_flag)			hyprintdata((char *)hym + hym->hym_mplen, len);#endif		hyrecvdata(ui, hym, (int)(len + hym->hym_mplen + HYM_SWLEN));		is->hy_state = IDLE;		break;	}	case XMITSENT:		if (is->hy_flags & RQ_XASSOC) {			register int len;			is->hy_flags &= ~RQ_XASSOC;			is->hy_state = XMITDATASENT;			is->hy_retry = 0;			len = (0xffff & (addr->hyd_wcr - is->hy_lastwcr)) << 1;			if (len > is->hy_olen) {				printf(				"hy%d: xmit error - len > hy_olen [%d > %d]\n",				ui->ui_unit, len, is->hy_olen);#ifdef DEBUG				hy_debug_flag = 1;#endif			}			hystart(ui, HYF_XMITLSTDATA, is->hy_olen - len,			    is->hy_ifuba.ifu_w.ifrw_info + HYM_SWLEN + len);			break;		}		/* fall through to ... */			case XMITDATASENT:		hyxmitdata(ui);		is->hy_state = IDLE;		break;	case WAITING:	/* wait for message complete or output requested */		if (HYS_RECVDATA(addr))			is->hy_state = IDLE;		else {			is->hy_state = CLEARSENT;			is->hy_retry = 0;			hystart(ui, HYF_CLRWFMSG, 0, 0);		}		break;	case MARKPORT:		is->hy_state = STARTUP;		if_down(&is->hy_if);		is->hy_if.if_flags &= ~IFF_UP;		goto endintr;		default:		printf("hy%d: DRIVER BUG - INVALID STATE %d\n",			ui->ui_unit, is->hy_state);		panic("HYPERCHANNEL IN INVALID STATE");		/*NOTREACHED*/	}	if (is->hy_state == IDLE)		goto actloop;endintr:	;#ifdef DEBUG	printD("hy%d: hyact, exit at \"%s\"\n", ui->ui_unit,		hy_state_names[is->hy_state]);#endif}struct sockproto hypproto = { PF_HYLINK };struct sockaddr_in hypdst = { sizeof(hypdst), AF_HYLINK };struct sockaddr_in hypsrc = { sizeof(hypsrc), AF_HYLINK };/* * Called from device interrupt when receiving data. * Examine packet to determine type.  Decapsulate packet * based on type and pass to type specific higher-level * input routine. */hyrecvdata(ui, hym, len)	struct uba_device *ui;	register struct hym_hdr *hym;	int len;{	register struct hy_softc *is = &hy_softc[ui->ui_unit];    	struct mbuf *m;	register struct ifqueue *inq;	is->hy_if.if_ipackets++;#ifdef DEBUG	printD("hy%d: recieved packet, len = %d\n", ui->ui_unit, len);#endif#ifdef HYLOG	{		struct {			short hlen;			struct hym_hdr hhdr;		} hh;		hh.hlen = len;		hh.hhdr = *hym;		hylog(HYL_RECV, sizeof(hh), (char *)&hh);	}#endif	if (len > HYMTU + MPSIZE || len == 0)		return;			/* sanity */	/*	 * Pull packet off interface.	 */	m = if_rubaget(&is->hy_ifuba, len, 0, &is->hy_if);	if (m == NULL)		return;	/*	 * if normal or adapter loopback response packet believe hym_type,	 * otherwise, use the raw input queue cause it's a response from an	 * adapter command.	 */	if (hym->hym_param != 0 && (u_short)hym->hym_param != 0x80ff)		goto rawlinkin;	switch (hym->hym_type) {#ifdef INET	case HYLINK_IP:		schednetisr(NETISR_IP);		inq = &ipintrq;		break;#endif	default:	rawlinkin:		{			M_PREPEND(m, sizeof(struct hym_hdr), M_DONTWAIT);			if (m == 0) {				m_freem(m);				return;			}			bcopy((caddr_t)hym, mtod(m, caddr_t), sizeof(struct hym_hdr));			hypproto.sp_protocol = 0;			hypdst.sin_addr = is->hy_addr;			hypsrc.sin_addr = is->hy_addr;			raw_input(m, &hypproto, (struct sockaddr *)&hypsrc,				(struct sockaddr *)&hypdst);			return;		}	}	if (IF_QFULL(inq)) {		IF_DROP(inq);		m_freem(m);	} else		IF_ENQUEUE(inq, m);}/* * Transmit done, release resources, bump counters. */hyxmitdata(ui)	struct uba_device *ui;{	register struct hy_softc *is = &hy_softc[ui->ui_unit];	is->hy_if.if_opackets++;	if (is->hy_ifuba.ifu_xtofree) {		m_freem(is->hy_ifuba.ifu_xtofree);		is->hy_ifuba.ifu_xtofree = 0;	}}hycancel(ui)	register struct uba_device *ui;{	register struct hy_softc *is = &hy_softc[ui->ui_unit];	if (is->hy_ifuba.ifu_xtofree) {		m_freem(is->hy_ifuba.ifu_xtofree);		is->hy_ifuba.ifu_xtofree = 0;	}#ifdef HYLOG	hylog(HYL_CANCEL, 0, (char *)0);#endif#ifdef DEBUG	if (hy_nodebug & 1)		hy_debug_flag = 1;#endif#ifdef DEBUG	printD("hy%d: cancel from state \"%s\" cmd=0x%x count=%d ptr=0x%x\n",		ui->ui_unit, hy_state_names[is->hy_state], is->hy_savedcmd,		is->hy_savedcount, is->hy_savedaddr);	printD("\tflags 0x%x olen %d lastwcr %d retry %d\n",		is->hy_flags, is->hy_olen, is->hy_lastwcr, is->hy_retry);	printD("\tsaved: state %d count %d ptr 0x%x cmd 0x%x\n",		is->hy_savedstate, is->hy_savedcount, is->hy_savedaddr,		is->hy_savedcmd);#endif	is->hy_state = IDLE;	is->hy_flags |= (RQ_ENDOP | RQ_STATUS);	hyact(ui);}#ifdef DEBUGhyprintdata(cp, len)	register char *cp;	register int len;{	register int count = 16;	register char *fmt;	static char regfmt[] = "\n\t %x";	fmt = &regfmt[2];	while (--len >= 0) {		printL(fmt, *cp++ & 0xff);		fmt = &regfmt[2];		if (--count <= 0) {			fmt = &regfmt[0];			count = 16;		}	}	printL("\n");}#endifhywatch(unit)	int unit;{	register struct hy_softc *is = &hy_softc[unit];	register struct uba_device *ui = hyinfo[unit];	register struct hydevice *addr = (struct hydevice *)ui->ui_addr;	int s;	s = splimp();#ifdef PI13	if ((addr->hyd_csr & S_POWEROFF) != 0) {		addr->hyd_csr |= S_POWEROFF;		DELAY(100);		if ((addr->hyd_csr & S_POWEROFF) == 0) {			printf("hy%d: Adapter Power Restored (hywatch)\n", unit);			is->hy_state = IDLE;			is->hy_flags |=			  (RQ_MARKUP | RQ_STATISTICS | RQ_ENDOP | RQ_STATUS);			hyact(ui);		}	}#endif	if (++is->hy_ntime >= 2 && is->hy_state != WAITING &&	  is->hy_state != STARTUP && is->hy_state != IDLE) {#ifdef HYLOG		printf("hy%d: watchdog timer expired in state \"%s\"\n", unit,			hy_state_names[is->hy_state]);#else		printf("hy%d: watchdog timer expired in state %d\n", unit,			is->hy_state);#endif		printf("hy%d: last command 0x%x, flags 0x%x, csr 0x%b\n", unit,			is->hy_savedcmd, is->hy_flags, addr->hyd_csr, HY_CSR_BITS);		hycancel(ui);	}	splx(s);	is->hy_if.if_timer = SCANINTERVAL;}#ifdef HYLOGhylog(code, len, ptr)	int code, len;	char *ptr;{	register unsigned char *p;	int s;	s = splimp();	if (hy_log.hyl_self != &hy_log) {		hy_log.hyl_eptr = &hy_log.hyl_buf[HYL_SIZE];		hy_log.hyl_ptr = &hy_log.hyl_buf[0];		hy_log.hyl_self = &hy_log;		hy_log.hyl_enable = HYL_CONTINUOUS;		hy_log.hyl_onerr = HYL_CONTINUOUS;		hy_log.hyl_count = 0;		hy_log.hyl_icount = 16;		hy_log.hyl_filter = 0xffff;	/* enable all */	}	if (hy_log.hyl_enable == HYL_DISABLED || ((1 << code) & hy_log.hyl_filter) == 0)		goto out;	p = hy_log.hyl_ptr;	if (p + len + 3 >= hy_log.hyl_eptr) {		bzero((caddr_t)p, (unsigned)(hy_log.hyl_eptr - p));		p = &hy_log.hyl_buf[0];		if (hy_log.hyl_enable != HYL_CONTINUOUS) {			hy_log.hyl_enable = HYL_DISABLED;			goto out;		}	}	*p++ = code;	*p++ = len;	bcopy((caddr_t)ptr, (caddr_t)p, (unsigned)len);	if (hy_log.hyl_count != 0 && --hy_log.hyl_count == 0) {		*p++ = '\0';		hy_log.hyl_enable = HYL_DISABLED;		hy_log.hyl_count = hy_log.hyl_icount;	}	p += len;	if (hy_log.hyl_wait != 0) {		/* wakeup HYGETLOG if wanted */		if (hy_log.hyl_wait <= p - hy_log.hyl_ptr) {			wakeup((caddr_t)&hy_log);			hy_log.hyl_wait = 0;		} else			hy_log.hyl_wait -= p - hy_log.hyl_ptr;	}	hy_log.hyl_ptr = p;out:	splx(s);}#endif/*ARGSUSED*/hyioctl(ifp, cmd, data)	register struct ifnet *ifp;	int cmd;	caddr_t	data;{	struct ifaddr *ifa = (struct ifaddr *) data;	struct hyrsetget *sg = (struct hyrsetget *)data;#if defined(HYLOG) || defined(HYELOG)	struct hylsetget *sgl = (struct hylsetget *)data;#endif	struct hy_route *r = (struct hy_route *)&hy_route[ifp->if_unit];	int s = splimp(), error = 0;#ifdef HYLOG	struct hy_softc *is = &hy_softc[ifp->if_unit];	struct {		u_char	hstate;		u_char	hflags;		u_short	iflags;		int	hcmd;			int	herror;		u_long	haddr;		u_long	hmisc;	} hil;	hil.hmisc = -1;	hil.hstate = is->hy_state;	hil.hflags = is->hy_flags;	hil.hcmd = cmd;#endif	switch(cmd) {	case SIOCSIFADDR:		if (ifa->ifa_addr->sa_family != AF_INET)			return(EINVAL);		if ((ifp->if_flags & IFF_RUNNING) == 0)			hyinit(ifp->if_unit);		hy_softc[ifp->if_unit].hy_addr = IA_SIN(ifa)->sin_addr;#ifdef HYLOG		hil.haddr = is->hy_addr.s_addr;#endif		break;	case HYSETROUTE:		if (error = suser(u.u_cred, &u.u_acflag))			goto out;		if (sg->hyrsg_len != sizeof(struct hy_route)) {			error = EINVAL;			goto out;		}		if (copyin((caddr_t)(sg->hyrsg_ptr), (caddr_t)r, sg->hyrsg_len)) {			r->hyr_lasttime = 0;	/* disable further routing if trouble */			error = EFAULT;			goto out;		}		r->hyr_lasttime = time.tv_sec;#ifdef HYLOG		hil.hmisc = r->hyr_lasttime;#endif		break;	case HYGETROUTE:		if (sg->hyrsg_len < sizeof(struct hy_route)) {			error = EINVAL;			goto out;		}		if (copyout((caddr_t)r, (caddr_t) (sg->hyrsg_ptr), sizeof(struct hy_route))) {			error = EFAULT;			goto out;		}		break;#ifdef HYELOG	case HYGETELOG:		if (sgl->hylsg_len < sizeof(hy_elog)) {			error = EINVAL;			goto out;		}		if (copyout((caddr_t)hy_elog, sgl->hylsg_ptr, sizeof(hy_elog))) {			error = EFAULT;			goto out;		}		if (sgl->hylsg_cmd) {			if (error = suser(u.u_cred, &u.u_acflag))				goto out;			bzero((caddr_t)hy_elog, sizeof(hy_elog));		}		break;#endif#ifdef HYLOG	case HYSETLOG:		if (error = suser(u.u_cred, &u.u_acflag))			goto out;		hy_log.hyl_enable = HYL_DISABLED;		hylog(HYL_NOP, 0, (char *)0);		/* force log init */		hy_log.hyl_enable = sgl->hylsg_cmd & 0x0f;		hy_log.hyl_onerr = (sgl->hylsg_cmd >> 4) & 0x0f;		hy_log.hyl_filter = (sgl->hylsg_cmd >> 8) & 0xffffff;		hy_log.hyl_count = hy_log.hyl_icount = sgl->hylsg_len;		wakeup((caddr_t)&hy_log);	/* wakeup sleeping HYGETLOG */		break;	case HYGETLOG:		if (sgl->hylsg_len < sizeof(hy_log)) {			error = EINVAL;			goto out;		}		if (sgl->hylsg_cmd != 0) {			if (hy_log.hyl_wait) {				error = EBUSY;				goto out;			}			hy_log.hyl_wait = sgl->hylsg_cmd;			sleep((caddr_t)&hy_log, PZERO - 1);		}		if (copyout((caddr_t)&hy_log, sgl->hylsg_ptr, sizeof(hy_log))) {			error = EFAULT;			goto out;		}		break;#endif	default:		error = EINVAL;		break;	}out:#ifdef HYLOG	hil.herror = error;	hil.iflags = ifp->if_flags;	hil.haddr = is->hy_addr.s_addr;	hylog(HYL_IOCTL, sizeof(hil), (char *)&hil);#endif	splx(s);	return (error);}#endif

⌨️ 快捷键说明

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