Annotation of kernel/bsd/netiso/tp_driver.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: #ifndef lint
                     26: static char *rcsid = "$Header/**/$";
                     27: #endif lint
                     28: #define _XEBEC_PG static
                     29: 
                     30: #include "tp_states.h"
                     31: 
                     32: static struct act_ent {
                     33:        int a_newstate;
                     34:        int a_action;
                     35: } statetable[] = { {0,0},
                     36: #include "tp_states.init"
                     37: };
                     38: 
                     39: /* @(#)tp.trans        8.1 (Berkeley) 6/10/93 */
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/socket.h>
                     43: #include <sys/socketvar.h>
                     44: #include <sys/protosw.h>
                     45: #include <sys/mbuf.h>
                     46: #include <sys/time.h>
                     47: #include <sys/errno.h>
                     48: #include <sys/ev.h>
                     49: 
                     50: #include <netiso/tp_param.h>
                     51: #include <netiso/tp_stat.h>
                     52: #include <netiso/tp_pcb.h>
                     53: #include <netiso/tp_tpdu.h>
                     54: #include <netiso/argo_debug.h>
                     55: #include <netiso/tp_trace.h>
                     56: #include <netiso/iso_errno.h>
                     57: #include <netiso/tp_seq.h>
                     58: #include <netiso/cons.h>
                     59: 
                     60: #define DRIVERTRACE TPPTdriver
                     61: #define sbwakeup(sb)   sowakeup(p->tp_sock, sb);
                     62: #define MCPY(d, w) (d ? m_copym(d, 0, (int)M_COPYALL, w): 0)
                     63: 
                     64: static         trick_hc = 1;
                     65: 
                     66: int    tp_emit(),
                     67:                tp_goodack(),                           tp_goodXack(),
                     68:                tp_stash()
                     69: ;
                     70: void   tp_indicate(),                          tp_getoptions(),        
                     71:                tp_soisdisconnecting(),         tp_soisdisconnected(),
                     72:                tp_recycle_tsuffix(),           
                     73: #ifdef TP_DEBUG_TIMERS
                     74:                tp_etimeout(),                          tp_euntimeout(),
                     75:                tp_ctimeout(),                          tp_cuntimeout(),
                     76:                tp_ctimeout_MIN(),
                     77: #endif
                     78:                tp_freeref(),                           tp_detach(),
                     79:                tp0_stash(),                            tp0_send(),
                     80:                tp_netcmd(),                            tp_send()
                     81: ;
                     82: 
                     83: typedef  struct tp_pcb tpcb_struct;
                     84: 
                     85: 
                     86: 
                     87: typedef tpcb_struct tp_PCB_;
                     88: 
                     89: #include "tp_events.h"
                     90: 
                     91: _XEBEC_PG int _Xebec_action(a,e,p)
                     92: int a;
                     93: struct tp_event *e;
                     94: tp_PCB_ *p;
                     95: {
                     96: switch(a) {
                     97: case -1:  return tp_protocol_error(e,p);
                     98: case 0x1: 
                     99:                {
                    100:                (void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL);
                    101:        }
                    102:                 break;
                    103: case 0x2: 
                    104:                {
                    105: #              ifdef TP_DEBUG
                    106:                if( e->ev_number != AK_TPDU )
                    107:                        printf("TPDU 0x%x in REFWAIT!!!!\n", e->ev_number);
                    108: #              endif TP_DEBUG
                    109:        }
                    110:                 break;
                    111: case 0x3: 
                    112:                {
                    113:                /* oh, man is this grotesque or what? */
                    114:                (void) tp_goodack(p, e->ev_union.EV_AK_TPDU.e_cdt, e->ev_union.EV_AK_TPDU.e_seq,  e->ev_union.EV_AK_TPDU.e_subseq);
                    115:                /* but it's necessary because this pseudo-ack may happen
                    116:                 * before the CC arrives, but we HAVE to adjust the
                    117:                 * snduna as a result of the ack, WHENEVER it arrives
                    118:                 */
                    119:        }
                    120:                 break;
                    121: case 0x4: 
                    122:                {
                    123:                tp_detach(p);
                    124:        }
                    125:                 break;
                    126: case 0x5: 
                    127:                {
                    128:                p->tp_refstate = REF_OPEN; /* has timers ??? */
                    129:        }
                    130:                 break;
                    131: case 0x6: 
                    132:                {
                    133:                IFTRACE(D_CONN)
                    134:                        tptrace(TPPTmisc, "CR datalen data", e->ev_union.EV_CR_TPDU.e_datalen, e->ev_union.EV_CR_TPDU.e_data,0,0);
                    135:                ENDTRACE
                    136:                IFDEBUG(D_CONN)
                    137:                        printf("CR datalen 0x%x data 0x%x", e->ev_union.EV_CR_TPDU.e_datalen, e->ev_union.EV_CR_TPDU.e_data);
                    138:                ENDDEBUG
                    139:                p->tp_refstate = REF_OPEN; /* has timers */
                    140:                p->tp_fcredit = e->ev_union.EV_CR_TPDU.e_cdt;
                    141: 
                    142:                if (e->ev_union.EV_CR_TPDU.e_datalen > 0) {
                    143:                        /* n/a for class 0 */
                    144:                        ASSERT(p->tp_Xrcv.sb_cc == 0); 
                    145:                        sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_CR_TPDU.e_data);
                    146:                        e->ev_union.EV_CR_TPDU.e_data = MNULL; 
                    147:                } 
                    148:        }
                    149:                 break;
                    150: case 0x7: 
                    151:                {
                    152:                IncStat(ts_tp0_conn);
                    153:                IFTRACE(D_CONN)
                    154:                        tptrace(TPPTmisc, "Confiming", p, 0,0,0);
                    155:                ENDTRACE
                    156:                IFDEBUG(D_CONN)
                    157:                        printf("Confirming connection: p" );
                    158:                ENDDEBUG
                    159:                soisconnected(p->tp_sock);
                    160:                (void) tp_emit(CC_TPDU_type, p, 0,0, MNULL) ;
                    161:                p->tp_fcredit = 1;
                    162:        }
                    163:                 break;
                    164: case 0x8: 
                    165:                {
                    166:                IncStat(ts_tp4_conn); /* even though not quite open */
                    167:                IFTRACE(D_CONN)
                    168:                        tptrace(TPPTmisc, "Confiming", p, 0,0,0);
                    169:                ENDTRACE
                    170:                IFDEBUG(D_CONN)
                    171:                        printf("Confirming connection: p" );
                    172:                ENDDEBUG
                    173:                tp_getoptions(p);
                    174:                soisconnecting(p->tp_sock);
                    175:                if ((p->tp_rx_strat & TPRX_FASTSTART) && (p->tp_fcredit > 0))
                    176:                        p->tp_cong_win = p->tp_fcredit * p->tp_l_tpdusize;
                    177:                p->tp_retrans = p->tp_Nretrans;
                    178:                tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
                    179:        }
                    180:                 break;
                    181: case 0x9: 
                    182:                {
                    183:                IFDEBUG(D_CONN)
                    184:                        printf("event: CR_TPDU emit CC failed done " );
                    185:                ENDDEBUG
                    186:                soisdisconnected(p->tp_sock);
                    187:                tp_recycle_tsuffix(p);
                    188:                tp_freeref(p->tp_lref);
                    189:                tp_detach(p);
                    190:        }
                    191:                 break;
                    192: case 0xa: 
                    193:                {
                    194:                int error;
                    195:                struct mbuf *data = MNULL;
                    196: 
                    197:                IFTRACE(D_CONN)
                    198:                        tptrace(TPPTmisc, "T_CONN_req flags ucddata", (int)p->tp_flags,
                    199:                        p->tp_ucddata, 0, 0);
                    200:                ENDTRACE
                    201:                data =  MCPY(p->tp_ucddata, M_WAIT);
                    202:                if (data) {
                    203:                        IFDEBUG(D_CONN)
                    204:                                printf("T_CONN_req.trans m_copy cc 0x%x\n", 
                    205:                                        p->tp_ucddata);
                    206:                                dump_mbuf(data, "sosnd @ T_CONN_req");
                    207:                        ENDDEBUG
                    208:                }
                    209: 
                    210:                if (error = tp_emit(CR_TPDU_type, p, 0, 0, data) )
                    211:                        return error; /* driver WON'T change state; will return error */
                    212:                
                    213:                p->tp_refstate = REF_OPEN; /* has timers */
                    214:                if(p->tp_class != TP_CLASS_0) {
                    215:                        p->tp_retrans = p->tp_Nretrans;
                    216:                        tp_ctimeout(p, TM_retrans, (int)p->tp_cr_ticks);
                    217:                }
                    218:        }
                    219:                 break;
                    220: case 0xb: 
                    221:                {
                    222:                sbflush(&p->tp_Xrcv); /* purge non-delivered data data */
                    223:                if (e->ev_union.EV_DR_TPDU.e_datalen > 0) {
                    224:                        sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_DR_TPDU.e_data);
                    225:                        e->ev_union.EV_DR_TPDU.e_data = MNULL;
                    226:                } 
                    227:                if (p->tp_state == TP_OPEN)
                    228:                        tp_indicate(T_DISCONNECT, p, 0);
                    229:                else {
                    230:                        int so_error = ECONNREFUSED;
                    231:                        if (e->ev_union.EV_DR_TPDU.e_reason != (E_TP_NO_SESSION ^ TP_ERROR_MASK) &&
                    232:                            e->ev_union.EV_DR_TPDU.e_reason != (E_TP_NO_CR_ON_NC ^ TP_ERROR_MASK) &&
                    233:                            e->ev_union.EV_DR_TPDU.e_reason != (E_TP_REF_OVERFLOW ^ TP_ERROR_MASK))
                    234:                                so_error = ECONNABORTED;
                    235:                        tp_indicate(T_DISCONNECT, p, so_error);
                    236:                }
                    237:                tp_soisdisconnected(p);
                    238:                if (p->tp_class != TP_CLASS_0) {
                    239:                        if (p->tp_state == TP_OPEN ) {
                    240:                                tp_euntimeout(p, TM_data_retrans); /* all */
                    241:                                tp_cuntimeout(p, TM_retrans);
                    242:                                tp_cuntimeout(p, TM_inact);
                    243:                                tp_cuntimeout(p, TM_sendack);
                    244:                                p->tp_flags &= ~TPF_DELACK;
                    245:                        }
                    246:                        tp_cuntimeout(p, TM_retrans);
                    247:                        if( e->ev_union.EV_DR_TPDU.e_sref !=  0 ) 
                    248:                                (void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL);
                    249:                }
                    250:        }
                    251:                 break;
                    252: case 0xc: 
                    253:                {
                    254:                if( e->ev_union.EV_DR_TPDU.e_sref != 0 )
                    255:                        (void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL); 
                    256:                /* reference timer already set - reset it to be safe (???) */
                    257:                tp_euntimeout(p, TM_reference); /* all */
                    258:                tp_etimeout(p, TM_reference, (int)p->tp_refer_ticks);
                    259:        }
                    260:                 break;
                    261: case 0xd: 
                    262:                {       
                    263:                tp_cuntimeout(p, TM_retrans);
                    264:                tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
                    265:                tp_soisdisconnected(p);
                    266:        }
                    267:                 break;
                    268: case 0xe: 
                    269:                {        
                    270:                tp_cuntimeout(p, TM_retrans);
                    271:                tp_soisdisconnected(p);
                    272:        }
                    273:                 break;
                    274: case 0xf: 
                    275:                {        
                    276:                tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
                    277:                tp_cuntimeout(p, TM_retrans);
                    278:                tp_soisdisconnected(p);
                    279:        }
                    280:                 break;
                    281: case 0x10: 
                    282:                {        
                    283:                tp_cuntimeout(p, TM_retrans);
                    284:                tp_soisdisconnected(p);
                    285:        }
                    286:                 break;
                    287: case 0x11: 
                    288:                {       /* don't ask me why we have to do this - spec says so */
                    289:                (void) tp_emit(DR_TPDU_type, p, 0, E_TP_NO_SESSION, MNULL);
                    290:                /* don't bother with retransmissions of the DR */
                    291:        }
                    292:                 break;
                    293: case 0x12: 
                    294:                {
                    295:                tp_soisdisconnecting(p->tp_sock);
                    296:                tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
                    297:                tp_soisdisconnected(p);
                    298:                tp_netcmd( p, CONN_CLOSE );
                    299:        }
                    300:                 break;
                    301: case 0x13: 
                    302:                {
                    303:                if (p->tp_state == TP_OPEN) {
                    304:                        tp_euntimeout(p, TM_data_retrans); /* all */
                    305:                        tp_cuntimeout(p, TM_inact);
                    306:                        tp_cuntimeout(p, TM_sendack);
                    307:                }
                    308:                tp_soisdisconnecting(p->tp_sock);
                    309:                tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
                    310:                p->tp_retrans = p->tp_Nretrans;
                    311:                tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
                    312:                (void) tp_emit(DR_TPDU_type, p, 0, E_TP_PROTO_ERR, MNULL);
                    313:        }
                    314:                 break;
                    315: case 0x14: 
                    316:                {       
                    317:                tp_cuntimeout(p, TM_retrans);
                    318:                IncStat(ts_tp0_conn);
                    319:                p->tp_fcredit = 1;
                    320:                soisconnected(p->tp_sock);
                    321:        }
                    322:                 break;
                    323: case 0x15: 
                    324:                {       
                    325:                IFDEBUG(D_CONN)
                    326:                        printf("trans: CC_TPDU in CRSENT state flags 0x%x\n", 
                    327:                                (int)p->tp_flags);
                    328:                ENDDEBUG
                    329:                IncStat(ts_tp4_conn);
                    330:                p->tp_fref = e->ev_union.EV_CC_TPDU.e_sref;
                    331:                p->tp_fcredit = e->ev_union.EV_CC_TPDU.e_cdt;
                    332:                if ((p->tp_rx_strat & TPRX_FASTSTART) && (e->ev_union.EV_CC_TPDU.e_cdt > 0))
                    333:                        p->tp_cong_win = e->ev_union.EV_CC_TPDU.e_cdt * p->tp_l_tpdusize;
                    334:                tp_getoptions(p);
                    335:                tp_cuntimeout(p, TM_retrans);
                    336:                if (p->tp_ucddata) {
                    337:                        IFDEBUG(D_CONN)
                    338:                                printf("dropping user connect data cc 0x%x\n",
                    339:                                        p->tp_ucddata->m_len);
                    340:                        ENDDEBUG
                    341:                        m_freem(p->tp_ucddata);
                    342:                        p->tp_ucddata = 0;
                    343:                }
                    344:                soisconnected(p->tp_sock);
                    345:                if (e->ev_union.EV_CC_TPDU.e_datalen > 0) {
                    346:                        ASSERT(p->tp_Xrcv.sb_cc == 0); /* should be empty */
                    347:                        sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_CC_TPDU.e_data);
                    348:                        e->ev_union.EV_CC_TPDU.e_data = MNULL;
                    349:                }
                    350: 
                    351:                (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
                    352:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    353:        }
                    354:                 break;
                    355: case 0x16: 
                    356:                {
                    357:                struct mbuf *data = MNULL;
                    358:                int error;
                    359: 
                    360:                IncStat(ts_retrans_cr);
                    361:                p->tp_cong_win = 1 * p->tp_l_tpdusize;
                    362:                data = MCPY(p->tp_ucddata, M_NOWAIT);
                    363:                if(p->tp_ucddata) {
                    364:                        IFDEBUG(D_CONN)
                    365:                                printf("TM_retrans.trans m_copy cc 0x%x\n", data);
                    366:                                dump_mbuf(p->tp_ucddata, "sosnd @ TM_retrans");
                    367:                        ENDDEBUG
                    368:                        if( data == MNULL )
                    369:                                return ENOBUFS;
                    370:                }
                    371: 
                    372:                p->tp_retrans --;
                    373:                if( error = tp_emit(CR_TPDU_type, p, 0, 0, data) ) {
                    374:                        p->tp_sock->so_error = error;
                    375:                }
                    376:                tp_ctimeout(p, TM_retrans, (int)p->tp_cr_ticks);
                    377:        }
                    378:                 break;
                    379: case 0x17: 
                    380:                {       
                    381:                IncStat(ts_conn_gaveup);
                    382:                p->tp_sock->so_error = ETIMEDOUT;
                    383:                tp_indicate(T_DISCONNECT, p, ETIMEDOUT);
                    384:                tp_soisdisconnected(p);
                    385:        }
                    386:                 break;
                    387: case 0x18: 
                    388:                {       
                    389:                int error;
                    390:                struct mbuf *data = MCPY(p->tp_ucddata, M_WAIT);
                    391: 
                    392:                if( error = tp_emit(CC_TPDU_type, p, 0, 0, data) ) {
                    393:                        p->tp_sock->so_error = error;
                    394:                }
                    395:                p->tp_retrans = p->tp_Nretrans;
                    396:                tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
                    397:        }
                    398:                 break;
                    399: case 0x19: 
                    400:                {
                    401:                int doack;
                    402: 
                    403:                /*
                    404:                 * Get rid of any confirm or connect data, so that if we
                    405:                 * crash or close, it isn't thought of as disconnect data.
                    406:                 */
                    407:                if (p->tp_ucddata) {
                    408:                        m_freem(p->tp_ucddata);
                    409:                        p->tp_ucddata = 0;
                    410:                }
                    411:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    412:                tp_cuntimeout(p, TM_retrans);
                    413:                soisconnected(p->tp_sock);
                    414:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    415: 
                    416:                /* see also next 2 transitions, if you make any changes */
                    417: 
                    418:                doack = tp_stash(p, e);
                    419:                IFDEBUG(D_DATA)
                    420:                        printf("tp_stash returns %d\n",doack);
                    421:                ENDDEBUG
                    422: 
                    423:                if (doack) {
                    424:                        (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL ); 
                    425:                        tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
                    426:                } else
                    427:                        tp_ctimeout( p, TM_sendack, (int)p->tp_sendack_ticks);
                    428:                
                    429:                IFDEBUG(D_DATA)
                    430:                        printf("after stash calling sbwakeup\n");
                    431:                ENDDEBUG
                    432:        }
                    433:                 break;
                    434: case 0x1a: 
                    435:                {
                    436:                tp0_stash(p, e);
                    437:                sbwakeup( &p->tp_sock->so_rcv );
                    438: 
                    439:                IFDEBUG(D_DATA)
                    440:                        printf("after stash calling sbwakeup\n");
                    441:                ENDDEBUG
                    442:        }
                    443:                 break;
                    444: case 0x1b: 
                    445:                {
                    446:                int doack; /* tells if we must ack immediately */
                    447: 
                    448:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    449:                sbwakeup( &p->tp_sock->so_rcv );
                    450: 
                    451:                doack = tp_stash(p, e);
                    452:                IFDEBUG(D_DATA)
                    453:                        printf("tp_stash returns %d\n",doack);
                    454:                ENDDEBUG
                    455: 
                    456:                if(doack)
                    457:                        (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL ); 
                    458:                else
                    459:                        tp_ctimeout_MIN( p, TM_sendack, (int)p->tp_sendack_ticks);
                    460:                
                    461:                IFDEBUG(D_DATA)
                    462:                        printf("after stash calling sbwakeup\n");
                    463:                ENDDEBUG
                    464:        }
                    465:                 break;
                    466: case 0x1c: 
                    467:                {       
                    468:                IFTRACE(D_DATA)
                    469:                        tptrace(TPPTmisc, "NIW seq rcvnxt lcredit ",
                    470:                                e->ev_union.EV_DT_TPDU.e_seq, p->tp_rcvnxt, p->tp_lcredit, 0);
                    471:                ENDTRACE
                    472:                IncStat(ts_dt_niw);
                    473:                m_freem(e->ev_union.EV_DT_TPDU.e_data);
                    474:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    475:                (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL ); 
                    476:        }
                    477:                 break;
                    478: case 0x1d: 
                    479:                {
                    480:                if (p->tp_ucddata) {
                    481:                        m_freem(p->tp_ucddata);
                    482:                        p->tp_ucddata = 0;
                    483:                }
                    484:                (void) tp_goodack(p, e->ev_union.EV_AK_TPDU.e_cdt, e->ev_union.EV_AK_TPDU.e_seq, e->ev_union.EV_AK_TPDU.e_subseq);
                    485:                tp_cuntimeout(p, TM_retrans);
                    486: 
                    487:                soisconnected(p->tp_sock);
                    488:                IFTRACE(D_CONN)
                    489:                        struct socket *so = p->tp_sock;
                    490:                        tptrace(TPPTmisc, 
                    491:                        "called sosiconn: so so_state rcv.sb_sel rcv.sb_flags",
                    492:                                so, so->so_state, so->so_rcv.sb_sel, so->so_rcv.sb_flags);
                    493:                        tptrace(TPPTmisc, 
                    494:                        "called sosiconn 2: so_qlen so_error so_rcv.sb_cc so_head",
                    495:                                so->so_qlen, so->so_error, so->so_rcv.sb_cc, so->so_head);
                    496:                ENDTRACE
                    497: 
                    498:                tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
                    499:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    500:        }
                    501:                 break;
                    502: case 0x1e: 
                    503:                {
                    504:                if( p->tp_state == TP_AKWAIT ) {
                    505:                        if (p->tp_ucddata) {
                    506:                                m_freem(p->tp_ucddata);
                    507:                                p->tp_ucddata = 0;
                    508:                        }
                    509:                        tp_cuntimeout(p, TM_retrans);
                    510:                        soisconnected(p->tp_sock);
                    511:                        tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
                    512:                        tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    513:                } 
                    514:                IFTRACE(D_XPD)
                    515:                tptrace(TPPTmisc, "XPD tpdu accepted Xrcvnxt, e_seq datalen m_len\n",
                    516:                                p->tp_Xrcvnxt,e->ev_union.EV_XPD_TPDU.e_seq,  e->ev_union.EV_XPD_TPDU.e_datalen, e->ev_union.EV_XPD_TPDU.e_data->m_len);
                    517:                ENDTRACE
                    518: 
                    519:                p->tp_sock->so_state |= SS_RCVATMARK;
                    520:                postevent(p->tp_sock, 0, EV_OOB);
                    521:                e->ev_union.EV_XPD_TPDU.e_data->m_flags |= M_EOR;
                    522:                sbinsertoob(&p->tp_Xrcv, e->ev_union.EV_XPD_TPDU.e_data);
                    523:                IFDEBUG(D_XPD)
                    524:                        dump_mbuf(e->ev_union.EV_XPD_TPDU.e_data, "XPD TPDU: tp_Xrcv");
                    525:                ENDDEBUG
                    526:                tp_indicate(T_XDATA, p, 0);
                    527:                sbwakeup( &p->tp_Xrcv );
                    528: 
                    529:                (void) tp_emit(XAK_TPDU_type, p, p->tp_Xrcvnxt, 0, MNULL);
                    530:                SEQ_INC(p, p->tp_Xrcvnxt);
                    531:        }
                    532:                 break;
                    533: case 0x1f: 
                    534:                {
                    535:                if( p->tp_Xrcv.sb_cc == 0 ) {
                    536:                        /* kludge for select(): */ 
                    537:                        /* p->tp_sock->so_state &= ~SS_OOBAVAIL; */
                    538:                }
                    539:        }
                    540:                 break;
                    541: case 0x20: 
                    542:                {
                    543:                IFTRACE(D_XPD)
                    544:                        tptrace(TPPTmisc, "XPD tpdu niw (Xrcvnxt, e_seq) or not cdt (cc)\n",
                    545:                                p->tp_Xrcvnxt, e->ev_union.EV_XPD_TPDU.e_seq,  p->tp_Xrcv.sb_cc , 0);
                    546:                ENDTRACE
                    547:                if( p->tp_Xrcvnxt != e->ev_union.EV_XPD_TPDU.e_seq )
                    548:                        IncStat(ts_xpd_niw);
                    549:                if( p->tp_Xrcv.sb_cc ) {
                    550:                        /* might as well kick 'em again */
                    551:                        tp_indicate(T_XDATA, p, 0);
                    552:                        IncStat(ts_xpd_dup);
                    553:                }
                    554:                m_freem(e->ev_union.EV_XPD_TPDU.e_data);
                    555:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    556:                /* don't send an xack because the xak gives "last one received", not
                    557:                 * "next one i expect" (dumb)
                    558:                 */
                    559:        }
                    560:                 break;
                    561: case 0x21: 
                    562:                {
                    563:                struct socket *so = p->tp_sock;
                    564: 
                    565:                /* detach from parent socket so it can finish closing */
                    566:                if (so->so_head) {
                    567:                        if (!soqremque(so, 0) && !soqremque(so, 1))
                    568:                                panic("tp: T_DETACH");
                    569:                        so->so_head = 0;
                    570:                }
                    571:                tp_soisdisconnecting(p->tp_sock);
                    572:                tp_netcmd( p, CONN_CLOSE);
                    573:                tp_soisdisconnected(p);
                    574:        }
                    575:                 break;
                    576: case 0x22: 
                    577:                {
                    578:                struct socket *so = p->tp_sock;
                    579:                struct mbuf *data = MNULL;
                    580: 
                    581:                /* detach from parent socket so it can finish closing */
                    582:                if (so->so_head) {
                    583:                        if (!soqremque(so, 0) && !soqremque(so, 1))
                    584:                                panic("tp: T_DETACH");
                    585:                        so->so_head = 0;
                    586:                }
                    587:                if (p->tp_state != TP_CLOSING) {
                    588:                        tp_soisdisconnecting(p->tp_sock);
                    589:                        data = MCPY(p->tp_ucddata, M_NOWAIT);
                    590:                        (void) tp_emit(DR_TPDU_type, p, 0, E_TP_NORMAL_DISC, data);
                    591:                        p->tp_retrans = p->tp_Nretrans;
                    592:                        tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
                    593:                }
                    594:        }
                    595:                 break;
                    596: case 0x23: 
                    597:                {
                    598:                tp_soisdisconnecting(p->tp_sock);
                    599:                tp_netcmd( p, CONN_CLOSE);
                    600:                tp_soisdisconnected(p);
                    601:        }
                    602:                 break;
                    603: case 0x24: 
                    604:                {
                    605:                struct mbuf *data = MCPY(p->tp_ucddata, M_WAIT);
                    606: 
                    607:                if(p->tp_state == TP_OPEN) {
                    608:                        tp_euntimeout(p, TM_data_retrans); /* all */
                    609:                        tp_cuntimeout(p, TM_inact);
                    610:                        tp_cuntimeout(p, TM_sendack);
                    611:                        p->tp_flags &= ~TPF_DELACK;
                    612:                }
                    613:                if (data) {
                    614:                        IFDEBUG(D_CONN)
                    615:                                printf("T_DISC_req.trans tp_ucddata 0x%x\n", 
                    616:                                        p->tp_ucddata);
                    617:                                dump_mbuf(data, "ucddata @ T_DISC_req");
                    618:                        ENDDEBUG
                    619:                }
                    620:                tp_soisdisconnecting(p->tp_sock);
                    621:                p->tp_retrans = p->tp_Nretrans;
                    622:                tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
                    623: 
                    624:                if( trick_hc )
                    625:                        return tp_emit(DR_TPDU_type, p, 0, e->ev_union.EV_T_DISC_req.e_reason, data);
                    626:        }
                    627:                 break;
                    628: case 0x25: 
                    629:                {
                    630:                int error;
                    631:                struct mbuf *data = MCPY(p->tp_ucddata, M_WAIT);
                    632: 
                    633:                IncStat(ts_retrans_cc);
                    634:                p->tp_retrans --;
                    635:                p->tp_cong_win = 1 * p->tp_l_tpdusize;
                    636: 
                    637:                if( error = tp_emit(CC_TPDU_type, p, 0, 0, data) ) 
                    638:                        p->tp_sock->so_error = error;
                    639:                tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
                    640:        }
                    641:                 break;
                    642: case 0x26: 
                    643:                {
                    644:                IncStat(ts_conn_gaveup);
                    645:                tp_soisdisconnecting(p->tp_sock);
                    646:                p->tp_sock->so_error = ETIMEDOUT;
                    647:                tp_indicate(T_DISCONNECT, p, ETIMEDOUT);
                    648:                (void) tp_emit(DR_TPDU_type, p, 0, E_TP_CONGEST, MNULL);
                    649:                p->tp_retrans = p->tp_Nretrans;
                    650:                tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
                    651:        }
                    652:                 break;
                    653: case 0x27: 
                    654:                {
                    655:                tp_euntimeout(p, TM_data_retrans); /* all */
                    656:                tp_cuntimeout(p, TM_inact); 
                    657:                tp_cuntimeout(p, TM_sendack);
                    658: 
                    659:                IncStat(ts_conn_gaveup);
                    660:                tp_soisdisconnecting(p->tp_sock);
                    661:                p->tp_sock->so_error = ETIMEDOUT;
                    662:                tp_indicate(T_DISCONNECT, p, ETIMEDOUT);
                    663:                (void) tp_emit(DR_TPDU_type, p, 0, E_TP_CONGEST_2, MNULL);
                    664:                p->tp_retrans = p->tp_Nretrans;
                    665:                tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
                    666:        }
                    667:                 break;
                    668: case 0x28: 
                    669:                {
                    670:                p->tp_cong_win = 1 * p->tp_l_tpdusize;
                    671:                /* resume XPD */
                    672:                if      ( p->tp_Xsnd.sb_mb )  {
                    673:                        struct mbuf *m = m_copy(p->tp_Xsnd.sb_mb, 0, (int)p->tp_Xsnd.sb_cc);
                    674:                        int shift;
                    675: 
                    676:                        IFTRACE(D_XPD)
                    677:                                tptrace(TPPTmisc, "XPD retrans: Xuna Xsndnxt sndnxt snduna",
                    678:                                        p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndnxt, 
                    679:                                        p->tp_snduna); 
                    680:                        ENDTRACE
                    681:                        IFDEBUG(D_XPD)
                    682:                                dump_mbuf(m, "XPD retrans emitting M");
                    683:                        ENDDEBUG
                    684:                        IncStat(ts_retrans_xpd);
                    685:                        p->tp_retrans --;
                    686:                        shift = max(p->tp_Nretrans - p->tp_retrans, 6);
                    687:                        (void) tp_emit(XPD_TPDU_type, p, p->tp_Xuna, 1, m);
                    688:                        tp_ctimeout(p, TM_retrans, ((int)p->tp_dt_ticks) << shift);
                    689:                }
                    690:        }
                    691:                 break;
                    692: case 0x29: 
                    693:                {       
                    694:                p->tp_rxtshift++;
                    695:                (void) tp_data_retrans(p);
                    696:        }
                    697:                 break;
                    698: case 0x2a: 
                    699:                {       
                    700:                p->tp_retrans --;
                    701:                (void) tp_emit(DR_TPDU_type, p, 0, E_TP_DR_NO_REAS, MNULL);
                    702:                IncStat(ts_retrans_dr);
                    703:                tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
                    704:        }
                    705:                 break;
                    706: case 0x2b: 
                    707:                {       
                    708:                p->tp_sock->so_error = ETIMEDOUT;
                    709:                p->tp_refstate = REF_FROZEN;
                    710:                tp_recycle_tsuffix( p );
                    711:                tp_etimeout(p, TM_reference, (int)p->tp_refer_ticks);
                    712:        }
                    713:                 break;
                    714: case 0x2c: 
                    715:                {
                    716:                tp_freeref(p->tp_lref);
                    717:                tp_detach(p);
                    718:        }
                    719:                 break;
                    720: case 0x2d: 
                    721:                {       
                    722:                if( p->tp_class != TP_CLASS_0) {
                    723:                        tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    724:                        if ( e->ev_number == CC_TPDU )
                    725:                                (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL); 
                    726:                }
                    727:                /* ignore it if class 0 - state tables are blank for this */
                    728:        }
                    729:                 break;
                    730: case 0x2e: 
                    731:                {
                    732:                IFTRACE(D_DATA)
                    733:                        tptrace(TPPTmisc, "T_DATA_req sndnxt snduna fcredit, tpcb",
                    734:                                p->tp_sndnxt, p->tp_snduna, p->tp_fcredit, p);
                    735:                ENDTRACE
                    736: 
                    737:                tp_send(p);
                    738:        }
                    739:                 break;
                    740: case 0x2f: 
                    741:                {
                    742:                int error = 0;
                    743: 
                    744:                /* resume XPD */
                    745:                if      ( p->tp_Xsnd.sb_mb )  {
                    746:                        struct mbuf *m = m_copy(p->tp_Xsnd.sb_mb, 0, (int)p->tp_Xsnd.sb_cc);
                    747:                        /* m_copy doesn't preserve the m_xlink field, but at this pt.
                    748:                         * that doesn't matter
                    749:                         */
                    750: 
                    751:                        IFTRACE(D_XPD)
                    752:                                tptrace(TPPTmisc, "XPD req: Xuna Xsndnxt sndnxt snduna",
                    753:                                        p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndnxt, 
                    754:                                        p->tp_snduna); 
                    755:                        ENDTRACE
                    756:                        IFDEBUG(D_XPD)
                    757:                                printf("T_XPD_req: sb_cc 0x%x\n", p->tp_Xsnd.sb_cc);
                    758:                                dump_mbuf(m, "XPD req emitting M");
                    759:                        ENDDEBUG
                    760:                        error = 
                    761:                                tp_emit(XPD_TPDU_type, p, p->tp_Xuna, 1, m);
                    762:                        p->tp_retrans = p->tp_Nretrans;
                    763: 
                    764:                        tp_ctimeout(p, TM_retrans, (int)p->tp_rxtcur);
                    765:                        SEQ_INC(p, p->tp_Xsndnxt);
                    766:                } 
                    767:                if(trick_hc)
                    768:                        return error;
                    769:        }
                    770:                 break;
                    771: case 0x30: 
                    772:                {
                    773:                struct sockbuf *sb = &p->tp_sock->so_snd;
                    774: 
                    775:                IFDEBUG(D_ACKRECV)
                    776:                        printf("GOOD ACK seq 0x%x cdt 0x%x\n", e->ev_union.EV_AK_TPDU.e_seq, e->ev_union.EV_AK_TPDU.e_cdt);
                    777:                ENDDEBUG
                    778:                if( p->tp_class != TP_CLASS_0) {
                    779:                        tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    780:                }
                    781:                sbwakeup(sb);
                    782:                IFDEBUG(D_ACKRECV)
                    783:                        printf("GOOD ACK new sndnxt 0x%x\n", p->tp_sndnxt);
                    784:                ENDDEBUG
                    785:        }
                    786:                 break;
                    787: case 0x31: 
                    788:                {
                    789:                IFTRACE(D_ACKRECV)
                    790:                        tptrace(TPPTmisc, "BOGUS ACK fcc_present, tp_r_subseq e_subseq", 
                    791:                                e->ev_union.EV_AK_TPDU.e_fcc_present, p->tp_r_subseq, e->ev_union.EV_AK_TPDU.e_subseq, 0);
                    792:                ENDTRACE
                    793:                if( p->tp_class != TP_CLASS_0 ) {
                    794: 
                    795:                        if ( !e->ev_union.EV_AK_TPDU.e_fcc_present ) {
                    796:                                /* send ACK with FCC */
                    797:                                IncStat( ts_ackreason[_ACK_FCC_] );
                    798:                                (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 1, MNULL);
                    799:                        }
                    800:                        tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    801:                } 
                    802:        }
                    803:                 break;
                    804: case 0x32: 
                    805:                {       
                    806:                tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    807:                tp_cuntimeout(p, TM_retrans);
                    808: 
                    809:                sbwakeup( &p->tp_sock->so_snd );
                    810: 
                    811:                /* resume normal data */
                    812:                tp_send(p);
                    813:        }
                    814:                 break;
                    815: case 0x33: 
                    816:                {
                    817:                IFTRACE(D_ACKRECV)
                    818:                        tptrace(TPPTmisc, "BOGUS XACK eventtype ", e->ev_number, 0, 0,0);
                    819:                ENDTRACE
                    820:                if( p->tp_class != TP_CLASS_0 ) {
                    821:                        tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
                    822:                } 
                    823:        }
                    824:                 break;
                    825: case 0x34: 
                    826:                {       
                    827:                int timo;
                    828:                IFTRACE(D_TIMER)
                    829:                        tptrace(TPPTsendack, -1, p->tp_lcredit, p->tp_sent_uwe, 
                    830:                        p->tp_sent_lcdt, 0);
                    831:                ENDTRACE
                    832:                IncPStat(p, tps_n_TMsendack);
                    833:                (void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
                    834:                if (p->tp_fcredit == 0) {
                    835:                        if (p->tp_rxtshift < TP_MAXRXTSHIFT)
                    836:                                p->tp_rxtshift++;
                    837:                        timo = (p->tp_dt_ticks) << p->tp_rxtshift;
                    838:                } else
                    839:                        timo = p->tp_sendack_ticks;
                    840:                tp_ctimeout(p, TM_sendack, timo);
                    841:        }
                    842:                 break;
                    843: case 0x35: 
                    844:                {
                    845:                if (sbspace(&p->tp_sock->so_rcv) > 0)
                    846:                        tp0_openflow(p);
                    847:        }
                    848:                 break;
                    849: case 0x36: 
                    850:                {       
                    851:                if( trick_hc ) {
                    852:                        SeqNum ack_thresh;
                    853:                        /*
                    854:                         * If the upper window edge has advanced a reasonable
                    855:                         * amount beyond what was known, send an ACK.
                    856:                         * A reasonable amount is 2 packets, unless the max window
                    857:                         * is only 1 or 2 packets, in which case we
                    858:                         * should send an ack for any advance in the upper window edge.
                    859:                         */
                    860:                        LOCAL_CREDIT(p);
                    861:                        ack_thresh = SEQ_SUB(p, p->tp_lcredit + p->tp_rcvnxt,
                    862:                                                                         (p->tp_maxlcredit > 2 ? 2 : 1));
                    863:                        if (SEQ_GT(p, ack_thresh, p->tp_sent_uwe)) {
                    864:                                IncStat(ts_ackreason[_ACK_USRRCV_]);
                    865:                                p->tp_flags &= ~TPF_DELACK;
                    866:                                return tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
                    867:                        }
                    868:                }
                    869:        }
                    870:                 break;
                    871: case 0x37: 
                    872:                {
                    873:                if(trick_hc)
                    874:                return ECONNABORTED;
                    875:        }
                    876:                 break;
                    877: case 0x38: 
                    878:                {
                    879:                ASSERT( p->tp_state != TP_LISTENING );
                    880:                tp_indicate(T_DISCONNECT, p, ECONNRESET);
                    881:                tp_soisdisconnected(p);
                    882:        }
                    883:                 break;
                    884:        }
                    885: return 0;
                    886: }
                    887: 
                    888: _XEBEC_PG int
                    889: _Xebec_index( e,p )
                    890:        struct tp_event *e;
                    891:        tp_PCB_ *p;
                    892: {
                    893: switch( (e->ev_number<<4)+(p->tp_state) ) {
                    894: case 0x12:
                    895:        if (    p->tp_retrans > 0 ) return 0x1e;
                    896:         else return 0x1f;
                    897: case 0x13:
                    898:        if ( p->tp_retrans > 0 ) return 0x2f;
                    899:         else return 0x30;
                    900: case 0x14:
                    901:        if ( p->tp_retrans > 0 ) return 0x32;
                    902:         else return 0x31;
                    903: case 0x15:
                    904:        if (    p->tp_retrans > 0 ) return 0x34;
                    905:         else return 0x35;
                    906: case 0x54:
                    907:        if (p->tp_rxtshift < TP_NRETRANS) return 0x33;
                    908:         else return 0x31;
                    909: case 0x64:
                    910:        if (p->tp_class == TP_CLASS_0) return 0x1a;
                    911:         else return 0x1b;
                    912: case 0x77:
                    913:        if ( p->tp_class == TP_CLASS_0) return 0xd;
                    914:         else return 0xe;
                    915: case 0x86:
                    916:        if ( e->ev_union.EV_DR_TPDU.e_sref !=  0 ) return 0x2;
                    917:         else return 0x3;
                    918: case 0xa2:
                    919:        if (p->tp_class == TP_CLASS_0) return 0x1c;
                    920:         else return 0x1d;
                    921: case 0xb2:
                    922:        if (p->tp_class == TP_CLASS_0) return 0x5;
                    923:         else return 0x0;
                    924: case 0xb4:
                    925:        if ( tp_goodack(p, e->ev_union.EV_AK_TPDU.e_cdt, e->ev_union.EV_AK_TPDU.e_seq, e->ev_union.EV_AK_TPDU.e_subseq)  ) return 0x3a;
                    926:         else return 0x3b;
                    927: case 0xc3:
                    928:        if ( IN_RWINDOW( p, e->ev_union.EV_DT_TPDU.e_seq,
                    929:                                        p->tp_rcvnxt, SEQ(p, p->tp_rcvnxt + p->tp_lcredit)) ) return 0x21;
                    930:         else return 0x24;
                    931: case 0xc4:
                    932:        if ( p->tp_class == TP_CLASS_0 ) return 0x22;
                    933:         else if ( IN_RWINDOW( p, e->ev_union.EV_DT_TPDU.e_seq,
                    934:                                        p->tp_rcvnxt, SEQ(p, p->tp_rcvnxt + p->tp_lcredit)) ) return 0x23;
                    935:         else return 0x25;
                    936: case 0xd3:
                    937:        if (p->tp_Xrcvnxt == e->ev_union.EV_XPD_TPDU.e_seq) return 0x27;
                    938:         else return 0x2a;
                    939: case 0xd4:
                    940:        if (p->tp_Xrcvnxt == e->ev_union.EV_XPD_TPDU.e_seq) return 0x27;
                    941:         else return 0x29;
                    942: case 0xe4:
                    943:        if ( tp_goodXack(p, e->ev_union.EV_XAK_TPDU.e_seq) ) return 0x3c;
                    944:         else return 0x3d;
                    945: case 0x102:
                    946:        if ( p->tp_class == TP_CLASS_0 ) return 0x2d;
                    947:         else return 0x2e;
                    948: case 0x104:
                    949:        if ( p->tp_class == TP_CLASS_0 ) return 0x2d;
                    950:         else return 0x2e;
                    951: case 0x144:
                    952:        if (p->tp_class == TP_CLASS_0) return 0x3f;
                    953:         else return 0x40;
                    954: case 0x162:
                    955:        if (p->tp_class == TP_CLASS_0) return 0x2b;
                    956:         else return 0x2c;
                    957: case 0x172:
                    958:        if ( p->tp_class != TP_CLASS_4 ) return 0x42;
                    959:         else return 0x46;
                    960: case 0x174:
                    961:        if ( p->tp_class != TP_CLASS_4 ) return 0x42;
                    962:         else return 0x47;
                    963: case 0x177:
                    964:        if ( p->tp_class != TP_CLASS_4 ) return 0x42;
                    965:         else return 0x43;
                    966: case 0x188:
                    967:        if ( p->tp_class == TP_CLASS_0 ) return 0xf;
                    968:         else if (tp_emit(CC_TPDU_type, p, 0,0, MCPY(p->tp_ucddata, M_NOWAIT)) == 0) return 0x10;
                    969:         else return 0x11;
                    970: default: return 0;
                    971: } /* end switch */
                    972: } /* _Xebec_index() */
                    973: static int inx[26][9] = { {0,0,0,0,0,0,0,0,0,},
                    974:  {0x0,0x0,0x0,0x0,0x31,0x0,0x0,0x0,0x0, },
                    975:  {0x0,0x0,-1,-1,-1,-1,0x0,0x0,0x0, },
                    976:  {0x0,0x0,0x0,0x0,0x3e,0x0,0x0,0x0,0x0, },
                    977:  {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, },
                    978:  {0x0,0x0,0x0,0x0,0x0,0x0,0x36,0x0,0x0, },
                    979:  {0x0,0x0,0x0,0x0,-1,0x0,0x0,0x0,0x0, },
                    980:  {0x0,0x7,0x15,0x1b,-1,0x17,0x3,0xa,0x0, },
                    981:  {0x0,0x19,0x6,0x20,0x37,0x8,0x3,-1,0x0, },
                    982:  {0x0,0x14,0x13,0x13,0x13,0x16,-1,0xa,0x0, },
                    983:  {0x0,0x7,0x6,0x1,0x9,0x18,0x3,0xa,0x0, },
                    984:  {0x0,0x19,-1,0x1,0x37,0x8,0x3,0xa,0x0, },
                    985:  {0x0,0x7,-1,0x26,-1,0x8,0x3,0xa,0x0, },
                    986:  {0x0,0x7,0x6,-1,-1,0x8,0x3,0xa,0x0, },
                    987:  {0x0,0x7,0x6,-1,-1,0x8,0x3,0xa,0x0, },
                    988:  {0x0,0x7,0x6,0x1,-1,0x8,0x3,0xa,0x0, },
                    989:  {0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0x0, },
                    990:  {0x0,0x0,-1,0x2e,-1,0x0,0x4,0x0,0x2e, },
                    991:  {0x0,0xb,0x0,0x0,0x0,0x0,0x0,0x0,0x0, },
                    992:  {0x0,0x0,0x0,0x0,0x38,0x0,0x0,0x0,0x0, },
                    993:  {0x0,0x0,0x0,0x0,0x39,0x0,0x0,0x0,0x0, },
                    994:  {0x0,0x0,0x0,0x0,-1,0x0,0x41,0x0,0x0, },
                    995:  {0x0,0x0,0x0,0x0,0x28,0x0,0x41,0x0,0x0, },
                    996:  {0x0,0xc,-1,0x2c,0x0,0x2c,0x4,0xc,0x2c, },
                    997:  {0x0,0x49,-1,0x45,-1,0x44,0x48,-1,0x0, },
                    998:  {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,-1, },
                    999: };
                   1000: tp_driver(p, e)
                   1001: register tp_PCB_ *p;
                   1002: register struct tp_event *e;
                   1003: {
                   1004:        register int index, error=0;
                   1005:        struct act_ent *a;
                   1006:        static struct act_ent erroraction = {0,-1};
                   1007: 
                   1008:        index = inx[1 + e->ev_number][p->tp_state];
                   1009:        if(index<0) index=_Xebec_index(e, p);
                   1010:        if (index==0) {
                   1011:                a = &erroraction;
                   1012:        } else
                   1013:                a = &statetable[index];
                   1014: 
                   1015:        if(a->a_action)
                   1016:                error = _Xebec_action( a->a_action, e, p );
                   1017:        IFTRACE(D_DRIVER)
                   1018:        tptrace(DRIVERTRACE,            a->a_newstate, p->tp_state, e->ev_number, a->a_action, 0);
                   1019:        ENDTRACE
                   1020:        if(error==0)
                   1021:        p->tp_state = a->a_newstate;
                   1022:        return error;
                   1023: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.