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