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

📄 if_hy.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 3 页
字号:
			printf("hy%d:  BAR overflow\n", unit);			hycancel(ui);		}	} else if (HYS_NORMAL(addr)) {		/*		 * Normal interrupt, bump state machine unless in state		 * waiting and no data present (assumed to be word count		 * zero interrupt or other hardware botch).		 */		if (is->hy_state != WAITING || HYS_RECVDATA(addr))			hyact(ui);	} else if (HYS_ABNORMAL(addr)) {		/*		 * Abnormal termination.		 * bump error counts, retry the last function		 * 'MAXRETRY' times before kicking the bucket.		 *		 * Don't reissue the cmd if in certain states, abnormal		 * on a reissued cmd or max retry exceeded.		 */#ifdef HYLOG		if (hy_log.hyl_enable != hy_log.hyl_onerr) {			hy_log.hyl_enable = hy_log.hyl_onerr;			goto logit;		}#endif#ifdef DEBUG		if (hy_nodebug & 4)			hy_debug_flag = 1;		printD("hy%d: abnormal interrupt, driver state \"%s\" (%d)\n",			unit, hy_state_names[is->hy_state], is->hy_state);		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 cmd 0x%x ptr 0x%x\n",			is->hy_savedstate, is->hy_savedcount,			is->hy_savedaddr, is->hy_savedcmd);#endif#ifdef PI13		addr->hyd_csr &= ~S_C;  /* clear the damned PI-13 */#endif		if (is->hy_state == XMITSENT || is->hy_state == XMITDATASENT)			is->hy_if.if_oerrors++;		else if (is->hy_state == RECVSENT || is->hy_state == RECVDATASENT)			is->hy_if.if_ierrors++;		else			is->hy_if.if_collisions++;	/* other errors */		if (is->hy_state == XMITDATASENT ||		    is->hy_state == RECVSENT ||		    is->hy_state == RECVDATASENT ||		    (is->hy_flags & RQ_REISSUE) != 0 || is->hy_retry > MAXRETRY)			hycancel(ui);		else {#ifdef DEBUG			if (hy_nodebug & 2)				hy_debug_flag = 1;#endif			is->hy_retry++;			is->hy_flags |= RQ_ENDOP | RQ_STATUS | RQ_REISSUE;			is->hy_state = IDLE;			hyact(ui);		}	} else {		/*		 * Interrupt is neither normal, abnormal, or interface error.		 * Ignore it. It's either stacked or a word count 0.		 */#ifdef HYLOG		if (hy_log.hyl_enable != hy_log.hyl_onerr) {			hy_log.hyl_enable = hy_log.hyl_onerr;			goto logit;		}#endif#ifdef DEBUG		printD("hy%d: possible stacked interrupt ignored\n", unit);#endif	}#ifdef DEBUG	printD("hy%d: hyint exit\n\n", unit);#endif	hyint_active = 0;}int hyoutprint = 0;/* * Encapsulate a packet of type family for the local net. */hyoutput(ifp, m0, dst)	struct ifnet *ifp;	struct mbuf *m0;	struct sockaddr *dst;{	register struct hym_hdr *hym;	register struct mbuf *m;	register char *mp;	int dlen;	/* packet size, incl hardware header, but not sw header */	int error = 0;	int s;	/*	 * Calculate packet length for later deciding whether it will fit	 * in a message proper or we also need associated data.	 */	dlen = 0;	for (m = m0; m; m = m->m_next)		dlen += m->m_len;	m = m0;	if (dst->sa_family == AF_HYLINK) {	/* don't add header */		dlen -= HYM_SWLEN;		goto headerexists;	}	/*	 * Add the software and hardware hyperchannel headers.	 * If there's not enough space in the first mbuf, allocate another.	 * If that should fail, drop this sucker.	 * No extra space for headers is allocated.	 */	mp = mtod(m, char *);	/* save pointer to real message */	M_PREPEND(m, sizeof(struct hym_hdr), M_DONTWAIT);	if (m == 0) {		error = ENOBUFS;		goto bad;	}	dlen += sizeof(struct hym_hdr) - HYM_SWLEN;	hym = mtod(m, struct hym_hdr *);	bzero((caddr_t)hym, sizeof(struct hym_hdr));	switch(dst->sa_family) {#ifdef INET	case AF_INET: {		int i;		/*		 * if loopback address, swizzle ip header so when		 * it comes back it looks like it was addressed to us		 */		i = hyroute(ifp, (u_long)in_lnaof(((struct sockaddr_in *)dst)->sin_addr), hym);		if (i < 0)			goto notfound;		if (i > 0) {			struct in_addr temp;			temp.s_addr = ((struct ip *)mp)->ip_dst.s_addr;			((struct ip *)mp)->ip_dst.s_addr = ((struct ip *)mp)->ip_src.s_addr;			((struct ip *)mp)->ip_src.s_addr = temp.s_addr;		}		/*		 * If entire packet won't fit in message proper, just		 * send hyperchannel hardware header and ip header in		 * message proper.		 *		 * This insures that the associated data is at least a		 * TCP/UDP header in length and thus prevents potential		 * problems with very short word counts.		 */		if (dlen > MPSIZE)			hym->hym_mplen = sizeof(struct hy_hdr) + (((struct ip *)mp)->ip_hl << 2);		hym->hym_type = HYLINK_IP;		break;	}#endif	default:		printf("hy%d: can't handle af%d\n", ifp->if_unit,			dst->sa_family);		error = EAFNOSUPPORT;		goto drop;	}headerexists:	/*	 * insure message proper is below the maximum	 */	if (hym->hym_mplen > MPSIZE || (dlen > MPSIZE && hym->hym_mplen == 0))		hym->hym_mplen = MPSIZE;	hym->hym_from = htons(hy_softc[ifp->if_unit].hy_host);	if (hym->hym_mplen)		hym->hym_ctl |= H_ASSOC;	else		hym->hym_ctl &= ~H_ASSOC;	if (hyoutprint) printf("hy%d: output mplen=%x ctl=%x access=%x to=%x from=%x param=%x type=%x\n",		ifp->if_unit, hym->hym_mplen, hym->hym_ctl,		hym->hym_access, hym->hym_to, hym->hym_from,		hym->hym_param, hym->hym_type);#ifdef DEBUG	printD("hy%d: output mplen=%x ctl=%x access=%x to=%x from=%x param=%x type=%x\n",		ifp->if_unit, hym->hym_mplen, hym->hym_ctl,		hym->hym_access, hym->hym_to, hym->hym_from,		hym->hym_param, hym->hym_type);#endif	s = splimp();	if (IF_QFULL(&ifp->if_snd)) {		IF_DROP(&ifp->if_snd);		error = ENOBUFS;		splx(s);		goto drop;	}	IF_ENQUEUE(&ifp->if_snd, m);	if (hy_softc[ifp->if_unit].hy_state == WAITING)		hyact(hyinfo[ifp->if_unit]);	splx(s);	return (0);notfound:	error = EHOSTUNREACH;drop:	m_freem(m);	return (error);}inthyroute(ifp, dest, hym)	register struct ifnet *ifp;	u_long dest;	register struct hym_hdr *hym;{#ifdef HYROUTE	register struct hy_route *rt = &hy_route[ifp->if_unit];	register struct hyr_hash *rhash;	register int i;#endif	hym->hym_param = 0;#ifdef HYROUTE	if (rt->hyr_lasttime != 0) {		i = HYRHASH(dest);		rhash = &rt->hyr_hash[i];		i = 0;		while (rhash->hyr_key != dest) {			if (rhash->hyr_flags == 0 || i > HYRSIZE)				return(-1);			rhash++; i++;			if (rhash >= &rt->hyr_hash[HYRSIZE])				rhash = &rt->hyr_hash[0];		}		if (rhash->hyr_flags & HYR_GATE) {			i = rhash->hyr_nextgate;			if (i >= rhash->hyr_egate)				rhash->hyr_nextgate = rhash->hyr_pgate;			else				rhash->hyr_nextgate++;			rhash = &rt->hyr_hash[rt->hyr_gateway[i]];			if ((rhash->hyr_flags & HYR_DIR) == 0)				return(-1);		} else if (rhash->hyr_flags & HYR_LOOP) {			hym->hym_param = H_LOOPBK;	/* adapter loopback */		} else if (rhash->hyr_flags & HYR_RLOOP) {			hym->hym_param = H_RLOOPBK;	/* A710 remote loopback */		}		hym->hym_ctl = rhash->hyr_ctl;		hym->hym_access = rhash->hyr_access;		hym->hym_to = rhash->hyr_dst;	} else {#endif		hym->hym_ctl = H_XTRUNKS | H_RTRUNKS;		hym->hym_access = 0;		hym->hym_to = htons((u_short)dest);		if (dest & 0x010000)			hym->hym_param = H_LOOPBK;	/* adapter loopback */		else if (dest & 0x020000)			hym->hym_param = H_RLOOPBK;	/* A710 remote loopback */#ifdef HYROUTE	}#endif	if (hym->hym_param == 0)		return(0);	else		return(1);}hyact(ui)	register struct uba_device *ui;{	register struct hy_softc *is = &hy_softc[ui->ui_unit];	register struct hydevice *addr = (struct hydevice *)ui->ui_addr;actloop:#ifdef DEBUG	printD("hy%d: hyact, enter state \"%s\"\n", ui->ui_unit,		hy_state_names[is->hy_state]);#endif	switch (is->hy_state) {	case STARTUP:		goto endintr;	case IDLE: {		register rq = is->hy_flags;		if (rq & RQ_STATUS) {			is->hy_flags &= ~RQ_STATUS;			is->hy_state = STATSENT;			hystart(ui, HYF_STATUS, sizeof (is->hy_status),			    is->hy_ifuba.ifu_r.ifrw_info);		} else if (rq & RQ_ENDOP) {			is->hy_flags &= ~RQ_ENDOP;			is->hy_state = ENDOPSENT;			hystart(ui, HYF_END_OP, 0, 0);		} else if (rq & RQ_STATISTICS) {			is->hy_flags &= ~RQ_STATISTICS;			is->hy_state = RSTATSENT;			hystart(ui, HYF_RSTATS, sizeof (is->hy_stat),			    is->hy_ifuba.ifu_r.ifrw_info);		} else if (HYS_RECVDATA(addr)) {			is->hy_state = RECVSENT;			is->hy_retry = 0;			hystart(ui, HYF_INPUTMSG, MPSIZE, is->hy_ifuba.ifu_r.ifrw_info + HYM_SWLEN);		} else if (rq & RQ_REISSUE) {			is->hy_flags &= ~RQ_REISSUE;			is->hy_state = is->hy_savedstate;#ifdef DEBUG			printD("hy%d: reissue cmd=0x%x count=%d",			  ui->ui_unit, is->hy_savedcmd, is->hy_savedcount);			printD(" ubaddr=0x%x retry=%d\n",			  is->hy_savedaddr, is->hy_retry);#endif			hystart(ui, is->hy_savedcmd, is->hy_savedcount,			    is->hy_savedaddr);		} else {			register struct mbuf *m;			IF_DEQUEUE(&is->hy_if.if_snd, m);			if (m != NULL) {				register struct hym_hdr *hym;				register int mplen;				register int cmd;				is->hy_state = XMITSENT;				is->hy_retry = 0;				hym = mtod(m, struct hym_hdr *);#ifdef HYLOG				hylog(HYL_XMIT, sizeof(struct hym_hdr),				    (char *)hym);#endif				mplen = hym->hym_mplen;				if (hym->hym_to_adapter == hym->hym_from_adapter)					cmd = HYF_XMITLOCMSG;				else					cmd = HYF_XMITMSG;#ifdef DEBUG				printD("hy%d: hym_hdr = ", ui->ui_unit);				if (hy_debug_flag)					hyprintdata((char *)hym,					    sizeof (struct hym_hdr));#endif				is->hy_olen = if_wubaput(&is->hy_ifuba, m) - HYM_SWLEN;				if (is->hy_ifuba.ifu_flags & UBA_NEEDBDP)					UBAPURGE(is->hy_ifuba.ifu_uba,						is->hy_ifuba.ifu_w.ifrw_bdp);#ifdef DEBUG				printD(		"hy%d: sending packet (mplen = %d, hy_olen = %d) data = ",					ui->ui_unit, mplen, is->hy_olen);				if (hy_debug_flag)					hyprintdata(					    is->hy_ifuba.ifu_w.ifrw_addr,					    is->hy_olen + HYM_SWLEN);#endif				if (mplen == 0) {					is->hy_flags &= ~RQ_XASSOC;					mplen = is->hy_olen;				} else {					is->hy_flags |= RQ_XASSOC;				}				hystart(ui, cmd, mplen, is->hy_ifuba.ifu_w.ifrw_info + HYM_SWLEN);			} else if (rq & RQ_MARKDOWN) {				is->hy_flags &= ~(RQ_MARKUP | RQ_MARKDOWN);				is->hy_state = MARKPORT;				is->hy_retry = 0;				/*				 * Port number is taken from status data				 */				hystart(ui,				 (int)(HYF_MARKP0|(PORTNUM(&is->hy_status)<<2)),				 0, 0);			} else if (rq & RQ_MARKUP) {				register struct ifnet *ifp = &is->hy_if;				is->hy_flags &= ~RQ_MARKUP;				is->hy_retry = 0;				/*				 * Fill in the host number				 * from the status buffer				 */				printf(	"hy%d: unit number 0x%x port %d type %x microcode level 0x%x\n",					ui->ui_unit,					is->hy_stat.hyc_uaddr,					PORTNUM(&is->hy_status),					(is->hy_stat.hyc_atype[0]<<8) |						is->hy_stat.hyc_atype[1],					is->hy_stat.hyc_atype[2]);				is->hy_host =				  (is->hy_stat.hyc_uaddr << 8) |					PORTNUM(&is->hy_status);				ifp->if_flags |= IFF_UP;#ifdef HYLOG				hylog(HYL_UP, 0, (char *)0);#endif			} else {				is->hy_state = WAITING;				is->hy_retry = 0;				hystart(ui, HYF_WAITFORMSG, 0, 0);			}		}		break;	}	case STATSENT:		bcopy(is->hy_ifuba.ifu_r.ifrw_addr, (caddr_t)&is->hy_status,		  sizeof (struct hy_status));#ifdef DEBUG		printD("hy%d: status - %x %x %x %x %x %x %x %x\n",			ui->ui_unit, is->hy_status.hys_gen_status,			is->hy_status.hys_last_fcn,			is->hy_status.hys_resp_trunk,			is->hy_status.hys_status_trunk,			is->hy_status.hys_recd_resp,			is->hy_status.hys_error,			is->hy_status.hys_caddr,			is->hy_status.hys_pad);#endif		is->hy_state = IDLE;#ifdef HYLOG		hylog(HYL_STATUS, sizeof (struct hy_status),			(char *)&is->hy_status);#endif#ifdef HYELOG		{			register int i;						i = is->hy_status.hys_error;			if (i > HYE_MAX)				i = HYE_MAX;			switch (is->hy_status.hys_last_fcn) {				case HYF_XMITLOCMSG:					i += HYE_MAX+1;	/* fall through */				case HYF_XMITLSTDATA:					i += HYE_MAX+1;	/* fall through */				case HYF_XMITMSG:					i += HYE_MAX+1;			}			hy_elog[i]++;		}#endif		break;	case RSTATSENT: {		register struct hy_stat *p =			(struct hy_stat *)is->hy_ifuba.ifu_r.ifrw_addr;		bcopy((caddr_t)p, (caddr_t)&is->hy_stat, sizeof(struct hy_stat));#ifdef DEBUG		printD("hy%d: statistics - df0 %d df1 %d df2 %d df3 %d\n",			ui->ui_unit,			(is->hy_stat.hyc_df0[0]<<16) | (is->hy_stat.hyc_df0[1]<<8) | is->hy_stat.hyc_df0[2],			(is->hy_stat.hyc_df1[0]<<16) | (is->hy_stat.hyc_df1[1]<<8) | is->hy_stat.hyc_df1[2],			(is->hy_stat.hyc_df2[0]<<16) | (is->hy_stat.hyc_df2[1]<<8) | is->hy_stat.hyc_df2[2],			(is->hy_stat.hyc_df3[0]<<16) | (is->hy_stat.hyc_df3[1]<<8) | is->hy_stat.hyc_df3[2]);		printD("	ret0 %d ret1 %d ret2 %d ret3 %d\n",			(is->hy_stat.hyc_ret0[0]<<16) | (is->hy_stat.hyc_ret0[1]<<8) | is->hy_stat.hyc_ret0[2],			(is->hy_stat.hyc_ret1[0]<<16) | (is->hy_stat.hyc_ret1[1]<<8) | is->hy_stat.hyc_ret1[2],			(is->hy_stat.hyc_ret2[0]<<16) | (is->hy_stat.hyc_ret2[1]<<8) | is->hy_stat.hyc_ret2[2],			(is->hy_stat.hyc_ret3[0]<<16) | (is->hy_stat.hyc_ret3[1]<<8) | is->hy_stat.hyc_ret3[2]);		printD("	cancel %d abort %d atype %x %x %x uaddr %x\n",			(is->hy_stat.hyc_cancel[0]<<8) | is->hy_stat.hyc_cancel[1],			(is->hy_stat.hyc_abort[0]<<8) | is->hy_stat.hyc_abort[1],			is->hy_stat.hyc_atype[0], is->hy_stat.hyc_atype[1],			is->hy_stat.hyc_atype[2], is->hy_stat.hyc_uaddr);#endif		is->hy_state = IDLE;#ifdef HYLOG		hylog(HYL_STATISTICS, sizeof (struct hy_stat),			(char *)&is->hy_stat);#endif		break;	}	case CLEARSENT:		is->hy_state = IDLE;		break;	case ENDOPSENT:		is->hy_state = IDLE;		break;	case RECVSENT: {		register struct hym_hdr *hym;		register unsigned len;

⌨️ 快捷键说明

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