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

📄 dli_init.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef	lintstatic char *sccsid = "@(#)dli_init.c	4.2	ULTRIX	9/4/90";#endif	lint/* * Program dli_init.c,  Module DLI  * * Copyright (C) 1985 by * Digital Equipment Corporation, Maynard, Mass. * * 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. * * 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. * * * Networks & Communications Software Engineering * * IDENT HISTORY: * * 1.00 10-Jul-1985 *      DECnet-ULTRIX   V1.0 * * 2.00 18-Apr-1986 *		DECnet-Ultrix	V2.0 * * Added sysid and point-to-point support * */#include "../../h/param.h"#include "../../h/systm.h"#include "../../h/mbuf.h"#include "../../h/protosw.h"#include "../../h/socket.h"#include "../../h/socketvar.h"#include "../../h/errno.h"#include "../../h/ioctl.h"#include "../../h/dir.h"#include "../../h/user.h"#include "../../h/kernel.h"#include "../../h/buf.h"#include "../../h/conf.h"#include "../../h/proc.h"#include "../../h/smp_lock.h"#include "../../h/cpudata.h"#include "../../net/net/if.h"#include "../../net/netinet/in.h"#include "../../net/netinet/if_ether.h"#include "../../net/netdnet/dli_var.h"extern struct ifqueue dli_intrq;extern u_short dli_ifq_maxlen;extern struct ether_header no_enet_header;extern struct dli_line dli_ltable[];extern struct dli_line *dli_ltableptrs[];extern struct dli_timers lback_timers[];extern u_char sysid_msg[];extern struct ether_pa *sysid_haddr_p;extern struct sockaddr_dl sysid_dst;extern struct lock_t lk_dli;extern u_char *sysid_devtyp_p;extern struct dli_sysid_to sysid_to[];extern struct dli_sysid_dev sysid_dev[];extern u_short nqna;extern u_char sysid_mcast[];extern struct if_isapt if_isapt[];/* *		d l i _ i n i t * * This routine is called during the system boot sequence to initialise the * DLI protocol module. * * Outputs:		None. * * Inputs:		None.   * * Version History: *	3/7/85	- ejf - account for MOP loopback capability */dli_init(){	int i, k = 0, n;	register struct ifnet *ifp = ifnet;	struct ifreq dreq;	int saveaffinity;   /* for nonsym drivers.  8.18.88.us  */	dli_intrq.ifq_maxlen = dli_ifq_maxlen;	lockinit(&lk_dliintrq, &lock_ifqueue_d);	lockinit(&lk_dli, &lock_dli_d);	/*	 * Lock DLI protocol even though boot is on primary processor.	 * This is for protection in case they choose to change this strategy	 * of booting on one processor in the future.	 */	smp_lock(&lk_dli, LK_RETRY);	/*	 * Clear out array containing structures and init lock for each line.	 */	for( i = 0; i < dli_maxline; i++ )	{		bzero((u_char *) &dli_ltable[i], sizeof(struct dli_line));		dli_ltableptrs[i] = &dli_ltable[i];		lockinit(&dli_ltable[i].dli_lk, &lock_dliline_d);	}	/*	 * init local variables	 */	bzero(&no_enet_header, sizeof(no_enet_header));	/*	 * Disable loopback timer data base.	 */	for( i = 0; i < DLI_MAX_LBTIMR; i++ )	{		lback_timers[i].tval = 0;	}	/*	 * enable MOP Loopback Multicast Address on each device.	 */	bzero(dreq.ifr_addr.sa_data, DLI_EADDRSIZE);	dreq.ifr_addr.sa_data[0] = 0xcf;	i = 0;	while ( ifp )	{		if ( (ifp->if_flags & (IFF_BROADCAST | IFF_DYNPROTO)) == (IFF_BROADCAST | IFF_DYNPROTO))		{			u_char devtyp;			smp_unlock(&lk_dli);			CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);			(*ifp->if_ioctl)(ifp, SIOCADDMULTI, &dreq);			RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);			smp_lock(&lk_dli, LK_RETRY);			/*			 * enable 802.3 data structures			 * 1 per ethernet device			 */			if( osi_802init(ifp) < 0)				printf("dli_init: osi_802init: device %d isap struct init failed\n", ifp->if_unit);			/*			 * check to see if sysid support is needed for device.			 */			if( (devtyp = dli_sysid_support(ifp->if_name)) && (i <= MAXQNAS) ) 			{				if(dli_init_sysidto(ifp, devtyp) < 0)					printf("dli_init: dli_init_sysidto: timeout struct %d init failed\n", ifp->if_unit);				else					i++;			}		}		ifp = ifp->if_next;	}	if(nqna = i)                 /* only build sysid msg if uVAX */		dli_init_sysidmsg();	smp_unlock(&lk_dli);}/* * * Build sysid messasge for uVAX's * hardware should have done this *  */dli_init_sysidmsg(){	u_char *msgp = sysid_msg;	int i;	/* outgoing information */	sysid_dst.dli_family = AF_DLI;           	sysid_dst.dli_substructype = DLI_ETHERNET;	bcopy("qe", sysid_dst.dli_device.dli_devname, 2);	sysid_dst.choose_addr.dli_eaddr.dli_protype = SYSIDPROTO;	*(struct ether_pa *)sysid_dst.choose_addr.dli_eaddr.dli_target = *(struct ether_pa *)sysid_mcast; /* initialize sysid message, have to do it this way to avoid padding */	PUT16B(msgp, (SYSID_MSGL-2));       /* length header */	PUT8B(msgp, SYSID_CODE);            /* sysid code */	PUT8B(msgp, NULL);                  /* reserved */	PUT16B(msgp, NULL);                 /* receipt number */	PUT16B(msgp, MAINTV);               /* info type, maint ver */	PUT8B(msgp, (3*sizeof(u_char)));   /* length of info */	PUT8B(msgp, VER);                   /* version */	PUT8B(msgp, ECO);                   /* eco */	PUT8B(msgp, USER_ECO);              /* user eco */	PUT16B(msgp, FUNCTIONS);            /* info type, functions */	PUT8B(msgp, sizeof(u_short));      /* length of info */	/* May need to worry about byte ordering */	PUT8B(msgp, (FNC_LOOP | FNC_CTRS));	PUT8B(msgp, NULL);                  /* reserved */	PUT8B(msgp, HADDR);                /* info type, hardware addr */	PUT8B(msgp, NULL);                  /* reserved */	PUT8B(msgp, sizeof(struct ether_pa)); /* length of info */	sysid_haddr_p = (struct ether_pa *)msgp;/* save ptr to hw_addr */	for(i = 0; i < sizeof(struct ether_pa); i++)		PUT8B(msgp, NULL);              /* clear it out and move ptr */	PUT8B(msgp, COMDEV);               /* info type, device */	PUT8B(msgp, NULL);                  /* reserved */	PUT8B(msgp, sizeof(u_char));       /* length of info */	sysid_devtyp_p = msgp;		   /* save for later */	PUT8B(msgp, 0);                   /* device type is NULL */	return;}/* * * Initialize the sysid time out structures * Note:  The DLI protocol lock must be taken * 	  out before this routine is called. * */dli_init_sysidto(ifp, devtyp)struct ifnet *ifp;u_char devtyp;{    static int i = 0;    int len, n = 0, c, j;     short tmp, unit;    char num[6];    int saveaffinity;    if(i >= MAXQNAS)    {	return(-1);    }    sysid_to[i].devtyp = devtyp;    sysid_to[i].ifp = ifp;    unit = ifp->if_unit;    do {        /* convert short to ascii (backwards) */	    num[n++] = unit % 10 + '0';    } while (( unit /= 10) > 0);    num[n] = '\0';    len = n + 1;    /* put it in the right order */    for(j = 0, n -= 1; j < n; j++, n--)    {	    c = num[j];	    num[j] = num[n];	    num[n] = c;    }    bcopy(ifp->if_name, sysid_to[i].dev.ifr_name, 2);    bcopy(num, &sysid_to[i].dev.ifr_name[2], len);    CALL_TO_NONSMP_DRIVER( (*ifp), saveaffinity);    (*ifp->if_ioctl)(ifp, SIOCRPHYSADDR, (caddr_t)&sysid_to[i].dev);    RETURN_FROM_NONSMP_DRIVER( (*ifp), saveaffinity);    tmp = *(short *)&sysid_to[i].dev.current_pa[4];    sysid_to[i].tr =  sysid_to[i].to = (tmp + 150000) * 4 / 500;    i++;    return(NULL);}/* *		d l i _ s y s i d _ s u p p o r t * * This routine checks to see if a device needs sysid support.  If so, it * returns the device type value stated in the MOP spec, Appendix A. * * Outputs:		device type if support needed, otherwise 0. * * Inputs:		device name as it appears in ifnet structure.   * */dli_sysid_support(devnam)u_char *devnam;{	int i, nsiz = 0; 	while ( *(devnam+nsiz) )		nsiz++;	i = -1;	while ( sysid_dev[++i].devtyp )		if ( bcmp(devnam, sysid_dev[i].devnam, nsiz) == 0 )			return(sysid_dev[i].devtyp);	return(0);}

⌨️ 快捷键说明

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