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

📄 if_hy.c

📁 open bsd vax module -if function
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (c) 1988 Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Tektronix Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)if_hy.c	7.7 (Berkeley) 12/16/90 *//* * 4.2 BSD Unix Kernel - Vax Network Interface Support * * $Header: if_hy.c,v 10.1 84/07/22 21:02:56 steveg Exp $ * $Locker:  $ * * Modifications from Berkeley 4.2 BSD * Copyright (c) 1983, Tektronix Inc. * All Rights Reserved * * $Log:	if_hy.c,v $ *	Revision 10.1  84/07/22  21:02:56  steveg *	define PI13 (moved from if_hyreg.h, somehow got dropped in the process) *	rework hywatch to check for power fails first *	 *	Revision 10.0  84/06/30  19:54:27  steveg *	Big Build *	 *	Revision 3.17  84/06/20  19:20:28  steveg *	increment hy_ntime in hywatch *	print out state name, csr, last command, and hy_flags when watchdog timer *	expires *	 *	Revision 3.16  84/06/20  19:09:34  steveg *	turn on continuous logging by default *	 *	Revision 3.15  84/05/30  22:19:09  steveg *	changes to reflect new layout ot statistics data *	 *	Revision 3.14  84/05/30  19:25:15  steveg *	move driver states to if_hy.h so log printing programs can use them *	 *	Revision 3.13  84/05/30  17:13:26  steveg *	make it compile *	 *	Revision 3.12  84/05/30  13:46:16  steveg *	rework logging *	 *	Revision 3.11  84/05/18  19:35:02  steveg *	clear IFF_RUNNING and IFF_UP on unibus reset to force resource allocation *	by the init routine *	 *	Revision 3.10  84/05/04  12:14:44  steveg *	more rework to make it actually work under 4.2 *	 *	Revision 3.9  84/05/01  23:34:52  steveg *	fix typo so it compiles (unit -> ui->ui_unit) *	 *	Revision 3.8  84/05/01  23:18:30  steveg *	changes after talking with rickk *	- check power off more closely *	- support remote loopback through A710 adapters *	- IMPLINK -> HYLINK *	- return EHOSTUNREACH on hyroute failure *	- bump if_collisions on abnormal interrupts that aren't input or output *	 * */#include "hy.h"#if NHY > 0/* * Network Systems Copropration Hyperchanel interface */#include "../include/pte.h"#include "sys/param.h"#include "sys/systm.h"#include "sys/mbuf.h"#include "sys/buf.h"#include "sys/protosw.h"#include "sys/socket.h"#include "sys/vmmac.h"#include "sys/errno.h"#include "sys/time.h"#include "sys/kernel.h"#include "sys/ioctl.h"#include "net/if.h"#include "net/netisr.h"#include "net/route.h"#ifdef	INET#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#endif#include "../include/cpu.h"#include "../include/mtpr.h"#include "../uba/ubareg.h"#include "../uba/ubavar.h"/* * configuration specific paramters *	- change as appropriate for particular installaions */#define	HYROUTE#define	HYELOG#define	HYLOG#define	HYMTU	1100#define PI13#ifdef	DEBUG#define	HYLOG#endif#include "if_hy.h"#include "if_hyreg.h"#include "if_uba.h"int	hyprobe(), hyattach(), hyinit(), hyioctl();int	hyoutput(), hyreset(), hywatch();struct	uba_device *hyinfo[NHY];u_short hystd[] = { 0772410, 0 };struct	uba_driver hydriver =	{ hyprobe, 0, hyattach, 0, hystd, "hy", hyinfo };/* * Hyperchannel software status per interface. * * Each interface is referenced by a network interface structure, * hy_if, which the routing code uses to locate the interface. * This structure contains the output queue for the interface, its address, ... * We also have, for each interface, a UBA interface structure, which * contains information about the UNIBUS resources held by the interface: * map registers, buffered data paths, etc.  Information is cached in this * structure for use by the if_uba.c routines in running the interface * efficiently. */struct	hy_softc {	struct	ifnet hy_if;		/* network-visible interface */	struct	ifuba hy_ifuba;		/* UNIBUS resources */	short	hy_flags;		/* flags */	short	hy_state;		/* driver state */	u_short	hy_host;		/* local host number */	struct	in_addr hy_addr;	/* internet address */	int	hy_olen;		/* packet length on output */	int	hy_lastwcr;		/* last command's word count */	short	hy_savedstate;		/* saved for reissue after status */	short	hy_savedcmd;		/* saved command for reissue */	int	hy_savedcount;		/* saved byte count for reissue */	int	hy_savedaddr;		/* saved unibus address for reissue */	int	hy_ntime;		/* number of timeouts since last cmd */	int	hy_retry;		/* retry counter */	struct	hy_stat hy_stat;	/* statistics */	struct	hy_status hy_status;	/* status */} hy_softc[NHY];#ifdef HYELOGu_long	hy_elog[HYE_SIZE];#endif#ifdef HYLOGstruct hy_log hy_log;#endif#ifdef HYROUTEstruct hy_route hy_route[NHY];#endif#ifdef DEBUG#define printL	printf#define printD	if (hy_debug_flag) printfint	hy_debug_flag = 0;/* * hy_nodebug bit 0x01	set hy_debug_flag on hycancel * hy_nodebug bit 0x02	set hy_debug_flag on command reissue * hy_nodebug bit 0x04	set hy_debug_flag on abnormal interrupt */int	hy_nodebug = 0x0;#endif#define SCANINTERVAL	10	/* seconds */#define MAXINTERVAL	20	/* seconds (max action) *//* * Cause a device interrupt.  This code uses a buffer starting at * location zero on the unibus (which is already mapped by the * autoconfigure code in the kernel). */hyprobe(reg)	caddr_t reg;{	register int br, cvec;		/* r11, r10 value-result */	register struct hydevice *addr = (struct hydevice *) reg;#ifdef lint	br = 0; cvec = br; br = cvec;	hyint(0);#endif	/*	 * request adapter status to a buffer starting at unibus location 0	 */	addr->hyd_bar = 0;	addr->hyd_wcr = -((sizeof(struct hy_status) + 1) >> 1);	addr->hyd_dbuf = HYF_STATUS;#ifdef PI13	addr->hyd_csr |= S_GO | S_IE | S_IATTN;#else	addr->hyd_csr |= S_GO | S_IE;#endif	DELAY(10000);#ifdef PI13	addr->hyd_csr |= S_CLRINT;	/* clear any stacked interrupts */#endif	addr->hyd_csr &= ~(S_IE | S_CLRINT);	/* disable further interrupts */	return(sizeof(struct hydevice));}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. */hyattach(ui)	struct uba_device *ui;{	register struct hy_softc *is = &hy_softc[ui->ui_unit];	register struct ifnet *ifp = &is->hy_if;	ifp->if_unit = ui->ui_unit;	ifp->if_name = "hy";	ifp->if_mtu = HYMTU;	is->hy_state = STARTUP;		/* don't allow state transitions yet */	ifp->if_init = hyinit;	ifp->if_ioctl = hyioctl;	ifp->if_output = hyoutput;	ifp->if_reset = hyreset;	ifp->if_watchdog = hywatch;	ifp->if_timer = SCANINTERVAL;	is->hy_ifuba.ifu_flags = UBA_CANTWAIT;#ifdef notdef	is->hy_ifuba.ifu_flags |= UBA_NEEDBDP;#endif	if_attach(ifp);}/* * Reset of interface after UNIBUS reset. * If interface is on specified uba, reset its state. */hyreset(unit, uban)	int unit, uban;{	register struct uba_device *ui;	register struct hy_softc *is;	if (unit >= NHY || (ui = hyinfo[unit]) == 0 || ui->ui_alive == 0 ||	  ui->ui_ubanum != uban)		return;	printf(" hy%d", unit);	is = &hy_softc[unit];		/* force unibus resource allocation */	is->hy_if.if_flags &= ~(IFF_UP|IFF_RUNNING);	hyinit(unit);}/* * Initialization of interface; clear recorded pending * operations, and reinitialize UNIBUS usage. */hyinit(unit)	int unit;{	register struct hy_softc *is = &hy_softc[unit];	register struct uba_device *ui = hyinfo[unit];	register struct mbuf *m;	int s;	if (is->hy_if.if_addrlist == 0)		/* address still unknown */		return;	if (is->hy_if.if_flags & IFF_RUNNING)	/* just reset the device */		goto justreset;	if (if_ubainit(&is->hy_ifuba, ui->ui_ubanum,	    sizeof (struct hym_hdr), (int)btoc(HYMTU)) == 0) { #ifdef DEBUG		if (hy_nodebug & 4)			hy_debug_flag = 1;#endif		printf("hy%d: can't initialize\n", unit);		is->hy_if.if_flags &= ~IFF_UP;		return;	}	is->hy_if.if_flags |= IFF_RUNNING;justreset:	/*	 * remove any left over outgoing messages, reset the hardware and	 * start the state machine	 */	s = splimp();#ifdef HYLOG	hylog(HYL_RESET, 0, (char *)0);#endif	is->hy_state = IDLE;	is->hy_flags = RQ_STATUS | RQ_STATISTICS | RQ_MARKUP;	is->hy_retry = 0;	for(;;) {		IF_DEQUEUE(&is->hy_if.if_snd, m);		if (m != NULL)			m_freem(m);		else			break;	}	hycancel(ui);		/* also bumps the state machine */	splx(s);}/* * Issue a command to the adapter */hystart(ui, cmd, count, ubaddr)	struct uba_device *ui;	int cmd, count, ubaddr;{	register struct hy_softc *is = &hy_softc[ui->ui_unit];	register struct hydevice *addr = (struct hydevice *)ui->ui_addr;#ifdef DEBUG	printD("hy%d: hystart cmd = 0x%x count=%d ubaddr=0x%x\n",		ui->ui_unit, cmd, count, ubaddr);	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	if (((is->hy_flags & RQ_REISSUE) == 0) &&	  (cmd != HYF_STATUS) && (cmd != HYF_END_OP) && (cmd != HYF_RSTATS)) {		is->hy_savedstate = is->hy_state;		is->hy_savedcmd = cmd;		is->hy_savedcount = count;		is->hy_savedaddr = ubaddr;	}#ifdef PI13	if (addr->hyd_csr & S_POWEROFF) {		printf("hy%d: \"Soft\" Adapter Power Failure (hystart)\n", ui->ui_unit);		addr->hyd_csr |= S_POWEROFF;		DELAY(100);		if (addr->hyd_csr & S_POWEROFF) {			printf( "hy%d: \"Hard\" Adapter Power Failure, Network Shutdown (hystart)\n", ui->ui_unit);			if_down(&is->hy_if);			is->hy_if.if_flags &= ~IFF_UP;			is->hy_state = STARTUP;		} else {			printf("hy%d: Adapter Power Restored (hystart)\n", ui->ui_unit);		}		return;	}#endif	addr->hyd_bar = ubaddr & 0xffff;	addr->hyd_wcr = is->hy_lastwcr = -((count+1) >> 1);	addr->hyd_dbuf = cmd;#ifdef PI13	addr->hyd_csr = ((ubaddr >> XBASHIFT) & S_XBA) | S_GO | S_IE | S_IATTN;#else	addr->hyd_csr = ((ubaddr >> XBASHIFT) & S_XBA) | S_GO | S_IE;#endif#ifdef DEBUG	printD("hy%d: exit hystart - 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#ifdef HYLOG	{		struct {			u_char	hcmd;			u_char	hstate;			short	hcount;		} hcl;		hcl.hcmd = cmd;		hcl.hstate = is->hy_state;		hcl.hcount = count;		hylog(HYL_CMD, sizeof(hcl), (char *)&hcl);	}#endif	is->hy_ntime = 0;}int hyint_active = 0;		/* set during hy interrupt *//* * Hyperchannel interface interrupt. * * An interrupt can occur for many reasons.  Examine the status of * the hyperchannel status bits to determine what to do next. * * If input error just drop packet. * Otherwise purge input buffered data path and examine  * packet to determine type.  Othewise decapsulate * packet based on type and pass to type specific higher-level * input routine. */hyint(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;	if (hyint_active)		panic("RECURSIVE HYPERCHANNEL INTERRUPT");	hyint_active++;#ifdef DEBUG	printD("hy%d: hyint enter - csr = 0x%b, bar = 0x%x, wcr = 0x%x\n",		unit, addr->hyd_csr, HY_CSR_BITS, addr->hyd_bar, addr->hyd_wcr);#endif#ifdef HYLOGlogit:	{		struct {			u_char	hstate;			u_char	hflags;			short	hcsr;			short	hwcr;		} hil;		hil.hstate = is->hy_state;		hil.hflags = is->hy_flags;		hil.hcsr = addr->hyd_csr;		hil.hwcr = addr->hyd_wcr;		hylog(HYL_INT, sizeof(hil), (char *)&hil);	}#endif	if (HYS_ERROR(addr) && ((addr->hyd_csr & S_ATTN) == 0)) {		/*		 * Error bit set, some sort of error in the interface.		 *		 * The adapter sets attn on command completion so that's not		 * a real error even though the interface considers it one.		 */#ifdef DEBUG		if (hy_nodebug & 4)			hy_debug_flag = 1;#endif		printf("csr = 0x%b\nbar = 0x%x\nwcr = 0x%x\n",			addr->hyd_csr, HY_CSR_BITS, addr->hyd_bar,			addr->hyd_wcr);		if (addr->hyd_csr & S_NEX) {			printf("hy%d: NEX - Non Existant Memory\n", unit);#ifdef PI13			addr->hyd_csr |= S_NEX;  /* as per PI13 manual */#else			addr->hyd_csr &= ~S_NEX;#endif			hycancel(ui);#ifdef PI13		} else if (addr->hyd_csr & S_POWEROFF) {			printf("hy%d: \"Soft\" Adapter Power Failure (hyint)\n", unit);			addr->hyd_csr |= S_POWEROFF;			DELAY(100);			if (addr->hyd_csr & S_POWEROFF) {				printf( "hy%d: \"Hard\" Adapter Power Failure, Network Shutdown (hyint)\n", unit);				if_down(&is->hy_if);				is->hy_if.if_flags &= ~IFF_UP;				is->hy_state = STARTUP;			} else {				printf("hy%d: Adapter Power Restored (hyint)\n", unit);			}#endif		} else {

⌨️ 快捷键说明

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