📄 lat_scl1.c
字号:
} } /* for */ if (req) /* Request ID has been defined */ { for ( i = 0 ; i <= nLAT1 ; i++ ) { if (statable[i].ecb_reqid == req) { if (lata[i].t_addr != 0) { *(reason) = STOP_SLINUSE; return(0); } else break; } else { if ( i == nLAT1 ) { *(reason) = STOP_SLNAME; return(0); } } } } else /* Find first available port */ { /* check if service name defined in lat_service[] */ int tempi = servnamelen; char *tempc = servname; for ( ; tempi; tempi--,tempc++) { if (*tempc >= 'a' && *tempc <= 'z') *tempc -= 0x20; /* convert to upper case */ } for (servid=0; servid<MAXSERVICE+1; servid++,ls++) { if (servid == MAXSERVICE || !ls->id) { servid = 0; break; } if (bcmp(ls->name, servname, servnamelen) == 0) { servid += LAT_SERVICEID; break; } } for (i = 0; i <= nLAT1; i++) { if (lata[i].t_addr == 0 && (statable[i].ecb_hostinit == servid) && (lata[i].t_state & TS_WOPEN) ) break; else { if ( i == nLAT1 ) { *(reason) = STOP_SLNORES; return (0); } continue; } } } lata[i].t_addr = (caddr_t)slot; lata[i].t_state |= TS_CARR_ON; slot->lsl_bslot |= 1; ttyflush(&lata[i], FREAD | FWRITE); /* for non-LAT service, save destination if defined */ lp = &lat_obj[i]; /* save destination name if defined */ if (destname) { dstnamecnt = *++destname; bcopy(++destname, lp->subj_port, dstnamecnt); lp->subj_portlen = dstnamecnt; } /* save server port name */ if (portname) { portnamecnt = *++portname; bcopy(++portname, lp->obj_port, portnamecnt); lp->obj_portlen = portnamecnt; } /* get the server name */ bcopy(vcir->lvc_mn, lp->obj_name, vcir->lvc_mnl); lp->obj_namelen = (u_char)vcir->lvc_mnl; return ((int)&lata[i]);}/* * r d a t a a _ c l a s s 1 * * Process a received data_a slot for a service class 1 device. * * Outputs: None. * * Inputs: * vcir = Pointer to virtual circuit descriptor. * slot = Pointer to slot descriptor. * m = Pointer to MBUF chain holding the slot data. * slen = Length of the slot data. *//*ARGSUSED*/rdataa_class1( vcir,slot,m,slen )struct lat_vc *vcir;struct lat_slot *slot;struct mbuf *m;int slen;{ register struct tty *tp = (struct tty *)slot->lsl_data; register caddr_t dptr; register int count; /* * Wake up any processes waiting for input. */ if ((tp->t_state & TS_ISOPEN) == 0) { wakeup((caddr_t)&tp->t_rawq); } /* * Pass the received characters into the terminal driver one at a time. */ do { count = min(slen, m->m_len); dptr = mtod(m, caddr_t); slen -= count; while (count--) { (*linesw[tp->t_line].l_rint)(*dptr++, tp); } m = m->m_next; } while (slen);}/* * r d a t a b _ c l a s s 1 * * Process a received data_b slot for a service class 1 device. * * Outputs: None. * * Inputs: * vcir = Pointer to virtual circuit descriptor. * slot = Pointer to slot descriptor. * m = Pointer to MBUF chain holding the slot data. * slen = Length of the slot data. *//*ARGSUSED*/rdatab_class1( vcir,slot,m,slen )struct lat_vc *vcir;struct lat_slot *slot;struct mbuf *m;int slen;{}/* * r o t h e r _ c l a s s 1 * * Process a received stop, reject or attention slot. * * Outputs: None. * * Inputs: * vcir = Pointer to virtual circuit descriptor. * slot = Pointer to slot descriptor. * m = Pointer to MBUF chain holding the slot. * slhdr = Pointer to the slot header. *//*ARGSUSED*/rother_class1( vcir,slot,m,slhdr )struct lat_vc *vcir;struct lat_slot *slot;struct mbuf *m;struct slot_hdr *slhdr;{ switch (slhdr->shd_type) { case SLOT_STOP: hangup_class1(vcir, slot); release_slot(slot); break; case SLOT_ATT: break; }}/* * s d a t a a _ c l a s s 1 * * Try to build a data_a slot for the service class 1 device. * * 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 which holds the data buffer. */sdataa_class1( vcir,slot,m )struct lat_vc *vcir;register struct lat_slot *slot;register struct mbuf *m;{ register struct slot_hdr *slhdr = mtoe(m, struct slot_hdr *); register caddr_t dataptr = (caddr_t)((int)slhdr + sizeof(struct slot_hdr)); register struct tty *tp = (struct tty *)slot->lsl_data; register int cc; int slotlen = 0; if (slot->lsl_loccredits) { if ((tp->t_state & (TS_TIMEOUT|TS_TTSTOP)) == 0) { while (tp->t_outq.c_cc) {#ifndef RELEASE if (tp->t_flags & (RAW|LITOUT))#else if ((tp->t_lflag_ext & PRAW) || (tp->t_oflag_ext & PLITOUT) || ((tp->t_oflag & OPOST) == 0))#endif { cc = ndqb(&tp->t_outq, 0); } else {#ifndef RELEASE cc = ndqb(&tp->t_outq, 0200);#else cc = ndqb(&tp->t_outq, DELAY_FLAG);#endif if (cc == 0) { /* * The first thing on the queue is a delay. Process it * as normal so that we do not affect the internal * operation of the tty driver too much. */ cc = getc(&tp->t_outq); timeout(ttrstrt, (caddr_t)tp,(int)(cc & 0x7f)+6); tp->t_state |= TS_TIMEOUT; break; } } /* * If there is insufficient space left in the buffer or * the slot to add the data, stop now and we will come * back later. */ if (((slotlen + cc ) > slot->lsl_datasize) || ((m->m_len + cc) > (1500 - sizeof(struct slot_hdr) - sizeof(struct vc_hdr)))) break; bcopy(tp->t_outq.c_cf, dataptr, cc); dataptr += cc; slotlen += cc; m->m_len += cc; ndflush(&tp->t_outq, cc); } if (!tp->t_outq.c_cc) vcir->lvc_rcvact &= 0x7f; /* latmaster */ else vcir->lvc_rcvact |= 0x80; /* latmaster */ if (slotlen) { buildslothdr(slhdr, slot, slotlen, SLOT_DATA_A, 0); vcir->lvc_rrf = 1; m->m_len = (m->m_len + sizeof(struct slot_hdr) + 1) & ~1; ltawakeup(tp); return (1); } } } else /* latmaster */ if (tp->t_outq.c_cc) vcir->lvc_rcvact |= 0x80; /* latmaster */ if (slot->lsl_remcredits) { /* * No data can be sent but we have some credits which need to be * sent to the remote system. Build a data_a slot with no slot * data to transfer the credits. */ if ((m->m_len + sizeof(struct slot_hdr)) < CLBYTES) { buildslothdr(slhdr, slot, 0, SLOT_DATA_A, 0); m->m_len += sizeof(struct slot_hdr); return (1); } } return (0);}/* * s d a t a b _ c l a s s 1 * * Try to build a data_b slot for the service class 1 device. * * 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 which holds the data buffer. */#define BREAK_RQST (SB1_BREAK|SB1_SET)>>4static u_short speed[14] = {0,50,75,110,135,150,200,300,600,1200,1800,2400,4800,9600};sdatab_class1( 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 slotb_1 *sbptr = (struct slotb_1 *)((int)slhdr + sizeof(struct slot_hdr)); register struct tty *tp = (struct tty *)slot->lsl_data; caddr_t dptr = (caddr_t) ((int)sbptr + sizeof(struct slotb_1)); int passall = 0; if (slot->lsl_loccredits) { if ((m->m_len + sizeof(struct slot_hdr) + sizeof(struct slotb_1)) < CLBYTES) { buildslothdr(slhdr, slot, sizeof(struct slotb_1)+11+2, SLOT_DATA_B, 0); vcir->lvc_rrf = 1;#ifndef RELEASE sbptr->sb1_spout = tp->t_stopc; sbptr->sb1_stout = tp->t_startc;#else sbptr->sb1_spout = tp->t_cc[VSTOP]; sbptr->sb1_stout = tp->t_cc[VSTART];#endif sbptr->sb1_spin = '\023'; sbptr->sb1_stin = '\021'; if ((tp->t_flags & RAW) || sbptr->sb1_spout!='\023' || sbptr->sb1_stout!='\021') sbptr->sb1_flags = passall = SB1_DISINPUT|SB1_DISOUTPUT; else sbptr->sb1_flags = SB1_ENAINPUT|SB1_ENAOUTPUT; if ((slot->lsl_reason & BREAK_RQST) == BREAK_RQST) sbptr->sb1_flags |= SB1_BREAK; sbptr->sb1_flags |= SB1_SET; *dptr++ = 2; /* set input speed */ *dptr++ = 2;#ifndef RELEASE bcopy(&speed[tp->t_ispeed], dptr, 2);#else bcopy(&speed[tp->t_cflag & CBAUD], dptr, 2);#endif dptr += 2; *dptr++ = 3; /* set output speed */ *dptr++ = 2;#ifndef RELEASE bcopy(&speed[tp->t_ospeed], dptr, 2);#else bcopy(&speed[tp->t_cflag_ext & CBAUD], dptr, 2);#endif dptr += 2; *dptr++ = 5; /* set transparency mode */ *dptr++ = 1; if (passall) *dptr++ = 1; else *dptr++ = 0; *dptr++ = 0; /* data_b slot must terminates with 0 */ *dptr++ = 0; m->m_len += sizeof(struct slot_hdr) + sizeof(struct slotb_1) + 11 + 2; return (1); } } return (0);}/* * h a n g u p _ c l a s s 1 * * The specified slot has been stop. Perform the necessary operations for the * operating system to see this. * * Outputs: None. * * Inputs: * vcir = Pointer to virtual circuit descriptor. * slot = Pointer to slot descriptor. *//*ARGSUSED*/hangup_class1( vcir,slot )struct lat_vc *vcir;struct lat_slot *slot;{ int s = splimp(); register struct tty *tp = (struct tty *)slot->lsl_data; int unit; gsignal(tp->t_pgrp, SIGHUP); gsignal(tp->t_pgrp, SIGCONT); ttyflush(tp, FREAD|FWRITE); tp->t_state &= ~(TS_CARR_ON|TS_ISOPEN); tp->t_addr = 0; unit = minor(tp->t_dev); if (statable[unit].ecb_hostinit == 0 || statable[unit].ecb_hostinit >= LAT_SERVICEID) lat_obj[unit].subj_portlen = lat_obj[unit].obj_portlen = lat_obj[unit].obj_namelen = 0; splx(s);}/* * s o t h e r _ c l a s s 1 * * Try to build a slot other than data_a or data_b for the service class 1 * device. * * Outputs: 1 if slot was built * 0 if no slot built * -1 if routine does not know how to build the slot * (i.e. use generic build routine). * * Inputs: * vcir = Pointer to virtual circuit descriptor. * slot = Pointer to slot descriptor. * m = Pointer to MBUF chain which holds the data buffer. *//*ARGSUSED*/sother_class1( vcir,slot,m )struct lat_vc *vcir;struct lat_slot *slot;struct mbuf *m;{ return (-1);}extern int lat_mflag; /* latmaster */#define LAT_MALIVE 2 /* latmaster *//* * o u t p u t _ c l a s s 1 * * One of the service class 1 devices (terminals) has some output available. * If we have credits available, try to build a virtual circuit run message * with this data present and any data available from other slots running * on the same virtual circuit. If a received run message is being processed * for this virtual circuit, we can delay processing so that it will all be * picked up on completion of processing the received message. * * Outputs: None. * * Inputs: * tp = Pointer to a tty structure. * bslot = 1 if data_b slot should be sent * 0 if data_a slot should be sent */output_class1( tp,bslot )struct tty *tp;int bslot;{ struct lat_slot *slot; struct lat_vc *vcir; int s = splnet(); if (slot = (struct lat_slot *)tp->t_addr) { slot->lsl_bslot |= bslot; vcir = slot->lsl_vc; /* * latmaster: if LAT_MALIVE set, transmit on circuit timer interval * if ack queue not empty, wait */ if (lat_master(vcir) && ((lat_mflag & LAT_MALIVE) || vcir->lvc_ackq.q_head)) vcir->lvc_rcvact |= 0x80; else if (((vcir->lvc_rcvact & 0x01) == 0) && slot->lsl_loccredits) { vcrun(vcir); } } splx(s);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -