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

📄 if_hy.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)if_hy.c	4.1 (ULTRIX) 7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1985 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *			Modification History				* *									* * 05-Feb-89  -- R. Bhanukitsiri					* *			Reflect V3.2 source pool changes. Also, include	* *			Lea's changes from 27-Jul-88 (added & typo).	* *									* * 12-Apr-88  -- lea	43.5bsd fixes					* *									* * 13-Jun-86   -- jaw 	fix to uba reset and drivers. *									* * 18-mar-86  -- jaw     br/cvec changed to NOT use registers. * *	Larry Cohen  -	09/16/85					* * 		Add 43bsd alpha tape changes for subnet routing		* *									* ************************************************************************//* * Copyright (c) 1982 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * *      @(#)if_hy.c     7.1 (Berkeley) 6/5/86 *//* * 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 || defined(BINARY)#include "../data/if_hy_data.c"/* * configuration specific paramters *	- change as appropriate for particular installaions */#define	HYELOG#define	HYLOG#define	HYMTU	1100#ifdef HYELOGu_long	hy_elog[HYE_SIZE];#endif#ifdef HYLOGstruct hy_log hy_log;#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) */int	hyprobe(), hyattach(), hyinit(), hyioctl();int	hyoutput(), hyreset(), hywatch();u_short hystd[] = { 0772410, 0 };struct	uba_driver hydriver =	{ hyprobe, 0, hyattach, 0, hystd, "hy", hyinfo };char *hy_state_names[] = {        "Startup",        "Idle",        "Status Sent",        "End op Sent",        "Recieve Message Proper Sent",        "Recieve Data Sent",        "Transmit Message Proper Sent",        "Transmit Data Sent",        "Wait for Message Sent",        "Clear Wait for Message Sent",        "Mark Port Down Sent",        "Read Statistics Sent"};/* * Network Systems Copropration Hyperchanel interface *//* * 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 struct hydevice *addr = (struct hydevice *) reg;#ifdef lint	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 >= nNHY || (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 {			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);

⌨️ 快捷键说明

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