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

📄 if_dmc.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifndef lintstatic char *sccsid = "@(#)if_dmc.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: /sys/vaxif/if_dmc.c * * 29-nov-88 -- jaw     remove sysproc stuff. * * 02-mar-87  -- ejf    check address of protocol switch routines before *			calling them. * * 04-jan-86  -- ejf    fixed problem whereby DECnet counters were being *			zeroed whenever the line cycled. * * 16-dec-86  -- ejf    manipulate Tx Q at splimp, not spl5. * * 18-apr-86  -- ejf     added DECnet support. * * 18-mar-86  -- jaw     br/cvec changed to NOT use registers. * *  03/12/86 -- Chet Juszczak *		Modify MCLGET macro call to match new definition * *  09/16/85 -- Larry Cohen * 		Add 43bsd alpha tape changes for subnet routing *							 * 19-Jun-85 -- jaw *	VAX8200 name change. * * 13 Mar 85 -- jaw *		add support for VAX 8200 and bua * * 29 Oct 84 -- jrs *	Update with latest version (1.12) from: *		Bill Nesheim (Cornell) *		Lou Salkind  (NYU) * *	Derived from 4.2BSD, labeled: *		if_dmc.c 6.1	83/07/29 * * ----------------------------------------------------------------------- */#include "dmc.h"#if NDMC > 0 || defined(BINARY)/* * DMC11 device driver, internet version *//* #define DEBUG 	/* for base table dump on fatal error */#include "../data/if_dmc_data.c"int	dmctimer;			/* timer started? */int	dmc_timeout = 25;		/* timeout value */int	dmcwatch();#define printd if(dmcdebug)printfint dmcdebug = 0;/* error reporting intervals */#define DMC_RPNBFS	50#define DMC_RPDSC	50#define	DMC_RPTMO	10#define DMC_RPDCK	10struct mbuf *dmc_get();extern struct protosw *iftype_to_proto(), *iffamily_to_proto();extern struct timeval time;extern int boot_cpu_mask;/* * DMC software status per interface. * * Each interface is referenced by a network interface structure, * sc_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  set of 7 UBA interface structures * for each, which * contain 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. *//* flags */#define DMC_ALLOC       01              /* unibus resources allocated */#define DMC_BMAPPED     02              /* base table mapped */#define	DMC_RESTART	04		/* software restart in progress */#define	DMC_ACTIVE	08		/* device active *//* * Driver information for auto-configuration stuff. */int     dmcprobe(), dmcattach(), dmcinit(), dmcioctl();int     dmcoutput(), dmcreset();u_short dmcstd[] = { 0 };struct  uba_driver dmcdriver =        { dmcprobe, 0, dmcattach, 0, dmcstd, "dmc", dmcinfo };/* * dmc software packet encapsulation.  This allows the dmc * link to be multiplexed among several protocols. * The first eight bytes of the dmc header are garbage, * since on a vax the uba has been known to mung these * bytes.  The next two bytes encapsulate packet type. */struct dmc_header {	char	dmc_buf[8];	/* space for uba on vax */	short	dmc_type;	/* encapsulate packet type */};/* queue manipulation macros */#define	QUEUE_AT_HEAD(qp, head, tail) \	(qp)->qp_next = (head); \	(head) = (qp); \	if((tail) == (struct dmc_command *) 0) \		(tail) = (head) #define QUEUE_AT_TAIL(qp, head, tail) \	if((tail)) \		(tail)->qp_next = (qp); \	else \		(head) = (qp); \	(qp)->qp_next = (struct dmc_command *) 0; \	(tail) = (qp)#define DEQUEUE(head, tail) \	(head) = (head)->qp_next;\	if((head) == (struct dmc_command *) 0)\		(tail) = (head)dmcprobe(reg)        caddr_t reg;{        register struct dmcdevice *addr = (struct dmcdevice *)reg;        register int i;#ifdef lint        dmcrint(0); dmcxint(0);#endif        addr->bsel1 = DMC_MCLR;        for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)                ;        if ((addr->bsel1 & DMC_RUN) == 0) {		printf("dmcprobe: can't start device\n" );                return (0);	}        addr->bsel0 = DMC_RQI|DMC_IEI;	/* let's be paranoid */        addr->bsel0 |= DMC_RQI|DMC_IEI;        DELAY(1000000);        addr->bsel1 = DMC_MCLR;        for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)                ;        return (1);}/* * Interface exists: make available by filling in network interface * record.  System will initialize the interface when it is ready * to accept packets. */dmcattach(ui)        register struct uba_device *ui;{        register struct dmc_softc *sc = &dmc_softc[ui->ui_unit];	struct dmcdevice *addr = (struct dmcdevice *)dmcinfo[ui->ui_unit]->ui_addr;        sc->sc_if.if_unit = ui->ui_unit;        sc->sc_if.if_name = "dmc";        sc->sc_if.if_mtu = DMCMTU;        sc->sc_if.if_init = dmcinit;        sc->sc_if.if_output = dmcoutput;        sc->sc_if.if_ioctl = dmcioctl;        sc->sc_if.if_reset = dmcreset;        sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_DYNPROTO;        sc->sc_if.d_affinity = boot_cpu_mask;        sc->sc_ifuba.ifu_flags = UBA_CANTWAIT;	bzero(&sc->sc_dmccs, sizeof(sc->sc_dmccs));	bzero(sc->sc_basectrs, sizeof(sc->sc_basectrs));	bzero(sc->sc_errctrs, sizeof(sc->sc_errctrs));	sc->sc_dmccs.if_family = AF_UNSPEC;	sc->sc_dmccs.if_next_family = AF_UNSPEC;	sc->sc_dmccs.if_mode = ui->ui_flags;	if ( (sc->sc_bufres.dmrdev = dmc_is_dmr(addr)) && 		(sc->sc_bufres.nxmt = ((NXMT_MASK & ui->ui_flags) >> NXMT_SHIFT)) > NXMT_MIN ) {		if (sc->sc_bufres.nxmt > NXMT_MAX) 			sc->sc_bufres.nxmt = NXMT_MAX;	} else		sc->sc_bufres.nxmt = NXMT_MIN;	sc->sc_bufres.nrcv = NRCV;	sc->sc_bufres.ntot = sc->sc_bufres.nrcv + sc->sc_bufres.nxmt;	sc->sc_bufres.ncmds = sc->sc_bufres.ntot + 4;        if_attach(&sc->sc_if);	if (dmctimer == 0) {		dmctimer = 1;		timeout(dmcwatch, (caddr_t) 0, hz);	}}/* * Check to see if device is a dmc or dmr. * Return 0 if dmc, return 1 if dmr. */dmc_is_dmr(addr)struct dmcdevice *addr;{	int i;	addr->bsel3 = DMC_DMRCHK;        addr->bsel1 = DMC_MCLR;        for (i = 100000; i && (addr->bsel1 & DMC_RUN) == 0; i--)                ;        if ((addr->bsel1 & DMC_RUN) == 0) {		printf("dmc_is_dmr: can't start device\n" );                return (0);	}	switch ( addr->bsel3 & DMR_MASK )	{		case DMR_0001:		case DMR_0002:		case DMR_0100:		case DMR_0200:			return(1);		default:			return(0);	}}/* * Reset of interface after UNIBUS reset. * If interface is on specified UBA, reset it's state. */dmcreset(unit, uban)        int unit, uban;{        register struct uba_device *ui;        register struct dmc_softc *sc = &dmc_softc[unit];        if (unit >= nNDMC || (ui = dmcinfo[unit]) == 0 || ui->ui_alive == 0 ||            ui->ui_ubanum != uban)                return;        printf(" dmc%d", unit);        sc->sc_flag = 0;        dmcinit(unit);}/* * Initialization of interface; reinitialize UNIBUS usage. */dmcinit(unit)        int unit;{        register struct dmc_softc *sc = &dmc_softc[unit];        register struct uba_device *ui = dmcinfo[unit];        register struct dmcdevice *addr;        register struct ifnet *ifp = &sc->sc_if;        register struct ifrw *ifrw;	register struct ifxmt *ifxp;        register struct dmcbufs *rp;	register struct dmc_command *qp;	register struct ifaddr *ifa;        int base;	int s;        addr = (struct dmcdevice *)ui->ui_addr;	for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)		if (ifa->ifa_addr.sa_family && ifa->ifa_dstaddr.sa_family)			break;	if (ifa == (struct ifaddr *) 0)		return;        if((addr->bsel1&DMC_RUN) == 0) {                printf("dmcinit: DMC not running\n");                ifp->if_flags &= ~(IFF_RUNNING|IFF_UP);                return;        }        /* map base table */        if ((sc->sc_flag & DMC_BMAPPED) == 0) {                sc->sc_ubinfo = uballoc(ui->ui_ubanum,                        (caddr_t)&dmc_base[unit],                        sizeof (struct dmc_base), 0);                sc->sc_flag |= DMC_BMAPPED;        }        /* initialize UNIBUS resources */        sc->sc_iused = sc->sc_oused = 0;        if ((sc->sc_flag & DMC_ALLOC) == 0) {                if (dmc_ubainit(&sc->sc_ifuba, ui->ui_ubanum,		    sizeof(struct dmc_header), (int)btoc(DMCMTU), &sc->sc_bufres) == 0) {                        printf("dmc%d: can't initialize\n", unit);                        ifp->if_flags &= ~IFF_UP;                        return;                }                sc->sc_flag |= DMC_ALLOC;        }        /* initialize buffer pool */        /* recieves */        ifrw= &sc->sc_ifuba.ifu_r[0];        for(rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[sc->sc_bufres.nrcv]; rp++) {                rp->ubinfo = ifrw->ifrw_info & 0x3ffff;		rp->cc = DMCMTU + sizeof (struct dmc_header);                rp->flags = DBUF_OURS|DBUF_RCV;                ifrw++;         }        /* transmits */        ifxp= &sc->sc_ifuba.ifu_w[0];        for(rp = &sc->sc_xbufs[0]; rp < &sc->sc_xbufs[sc->sc_bufres.nxmt]; rp++) {                rp->ubinfo = ifxp->x_ifrw.ifrw_info & 0x3ffff;                rp->cc = 0;                rp->flags = DBUF_OURS|DBUF_XMIT;                ifxp++;         }	/* set up command queues */	sc->sc_qfreeh = sc->sc_qfreet		 = sc->sc_qhead = sc->sc_qtail = sc->sc_qactive =		(struct dmc_command *)0;	/* set up free command buffer list */	for (qp = &sc->sc_cmdbuf[0]; qp < &sc->sc_cmdbuf[sc->sc_bufres.ncmds]; qp++) {		QUEUE_AT_HEAD(qp, sc->sc_qfreeh, sc->sc_qfreet);	}	/*	 * if coming through for the first time, zero out counters.	 * else remember counters	 */	if ( ! (ifp->if_flags & IFF_RUNNING) ) {		sc->sc_ztime = time.tv_sec;		bzero(&sc->sc_rxtxctrs[DMCZ_RXBYTE], sizeof(sc->sc_rxtxctrs));		bzero(sc->sc_errctrs, sizeof(sc->sc_errctrs));	}	else		dmc_update_errctrs(sc, (u_char *) &dmc_base[unit].d_base[0]);	bzero(sc->sc_basectrs, sizeof(sc->sc_basectrs));	/* set up internal loopback if requested */	if ( ifp->if_flags & IFF_LOOPBACK )		addr->bsel1 |= DMC_ILOOP;        /* base in */        base = sc->sc_ubinfo & 0x3ffff;        dmcload(sc, DMC_BASEI, base, (base>>2) & DMC_XMEM);        /* specify half duplex operation, flags tell if primary */        /* or secondary station */        if (sc->sc_dmccs.if_mode == 0)                /* use DDMCP mode in full duplex */		dmcload(sc, DMC_CNTLI, 0, 0);        else if (sc->sc_dmccs.if_mode == 1)                /* use MAINTENENCE mode */                dmcload(sc, DMC_CNTLI, 0, DMC_MAINT );        else if (sc->sc_dmccs.if_mode == 2)                /* use DDCMP half duplex as primary station */                dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX);        else if (sc->sc_dmccs.if_mode == 3)                /* use DDCMP half duplex as secondary station */                dmcload(sc, DMC_CNTLI, 0, DMC_HDPLX | DMC_SEC);        /* enable operation done interrupts */        sc->sc_flag &= ~DMC_ACTIVE;        while ((addr->bsel2 & DMC_IEO) == 0)                addr->bsel2 |= DMC_IEO;        s = splimp();        /* queue first NRCV buffers for DMC to fill */        for(rp = &sc->sc_rbufs[0]; rp < &sc->sc_rbufs[sc->sc_bufres.nrcv]; rp++) {                rp->flags |= DBUF_DMCS;                dmcload(sc, DMC_READ, rp->ubinfo,                        (((rp->ubinfo>>2)&DMC_XMEM) | rp->cc));                sc->sc_iused++;        }	splx(s);        ifp->if_flags |= IFF_UP|IFF_RUNNING;	if ( sc->sc_dmccs.if_mode == IFS_MOP )		ifp->if_flags |= IFF_MOP;	else		ifp->if_flags &= ~IFF_MOP;

⌨️ 快捷键说明

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