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

📄 lat_hic.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
  */int lat_pathlen(path)caddr_t path;{    int count;    count = 1;    while (*path != '\0' && *path != ':')        count++, path++;    return (count);}/****maserver****//* * For the server, a few 'quick and dirty' kludges need to be fixed: *  - add a bit/byte to lat_vc for master indicator, instead of using *    lvc_dgsize (<= 60 implied as a master). *  - add a master keep_alive byte to lat_vc, instead of using  *    lvc_dgsize (timer count up to 60 for 30 seconds keep alive interval). *  - lvc_rcvact in lat_vc is used as multiple bit filed: *    1000 0000 - outgoing data waiting for master vc *    0100 0000 - master vc in balance mode *    0000 0001 - vc receiver active *  - add a byte filed to lat_slot for credit count for master side, instead *    of using ls1_attsize. * * The master timer (defined in lat_mtick, set to 80 milliseconds) is * used to check if the tty input queue is empty so credit can be granted * to the remote slave. Without checking for empty tty queue can easily * cause the queue to overflow. * Master mode also ensures no more outgoing message unless ack queue is * empty.  Unack sequence number greater than 1 seems to get acknowledgement * handshaking into chaos.  See traces. *//****maserver****/int lat_debug = 0;int lat_mtick = 0x08;int lat_msize = 0x0ff;int lat_mflag = 0;#define LAT_MASTIMER 1/* *	m v c s t a r t */mvcstart(unit){#ifndef LATMASTER    return(0);#else    extern int lat_mtimer();    extern struct lat_vc *vcduplicate();     register struct mbuf *m;    register struct lat_vc *vcir;    struct ecb *ecbp = &(statable[unit]);    struct hic_entity *h = &(lat_obj[unit]);    struct vc_hdr *hdr;    struct vc_start *vst;    struct lat_slot *slot;    struct slot_hdr *slhdr;    struct slot_start *ssl;    struct mbuf *page;    caddr_t sptr,nptr;    char ch;    struct ifnet *ifp = ifnet;    struct proc *pp = u.u_procp;    int i,s;    /*     * if lat not running, return error     */    if (!sclass[1] || (sclass[1]->scl_state != LST_RUNNING))         return(ENOPROTOOPT);    /*     * if host-initiated connection not defined, return     */    if (ecbp->ecb_hostinit != LAT_HIC) return(0);    /*     * if not defined as master, return     */     if (h->status & OBJPORT) return(0);     /*     * if host master initiated connection not fully defined, return error     */    if ((h->status & MHIC) != MHIC) return (EDESTADDRREQ);     /*     * host_initiated open should be exclusive      * unless multiplexing has been added     */    if ((ecbp->ecb_inuse & ECB_INUSE) || lata[unit].t_addr)	return(EBUSY);    /* set up id for signals */    lata[unit].t_pgrp = pp->p_pgrp;      s = splnet();    /* see if vc exists */    if (vcir = vcduplicate(h)) goto startslot1;    /* get vc block */    if (vcir = newvc())    {        bcopy(h->obj_port, vcir->lvc_addr.lat_addr, 6);         vcir->lvc_addr.lat_family = AF_LAT;        vcir->lvc_ack = 255;        vcir->lvc_dgsize = 0;    }    else goto nobuf;    ecbp->ecb_inuse |= ECB_INUSE;    while (ifp)    {	if ((ifp->if_flags & (IFF_BROADCAST|IFF_DYNPROTO|IFF_UP)) == (IFF_BROADCAST|IFF_DYNPROTO|IFF_UP))	{            if (m = m_get(M_DONTWAIT, MT_DATA))            {	        MCLGET(m,page);	        if (page)	        {                    hdr = (struct vc_hdr *)page;	            vcir->lvc_state = VST_RUNNING;                    vcir->lvc_if = ifp;	            sptr = buildvchdr(vcir, (struct vc_hdr *)page, 0, MSG_START, 0);                    hdr->vhd_mas = 1;	            bcopy((char *)&startvc, (char *)sptr, sizeof(struct vc_start));                    vst = (struct vc_start *)sptr;                    vst->vst_dgsize = 1518;                    vst->vst_slots = 0x30;                    vst->vst_product = 0x102;                     vst->vst_stimer = 8;                    vst->vst_kalive = vcir->lvc_kalive = 30;	            sptr += sizeof(struct vc_start);                    if (*sptr++ = h->obj_namelen)	            {		        nptr = (caddr_t)h->obj_name;		        while (ch = *nptr++)		        {	    	            if (('a' <= ch) && (ch <= 'z')) ch = ch -'a' + 'A';	    	            *sptr++ = ch;	        	}	            }	            if (*sptr++ = hostnamelen)	            {		        nptr = hostname;		        while (ch = *nptr++)		        {		            if (('a' <= ch) && (ch <= 'z')) ch = ch -'a' + 'A';		            *sptr++ = ch;	                }	            }	            /*  Terminate the parameters  */	            *sptr++ = 0;	            m->m_len = (int)sptr - (int)page;	            INC(lco_xmtframes);	            ENQUEUE(&vcir->lvc_xmtq, m);	            latsend(vcir);                    sleep(m, TTIPRI);	                        /* check if timeout */                    if (vcir->lvc_remid) goto startslot;                    break; 	        }	        m_free(m);                ecbp->ecb_inuse &= ~ECB_INUSE;                goto nobuf;            }            else            {                ecbp->ecb_inuse &= ~ECB_INUSE;                goto nobuf;            }        }	ifp = ifp->if_next;    }    ecbp->ecb_inuse &= ~ECB_INUSE;    splx(s);    return (ENETUNREACH);nobuf:    splx(s);    return (ENOBUFS);startslot:    vcir->lvc_state = VST_RUNNING;startslot1:    /* get a slot table entry  */    for (slot = sl, i = 0; i < LAT_MAXSLOTS; slot++, i++)        if (slot->lsl_state == SST_FREE) break;    /* Initialise the new slot database  */    slotsinuse++;    vcir->lvc_act++;    slot->lsl_vc = vcir;    slot->lsl_class = 1;    slot->lsl_state = SST_STARTING;    slot->lsl_locid = i + 1;    slot->lsl_remid = 0;    slot->lsl_remcredits = 0;    slot->lsl_loccredits = 0;    slot->lsl_attsize = 0;     slot->lsl_scl = sclass[1];        lata[unit].t_addr = (caddr_t)slot;    lata[unit].t_state |= TS_CARR_ON;    lata[unit].t_flags &= ~ECHO;    slot->lsl_data = (caddr_t) &lata[unit];    slot->lsl_bslot = 0;    ttyflush(&lata[i], FREAD|FWRITE);    if (m = m_get(M_DONTWAIT, MT_DATA))    {        MCLGET(m,page);        if (page)        {            hdr = (struct vc_hdr *)page;	    sptr = buildvchdr(vcir, (struct vc_hdr *)page, 1, MSG_RUN, 0);            hdr->vhd_mas = 1;            slhdr = (struct slot_hdr *)sptr;            slhdr->shd_dstid = 0;            slhdr->shd_srcid = slot->lsl_locid;            slhdr->shd_count = 4;            slhdr->shd_credits = 0;             slhdr->shd_type = SLOT_START;            sptr += sizeof(struct slot_hdr);            ssl = (struct slot_start *)sptr;            ssl->sst_class = slot->lsl_class = 1;            ssl->sst_minAsize = ssl->sst_minDsize =slot->lsl_datasize=lat_msize;            sptr += sizeof(struct slot_start);            if (*sptr++ = h->obj_namelen)	    {	        nptr = (caddr_t)h->obj_name;	        while (ch = *nptr++)	        {	            if (('a' <= ch) && (ch <= 'z')) ch = ch -'a' + 'A';	            *sptr++ = ch;		}	    }            slhdr->shd_count += h->obj_namelen + 1;            if (*sptr++ = h->subj_portlen)	    {	        nptr = (caddr_t)h->subj_port;	        while (ch = *nptr++)	        {	            if (('a' <= ch) && (ch <= 'z')) ch = ch -'a' + 'A';	            *sptr++ = ch;		}	    }            slhdr->shd_count += h->subj_portlen + 1;            /* add group code ??????? */            *sptr++ = 0;	    m->m_len = (int)sptr - (int)page;	    INC(lco_xmtframes);	    ENQUEUE(&vcir->lvc_xmtq, m);	    latsend(vcir);            sleep(m, TTIPRI);                          /* check for timeout */            if (!slot->lsl_remid)             {                ecbp->ecb_inuse &= ~ECB_INUSE;		splx(s);                return (ENETUNREACH);            }            lat_mack(vcir);            if (!(lat_mflag & LAT_MASTIMER)) timeout(lat_mtimer, 0, lat_mtick);        }        splx(s);        return(0);    }    splx(s);    return(ENOBUFS);#endif}/* *	l a t _ m a c k */lat_mack(vcir)struct lat_vc *vcir;{#ifdef LATMASTER    vcir->lvc_rrf = 0;    vcrun(vcir);#endif}/* * 	m v c s t a r t 1 */mvcstart1(m,vhdr)struct mbuf *m;struct vc_hdr *vhdr;{#ifndef LATMASTER    return(0);#else    register struct lat_vc *vcir;    struct mbuf *m0;    int index;    index = vhdr->vhd_dstid & 0377;    vcir = vc[index];    vcir->lvc_remid = vhdr->vhd_srcid;    vcir->lvc_ack++;    DEQUEUE(&vcir->lvc_ackq, m0);    if (m0)    {        wakeup(m0);        m_freem(m0);    }    m_freem(m);#endif}/* * 	m s l o t s t a r t */mslotstart(slothdr)struct slot_hdr *slothdr;{#ifndef LATMASTER    return(0);#else    register struct lat_vc *vcir;    register struct lat_slot *slot;    struct mbuf *m0;    if (vcir = findvc())    {        vcir->lvc_ack++;        vcir->lvc_lxmt++;        slot = &sl[slothdr->shd_dstid-1];        slot->lsl_remid = slothdr->shd_srcid;        slot->lsl_loccredits += slothdr->shd_credits;        slot->lsl_remcredits = 1; /* set credit to 1 for now */        slot->lsl_state = SST_RUNNING;        DEQUEUE(&vcir->lvc_ackq, m0);        if (m0)        {            wakeup(m0);            m_freem(m0);        }    }#endif}lat_master(vcir)register struct lat_vc *vcir;{#ifdef LATMASTER    if (vcir->lvc_dgsize <= 60) return (1);#endif    return(0);}#ifdef LATMASTER/* * 	l a t _ m t i m e r * * LAT master 80 millisecond timer (in lat_mtick) * */lat_mtimer(){    register struct lat_vc *vcir;    register struct lat_slot *slot;    register struct tty *tp;    int s = splnet();    int i, j, cr;    lat_mflag &= ~LAT_MASTIMER;    for (i=1; i<nLAT1; i++)    {        if (vcir = vc[i])        {            if (!lat_master(vcir)) continue;            lat_mflag |= LAT_MASTIMER;	    /* 	     * If there are more than 1 unacked sequence number,  	     * the whole acknowledgement hand shaking may become	     * chaos unless some coding changes in process_vc_run().	     * For now, do not send if ack queue not empty	     */	    if (vcir->lvc_ackq.q_head) continue;	    cr = 0;            for (slot=sl,j=0; j<nLAT1; slot++,j++)            {                if ((slot->lsl_vc == vcir) && (slot->lsl_state == SST_RUNNING))                {                    tp = (struct tty *)slot->lsl_data;		    /* grant credit only if tty queue is empty */                    if (slot->lsl_attsize && !tp->t_rawq.c_cc)                    {                        slot->lsl_remcredits = slot->lsl_attsize;                        slot->lsl_attsize = 0;                        cr = 1;                    }		    /* check if anything can be sent out */		    else if (tp->t_outq.c_cc)		    {			/* if no credit, set flag for data waiting */		        if (!slot->lsl_loccredits) 			    vcir->lvc_rcvact |= 0x80;			else                             cr = 1;		    }                }               }	    if (cr) lat_mack(vcir);        }    }    /* start timer if there is master virtual circuit */    if (lat_mflag & LAT_MASTIMER) timeout(lat_mtimer, 0, lat_mtick);    splx(s);}#endiflat_alive(vcir)struct lat_vc *vcir;{#ifdef LATMASTER    if (lat_master(vcir))    { 	/* 	 * latmaster - vms: a possible bug in vms driver not returning	 * 		    credit in time, send a message as reminder	 *		    if output data waiting         */        if ((vcir->lvc_dgsize == 60) || (vcir->lvc_rcvact & 0x80))         {  	    vcir->lvc_rcvact &= 0x0bf;	    if (!(vcir->lvc_ackq.q_head)) lat_mack(vcir);            vcir->lvc_dgsize = 0;         }        else vcir->lvc_dgsize++;    }#endif}#ifdef LATMASTERstruct lat_vc *vcduplicate(hptr)struct hic_entity *hptr;{    register struct lat_vc *vcir;    register int index;    for (index = 1; index < LAT_MAXVC; index++)    {	if (vcir = vc[index])	    if (lat_master(vcir))	        if (bcmp(hptr->obj_port, vcir->lvc_addr.lat_addr, 6) == 0)		    return (vcir);    }    return (0);}#endif/* * Input:	flag = 1: add multicast address *		     = 0: delete multicast address */lat_multi(flag)int flag;{        register struct ifnet *ifp = ifnet;    struct ifreq dreq;    /*     * enable LAT Multicast Address on each device.     */    bzero(dreq.ifr_addr.sa_data, 6);    dreq.ifr_addr.sa_data[0] = 0x09;    dreq.ifr_addr.sa_data[2] = 0x2b;    dreq.ifr_addr.sa_data[5] = 0x0f;    while ( ifp )    {        if ((ifp->if_flags & (IFF_BROADCAST|IFF_DYNPROTO)) == (IFF_BROADCAST|IFF_DYNPROTO))        {	    if (flag) (*ifp->if_ioctl)(ifp, SIOCADDMULTI, &dreq);	    else (*ifp->if_ioctl)(ifp, SIOCDELMULTI, &dreq);        }        ifp = ifp->if_next;    }}

⌨️ 快捷键说明

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