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

📄 if_scs.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifndef lintstatic char *sccsid = "@(#)if_scs.c	4.2	(ULTRIX)	11/14/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 - 1989 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: * *	23-Aug-1990	larry *		Can only pre map transmit ptes on a VAX.  For mips we have  *		to map transmit buffers just before the send and unmap *		when transfer is acked.  * *	20-Jun-1989	larry *		In scsnet_msgevent: init mbuf pointer to 0 and do not *			free mbuf when cant allocate cluster (just goto bad). *			The latter change should clear up an mbuf panic. * *	15-Jun-1989	jaw *		move IPL raising to earlier in scs_init code.  This is *		to fix a panic while doing an ifconf.... * *	14-May-1989	Todd M. Katz		TMK0002 *		This is the original modification history for the V3.1 pool *		merged by means of the previous two changes: *		1. The macro Scaaddr_lol() has been renamed to Scaaddr_low(). *		   It now accesses only the low order word( instead of low *		   order longword ) of a SCA system address.  The macro *		   Scaaddr_hos() has been renamed to Scaaddr_hi().  Make use of *		   the new macro Scaaadr_mid(). *		2. Modify TMK0001 to use the shorthand notation Lproc_name when *		   refering to the corresponding MSB field. * *	8-May-1989 - Larry Cohen *		Merge in delta's 9.2 and 9.3 from the 3.1 pool * *	4-Apr-1989 - Larry Cohen *		Add smp support.  Output serialized on each system.  Can *		send to  multiple systems at once. * *	15-Mar-1989	Tim Burke *		Changed queue manipulations to use the following macros: *		remque ..... Remove_entry *		insque ..... Insert_entry * *	28-Dec-1988 - Larry Cohen *		- remove "cant copy mbuf" printf.  Out of memory when *			when this happens. Consistent with other drivers. * *	17-Oct-1988 - Larry Cohen *		- validate host number during init. *		- remove scs_disconnect's because they will fail anyway. *			They need to be scheduled with ksched. *		- change reject failures from panics to printfs. * *	02-Sep-1988 - Todd M. Katz		TMK0001 *		Pass local SYSAP name to SCS when crashing path. * *	31-Aug-1988 - Larry Cohen *		- bug fixes.  handle offset packets correctly. * *	29-July-1988 - Larry Cohen *		- added version number to link level protocol *		- made data structures configurable based on SCSNET_MAXHOSTS * *	12-July-1988 - Larry Cohen *		Use one typeII mbuf for receiving block transfers.   *		Return if not IFF_UP. *		TBIS when finish xmit instead of at start. * *	27-Jun-1988 - Larry Cohen *		when transmit times out crash the path * *      02-Jun-1988     Ricky S. Palmer *              Removed inclusion of header file ../vaxmsi/msisysap.h * *	15-Mar-88 - Larry Cohen *		remove m_clalloc and kmalloc pages only. *	 *	15-Jan-88 - lp *	Changed usage of Mbutl as it is gone */#include "../data/if_scs_data.c"/**************************************************************************** *			       Overview * * This driver provides an Internet only interface to the System * Communications Services (SCS) subsystem. * The driver is initialized by the ifconfig(8) command.  Broadcasting * is supported. * * RESTRICTIONS that apply are as follows: * 1.  The SCS message size must be at least 256 bytes. * 2.  Any host that participates in an SCS based subnet must have a host number *	between 1 and 16 inclusive. * * When the driver is initialized an attempt is made to connect to all known * SCS nodes.  Each connection attempt contains the local internet address. * If the remote node is an ULTRIX-32 node and a corresponding * driver is configured into the remote node, an accept will be issued that  * includes the remote nodes internet address.  Connection collisions * are handled simply by rejecting a request if the remote SCS system ID is  * greater than the SCS system ID of the local node. * After each connection is established the driver adds the connection * identification information to a known system list that is indexed off * of the internet host number.  The driver can now easily translate the * internet destination of a packet into a SCS connection identifier. *  * Transmission of packets is handled in the following manner: *	The protocol layer calls the output routine with a packet to  * transmit.   The output routine will size the packet and if it is less * than or equal to the size of an SCS datagram the packet is copied into * the datagram and shipped.  If the packet is larger than a datagram a  * SCS block transfer is used to transfer the data to the remote host. * 	The link level protocol for datagrams is quite simple.  A long word  * at the beginning of the datagram is reserved for the protocol family.   * (Only the Internet family is supported for now)  The data is then copied into * the remaining portion of the datagram.  If the driver is unable to * transmit the datagram for any reason, the  data is released.  Datagrams * are not retransmitted or queued. It is the responsibility of higher level * protocols to retransmit.  After the SCS layer transmits the datagram the * datagram buffer is deallocated. * Upon receiving the data the remote driver copies the data into an mbuf chain * and passes the chain up to the higher level protocols.  The datagram buffer * is requeued for reception. * 	The block transfer protocol is a little more complicated.  The local * driver must first determine if there enough resources to initiate the * transfer.   Initially there are enough resources to handle five concurrent * block transfers to each host.  If there are not enough resources the block * transfer is queued in the driver.  The resource in this case is a set * of pte's which are used to map the output packet into a virtually * contiguous buffer. The SCS subsystem requires that the data to be transferred * be virtually contiguous.  Unfortunately the data arrives as a noncontiguous * chain of mbufs.  Rather than allocate or reserve large chunks of memory and * copy the data into it, the driver tries its best to copy ptes instead.  It * can only do this if the data to be copied is in cluster sized and cluster * aligned chunks.   Once the data fails to meet the latter requirement, storage * is allocated and mapped.  The data is then copied into the new buffer.   * After the data is mapped a sequenced message is sent to the remote driver * requesting the initiation of a block transfer. * The format of a sequenced message is as follows: *  *	struct _bhandle bhandle;	 *	u_long  rspid;		 *	long totlen; *	u_short cmd; *	u_short off; *   	char proto_hdr[];	 * *   bhandle is the local buffer handle.  The remote driver uses this handle to *	point SCS to the local buffer.   * *   rspid doubles as a transaction response identifier and as an index into *	a transaction control block that contains information about the *	transaction. * *   totlen is the length of the block transfer.      * *   cmd represents the purpose of the message.   The message could be a request *	to initiate a block transfer or an acknowledgement from the remote *	driver. * *   off is the offset into the local buffer where the transaction begins. * *   proto_hdr marks the the point in the sequenced message where the protocol *	type is stored and possibly one mbufs worth of data (which *	is usually a higher level protocol header) * * * Upon receiving the block transfer request the remote driver will gather up * enough storage to hold the incoming transfer.   Just as in the output case * the receive buffer must be virtually contiguous.  To accomodate SCS one  * type II mbuf is allocated.  If there is enough * memory for a receive buffer a SCS block request is started. * Otherwise a negative acknowledgement is returned.  If the local driver * receives a negative acknowledgement the output packet is discarded.  Since * the remote driver is initially prepared to handle all incoming requests * from each host and a host will not send more than it's quota, the only  * valid reason for a failure is the inability of the remote host to obtain * memory.  If the block transfer completes successfully the remote * driver sends back a positive acknowledgement.  The local driver will then * free up the output packet and check to see if there are any pending  * transactions. * *****************************************************************************//*TODO:have to fork off scs event disconnects Most should never happen but ...Need to make scsmempt in spt.s configurable.  Currently we have enoughptes for 32 hosts, 5 xfers per host, 17 ptes per xfer.Currently need to reboot if set address of the interface incorrectly withifconfig.   Should do something like crash all paths if we set interfaceto a new address and then reestablish connections with new address.stats:	keep track of failures to send data: datagram and block transfers.protocol independent.SMP flag to copy instead of pte flip.SMP safe.Place xfer control blocks in netsys structure.Dynamically allocate data structures.Get rid of overly complicated output code.In future versions we may want to use the VERSION field in the conn datato reject a connection.  Algorithm:  lower versions are passive and issuean accept if they receive a higher number version.  Higher versions issuethe reject if they receive a lower number version during a remote connectrequest or when their active connect request completes.*/int scsnet_timer = 0; 		/* watch dog timer on/off indicator */int scsnet_timeo;/* *	Commonly used macros */#define Scsnet_msg_hdr_siz  ((char *)&scsnet_msg_x.proto_hdr[0] - \				(char *)&scsnet_msg_x)#define Scsnet_Return_ENOBUFS \	(void)splx( ipl ); \	m_freem(m0);	   \	ifp->if_oerrors++;   \	return( ENOBUFS ); #define Scsnet_If_Enqueue_Return \        if (IF_QFULL(&ifp->if_snd)) {   \                IF_DROP(&ifp->if_snd);  \		smp_unlock(&scs_dst->lk_netsys); \		Scsnet_Return_ENOBUFS   \        }				\	m = m_get(M_DONTWAIT, MT_DATA); \	if (m == 0) {			\		smp_unlock(&scs_dst->lk_netsys); \		Scsnet_Return_ENOBUFS   \	}				\	{				\	struct sockaddr *sdst; \	sdst = mtod(m, struct sockaddr *); \	*sdst = *dst;		\	m->m_next = m0;			\	}				\        IF_ENQUEUE(&ifp->if_snd, m);	\	smp_unlock(&scs_dst->lk_netsys); \	(void)splx( ipl );		\	return(0);			#define Sysid_greater(h,t) 					\	( Scaaddr_hi( h ) > Scaaddr_hi( t )	 	||	\	  ( Scaaddr_hi( h ) == Scaaddr_hi( t ) &&		\	    Scaaddr_mid( h ) > Scaaddr_mid( t ))	||	\	  ( Scaaddr_hi( h ) == Scaaddr_hi( t )   &&		\	    Scaaddr_mid( h ) == Scaaddr_mid( t ) &&		\	    Scaaddr_low( h ) > Scaaddr_low( t )))#define Print_sysid(s) \        printf("sysid=%d,%d,%d\n",                      \                Scaaddr_hi( s ), Scaaddr_mid( s ), Scaaddr_low( s ));#define Scsnet_enqueue(m) {						\	struct ifqueue *inq;						\	u_long *proto_type;						\	int ipl;							\									\	proto_type = mtod (m , u_long *);  /* protocol type */ 		\	m->m_off += sizeof(long); /* point to beginning of data */ 	\	m->m_len -= sizeof(long); 					\									\	if (*proto_type == AF_INET) {					\	/* enqueue mbuf chain on protocol queue */			\		if (nINET==0) {						\			m->m_off -= sizeof(long);			\			m_freem(m);					\		} else {						\			inq = &ipintrq;					\			ipl = splimp();					\			smp_lock(&inq->lk_ifqueue, LK_RETRY);		\			schednetisr(NETISR_IP);				\			if (IF_QFULL(inq)) {				\				IF_DROP(inq);				\				m->m_off -= sizeof(long);		\				m_freem(m);				\			} else						\				IF_ENQUEUE(inq, m);			\			smp_unlock(&inq->lk_ifqueue);			\			(void)splx(ipl);				\		}							\	}								\	else								\		panic("scsnet_event - unknown proto");			\    }								/* Scsnet_resolve - resolve an Internet address into an SCS address */#define Scsnet_resolve(inet_dst,scs_dst) {   				\	register int rmthost = in_lnaof(inet_dst) & 0xff;		\	register struct _netsystem *netsys;				\									\	/* check validity of inet address */				\	if (rmthost>=SCSNET_MAXHOSTS || rmthost<0) {			\		printf("scsnet_resolve: invalid host %d\n", rmthost);	\		m_freem(m0);						\		return(0);						\	}								\									\	/*								\	 * are we connected to this system yet?  If not then		\	 * we return failure and hope that we are informed		\	 * about this system later and connect to it.			\	 */								\	if ((netsys = knownsystems[rmthost]) == SCSNET_NO_SYS) {	\		if (scsnetdebug)					\		    printf("scsnet: conn not resolved to %d\n", rmthost);\		m_freem(m0);						\		return(0);						\	}								\									\	if (netsys->status == SCSNET_CONN_OPEN)				\		scs_dst = netsys;					\	else {								\		if (scsnetdebug)					\		     printf("scsnet_resolve: conn is not open, status=%d\n", \			netsys->status);				\		m_freem(m0);						\		return(0);						\	}								\    }									\int scsnet_ioctl(), scsnet_output();void scsnet_control(), scsnet_attach();void scsnet_dgevent();void scsnet_msgevent();struct _netsystem * alloc_netsys();void scsnet_watch();int scsnetdebug = 0;/* track packet sizes */int scsnetstaton = 0;int scsnetstat[10];scaaddr scsnet_nosysid = { -1, -1 };/* scsnet_attach() - make interface known to system *  * Inputs: * 	scsnetif - system wide network interface information * Output: * 	scsnetif  * */voidscsnet_attach(){	register struct ifnet *ifp = &scsnetif;	register int i;	extern u_short scs_msg_size;	if (scs_msg_size < scsnet_min_msg_siz) {		printf("scsnet: attach failed, scs_msg_size is less than %d\n",			scsnet_min_msg_siz);		return;	}	ifp->if_name = "scs";	/* 	 * ASSUMPTION:  upper protocols always store protocol header at	 * the head of the data chain in a small mbuf.  This being true	 * we can transfer the protocol header in a msg buffer while the	 * rest of the data is transmitted via a block transfer.	 */	ifp->if_mtu = scsnet_block_size + scs_msg_size - SCSNET_HDR_SIZ;	ifp->if_ioctl = scsnet_ioctl;	ifp->if_output = scsnet_output;	ifp->if_flags |= IFF_BROADCAST;	ifp->d_affinity = ALLCPU;	lockinit(&lk_scsnetknownsys,  &lock_scsnetknownsys_d);	lockinit(&lk_netsystems, &lock_scsnetknownsys_d);	lockinit(&lk_scsnetrecvs, &lock_scsnetrecvs_d);	lockinit(&scsnetif.if_snd.lk_ifqueue, &lock_device15_d);	for (i=0; i<SCSNET_MAXHOSTS; i++)		lockinit(&netsystems[i].lk_netsys, &lock_scsnetsys_d);	if_attach(ifp);}/******************************************************************* *   scsnet_init() - Initialize the scs network sysap. *	1.  place scs network sysap in listening state so that remote *		network sysaps can establish a connection to us. *	2.  determine known systems and establish connections to  *		those systems that are running an scs network sysap. *      3.  mark up and running. * *  Inputs: *	knownsystems *	scsnet_local - local system SCS info. *	scsnetif *  Outputs: *	knownsystems */scsnet_init() {	struct ifnet *ifp = &scsnetif;	register ISB *isb = &netisb;	register struct _netsystem *netsystem;	register struct ifaddr *ifa;	register SIB *s;	register int i;	int ret;	scaaddr sid;	int ipl;	extern int ifqmaxlen;

⌨️ 快捷键说明

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