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

📄 lat_slot.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char *sccsid = "@(#)lat_slot.c	4.1.1.3	2/29/88";#endif lint/************************************************************************ *									* *			Copyright (c) 1984 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.			* *									* *   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				* *									* *      Chung Wong - 1/7/88                                             * *		Add check for valid credit count in DATA slots 		* *		and ATTENTION slot for conformance.			* *                                                                      * *      Chung Wong - 7/17/87                                            * *		Added '*dptr++ = 0' in generic_start() to ensure        * *		START SLOT end with 0's.                                * *                                                                      * *	Peter Harbo - 4/15/86						* *		Modification of newslot() routine for new start slot    * *		format.							* *                                                                      * ************************************************************************//*	lat_slot.c	0.0	11/9/84	*//*	lat_slot.c	2.0	04/15/86 */#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/tty.h"#include "../net/if.h"#include "../netinet/in.h"#include "../netinet/if_ether.h"#include "../lat/lat.h"#include "../lat/lat_protocol.h"#include "../lat/lat_var.h"extern struct lat_slot sl[];extern struct sclass *sclass[];extern int maxclass;extern struct lat_counters latctrs;extern u_char slotsinuse;static struct slot_hdr shdr;struct lat_slot *findslot();caddr_t buildvchdr();/* * LAT slot management. *//* *		d e m u x * * De-multiplex a received run message among the slots present in the message. * * Outputs:		Pointer to remaining MBUF chain. * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. *	m		= Pointer to an MBUF chain containing the slot data. *	slots		= Number of slots present in the message. */struct mbuf *demux( vcir,m,slots )register struct lat_vc *vcir;register struct mbuf *m;int slots;{    register struct slot_hdr *hdr;    register struct lat_slot *slot;    u_char slotlen;    vcir->lvc_rcvact |= 1;    while (slots-- && m)    {	if (m = LAT_PULLUP(m, sizeof(struct slot_hdr)))	{	    hdr = mtod(m, struct slot_hdr *);	    shdr = *hdr;	    slotlen = shdr.shd_count;	    m_adj(m, sizeof(struct slot_hdr));	    if (shdr.shd_type == SLOT_START)	    {		if (m = LAT_PULLUP(m, min(slotlen,MLEN) ) ) 		{		    newslot(vcir, m);		}	    }	    else	    {		if (slot = findslot(vcir))		{		    switch (shdr.shd_type)		    {			case SLOT_DATA_A:			    if (slotlen)			    {                                if (slot->lsl_remcredits >= 2) goto badslot;				(*slot->lsl_scl->scl_rdataa)(vcir, slot, m, slotlen);                                if (lat_master(vcir)) /* latmaster */				    slot->lsl_attsize++;                                 else 				    slot->lsl_remcredits++;			    }			    break;			case SLOT_DATA_B:			    if (slotlen)			    {                                if (slot->lsl_remcredits >= 2) goto badslot;				(*slot->lsl_scl->scl_rdatab)(vcir, slot, m, slotlen);				slot->lsl_remcredits++;                                vcir->lvc_rcvact &= 0x0bf; 			    }			    break;			case SLOT_ATT:                            /*                             * credit filed in attention slot MBZ                             */                            if (shdr.shd_credits) goto badslot;			case SLOT_STOP:			    (*slot->lsl_scl->scl_rother)(vcir, slot, m, &shdr);			    break;			/*			 * Bad slot type received. Count the error and ignore			 * the slot.			 */badslot:			default:			    INC(lco_badslots);			    terminatevc(vcir, STOP_BADFORMAT);			    break;		    }		}	    }	    /*	     * Remove the slot data from the MBUF chain.	     */	    m_adj(m, (slotlen+1) & ~1);	}    }    vcir->lvc_rcvact &= 0x0fe;     return (m);}/* *		b u i l d s l o t h d r * * Build a slot header in the specified buffer. * * Outputs:		None. * * Inputs: *	slhdr		= Pointer to the slot header to be built. *	slot		= Pointer to slot descriptor. *	count		= Size of the slot data. *	msgtype		= Slot message type. *	reason		=  0 to include credits in slot header *			!= 0 code to place in reason field */buildslothdr( slhdr,slot,count,msgtype,reason )register struct slot_hdr *slhdr;struct lat_slot *slot;int count,msgtype,reason;{    slhdr->shd_dstid = slot->lsl_remid;    slhdr->shd_srcid = slot->lsl_locid;    slhdr->shd_count = count;    if (reason)    {	slhdr->shd_reason = reason;    }    else    {	if (lat_master(slot->lsl_vc))	/* latmaster */	    if (slot->lsl_attsize)	    {	 	register struct tty *tp = (struct tty *)slot->lsl_data;		if (!tp->t_rawq.c_cc)		{		    slot->lsl_remcredits = slot->lsl_attsize;		    slot->lsl_attsize = 0;		}	    }	slhdr->shd_credits = slot->lsl_remcredits;	slot->lsl_remcredits = 0;    }    slhdr->shd_type = msgtype;}/* *		n e w s l o t * * Try to allocate and start a new slot on the specified virtual circuit. * * Outputs:		None. * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. *	m		= Pointer to MBUF chain holding the start slot. */newslot( vcir,m )register struct lat_vc *vcir;struct mbuf *m;{    register struct lat_slot *slot;    register struct slot_start *sst = mtod(m, struct slot_start *);    register int i;    register struct sclass *class;    int reason = STOP_SLINVSERV;    register struct slot_hdr *slhdr;    struct mbuf *m0;    /*     * Make sure that we support the requested service class.     */    if ((sst->sst_class <= MAXCLASS) && (class = sclass[sst->sst_class]))    {	/*	 * Scan the system slot table for a free one.	 */	for (slot = sl,i = 0; i < LAT_MAXSLOTS; slot++,i++)	{	    if (slot->lsl_state == SST_FREE)	    {	      if ((class->scl_state == LST_RUNNING) && 	       (slot->lsl_data = (caddr_t)(*class->scl_new)(vcir, slot,sst,			&reason,shdr.shd_count)))		{		    /*		     * Initialise the new slot database.		     */		    slotsinuse++;		    vcir->lvc_act++;		    slot->lsl_vc = vcir;		    slot->lsl_class = sst->sst_class;		    slot->lsl_state = SST_STARTING;		    slot->lsl_locid = i + 1;		    slot->lsl_remid = shdr.shd_srcid;		    slot->lsl_remcredits = 2;		    slot->lsl_loccredits = shdr.shd_credits;		    slot->lsl_attsize = sst->sst_minAsize;		    slot->lsl_datasize = sst->sst_minDsize;		    slot->lsl_scl = class;                    /*                      * should be able to reuse a VC before torn down                     */	            if (vcir->lvc_state == VST_STOPING)	               vcir->lvc_state = VST_RUNNING;		    return;		}	      else	      {		  if ((reason == STOP_SLINUSE) || (reason == STOP_SLNAME) ||			(reason == STOP_SLINVSLOT) || (reason == STOP_SLNORES))			break;	      }	    }	}    }	    /*     * If this was the first slot on this virtual circuit, we should stop the     * virtual circuit after sending the reject slot.     */    if (vcir->lvc_act == 0)    {	vcir->lvc_state = VST_STOPING;    }    /*     * Build and send a reject slot because we cannot add the new slot.     */    if (m0 = m_get(M_DONTWAIT, MT_DATA))    {	slhdr = (struct slot_hdr *)buildvchdr(vcir,		mtod(m0, struct vc_hdr *), 1, MSG_RUN, 0);	slhdr->shd_dstid = shdr.shd_srcid;	slhdr->shd_srcid = 0;	slhdr->shd_count = 0;	slhdr->shd_reason = reason;	slhdr->shd_type = SLOT_REJECT;	m0->m_len = sizeof(struct vc_hdr) + sizeof(struct slot_hdr);	vcir->lvc_rrf = 1;	ENQUEUE(&vcir->lvc_xmtq, m0);	latsend(vcir);    }}/* *		b u i l d s l o t s * * Build the output slot information into the single cluster data buffer * provided. * * Outputs:		Number of slots built. * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. *	m		= Pointer to MBUF which describes the data buffer. */int buildslots( vcir,m )register struct lat_vc *vcir;register struct mbuf *m;{    register struct lat_slot *slot;    register struct slot_hdr *slhdr;    register int i;    int islots,slots = 0,change;    do    {	islots = slots;	for (slot = sl,i = 0; i < LAT_MAXSLOTS; slot++,i++)	{	    if (slot->lsl_vc == vcir)	    {		slhdr = mtoe(m, struct slot_hdr *);		switch (slot->lsl_state)		{		    case SST_RUNNING:			if (slot->lsl_bslot)			{			    if (change = (*slot->lsl_scl->scl_sdatab)(vcir, slot, m))			    {				slot->lsl_bslot = 0;			    }			}			else			{			    change = (*slot->lsl_scl->scl_sdataa)(vcir, slot, m);			}			if (change)			{			    slots += change;			    if (slhdr->shd_count)			    {				slot->lsl_loccredits -= change;			    }			}			break;		    case SST_STARTING:			if ((change = (*slot->lsl_scl->scl_sother)(vcir, slot, m)) == -1)			{			    change = generic_start(vcir, slot, m);			}			if (change)			{			    slots++;			slot->lsl_state = SST_RUNNING;			}			break;		    case SST_REJECT:			if ((change = (*slot->lsl_scl->scl_sother)(vcir, slot, m)) == -1)			{			    change = generic_reject(vcir, slot, m);			}			if (change)			{			    slots++;			    release_slot(slot);			}			break;		    case SST_STOP:			if ((change = 			    (*slot->lsl_scl->scl_sother)(vcir, slot, m)) == -1)			{			    change = generic_stop(vcir, slot, m);			}			if (change)			{			    slots++;			    release_slot(slot);			}			break;		}		m->m_len = (m->m_len + 1) & ~1;	    }	}    } while (islots != slots);    return (slots);}/* *		t e r m i n a t e s l o t * * Terminate the operation of the specified slot. * * Outputs:		None. * * Inputs: *	slot		= Pointer to the slot descriptor. */terminateslot( slot )register struct lat_slot *slot;{    int s = splnet();    if (slot->lsl_vc)    {	slot->lsl_state = SST_STOP;	slot->lsl_reason = STOP_SLDISC;	vcrun(slot->lsl_vc);    }    splx(s);}/* *		s t o p s l o t s * * Stop all of the slots running on the specified virtual circuit. * * Outputs:		None. * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. */stopslots( vcir )struct lat_vc *vcir;{    register struct lat_slot *slot;    register int i;    for (slot = sl,i = 0; i < LAT_MAXSLOTS; slot++,i++)    {	if (slot->lsl_vc == vcir)	{	    (*slot->lsl_scl->scl_hangup)(vcir, slot);	    release_slot(slot);	}    }}/* *		f i n d s l o t * * Find the slot defined by the slot header on an incoming message, updating * the credits extended by the remote system. * * Outputs:		Pointer to the slot descriptor *			0 if none. * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. */struct lat_slot *findslot( vcir )struct lat_vc *vcir;{    register struct lat_slot *slot;    u_char srcid = 0;    if (shdr.shd_dstid <= LAT_MAXSLOTS)    {	slot = &sl[shdr.shd_dstid - 1];	if (shdr.shd_type != SLOT_STOP)	{	    srcid = slot->lsl_remid;	}	if (slot->lsl_locid == shdr.shd_dstid && srcid == shdr.shd_srcid && slot->lsl_vc == vcir)	{	    slot->lsl_loccredits += shdr.shd_credits;	    return (slot);	}    }    return (0);}/* *		r e l e a s e _ s l o t * * Free up the data structures associated with the specified slot. * * Outputs:		None. * * Inputs: *	slot		= Pointer to slot descriptor. */release_slot( slot )struct lat_slot *slot;{    struct lat_vc *vcir;    slot->lsl_state = SST_FREE;    if (vcir = slot->lsl_vc)    {	slot->lsl_vc = 0;	slotsinuse--;	if (--vcir->lvc_act == 0)	{	    vcir->lvc_state = VST_STOPING;	}    }}/* *		g e n e r i c _ r e j e c t * * Build a generic reject slot. * * Outputs:		1 if slot successfully built *			0 if no slot built * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. *	slot		= Pointer to slot descriptor. *	m		= Pointer to MBUF holding the data buffer. *//*ARGSUSED*/generic_reject( vcir,slot,m )struct lat_vc *vcir;struct lat_slot *slot;struct mbuf *m;{    register struct slot_hdr *slhdr = mtoe(m, struct slot_hdr *);    if ((m->m_len + sizeof(struct slot_hdr)) < CLBYTES)    {	buildslothdr(slhdr, slot, 0, SLOT_REJECT,(int)slot->lsl_reason);	m->m_len += sizeof(struct slot_hdr);	return (1);    }    return (0);}/* *		g e n e r i c _ s t a r t * * Build a generic start slot. * * Outputs:		1 if slot successfully built *			0 if no slot built * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. *	slot		= Pointer to slot descriptor. *	m		= Pointer to MBUF holding the data buffer. *//*ARGSUSED*/generic_start( vcir,slot,m )struct lat_vc *vcir;struct lat_slot *slot;struct mbuf *m;{    register struct slot_hdr *slhdr = mtoe(m, struct slot_hdr *);    register struct slot_start *ssl = (struct slot_start *)((int)slhdr + sizeof(struct slot_hdr));    register caddr_t dptr = (caddr_t)((int)ssl + sizeof(struct slot_start));    if ((m->m_len + sizeof(struct slot_hdr) + sizeof(struct slot_start) + 3) < CLBYTES)     {	ssl->sst_class = slot->lsl_class;	ssl->sst_minAsize = MINASIZE;	ssl->sst_minDsize = MINDSIZE;	*dptr++ = 0;	*dptr++ = 0;	*dptr++ = 0; /* ensure packet end with 0's */	buildslothdr(slhdr, slot, (int)dptr - (int)ssl, SLOT_START,(int)0);	m->m_len += (int)dptr - (int)slhdr;	return (1);    }    return (0);}/* *		g e n e r i c _ s t o p * * Build a generic stop slot. * * Outputs:		1 if slot successfully built *			0 if no slot built * * Inputs: *	vcir		= Pointer to virtual circuit descriptor. *	slot		= Pointer to slot descriptor. *	m		= Pointer to MBUF holding the data buffer. *//*ARGSUSED*/generic_stop( vcir,slot,m )struct lat_vc *vcir;struct lat_slot *slot;struct mbuf *m;{    register struct slot_hdr *slhdr = mtoe(m, struct slot_hdr *);    if ((m->m_len + sizeof(struct slot_hdr)) < CLBYTES)    {	buildslothdr(slhdr, slot, 0, SLOT_STOP,(int)slot->lsl_reason);	slhdr->shd_srcid = 0;	m->m_len += sizeof(struct slot_hdr);	return (1);    }    return (0);}

⌨️ 快捷键说明

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