|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1995 Apple Computer, Inc. ! 3: * ! 4: * The information contained herein is subject to change without ! 5: * notice and should not be construed as a commitment by Apple ! 6: * Computer, Inc. Apple Computer, Inc. assumes no responsibility ! 7: * for any errors that may appear. ! 8: * ! 9: * Confidential and Proprietary to Apple Computer, Inc. ! 10: * ! 11: */ ! 12: #ifdef _AIX ! 13: #include <sys/sleep.h> ! 14: #endif ! 15: #include <h/sysglue.h> ! 16: #include <h/debug.h> ! 17: #include <h/at-config.h> ! 18: #include <at/appletalk.h> ! 19: #include <at/ddp.h> ! 20: #include <at/at_atp.h> ! 21: #include <at/asp_if.h> ! 22: #include <at/asp_errno.h> ! 23: #include <at_asp.h> ! 24: #include <atlog.h> ! 25: #undef e_sleep_thread ! 26: ! 27: #define atpBDSsize (sizeof(struct atpBDS)*AT_ATP_TRESP_MAX) ! 28: #define aspCMDsize (atpBDSsize+sizeof(struct atp_set_default)+ATP_HDR_SIZE) ! 29: #define SCBS_PER_BLK 16 ! 30: #define TICKS_PER_SEC HZ ! 31: #define SESS_TMO_RES 2 ! 32: #define DEF_SESS_TMO 120 ! 33: #define NEXT_SEQ_NUM(x) (x = (x == 65535) ? 0 : (x + 1)) ! 34: #define MAX_RCV_CNT 5 ! 35: #define BAD_REMADDR(addr) \ ! 36: ( (*(long *)&scb->rem_addr != *(long *)&addr) \ ! 37: && ((*(short *)scb->rem_addr.net != *(short *)addr.net) \ ! 38: || (scb->rem_addr.node != addr.node)) ) ! 39: ! 40: int ASPputmsg(); ! 41: int ASPgetmsg(); ! 42: void asp_init(); ! 43: void asp_ack_reply(); ! 44: void asp_nak_reply(); ! 45: void asp_stop(); ! 46: void asp_timer(); ! 47: int asp_open(); ! 48: int asp_close(); ! 49: int asp_wput(); ! 50: StaticProc asp_scb_t *asp_find_scb(); ! 51: StaticProc asp_scb_t *asp_scb_alloc(); ! 52: StaticProc void asp_wakeup(); ! 53: StaticProc void asp_putnext(); ! 54: StaticProc void asp_clock(); ! 55: StaticProc void asp_iocack(); ! 56: StaticProc void asp_iocnak(); ! 57: StaticProc void asp_dequeue_scb(); ! 58: StaticProc void asp_scb_free(); ! 59: StaticProc void asp_timout(); ! 60: StaticProc void asp_untimout(); ! 61: StaticProc void asp_hangup(); ! 62: StaticProc void asp_send_tickle(); ! 63: StaticProc void asp_accept(); ! 64: StaticProc int asp_send_req(); ! 65: ! 66: extern int atp_pidM[]; ! 67: extern gref_t *atp_inputQ[]; ! 68: gbuf_t *scb_resource_m = 0; ! 69: unsigned char asp_inpC[256]; ! 70: asp_scb_t *asp_scbQ[256]; ! 71: ! 72: extern void atalk_kfree(); ! 73: extern void *atalk_kalloc(); ! 74: ! 75: static void *asp_clock_tmo = 0; ! 76: static at_retry_t asp_def_retry = {2, -1, 1}; ! 77: static char asp_off_flag; ! 78: static unsigned char scb_tmo_cnt; ! 79: static asp_scb_t *scb_used_list; ! 80: static asp_scb_t *scb_tmo_list; ! 81: static asp_scb_t *scb_free_list; ! 82: static atlock_t aspall_lock; ! 83: static atlock_t asptmo_lock; ! 84: ! 85: int ! 86: asp_readable(gref) ! 87: gref_t *gref; ! 88: { ! 89: return (((asp_scb_t *)gref->info)->sess_ioc ? 1 : 0); ! 90: } ! 91: ! 92: void ! 93: asp_init() ! 94: { ! 95: scb_tmo_cnt = 1; ! 96: scb_tmo_list = 0; ! 97: scb_used_list = 0; ! 98: scb_free_list = 0; ! 99: asp_off_flag = 0; ! 100: bzero(asp_inpC, sizeof(asp_inpC)); ! 101: bzero(asp_scbQ, sizeof(asp_scbQ)); ! 102: ATLOCKINIT(aspall_lock); ! 103: ATLOCKINIT(asptmo_lock); ! 104: } ! 105: ! 106: /* ! 107: * the open routine allocates a state structure ! 108: */ ! 109: int ! 110: asp_open(gref) ! 111: gref_t *gref; ! 112: { ! 113: int s; ! 114: unsigned char j; ! 115: unsigned short i; ! 116: gbuf_t *m; ! 117: asp_scb_t *scb; ! 118: ! 119: /* ! 120: * if not ready, return error ! 121: */ ! 122: if (asp_off_flag) ! 123: return ENOTREADY; ! 124: ! 125: /* ! 126: * if no asp structure available, return failure ! 127: */ ! 128: if ((scb = asp_scb_alloc()) == 0) ! 129: return ENOBUFS; ! 130: ! 131: /* ! 132: * initialize the gref data structure ! 133: */ ! 134: gref->info = (void *)scb; ! 135: gref->readable = asp_readable; ! 136: ! 137: /* ! 138: * initialize the scb data structure ! 139: */ ! 140: scb->dflag = 1; ! 141: scb->magic_num = 222; ! 142: scb->state = ASPSTATE_Idle; ! 143: scb->pid = gref->pid; ! 144: scb->gref = gref; ! 145: scb->session_timer = DEF_SESS_TMO; ! 146: scb->cmd_retry = asp_def_retry; ! 147: ATDISABLE(s, aspall_lock); ! 148: if ((scb->next_scb = scb_used_list) != 0) ! 149: scb->next_scb->prev_scb = scb; ! 150: scb_used_list = scb; ! 151: ATENABLE(s, aspall_lock); ! 152: ! 153: /* ! 154: * return success ! 155: */ ! 156: dPrintf(D_M_ASP,D_L_INFO, "asp_open: pid=%d\n", scb->pid,0,0,0,0); ! 157: return 0; ! 158: } ! 159: ! 160: /* ! 161: * the close routine frees all the data structures ! 162: */ ! 163: int ! 164: asp_close(gref) ! 165: gref_t *gref; ! 166: { ! 167: int s; ! 168: unsigned char sock_num, j; ! 169: unsigned short i; ! 170: asp_scb_t *scb, *new_scb; ! 171: gbuf_t *m; ! 172: ! 173: scb = (asp_scb_t *)gref->info; ! 174: dPrintf(D_M_ASP,D_L_INFO, "asp_close: loc=%d\n", ! 175: scb->loc_addr.socket,0,0,0,0); ! 176: ! 177: if (scb->atp_state) { ! 178: if (scb->pid && scb->sess_ioc && (scb->dflag != 1)) { ! 179: /* ! 180: * send the CloseSess response to peer ! 181: */ ! 182: if (gbuf_type(scb->sess_ioc) != MSG_PROTO) { ! 183: ATDISABLE(s, scb->lock); ! 184: m = scb->sess_ioc; ! 185: scb->sess_ioc = gbuf_next(m); ! 186: ATENABLE(s, scb->lock); ! 187: atp_send_rsp(scb->gref, m); ! 188: } ! 189: } ! 190: ! 191: sock_num = scb->loc_addr.socket; ! 192: ATDISABLE(s, aspall_lock); ! 193: if ((scb->dflag != 1) && scb->stat_msg) { ! 194: extern int atp_retry_req(); ! 195: atalk_untimeout(atp_retry_req, scb->stat_msg, 0); ! 196: gbuf_freem(scb->stat_msg); ! 197: scb->stat_msg = 0; ! 198: } ! 199: if (asp_scbQ[sock_num]->next_scb == 0) { ! 200: asp_scbQ[sock_num] = 0; ! 201: asp_inpC[sock_num] = 0; ! 202: ATENABLE(s, aspall_lock); ! 203: dPrintf(D_M_ASP,D_L_INFO, ! 204: " : atp_close(), loc=%d\n", scb->loc_addr.socket,0,0,0,0); ! 205: atp_close(gref, 0); ! 206: } else { ! 207: asp_inpC[sock_num]--; ! 208: if (scb == asp_scbQ[sock_num]) { ! 209: new_scb = scb->next_scb; ! 210: new_scb->prev_scb = 0; ! 211: asp_scbQ[sock_num] = new_scb; ! 212: new_scb->atp_state->atp_gref = new_scb->gref; ! 213: new_scb->atp_state->pid = new_scb->pid; ! 214: atp_inputQ[sock_num] = new_scb->gref; ! 215: } else { ! 216: if ((scb->prev_scb->next_scb = scb->next_scb) != 0) ! 217: scb->next_scb->prev_scb = scb->prev_scb; ! 218: } ! 219: scb->next_scb = 0; ! 220: ATENABLE(s, aspall_lock); ! 221: } ! 222: } else ! 223: asp_dequeue_scb(scb); ! 224: ! 225: /* ! 226: * free all allocated blocks if any ! 227: */ ! 228: ATDISABLE(s, scb->lock); ! 229: if (scb->stat_msg) { ! 230: gbuf_freem(scb->stat_msg); ! 231: scb->stat_msg = 0; ! 232: } ! 233: if (scb->sess_ioc) { ! 234: gbuf_freel(scb->sess_ioc); ! 235: scb->sess_ioc = 0; ! 236: } ! 237: if (scb->req_msgq) { ! 238: gbuf_freel(scb->req_msgq); ! 239: scb->req_msgq = 0; ! 240: } ! 241: ! 242: scb->rem_addr.node = 0; ! 243: ATENABLE(s, scb->lock); ! 244: ! 245: /* ! 246: * stop all timers ! 247: */ ! 248: scb->tmo_cnt = 0; ! 249: asp_untimout(asp_hangup, scb); ! 250: ! 251: /* ! 252: * free the asp session control block ! 253: */ ! 254: scb->state = ASPSTATE_Close; ! 255: asp_scb_free(scb); ! 256: return 0; ! 257: } ! 258: ! 259: /* ! 260: * the write routine ! 261: */ ! 262: int ! 263: asp_wput(gref, m) ! 264: gref_t *gref; ! 265: gbuf_t *m; ! 266: { ! 267: int s; ! 268: unsigned char type; ! 269: unsigned char sockSav, sock_num, *wptr; ! 270: unsigned short tid; ! 271: int i, err, nbds, result, msize, len, Primitive; ! 272: gbuf_t *mioc, *mdata, *mx; ! 273: ioc_t *iocbp; ! 274: asp_scb_t *scb, *server_scb, *curr_scb; ! 275: at_inet_t *addr; ! 276: struct atp_set_default *sd; ! 277: at_ddp_t *ddp; ! 278: at_atp *atp; ! 279: struct atpBDS *atpBDS; ! 280: asp_word_t aw, *awp; ! 281: union asp_primitives *primitives; ! 282: asp_status_cmd_t *status_cmd; ! 283: asp_open_cmd_t *open_cmd; ! 284: at_retry_t Retry; ! 285: ! 286: scb = (asp_scb_t *)gref->info; ! 287: if (scb->dflag == 0) ! 288: return atp_wput(gref, m); ! 289: ! 290: if ((gbuf_type(m) != MSG_IOCTL) && (scb->state == ASPSTATE_Close)) { ! 291: l_err: gbuf_freem(m); ! 292: return 0; ! 293: } ! 294: ! 295: switch (gbuf_type(m)) { ! 296: case MSG_PROTO: ! 297: mioc = m; ! 298: type = gbuf_type(m); ! 299: gbuf_type(mioc) = MSG_IOCTL; ! 300: iocbp = (ioc_t *)gbuf_rptr(mioc); ! 301: mdata = gbuf_cont(mioc); ! 302: primitives = (union asp_primitives *)gbuf_rptr(m); ! 303: Primitive = primitives->Primitive; ! 304: ! 305: switch (Primitive) { ! 306: case ASPFUNC_Command: ! 307: case ASPFUNC_Write: ! 308: case ASPFUNC_WriteContinue: ! 309: case ASPFUNC_Attention: ! 310: /* ! 311: * build the command/write/write_continue request ! 312: */ ! 313: wptr = gbuf_rptr(mdata); ! 314: atpBDS = (struct atpBDS *)wptr; ! 315: wptr += atpBDSsize; ! 316: for (i=0; i < AT_ATP_TRESP_MAX; i++) { ! 317: *(unsigned long *)atpBDS[i].bdsBuffAddr = 1; ! 318: *(unsigned short *)atpBDS[i].bdsBuffSz = AT_ATP_DATA_SIZE; ! 319: } ! 320: sd = (struct atp_set_default *)wptr; ! 321: wptr += sizeof(struct atp_set_default); ! 322: sd->def_retries = (scb->cmd_retry.retries == -1) ? ! 323: ATP_INFINITE_RETRIES : scb->cmd_retry.retries; ! 324: sd->def_rate = scb->cmd_retry.interval*TICKS_PER_SEC; ! 325: sd->def_BDSlen = atpBDSsize; ! 326: ddp = (at_ddp_t *)wptr; ! 327: NET_NET(ddp->src_net, scb->loc_addr.net); ! 328: ddp->src_node = scb->loc_addr.node; ! 329: NET_NET(ddp->dst_net, scb->rem_addr.net); ! 330: ddp->dst_node = scb->rem_addr.node; ! 331: ddp->dst_socket = scb->rem_addr.socket; ! 332: UAS_ASSIGN(ddp->checksum, 0); ! 333: atp = ATP_ATP_HDR(wptr); ! 334: wptr += ATP_HDR_SIZE; ! 335: atp->at_atp_xo = 1; ! 336: atp->at_atp_xo_relt = 1; ! 337: atp->at_atp_bitmap_seqno = 0xff; ! 338: awp = (asp_word_t *)atp->at_atp_user_bytes; ! 339: awp->func = (unsigned char)Primitive; ! 340: awp->param1 = scb->sess_id; ! 341: awp->param2 = scb->snd_seq_num; ! 342: iocbp->ioc_private = (void *)scb; ! 343: iocbp->ioc_count = gbuf_len(mdata); ! 344: iocbp->ioc_rval = 0; ! 345: iocbp->ioc_cmd = AT_ATP_ISSUE_REQUEST_DEF; ! 346: ! 347: /* ! 348: * send the command/write/write_continue/attention request ! 349: */ ! 350: ATDISABLE(s, scb->lock); ! 351: if (scb->state == ASPSTATE_Close) { ! 352: ATENABLE(s, scb->lock); ! 353: goto l_err; ! 354: } ! 355: switch (awp->func) { ! 356: case ASPFUNC_Command: ! 357: scb->state = ASPSTATE_WaitingForCommandRsp; ! 358: break; ! 359: case ASPFUNC_Write: ! 360: scb->state = ASPSTATE_WaitingForWriteRsp; ! 361: break; ! 362: case ASPFUNC_WriteContinue: ! 363: scb->state = ASPSTATE_WaitingForWriteContinueRsp; ! 364: awp->param2 = scb->wrt_seq_num; ! 365: break; ! 366: case ASPFUNC_Attention: ! 367: scb->state = ASPSTATE_WaitingForCommandRsp; ! 368: atp->at_atp_xo = 0; ! 369: atp->at_atp_xo_relt = 0; ! 370: atp->at_atp_bitmap_seqno = 0x01; ! 371: gbuf_wdec(mdata,2); ! 372: awp->param2 = *(unsigned short *)gbuf_wptr(mdata); ! 373: break; ! 374: } ! 375: ATENABLE(s, scb->lock); ! 376: dPrintf(D_M_ASP,D_L_INFO, ! 377: "asp_wput: %s, loc=%d, rem=%x.%x.%d\n", ! 378: (awp->func == ASPFUNC_Command ? "CommandReq" : ! 379: awp->func == ASPFUNC_Write ? "WriteReq" : ! 380: awp->func == ASPFUNC_WriteContinue ? "WriteContinue" : ! 381: "AttentionReq"),scb->loc_addr.socket, ! 382: *(unsigned short *)ddp->dst_net,ddp->dst_node,ddp->dst_socket); ! 383: atp_send_req(gref, mioc); ! 384: return 0; ! 385: ! 386: case ASPFUNC_CmdReply: ! 387: ATDISABLE(s, scb->lock); ! 388: if (scb->req_msgq) { ! 389: mx = scb->req_msgq; ! 390: scb->req_msgq = gbuf_next(mx); ! 391: gbuf_next(mx) = 0; ! 392: ATENABLE(s, scb->lock); ! 393: asp_putnext(scb->gref, mx); ! 394: } else { ! 395: scb->req_flag = 0; ! 396: ATENABLE(s, scb->lock); ! 397: } ! 398: result = primitives->CmdReplyReq.CmdResult; ! 399: tid = primitives->CmdReplyReq.ReqRefNum; ! 400: mx = mdata; ! 401: ! 402: /* ! 403: * allocate an ATP buffer for the Command reply ! 404: */ ! 405: mdata = m; ! 406: gbuf_rinc(mdata,sizeof(void *)); ! 407: gbuf_wset(mdata,0); ! 408: ddp = (at_ddp_t *)gbuf_wptr(mdata); ! 409: gbuf_winc(mdata,DDP_X_HDR_SIZE); ! 410: atp = (at_atp *)gbuf_wptr(mdata); ! 411: gbuf_winc(mdata,AT_ATP_HDR_SIZE); ! 412: NET_NET(ddp->src_net, scb->loc_addr.net); ! 413: ddp->src_node = scb->loc_addr.node; ! 414: NET_NET(ddp->dst_net, scb->rem_addr.net); ! 415: ddp->dst_node = scb->rem_addr.node; ! 416: ddp->dst_socket = scb->reply_socket; ! 417: ddp->type = AT_DDP_TYPE_ATP; ! 418: UAS_ASSIGN(ddp->checksum, 0); ! 419: UAS_ASSIGN(atp->at_atp_transaction_id, tid); ! 420: if (scb->attn_flag && (tid == scb->attn_tid)) { ! 421: scb->attn_flag = 0; ! 422: atp->at_atp_xo = 0; ! 423: atp->at_atp_xo_relt = 0; ! 424: } else { ! 425: atp->at_atp_xo = 1; ! 426: atp->at_atp_xo_relt = 1; ! 427: } ! 428: atpBDS = (struct atpBDS *)gbuf_wptr(mdata); ! 429: msize = mx ? gbuf_msgsize(mx) : 0; ! 430: for (nbds=0; (nbds < AT_ATP_TRESP_MAX) && (msize > 0); nbds++) { ! 431: len = msize < AT_ATP_DATA_SIZE ? msize : AT_ATP_DATA_SIZE; ! 432: msize -= AT_ATP_DATA_SIZE; ! 433: *(long *)atpBDS[nbds].bdsUserData = 0; ! 434: UAL_ASSIGN(atpBDS[nbds].bdsBuffAddr, 1); ! 435: UAS_ASSIGN(atpBDS[nbds].bdsBuffSz, len); ! 436: } ! 437: UAS_ASSIGN(atpBDS[0].bdsDataSz, nbds); ! 438: *(long *)atpBDS[0].bdsUserData = (long)result; ! 439: *(long *)atp->at_atp_user_bytes = (long)result; ! 440: gbuf_winc(mdata,atpBDSsize); ! 441: dPrintf(D_M_ASP,D_L_INFO, ! 442: "asp_wput: %s, loc=%d, len=%d, state=%d, %d\n", ! 443: "CmdReplyReq", scb->loc_addr.socket,gbuf_len(mx), ! 444: scb->state,ddp->dst_socket); ! 445: atp_send_rsp(gref, mdata); ! 446: return 0; ! 447: } ! 448: ! 449: gbuf_freem(m); ! 450: break; ! 451: ! 452: case MSG_IOCTL: ! 453: mioc = m; ! 454: iocbp = (ioc_t *)gbuf_rptr(mioc); ! 455: ! 456: switch (iocbp->ioc_cmd) { ! 457: case ASPIOC_CloseSession: ! 458: if ((scb->state == ASPSTATE_Close) || (scb->rem_addr.node == 0)) ! 459: break; ! 460: else { ! 461: Retry.retries = 3; ! 462: Retry.interval = 1; ! 463: } ! 464: aw.func = ASPFUNC_CloseSess; ! 465: aw.param1 = scb->sess_id; ! 466: aw.param2 = 0; ! 467: iocbp->ioc_private = (void *)scb; ! 468: scb->ioc_wait = (unsigned char)(iocbp->ioc_cmd & 0xff); ! 469: iocbp->ioc_cmd = AT_ATP_ISSUE_REQUEST_DEF; ! 470: asp_send_req(gref, mioc, &scb->rem_addr, ! 471: &Retry, &aw, 0, ASPSTATE_WaitingForCloseSessRsp, 0x01); ! 472: return 0; ! 473: ! 474: case ASPIOC_ClientBind: ! 475: /* ! 476: * open an ATP channel ! 477: */ ! 478: if ((err = atp_open(gref, 0)) != 0) { ! 479: asp_iocnak(gref, mioc, err); ! 480: return 0; ! 481: } ! 482: scb->atp_state = (atp_state_t *)gref->info; ! 483: scb->atp_state->pid = scb->pid; ! 484: ! 485: /* ! 486: * bind to any available socket ! 487: */ ! 488: scb->dflag = 2; ! 489: sockSav = scb->dflag; ! 490: if ((sock_num = (at_socket)atp_bind(gref, 0, &sockSav)) == 0) { ! 491: scb->atp_state = (atp_state_t *)0; ! 492: atp_close(gref, 0); ! 493: gref->info = (void *)scb; ! 494: asp_iocnak(gref, mioc, EINVAL); ! 495: return 0; ! 496: } ! 497: gref->info = (void *)scb; ! 498: asp_dequeue_scb(scb); ! 499: scb->atp_state->dflag = scb->dflag; ! 500: scb->loc_addr.socket = sock_num; ! 501: asp_scbQ[sock_num] = scb; ! 502: asp_inpC[sock_num]++; ! 503: atp_pidM[sock_num] = 0; ! 504: break; ! 505: ! 506: case ASPIOC_ListenerBind: ! 507: /* ! 508: * open an ATP channel ! 509: */ ! 510: if ((err = atp_open(gref, 0)) != 0) { ! 511: asp_iocnak(gref, mioc, err); ! 512: return 0; ! 513: } ! 514: scb->atp_state = (atp_state_t *)gref->info; ! 515: scb->atp_state->pid = scb->pid; ! 516: ! 517: /* ! 518: * bind to any available socket ! 519: */ ! 520: if ((sock_num = (at_socket)atp_bind(gref, 0, 0)) == 0) { ! 521: scb->atp_state = (atp_state_t *)0; ! 522: atp_close(gref, 0); ! 523: gref->info = (void *)scb; ! 524: asp_iocnak(gref, mioc, EINVAL); ! 525: return 0; ! 526: } ! 527: gref->info = (void *)scb; ! 528: asp_dequeue_scb(scb); ! 529: scb->atp_state->dflag = scb->dflag; ! 530: scb->loc_addr.socket = sock_num; ! 531: asp_scbQ[sock_num] = scb; ! 532: asp_inpC[sock_num]++; ! 533: if (gbuf_cont(mioc)) ! 534: *(at_inet_t *)gbuf_rptr(gbuf_cont(mioc)) = scb->loc_addr; ! 535: break; ! 536: ! 537: case ASPIOC_GetLocEntity: ! 538: if ((gbuf_cont(mioc) == 0) || (scb->atp_state == 0)) { ! 539: asp_iocnak(gref, mioc, EPROTO); ! 540: return 0; ! 541: } ! 542: *(at_inet_t *)gbuf_rptr(gbuf_cont(mioc)) = scb->loc_addr; ! 543: break; ! 544: ! 545: case ASPIOC_GetRemEntity: ! 546: if ((gbuf_cont(mioc) == 0) || (scb->atp_state == 0)) { ! 547: asp_iocnak(gref, mioc, EPROTO); ! 548: return 0; ! 549: } ! 550: *(at_inet_t *)gbuf_rptr(gbuf_cont(mioc)) = scb->rem_addr; ! 551: break; ! 552: ! 553: case ASPIOC_GetSession: ! 554: if ((mdata = gbuf_cont(mioc)) == 0) { ! 555: asp_iocnak(gref, mioc, EPROTO); ! 556: return 0; ! 557: } ! 558: addr = (at_inet_t *)gbuf_rptr(mdata); ! 559: scb->tickle_interval = (unsigned short)addr->node; ! 560: scb->session_timer = *(unsigned short *)addr->net; ! 561: server_scb = asp_scbQ[addr->socket]; ! 562: if (server_scb->sess_ioc == 0) { ! 563: asp_iocnak(gref, mioc, EPROTO); ! 564: return 0; ! 565: } ! 566: ! 567: /* ! 568: * open an ATP channel ! 569: */ ! 570: if ((err = atp_open(gref, 0)) != 0) { ! 571: gref->info = (void *)scb; ! 572: asp_iocnak(gref, mioc, err); ! 573: return 0; ! 574: } ! 575: scb->atp_state = (atp_state_t *)gref->info; ! 576: scb->atp_state->pid = scb->pid; ! 577: ! 578: /* ! 579: * bind to any available socket ! 580: */ ! 581: scb->dflag = 3; ! 582: sockSav = scb->dflag; ! 583: if ((sock_num = (at_socket)atp_bind(gref, 0, &sockSav)) == 0) { ! 584: atp_close(gref, 0); ! 585: asp_dequeue_scb(scb); ! 586: ATDISABLE(s, aspall_lock); ! 587: sock_num = sockSav; ! 588: scb->loc_addr.socket = sock_num; ! 589: for (curr_scb = asp_scbQ[sock_num]; ! 590: curr_scb->next_scb; curr_scb = curr_scb->next_scb) ; ! 591: scb->prev_scb = curr_scb; ! 592: curr_scb->next_scb = scb; ! 593: scb->atp_state = curr_scb->atp_state; ! 594: ATENABLE(s, aspall_lock); ! 595: } else { ! 596: asp_dequeue_scb(scb); ! 597: ATDISABLE(s, aspall_lock); ! 598: scb->loc_addr.socket = sock_num; ! 599: asp_scbQ[sock_num] = scb; ! 600: scb->atp_state->dflag = scb->dflag; ! 601: ATENABLE(s, aspall_lock); ! 602: } ! 603: gref->info = (void *)scb; ! 604: asp_inpC[sock_num]++; ! 605: gbuf_cont(mioc) = 0; ! 606: asp_accept(server_scb, scb, mdata); ! 607: break; ! 608: ! 609: case ASPIOC_GetStatus: ! 610: if ((mdata = gbuf_cont(mioc)) == 0) { ! 611: asp_iocnak(gref, mioc, EINVAL); ! 612: return 0; ! 613: } ! 614: gbuf_cont(mioc) = 0; ! 615: status_cmd = (asp_status_cmd_t *)gbuf_rptr(mdata); ! 616: aw.func = ASPFUNC_GetStatus; ! 617: aw.param1 = 0; ! 618: aw.param2 = 0; ! 619: scb->ioc_wait = (unsigned char)(iocbp->ioc_cmd & 0xff); ! 620: iocbp->ioc_cmd = AT_ATP_ISSUE_REQUEST_DEF; ! 621: asp_send_req(gref, mioc, &status_cmd->SLSEntityIdentifier, ! 622: &status_cmd->Retry, &aw, 1, ASPSTATE_WaitingForGetStatusRsp, 0xff); ! 623: gbuf_freeb(mdata); ! 624: return 0; ! 625: ! 626: case ASPIOC_OpenSession: ! 627: if ((mdata = gbuf_cont(mioc)) == 0) { ! 628: asp_iocnak(gref, mioc, EINVAL); ! 629: return 0; ! 630: } ! 631: gbuf_cont(mioc) = 0; ! 632: open_cmd = (asp_open_cmd_t *)gbuf_rptr(mdata); ! 633: scb->svc_addr = open_cmd->SLSEntityIdentifier; ! 634: scb->rem_addr = scb->svc_addr; ! 635: scb->rem_node = scb->rem_addr.node; ! 636: scb->rem_addr.node = 0; ! 637: scb->tickle_interval = open_cmd->TickleInterval; ! 638: scb->session_timer = open_cmd->SessionTimer; ! 639: aw.func = ASPFUNC_OpenSess; ! 640: aw.param1 = scb->loc_addr.socket; ! 641: aw.param2 = ASP_Version; ! 642: scb->ioc_wait = (unsigned char)(iocbp->ioc_cmd & 0xff); ! 643: iocbp->ioc_cmd = AT_ATP_ISSUE_REQUEST_DEF; ! 644: asp_send_req(gref, mioc, &open_cmd->SLSEntityIdentifier, ! 645: &open_cmd->Retry, &aw, 1, ASPSTATE_WaitingForOpenSessRsp, 0x01); ! 646: gbuf_freeb(mdata); ! 647: return 0; ! 648: ! 649: case ASPIOC_StatusBlock: ! 650: /* ! 651: * save the server status block ! 652: */ ! 653: if (scb->stat_msg) ! 654: gbuf_freem(scb->stat_msg); ! 655: scb->stat_msg = gbuf_cont(mioc); ! 656: gbuf_cont(mioc) = 0; ! 657: break; ! 658: ! 659: case ASPIOC_SetPid: ! 660: if (gbuf_cont(mioc) == 0) { ! 661: asp_iocnak(gref, mioc, EINVAL); ! 662: return 0; ! 663: } ! 664: scb->pid = *(int *)gbuf_rptr(gbuf_cont(mioc)); ! 665: break; ! 666: ! 667: case ASPIOC_GetSessId: ! 668: if (gbuf_cont(mioc) == 0) { ! 669: asp_iocnak(gref, mioc, EINVAL); ! 670: return 0; ! 671: } ! 672: *(gref_t **)gbuf_rptr(gbuf_cont(mioc)) = gref; ! 673: break; ! 674: ! 675: case ASPIOC_EnableSelect: ! 676: scb->sel_on = 1; ! 677: if (scb->sess_ioc) ! 678: atalk_notify_sel(gref); ! 679: break; ! 680: ! 681: case ASPIOC_Look: ! 682: if (gbuf_cont(mioc) == 0) { ! 683: asp_iocnak(gref, mioc, EINVAL); ! 684: return 0; ! 685: } ! 686: if (scb->sess_ioc) { ! 687: primitives = (union asp_primitives *)gbuf_rptr(scb->sess_ioc); ! 688: if (primitives->Primitive == ASPFUNC_CmdReply) ! 689: *(int *)gbuf_rptr(gbuf_cont(mioc)) = 0; ! 690: else ! 691: *(int *)gbuf_rptr(gbuf_cont(mioc)) = 1; ! 692: } else ! 693: *(int *)gbuf_rptr(gbuf_cont(mioc)) = -1; ! 694: break; ! 695: ! 696: case DDP_IOC_GET_CFG: ! 697: scb->state = ASPSTATE_WaitingForCfgAck; ! 698: atp_wput(gref, mioc); ! 699: return 0; ! 700: ! 701: default: ! 702: asp_iocnak(gref, mioc, EINVAL); ! 703: return 0; ! 704: } ! 705: ! 706: asp_iocack(gref, mioc); ! 707: break; ! 708: ! 709: default: ! 710: dPrintf(D_M_ASP,D_L_WARNING, ! 711: "asp_wput: UNKNOWN message, type=%d\n", gbuf_type(m),0,0,0,0); ! 712: gbuf_freem(m); ! 713: } ! 714: ! 715: return 0; ! 716: } ! 717: ! 718: /* ! 719: * send request routine ! 720: */ ! 721: StaticProc int ! 722: asp_send_req(gref, mioc, dest, retry, awp, xo, state, bitmap) ! 723: gref_t *gref; ! 724: gbuf_t *mioc; ! 725: at_inet_t *dest; ! 726: at_retry_t *retry; ! 727: asp_word_t *awp; ! 728: unsigned char xo; ! 729: unsigned char state; ! 730: unsigned char bitmap; ! 731: { ! 732: int i; ! 733: gbuf_t *mdata; ! 734: ioc_t *iocbp; ! 735: struct atp_set_default *sd; ! 736: at_ddp_t *ddp; ! 737: at_atp *atp; ! 738: struct atpBDS *atpBDS; ! 739: asp_scb_t *scb = (asp_scb_t *)gref->info; ! 740: ! 741: /* ! 742: * allocate an ATP buffer for the request ! 743: */ ! 744: if ((gbuf_cont(mioc) = gbuf_alloc(aspCMDsize, PRI_MED)) == 0) { ! 745: if (awp->func == ASPFUNC_Tickle) ! 746: gbuf_freem(mioc); ! 747: else ! 748: asp_iocnak(gref, mioc, ENOBUFS); ! 749: dPrintf(D_M_ASP,D_L_WARNING, ! 750: "asp_send_req: ENOBUFS, loc=%d\n", scb->loc_addr.socket,0,0,0,0); ! 751: return -1; ! 752: } ! 753: mdata = gbuf_cont(mioc); ! 754: iocbp = (ioc_t *)gbuf_rptr(mioc); ! 755: ! 756: /* ! 757: * build the request ! 758: */ ! 759: atpBDS = (struct atpBDS *)gbuf_rptr(mdata); ! 760: gbuf_wset(mdata,atpBDSsize); ! 761: for (i=0; i < AT_ATP_TRESP_MAX; i++) { ! 762: *(unsigned long *)atpBDS[i].bdsBuffAddr = 1; ! 763: *(unsigned short *)atpBDS[i].bdsBuffSz = AT_ATP_DATA_SIZE; ! 764: } ! 765: sd = (struct atp_set_default *)gbuf_wptr(mdata); ! 766: gbuf_winc(mdata,sizeof(struct atp_set_default)); ! 767: sd->def_retries = (retry->retries == -1) ? ! 768: ATP_INFINITE_RETRIES : retry->retries; ! 769: sd->def_rate = retry->interval*TICKS_PER_SEC; ! 770: sd->def_BDSlen = atpBDSsize; ! 771: ddp = (at_ddp_t *)gbuf_wptr(mdata); ! 772: NET_NET(ddp->src_net, scb->loc_addr.net); ! 773: ddp->src_node = scb->loc_addr.node; ! 774: NET_NET(ddp->dst_net, dest->net); ! 775: ddp->dst_node = dest->node; ! 776: ddp->dst_socket = dest->socket; ! 777: UAS_ASSIGN(ddp->checksum, 0); ! 778: atp = ATP_ATP_HDR(gbuf_wptr(mdata)); ! 779: atp->at_atp_xo = xo; ! 780: atp->at_atp_xo_relt = xo; ! 781: atp->at_atp_bitmap_seqno = bitmap; ! 782: gbuf_winc(mdata,ATP_HDR_SIZE); ! 783: *(asp_word_t *)atp->at_atp_user_bytes = *awp; ! 784: iocbp->ioc_count = gbuf_len(mdata); ! 785: iocbp->ioc_rval = 0; ! 786: ! 787: /* ! 788: * send the request ! 789: */ ! 790: scb->state = state; ! 791: dPrintf(D_M_ASP,D_L_INFO, ! 792: "asp_send_req: %s, loc=%d, len=%d, state=%d, %d\n", ! 793: (awp->func == ASPFUNC_GetStatus ? "GetStatusReq" : ! 794: (awp->func == ASPFUNC_OpenSess ? "OpenSessReq" : ! 795: (awp->func == ASPFUNC_CloseSess ? "CloseSessReq" : "TickleReq"))), ! 796: scb->loc_addr.socket,iocbp->ioc_count,scb->state,ddp->dst_socket); ! 797: atp_send_req(gref, mioc); ! 798: return 0; ! 799: } ! 800: ! 801: /* ! 802: * send tickle routine ! 803: */ ! 804: StaticProc void ! 805: asp_send_tickle(scb) ! 806: asp_scb_t *scb; ! 807: { ! 808: gbuf_t *mioc; ! 809: at_retry_t retry; ! 810: asp_word_t aw; ! 811: at_inet_t *dest; ! 812: ! 813: /* ! 814: * make sure the connection is still there ! 815: */ ! 816: if (scb->rem_addr.node == 0) ! 817: return; ! 818: ! 819: if ((mioc = gbuf_alloc(sizeof(ioc_t), PRI_HI)) == 0) { ! 820: dPrintf(D_M_ASP,D_L_WARNING, ! 821: "asp_send_tickle: ENOBUFS 0, loc=%d, rem=%d\n", ! 822: scb->loc_addr.socket,scb->rem_addr.socket,0,0,0); ! 823: atalk_timeout(asp_send_tickle, (void *)scb, 10); ! 824: return; ! 825: } ! 826: gbuf_wset(mioc,sizeof(ioc_t)); ! 827: gbuf_type(mioc) = MSG_IOCTL; ! 828: ! 829: dest = scb->svc_addr.node ? ! 830: (at_inet_t *)&scb->svc_addr : (at_inet_t *)&scb->rem_addr; ! 831: retry.interval = scb->tickle_interval; ! 832: retry.retries = -1; ! 833: retry.backoff = 1; ! 834: aw.func = ASPFUNC_Tickle; ! 835: aw.param1 = scb->sess_id; ! 836: aw.param2 = 0; ! 837: ((ioc_t *)gbuf_rptr(mioc))->ioc_cr = (void *)scb; ! 838: ((ioc_t *)gbuf_rptr(mioc))->ioc_cmd = AT_ATP_ISSUE_REQUEST_DEF_NOTE; ! 839: ! 840: if (asp_send_req(scb->gref, mioc, dest, &retry, &aw, 0, scb->state, 0)) { ! 841: dPrintf(D_M_ASP,D_L_WARNING, ! 842: "asp_send_tickle: ENOBUFS 1, loc=%d, rem=%d\n", ! 843: scb->loc_addr.socket,scb->rem_addr.socket,0,0,0); ! 844: atalk_timeout(asp_send_tickle, (void *)scb, 10); ! 845: return; ! 846: } ! 847: } ! 848: ! 849: /* ! 850: * accept connection routine ! 851: */ ! 852: StaticProc void ! 853: asp_accept(scb, sess_scb, m) ! 854: asp_scb_t *scb; ! 855: asp_scb_t *sess_scb; ! 856: gbuf_t *m; ! 857: { ! 858: int s; ! 859: gbuf_t *mdata; ! 860: at_ddp_t *ddp; ! 861: at_atp *atp; ! 862: asp_word_t *awp; ! 863: at_inet_t rem_addr; ! 864: ! 865: mdata = scb->sess_ioc; ! 866: ddp = (at_ddp_t *)gbuf_rptr(mdata); ! 867: atp = (at_atp *)(gbuf_rptr(mdata) + DDP_X_HDR_SIZE); ! 868: NET_NET(rem_addr.net, ddp->src_net); ! 869: rem_addr.node = ddp->src_node; ! 870: rem_addr.socket = ddp->src_socket; ! 871: awp = (asp_word_t *)atp->at_atp_user_bytes; ! 872: ! 873: NET_NET(sess_scb->loc_addr.net, ddp->dst_net); ! 874: sess_scb->loc_addr.node = ddp->dst_node; ! 875: NET_NET(ddp->src_net, sess_scb->loc_addr.net); ! 876: ddp->src_node = sess_scb->loc_addr.node; ! 877: NET_NET(ddp->dst_net, rem_addr.net); ! 878: ddp->dst_node = rem_addr.node; ! 879: ddp->dst_socket = rem_addr.socket; ! 880: ! 881: sess_scb->sess_id = sess_scb->loc_addr.socket; ! 882: sess_scb->rem_socket = rem_addr.socket; ! 883: sess_scb->rem_addr = rem_addr; ! 884: sess_scb->rem_addr.socket = awp->param1; ! 885: sess_scb->reply_socket = sess_scb->rem_addr.socket; ! 886: awp->func = sess_scb->loc_addr.socket; ! 887: awp->param1 = sess_scb->sess_id; ! 888: awp->param2 = 0; ! 889: gbuf_freeb(m); ! 890: ATDISABLE(s, scb->lock); ! 891: scb->sess_ioc = gbuf_next(mdata); ! 892: ATENABLE(s, scb->lock); ! 893: gbuf_next(mdata) = 0; ! 894: asp_timout(asp_hangup, sess_scb, sess_scb->session_timer); ! 895: atp_send_rsp(scb->gref, mdata); ! 896: asp_send_tickle(sess_scb); ! 897: dPrintf(D_M_ASP,D_L_INFO, ! 898: "asp_accept: ACCEPT connect request, loc=%d, rem=%x.%x.%d\n", ! 899: sess_scb->loc_addr.socket, ! 900: *(unsigned short *)sess_scb->rem_addr.net, ! 901: sess_scb->rem_addr.node,sess_scb->rem_addr.socket,0); ! 902: } ! 903: ! 904: /* ! 905: * timer routine ! 906: */ ! 907: void ! 908: asp_timer(arg, flag) ! 909: void *arg; ! 910: int flag; ! 911: { ! 912: int s; ! 913: asp_scb_t *scb; ! 914: void (*tmo_func)(); ! 915: ! 916: if (asp_off_flag) ! 917: return; ! 918: if (flag) { ! 919: asp_off_flag = 1; ! 920: atalk_untimeout(asp_clock, (void *)arg, asp_clock_tmo); ! 921: if (scb_resource_m) { ! 922: gbuf_freem(scb_resource_m); ! 923: scb_resource_m = 0; ! 924: } ! 925: return; ! 926: } ! 927: ! 928: ATDISABLE(s, asptmo_lock); ! 929: if (scb_tmo_list) ! 930: scb_tmo_list->tmo_delta--; ! 931: while (((scb = scb_tmo_list) != 0) && (scb_tmo_list->tmo_delta == 0)) { ! 932: if ((scb_tmo_list = scb->next_tmo) != 0) ! 933: scb_tmo_list->prev_tmo = 0; ! 934: if ((tmo_func = scb->tmo_func) != 0) { ! 935: scb->tmo_func = 0; ! 936: ATENABLE(s, asptmo_lock); ! 937: (*tmo_func)(scb); ! 938: ATDISABLE(s, asptmo_lock); ! 939: } ! 940: } ! 941: ATENABLE(s, asptmo_lock); ! 942: ! 943: if (++scb_tmo_cnt == 0) scb_tmo_cnt++; ! 944: asp_clock_tmo = (void *) ! 945: atalk_timeout(asp_clock, (void *)arg, (1<<SESS_TMO_RES)*TICKS_PER_SEC); ! 946: } ! 947: ! 948: /* ! 949: * ACK reply routine ! 950: */ ! 951: void ! 952: asp_ack_reply(gref, mioc) ! 953: register gref_t *gref; ! 954: register gbuf_t *mioc; ! 955: { ! 956: int s; ! 957: int len, msize, nbds, result; ! 958: register gbuf_t *mdata, *m, *mx; ! 959: struct atpBDS *atpBDS; ! 960: at_ddp_t *ddp; ! 961: at_atp *atp; ! 962: register asp_scb_t *scb, *sess_scb; ! 963: register ioc_t *iocbp; ! 964: register asp_word_t *awp; ! 965: register asp_command_ind_t *command_ind; ! 966: register asp_cmdreply_ind_t *cmdreply_ind; ! 967: at_inet_t rem_addr; ! 968: ! 969: iocbp = (ioc_t *)gbuf_rptr(mioc); ! 970: ! 971: if (iocbp->ioc_cmd == AT_ATP_ISSUE_REQUEST_DEF_NOTE) { ! 972: /* ! 973: * ignore the ack for the tickle request ! 974: */ ! 975: scb = (asp_scb_t *)iocbp->ioc_cr; ! 976: scb->tickle_tid = (unsigned short)iocbp->ioc_rval; ! 977: gbuf_freem(mioc); ! 978: return; ! 979: } ! 980: ! 981: scb = (asp_scb_t *)gref->info; ! 982: if (scb == 0) { ! 983: gbuf_freem(mioc); ! 984: return; ! 985: } ! 986: ! 987: if (iocbp->ioc_cmd == AT_ATP_GET_POLL) { ! 988: /* ! 989: * if no data, just drop the request ! 990: */ ! 991: if ((mdata = gbuf_cont(mioc)) == 0) { ! 992: gbuf_freeb(mioc); ! 993: return; ! 994: } ! 995: ! 996: gbuf_type(mioc) = MSG_IOCTL; ! 997: ddp = (at_ddp_t *)gbuf_rptr(mdata); ! 998: gbuf_rinc(mdata,DDP_X_HDR_SIZE); ! 999: atp = (at_atp *)gbuf_rptr(mdata); ! 1000: gbuf_rinc(mdata,AT_ATP_HDR_SIZE); ! 1001: NET_NET(rem_addr.net, ddp->src_net); ! 1002: rem_addr.node = ddp->src_node; ! 1003: rem_addr.socket = ddp->src_socket; ! 1004: awp = (asp_word_t *)atp->at_atp_user_bytes; ! 1005: ! 1006: if (scb->next_scb) { ! 1007: /* ! 1008: * find the responsible scb ! 1009: */ ! 1010: if ((scb = asp_find_scb(scb->loc_addr.socket, &rem_addr)) == 0) { ! 1011: gbuf_freem(mioc); ! 1012: return; ! 1013: } ! 1014: } ! 1015: dPrintf(D_M_ASP,D_L_INFO, ! 1016: "asp_ack_reply: FUNC=%d, loc=%d, rem=%x.%x.%d\n", ! 1017: awp->func,scb->loc_addr.socket, ! 1018: *(unsigned short *)ddp->src_net,ddp->src_node,ddp->src_socket); ! 1019: ! 1020: if (scb->rem_addr.node) ! 1021: asp_untimout(asp_hangup, scb); ! 1022: ! 1023: switch (awp->func) { ! 1024: case ASPFUNC_GetStatus: ! 1025: /* ! 1026: * ignore if this is not a server socket ! 1027: */ ! 1028: mx = 0; ! 1029: if ((scb->dflag != 1) || (scb->stat_msg ! 1030: && ((mx = gbuf_dupb(scb->stat_msg)) == 0))) ! 1031: break; ! 1032: gbuf_freeb(mioc); ! 1033: ! 1034: /* ! 1035: * send the status block ! 1036: */ ! 1037: if (gbuf_cont(mdata)) { ! 1038: gbuf_freem(gbuf_cont(mdata)); ! 1039: gbuf_cont(mdata) = 0; ! 1040: } ! 1041: gbuf_rdec(mdata,ATP_HDR_SIZE); ! 1042: if ((m = gbuf_alloc( (ATP_HDR_SIZE+atpBDSsize), PRI_MED)) == 0) { ! 1043: gbuf_freem(mdata); ! 1044: gbuf_freeb(mx); ! 1045: goto l_done; ! 1046: } ! 1047: bcopy(gbuf_rptr(mdata), gbuf_rptr(m), ATP_HDR_SIZE); ! 1048: gbuf_freeb(mdata); ! 1049: mdata = m; ! 1050: ddp = (at_ddp_t *)gbuf_rptr(mdata); ! 1051: gbuf_wset(mdata,DDP_X_HDR_SIZE); ! 1052: atp = (at_atp *)gbuf_wptr(mdata); ! 1053: gbuf_winc(mdata,AT_ATP_HDR_SIZE); ! 1054: awp = (asp_word_t *)atp->at_atp_user_bytes; ! 1055: NET_NET(ddp->src_net, ddp->dst_net); ! 1056: ddp->src_node = ddp->dst_node; ! 1057: NET_NET(ddp->dst_net, rem_addr.net); ! 1058: ddp->dst_node = rem_addr.node; ! 1059: ddp->dst_socket = rem_addr.socket; ! 1060: UAS_ASSIGN(ddp->checksum, 0); ! 1061: atpBDS = (struct atpBDS *)gbuf_wptr(mdata); ! 1062: msize = mx ? gbuf_msgsize(mx) : 0; ! 1063: for (nbds=0; (nbds < AT_ATP_TRESP_MAX) && (msize > 0); nbds++) { ! 1064: len = msize < AT_ATP_DATA_SIZE ? msize : AT_ATP_DATA_SIZE; ! 1065: msize -= AT_ATP_DATA_SIZE; ! 1066: *(long *)atpBDS[nbds].bdsUserData = 0; ! 1067: UAL_ASSIGN(atpBDS[nbds].bdsBuffAddr, 1); ! 1068: UAS_ASSIGN(atpBDS[nbds].bdsBuffSz, len); ! 1069: } ! 1070: UAS_ASSIGN(atpBDS[0].bdsDataSz, nbds); ! 1071: gbuf_winc(mdata,atpBDSsize); ! 1072: gbuf_cont(mdata) = mx; ! 1073: atp_send_rsp(gref, mdata); ! 1074: goto l_done; ! 1075: ! 1076: case ASPFUNC_OpenSess: ! 1077: /* ! 1078: * ignore if server is not ready ! 1079: */ ! 1080: if ((scb->dflag != 1) || (scb->stat_msg == 0)) ! 1081: break; ! 1082: gbuf_freeb(mioc); ! 1083: ! 1084: if (gbuf_cont(mdata)) { ! 1085: gbuf_freem(gbuf_cont(mdata)); ! 1086: gbuf_cont(mdata) = 0; ! 1087: } ! 1088: gbuf_rdec(mdata,ATP_HDR_SIZE); ! 1089: gbuf_wset(mdata,ATP_HDR_SIZE); ! 1090: if (awp->param2 != ASP_Version) { ! 1091: /* ! 1092: * bad version number, send the OpenSession response ! 1093: */ ! 1094: awp->func = 0; ! 1095: awp->param1 = 0; ! 1096: awp->param2 = (unsigned short)ASPERR_BadVersNum; ! 1097: dPrintf(D_M_ASP,D_L_INFO, ! 1098: " : version=%d\n", ASPERR_BadVersNum,0,0,0,0); ! 1099: NET_NET(ddp->src_net, ddp->dst_net); ! 1100: ddp->src_node = ddp->dst_node; ! 1101: NET_NET(ddp->dst_net, rem_addr.net); ! 1102: ddp->dst_node = rem_addr.node; ! 1103: ddp->dst_socket = rem_addr.socket; ! 1104: atp_send_rsp(gref, mdata); ! 1105: return; ! 1106: } ! 1107: ! 1108: /* ! 1109: * queue the connection request ! 1110: */ ! 1111: ATDISABLE(s, scb->lock); ! 1112: gbuf_next(mdata) = 0; ! 1113: if ((m = scb->sess_ioc) == 0) { ! 1114: scb->sess_ioc = mdata; ! 1115: if (scb->get_wait) ! 1116: #ifdef _AIX ! 1117: e_wakeup(&scb->event); ! 1118: #else ! 1119: thread_wakeup(&scb->event); ! 1120: #endif ! 1121: else ! 1122: atalk_notify_sel(gref); ! 1123: } else { ! 1124: while (gbuf_next(m)) ! 1125: m = gbuf_next(m); ! 1126: gbuf_next(m) = mdata; ! 1127: } ! 1128: ATENABLE(s, scb->lock); ! 1129: dPrintf(D_M_ASP,D_L_INFO, ! 1130: " : QUEUE connect request\n", 0,0,0,0,0); ! 1131: return; ! 1132: ! 1133: case ASPFUNC_Command: ! 1134: case ASPFUNC_Write: ! 1135: if ( (scb->sess_id != awp->param1) ! 1136: || (scb->rcv_seq_num != awp->param2) ! 1137: || BAD_REMADDR(rem_addr) ) { ! 1138: char era[8], ra[8]; ! 1139: sprintf(era,"%d.%d", scb->rem_addr.node,scb->rem_addr.socket); ! 1140: sprintf(ra,"%d.%d", rem_addr.node,rem_addr.socket); ! 1141: dPrintf(D_M_ASP,D_L_WARNING, ! 1142: " : DROP, id=%d,esn=%d,sn=%d,erem=%s,rem=%s\n", ! 1143: scb->sess_id,scb->rcv_seq_num,awp->param2,era,ra); ! 1144: gbuf_cont(mioc) = 0; ! 1145: gbuf_rdec(mdata,ATP_HDR_SIZE); ! 1146: atp_drop_req(gref, mdata); ! 1147: break; ! 1148: } ! 1149: scb->reply_socket = rem_addr.socket; ! 1150: if (awp->func == ASPFUNC_Write) ! 1151: scb->wrt_seq_num = scb->rcv_seq_num; ! 1152: NEXT_SEQ_NUM(scb->rcv_seq_num); ! 1153: gbuf_type(mioc) = MSG_PROTO; ! 1154: gbuf_wset(mioc,sizeof(asp_command_ind_t)); ! 1155: command_ind = (asp_command_ind_t *)gbuf_rptr(mioc); ! 1156: command_ind->Primitive = (int)awp->func; ! 1157: command_ind->ReqRefNum = ! 1158: *(unsigned short *)atp->at_atp_transaction_id; ! 1159: command_ind->ReqType = awp->func; ! 1160: while (mdata && (gbuf_len(mdata) == 0)) { ! 1161: m = gbuf_cont(mdata); ! 1162: gbuf_freeb(mdata); ! 1163: mdata = m; ! 1164: } ! 1165: gbuf_cont(mioc) = mdata; ! 1166: ATDISABLE(s, scb->lock); ! 1167: if (scb->req_flag) { ! 1168: if ((mx = scb->req_msgq) != 0) { ! 1169: while (gbuf_next(mx)) ! 1170: mx = gbuf_next(mx); ! 1171: gbuf_next(mx) = mioc; ! 1172: } else ! 1173: scb->req_msgq = mioc; ! 1174: ATENABLE(s, scb->lock); ! 1175: } else { ! 1176: scb->req_flag = 1; ! 1177: ATENABLE(s, scb->lock); ! 1178: asp_putnext(scb->gref, mioc); ! 1179: } ! 1180: goto l_done; ! 1181: ! 1182: case ASPFUNC_WriteContinue: ! 1183: if ( (scb->sess_id != awp->param1) ! 1184: || (scb->snd_seq_num != awp->param2) ! 1185: || BAD_REMADDR(rem_addr) ) { ! 1186: break; ! 1187: } ! 1188: scb->reply_socket = rem_addr.socket; ! 1189: gbuf_type(mioc) = MSG_PROTO; ! 1190: gbuf_wset(mioc,sizeof(asp_command_ind_t)); ! 1191: command_ind = (asp_command_ind_t *)gbuf_rptr(mioc); ! 1192: command_ind->Primitive = (int)awp->func; ! 1193: command_ind->ReqRefNum = ! 1194: *(unsigned short *)atp->at_atp_transaction_id; ! 1195: command_ind->ReqType = awp->func; ! 1196: while (mdata && (gbuf_len(mdata) == 0)) { ! 1197: m = gbuf_cont(mdata); ! 1198: gbuf_freeb(mdata); ! 1199: mdata = m; ! 1200: } ! 1201: gbuf_cont(mioc) = mdata; ! 1202: asp_putnext(scb->gref, mioc); ! 1203: goto l_done; ! 1204: ! 1205: case ASPFUNC_Tickle: ! 1206: if (scb->stat_msg) { ! 1207: sess_scb = asp_scbQ[awp->param1]; ! 1208: if (sess_scb->next_scb) ! 1209: sess_scb = asp_find_scb( ! 1210: sess_scb->loc_addr.socket, &rem_addr); ! 1211: if (sess_scb) { ! 1212: if (sess_scb->rem_addr.node) ! 1213: asp_untimout(asp_hangup, sess_scb); ! 1214: if (sess_scb->rem_addr.node) ! 1215: asp_timout(asp_hangup, sess_scb, sess_scb->session_timer); ! 1216: } ! 1217: } ! 1218: dPrintf(D_M_ASP,D_L_INFO, ! 1219: " : Tickle, %d -> %d, id=%d\n", ! 1220: ddp->src_socket,ddp->dst_socket,awp->param1,0,0); ! 1221: break; ! 1222: ! 1223: case ASPFUNC_CloseSess: ! 1224: if ( (scb->sess_id != awp->param1) ! 1225: || (scb->state == ASPSTATE_Close) ! 1226: || (*(short *)scb->rem_addr.net != *(short *)rem_addr.net) ! 1227: || (scb->rem_addr.node != rem_addr.node) ) { ! 1228: dPrintf(D_M_ASP,D_L_INFO, ! 1229: " : CLOSE retry, loc=%d, rem=%x.%x.%d\n", ! 1230: scb->loc_addr.socket,*(unsigned short *)scb->rem_addr.net, ! 1231: scb->rem_addr.node,scb->rem_addr.socket,0); ! 1232: break; ! 1233: } ! 1234: gbuf_freeb(mioc); ! 1235: ! 1236: /* ! 1237: * build the CloseSess response to be sent to peer ! 1238: * when the session is closed by the user. ! 1239: */ ! 1240: if (gbuf_cont(mdata)) { ! 1241: gbuf_freem(gbuf_cont(mdata)); ! 1242: gbuf_cont(mdata) = 0; ! 1243: } ! 1244: gbuf_rdec(mdata,ATP_HDR_SIZE); ! 1245: gbuf_wset(mdata,ATP_HDR_SIZE); ! 1246: NET_NET(ddp->src_net, ddp->dst_net); ! 1247: ddp->src_node = ddp->dst_node; ! 1248: NET_NET(ddp->dst_net, rem_addr.net); ! 1249: ddp->dst_node = rem_addr.node; ! 1250: ddp->dst_socket = rem_addr.socket; ! 1251: awp->func = 0; ! 1252: awp->param1 = 0; ! 1253: awp->param2 = 0; ! 1254: dPrintf(D_M_ASP,D_L_INFO, ! 1255: " : CLOSE, loc=%d, rem=%x.%x.%d\n", ! 1256: scb->loc_addr.socket,*(unsigned short *)scb->rem_addr.net, ! 1257: scb->rem_addr.node,scb->rem_addr.socket,0); ! 1258: gbuf_next(mdata) = 0; ! 1259: ATDISABLE(s, scb->lock); ! 1260: if (scb->sess_ioc) ! 1261: gbuf_freel(scb->sess_ioc); ! 1262: scb->sess_ioc = mdata; ! 1263: scb->state = ASPSTATE_Close; ! 1264: ATENABLE(s, scb->lock); ! 1265: ! 1266: /* ! 1267: * notify upstream of the CloseSess from peer ! 1268: */ ! 1269: asp_hangup(scb); ! 1270: return; ! 1271: ! 1272: case ASPFUNC_Attention: ! 1273: if ( (scb->sess_id != awp->param1) ! 1274: || (*(short *)scb->rem_addr.net != *(short *)rem_addr.net) ! 1275: || (scb->rem_addr.node != rem_addr.node) ) { ! 1276: break; ! 1277: } ! 1278: gbuf_type(mioc) = MSG_PROTO; ! 1279: gbuf_wset(mioc,sizeof(asp_command_ind_t)); ! 1280: command_ind = (asp_command_ind_t *)gbuf_rptr(mioc); ! 1281: command_ind->Primitive = (int)awp->func; ! 1282: command_ind->ReqRefNum = ! 1283: *(unsigned short *)atp->at_atp_transaction_id; ! 1284: command_ind->ReqType = awp->func; ! 1285: scb->attn_tid = *(unsigned short *)atp->at_atp_transaction_id; ! 1286: scb->attn_flag = 1; ! 1287: gbuf_rdec(mdata,2); /* attention code */ ! 1288: while (mdata && (gbuf_len(mdata) == 0)) { ! 1289: m = gbuf_cont(mdata); ! 1290: gbuf_freeb(mdata); ! 1291: mdata = m; ! 1292: } ! 1293: gbuf_cont(mioc) = mdata; ! 1294: asp_putnext(scb->gref, mioc); ! 1295: goto l_done; ! 1296: ! 1297: default: ! 1298: dPrintf(D_M_ASP,D_L_WARNING, ! 1299: " : UNKNOWN func, func=%d\n", awp->func,0,0,0,0); ! 1300: break; ! 1301: } ! 1302: } ! 1303: ! 1304: else if (iocbp->ioc_cmd == AT_ATP_REQUEST_COMPLETE) { ! 1305: if (scb->next_scb) { ! 1306: /* ! 1307: * find the responsible scb ! 1308: */ ! 1309: scb = (asp_scb_t *)iocbp->ioc_private; ! 1310: if ((scb == 0) || (scb->magic_num != 222)) { ! 1311: dPrintf(D_M_ASP,D_L_ERROR, ! 1312: "asp_ack_reply: CAN'T find scb 1\n", 0,0,0,0,0); ! 1313: gbuf_freem(mioc); ! 1314: return; ! 1315: } ! 1316: } ! 1317: dPrintf(D_M_ASP,D_L_INFO, ! 1318: "asp_ack_reply: RSP, loc=%d, rem=%x.%x.%d, state=%d\n", ! 1319: scb->loc_addr.socket,*(unsigned short *)scb->rem_addr.net, ! 1320: scb->rem_addr.node,scb->rem_addr.socket,scb->state); ! 1321: ! 1322: switch (scb->state) { ! 1323: case ASPSTATE_Close: ! 1324: case ASPSTATE_Idle: ! 1325: scb->rem_addr.node = 0; ! 1326: gbuf_freem(mioc); ! 1327: ATDISABLE(s, scb->lock); ! 1328: if (scb->get_wait) ! 1329: #ifdef _AIX ! 1330: e_wakeup(&scb->event); ! 1331: #else ! 1332: thread_wakeup(&scb->event); ! 1333: #endif ! 1334: ATENABLE(s, scb->lock); ! 1335: return; ! 1336: ! 1337: case ASPSTATE_WaitingForGetStatusRsp: ! 1338: scb->ioc_wait = 0; ! 1339: scb->state = ASPSTATE_Idle; ! 1340: mx = gbuf_cont(mioc); ! 1341: gbuf_cont(mioc) = 0; ! 1342: mdata = gbuf_cont(mx); ! 1343: gbuf_cont(mx) = 0; ! 1344: iocbp->ioc_cmd = ASPIOC_GetStatus; ! 1345: iocbp->ioc_count = 0; ! 1346: iocbp->ioc_rval = mdata ? gbuf_msgsize(mdata) : 0; ! 1347: gbuf_freeb(mx); ! 1348: atalk_putnext(gref, mioc); ! 1349: atalk_putnext(gref, mdata); ! 1350: return; ! 1351: ! 1352: case ASPSTATE_WaitingForOpenSessRsp: ! 1353: scb->ioc_wait = 0; ! 1354: scb->state = ASPSTATE_Idle; ! 1355: mx = gbuf_cont(mioc); ! 1356: gbuf_cont(mioc) = 0; ! 1357: if (gbuf_cont(mx)) { ! 1358: gbuf_freem(gbuf_cont(mx)); ! 1359: gbuf_cont(mx) = 0; ! 1360: } ! 1361: iocbp->ioc_cmd = ASPIOC_OpenSession; ! 1362: iocbp->ioc_rval = 0; ! 1363: iocbp->ioc_count = 0; ! 1364: atpBDS = (struct atpBDS *)gbuf_rptr(mx); ! 1365: awp = (asp_word_t *)atpBDS->bdsUserData; ! 1366: if (awp->param2) { ! 1367: gbuf_freeb(mx); ! 1368: asp_iocnak(gref, mioc, ECONNREFUSED); ! 1369: } else { ! 1370: scb->rem_addr.node = scb->rem_node; ! 1371: scb->rem_addr.socket = awp->func; ! 1372: scb->sess_id = awp->param1; ! 1373: gbuf_freeb(mx); ! 1374: atalk_putnext(gref, mioc); ! 1375: asp_timout(asp_hangup, scb, scb->session_timer); ! 1376: asp_send_tickle(scb); ! 1377: dPrintf(D_M_ASP,D_L_INFO, ! 1378: "asp_ack_reply: CONNECT, loc=%d, rem=%x.%x.%d\n", ! 1379: scb->loc_addr.socket, ! 1380: *(unsigned short *)scb->rem_addr.net, ! 1381: scb->rem_addr.node,scb->rem_addr.socket,0); ! 1382: } ! 1383: return; ! 1384: ! 1385: case ASPSTATE_WaitingForCommandRsp: ! 1386: case ASPSTATE_WaitingForWriteRsp: ! 1387: case ASPSTATE_WaitingForWriteContinueRsp: ! 1388: if (scb->rem_addr.node) ! 1389: asp_untimout(asp_hangup, scb); ! 1390: NEXT_SEQ_NUM(scb->snd_seq_num); ! 1391: scb->state = ASPSTATE_Idle; ! 1392: gbuf_type(mioc) = MSG_PROTO; ! 1393: mx = gbuf_cont(mioc); ! 1394: mdata = gbuf_cont(mx); ! 1395: gbuf_cont(mioc) = mdata; ! 1396: atpBDS = (struct atpBDS *)gbuf_rptr(mx); ! 1397: cmdreply_ind = (asp_cmdreply_ind_t *)gbuf_rptr(mioc); ! 1398: cmdreply_ind->Primitive = ASPFUNC_CmdReply; ! 1399: cmdreply_ind->CmdResult = *(int *)atpBDS->bdsUserData; ! 1400: gbuf_wset(mioc,sizeof(asp_cmdreply_ind_t)); ! 1401: gbuf_freeb(mx); ! 1402: asp_putnext(scb->gref, mioc); ! 1403: goto l_done; ! 1404: ! 1405: case ASPSTATE_WaitingForCloseSessRsp: ! 1406: scb->ioc_wait = 0; ! 1407: scb->state = ASPSTATE_Close; ! 1408: scb->rem_addr.node = 0; ! 1409: iocbp->ioc_cmd = ASPIOC_CloseSession; ! 1410: iocbp->ioc_rval = 0; ! 1411: if (gbuf_cont(mioc)) { ! 1412: gbuf_freem(gbuf_cont(mioc)); ! 1413: gbuf_cont(mioc) = 0; ! 1414: } ! 1415: atalk_putnext(scb->gref, mioc); ! 1416: atp_cancel_req(scb->gref, (unsigned int)scb->tickle_tid); ! 1417: scb->tickle_tid = 0; ! 1418: return; ! 1419: ! 1420: default: ! 1421: dPrintf(D_M_ASP,D_L_WARNING, ! 1422: " : UNKNOWN state, state=%d\n", scb->state,0,0,0,0); ! 1423: break; ! 1424: } ! 1425: } ! 1426: ! 1427: else { ! 1428: if (scb->next_scb) { ! 1429: /* ! 1430: * find the responsible scb ! 1431: */ ! 1432: scb = (asp_scb_t *)iocbp->ioc_cr; ! 1433: if ((scb == 0) || (scb->magic_num != 222)) { ! 1434: dPrintf(D_M_ASP,D_L_ERROR, ! 1435: "asp_ack_reply: CAN'T find scb 2\n", 0,0,0,0,0); ! 1436: gbuf_freem(mioc); ! 1437: return; ! 1438: } ! 1439: } ! 1440: ! 1441: switch (scb->state) { ! 1442: case ASPSTATE_Close: ! 1443: scb->rem_addr.node = 0; ! 1444: break; ! 1445: ! 1446: case ASPSTATE_WaitingForCfgAck: ! 1447: scb->state = ASPSTATE_Idle; ! 1448: atalk_putnext(scb->gref, mioc); ! 1449: return; ! 1450: } ! 1451: } ! 1452: ! 1453: if (mioc != 0) ! 1454: gbuf_freem(mioc); ! 1455: ! 1456: l_done: ! 1457: if (scb->rem_addr.node) ! 1458: asp_timout(asp_hangup, scb, scb->session_timer); ! 1459: } ! 1460: ! 1461: /* ! 1462: * NAK reply routine ! 1463: */ ! 1464: void ! 1465: asp_nak_reply(gref, mioc) ! 1466: register gref_t *gref; ! 1467: register gbuf_t *mioc; ! 1468: { ! 1469: register asp_scb_t *scb; ! 1470: register ioc_t *iocbp; ! 1471: ! 1472: iocbp = (ioc_t *)gbuf_rptr(mioc); ! 1473: ! 1474: if (iocbp->ioc_cmd == AT_ATP_ISSUE_REQUEST_DEF_NOTE) { ! 1475: /* ! 1476: * no tickle, close session ! 1477: */ ! 1478: scb = (asp_scb_t *)iocbp->ioc_cr; ! 1479: gbuf_freem(mioc); ! 1480: asp_hangup(scb); ! 1481: dPrintf(D_M_ASP,D_L_WARNING, ! 1482: "tickle_nak: loc=%d, rem=%x.%x.%d, state=%d\n", ! 1483: scb->loc_addr.socket, *(unsigned short *)scb->rem_addr.net, ! 1484: scb->rem_addr.node,scb->rem_addr.socket,scb->state); ! 1485: return; ! 1486: } ! 1487: ! 1488: scb = (asp_scb_t *)gref->info; ! 1489: if (scb == 0) { ! 1490: gbuf_freem(mioc); ! 1491: return; ! 1492: } ! 1493: ! 1494: if (iocbp->ioc_cmd == AT_ATP_REQUEST_COMPLETE) { ! 1495: if (scb->next_scb) { ! 1496: /* ! 1497: * find the responsible scb ! 1498: */ ! 1499: scb = (asp_scb_t *)iocbp->ioc_private; ! 1500: if ((scb == 0) || (scb->magic_num != 222)) { ! 1501: dPrintf(D_M_ASP,D_L_ERROR, ! 1502: "asp_nak_reply: CAN'T find scb 1\n", 0,0,0,0,0); ! 1503: gbuf_freem(mioc); ! 1504: return; ! 1505: } ! 1506: } ! 1507: dPrintf(D_M_ASP,D_L_WARNING, ! 1508: "asp_nak_reply: RSP, loc=%d, rem=%x.%x.%d, state=%d\n", ! 1509: scb->loc_addr.socket,*(unsigned short *)scb->rem_addr.net, ! 1510: scb->rem_addr.node,scb->rem_addr.socket,scb->state); ! 1511: ! 1512: switch (scb->state) { ! 1513: case ASPSTATE_WaitingForGetStatusRsp: ! 1514: iocbp->ioc_cmd = ASPIOC_GetStatus; ! 1515: break; ! 1516: ! 1517: case ASPSTATE_WaitingForOpenSessRsp: ! 1518: iocbp->ioc_cmd = ASPIOC_OpenSession; ! 1519: break; ! 1520: ! 1521: case ASPSTATE_WaitingForCommandRsp: ! 1522: case ASPSTATE_WaitingForWriteRsp: ! 1523: case ASPSTATE_WaitingForWriteContinueRsp: ! 1524: scb->state = ASPSTATE_Idle; ! 1525: gbuf_type(mioc) = MSG_ERROR; ! 1526: gbuf_rptr(mioc)[0] = EPROTO; ! 1527: gbuf_wset(mioc,1); ! 1528: asp_putnext(scb->gref, mioc); ! 1529: return; ! 1530: ! 1531: case ASPSTATE_WaitingForCloseSessRsp: ! 1532: scb->state = ASPSTATE_Close; ! 1533: scb->rem_addr.node = 0; ! 1534: iocbp->ioc_cmd = ASPIOC_CloseSession; ! 1535: iocbp->ioc_rval = 0; ! 1536: if (gbuf_cont(mioc)) { ! 1537: gbuf_freem(gbuf_cont(mioc)); ! 1538: gbuf_cont(mioc) = 0; ! 1539: } ! 1540: gbuf_type(mioc) = MSG_IOCACK; ! 1541: atalk_putnext(scb->gref, mioc); ! 1542: return; ! 1543: ! 1544: default: ! 1545: gbuf_freem(mioc); ! 1546: return; ! 1547: } ! 1548: scb->state = ASPSTATE_Idle; ! 1549: atalk_putnext(gref, mioc); ! 1550: } ! 1551: ! 1552: else { ! 1553: if (scb->next_scb) { ! 1554: /* ! 1555: * find the responsible scb ! 1556: */ ! 1557: scb = (asp_scb_t *)iocbp->ioc_cr; ! 1558: if ((scb == 0) || (scb->magic_num != 222)) { ! 1559: dPrintf(D_M_ASP,D_L_ERROR, ! 1560: "asp_nak_reply: CAN'T find scb 2\n", 0,0,0,0,0); ! 1561: gbuf_freem(mioc); ! 1562: return; ! 1563: } ! 1564: } ! 1565: ! 1566: switch (scb->state) { ! 1567: case ASPSTATE_Close: ! 1568: scb->rem_addr.node = 0; ! 1569: break; ! 1570: ! 1571: case ASPSTATE_WaitingForCfgAck: ! 1572: scb->state = ASPSTATE_Idle; ! 1573: atalk_putnext(scb->gref, mioc); ! 1574: return; ! 1575: } ! 1576: ! 1577: gbuf_freem(mioc); ! 1578: } ! 1579: } ! 1580: ! 1581: /* ! 1582: * stop ASP now ! 1583: */ ! 1584: void ! 1585: asp_stop(m, flag) ! 1586: gbuf_t *m; ! 1587: int flag; ! 1588: { ! 1589: int k, s, *x_wptr; ! 1590: asp_scb_t *scb; ! 1591: ! 1592: if (flag) ! 1593: asp_off_flag = 1; ! 1594: ! 1595: ATDISABLE(s, aspall_lock); ! 1596: x_wptr = (int *)gbuf_wptr(m); ! 1597: for (scb = scb_used_list; scb; scb = scb->next_scb) { ! 1598: if (flag == 2) { ! 1599: scb->pid = 0; ! 1600: asp_hangup(scb); ! 1601: } else { ! 1602: *(int *)gbuf_wptr(m) = scb->pid; ! 1603: gbuf_winc(m,sizeof(int)); ! 1604: } ! 1605: } ! 1606: ! 1607: for (k=0; k < 256; k++) { ! 1608: if ((scb = asp_scbQ[k]) == 0) ! 1609: continue; ! 1610: do { ! 1611: if (flag == 2) { ! 1612: scb->pid = 0; ! 1613: asp_hangup(scb); ! 1614: } else { ! 1615: *(int *)gbuf_wptr(m) = scb->pid; ! 1616: gbuf_winc(m,sizeof(int)); ! 1617: } ! 1618: } while ((scb = scb->next_scb) != 0); ! 1619: } ! 1620: ATENABLE(s, aspall_lock); ! 1621: ! 1622: while (x_wptr != (int *)gbuf_wptr(m)) { ! 1623: dPrintf(D_M_ASP,D_L_TRACE, "asp_stop: pid=%d\n", *x_wptr,0,0,0,0); ! 1624: x_wptr++; ! 1625: } ! 1626: } ! 1627: ! 1628: /* ! 1629: * delete scb from the use list ! 1630: */ ! 1631: StaticProc void ! 1632: asp_dequeue_scb(scb) ! 1633: asp_scb_t *scb; ! 1634: { ! 1635: int s; ! 1636: ! 1637: ATDISABLE(s, aspall_lock); ! 1638: if (scb == scb_used_list) { ! 1639: if ((scb_used_list = scb->next_scb) != 0) ! 1640: scb->next_scb->prev_scb = 0; ! 1641: } else { ! 1642: if ((scb->prev_scb->next_scb = scb->next_scb) != 0) ! 1643: scb->next_scb->prev_scb = scb->prev_scb; ! 1644: } ! 1645: ATENABLE(s, aspall_lock); ! 1646: ! 1647: scb->next_scb = 0; ! 1648: scb->prev_scb = 0; ! 1649: } ! 1650: ! 1651: /* ! 1652: * find scb routine ! 1653: */ ! 1654: StaticProc asp_scb_t * ! 1655: asp_find_scb(sock_num, rem_addr) ! 1656: unsigned char sock_num; ! 1657: at_inet_t *rem_addr; ! 1658: { ! 1659: int s; ! 1660: asp_scb_t *scb; ! 1661: asp_scb_t *alt_scb = 0; ! 1662: ! 1663: ATDISABLE(s, aspall_lock); ! 1664: for (scb = asp_scbQ[sock_num]; scb; scb = scb->next_scb) { ! 1665: if ((*(short *)scb->rem_addr.net == *(short *)rem_addr->net) ! 1666: && (scb->rem_addr.node == rem_addr->node)) { ! 1667: if ((scb->rem_addr.socket == rem_addr->socket) ! 1668: || (scb->rem_socket == rem_addr->socket)) ! 1669: break; ! 1670: else if (alt_scb == 0) ! 1671: alt_scb = scb; ! 1672: } ! 1673: } ! 1674: ! 1675: if ((scb == 0) && ((scb = alt_scb) == 0)) { ! 1676: dPrintf(D_M_ASP,D_L_ERROR, ! 1677: "asp_find_scb: CAN'T find scb, loc=%d, rem=%x.%x.%d\n", ! 1678: sock_num,*(unsigned short *)rem_addr->net, ! 1679: rem_addr->node,rem_addr->socket,0); ! 1680: } ! 1681: ATENABLE(s, aspall_lock); ! 1682: ! 1683: return scb; ! 1684: } ! 1685: ! 1686: /* ! 1687: * timout routine ! 1688: */ ! 1689: StaticProc void ! 1690: asp_timout(func, scb, seconds) ! 1691: void (*func)(); ! 1692: register asp_scb_t *scb; ! 1693: int seconds; ! 1694: { ! 1695: int s; ! 1696: unsigned char sum; ! 1697: register asp_scb_t *curr_scb, *prev_scb; ! 1698: ! 1699: if (scb->tmo_func) ! 1700: return; ! 1701: ! 1702: scb->tmo_func = func; ! 1703: scb->tmo_delta = (seconds>>SESS_TMO_RES); ! 1704: scb->tmo_cnt = scb_tmo_cnt; ! 1705: ! 1706: ATDISABLE(s, asptmo_lock); ! 1707: if (scb_tmo_list == 0) { ! 1708: scb->next_tmo = scb->prev_tmo = 0; ! 1709: scb_tmo_list = scb; ! 1710: ATENABLE(s, asptmo_lock); ! 1711: return; ! 1712: } ! 1713: ! 1714: prev_scb = 0; ! 1715: curr_scb = scb_tmo_list; ! 1716: sum = 0; ! 1717: ! 1718: while (1) { ! 1719: sum += curr_scb->tmo_delta; ! 1720: if (sum > scb->tmo_delta) { ! 1721: sum -= curr_scb->tmo_delta; ! 1722: scb->tmo_delta -= sum; ! 1723: curr_scb->tmo_delta -= scb->tmo_delta; ! 1724: break; ! 1725: } ! 1726: prev_scb = curr_scb; ! 1727: if ((curr_scb = curr_scb->next_tmo) == 0) { ! 1728: scb->tmo_delta -= sum; ! 1729: break; ! 1730: } ! 1731: } ! 1732: ! 1733: if (prev_scb) { ! 1734: scb->prev_tmo = prev_scb; ! 1735: if ((scb->next_tmo = prev_scb->next_tmo) != 0) ! 1736: prev_scb->next_tmo->prev_tmo = scb; ! 1737: prev_scb->next_tmo = scb; ! 1738: } else { ! 1739: scb->prev_tmo = 0; ! 1740: scb->next_tmo = scb_tmo_list; ! 1741: scb_tmo_list->prev_tmo = scb; ! 1742: scb_tmo_list = scb; ! 1743: } ! 1744: ATENABLE(s, asptmo_lock); ! 1745: } ! 1746: ! 1747: /* ! 1748: * untimout routine ! 1749: */ ! 1750: StaticProc void ! 1751: asp_untimout(func, scb) ! 1752: void (*func)(); ! 1753: register asp_scb_t *scb; ! 1754: { ! 1755: int s; ! 1756: ! 1757: if ((scb->tmo_cnt == scb_tmo_cnt) || (scb->tmo_func == 0)) ! 1758: return; ! 1759: ! 1760: ATDISABLE(s, asptmo_lock); ! 1761: if (scb_tmo_list == scb) { ! 1762: if ((scb_tmo_list = scb->next_tmo) != 0) { ! 1763: scb_tmo_list->prev_tmo = 0; ! 1764: scb->next_tmo->tmo_delta += scb->tmo_delta; ! 1765: } ! 1766: } else if (scb->prev_tmo) { ! 1767: if ((scb->prev_tmo->next_tmo = scb->next_tmo) != 0) { ! 1768: scb->next_tmo->prev_tmo = scb->prev_tmo; ! 1769: scb->next_tmo->tmo_delta += scb->tmo_delta; ! 1770: } ! 1771: scb->prev_tmo = 0; ! 1772: } ! 1773: scb->tmo_func = 0; ! 1774: ATENABLE(s, asptmo_lock); ! 1775: } ! 1776: ! 1777: /* ! 1778: * hangup routine ! 1779: */ ! 1780: StaticProc void ! 1781: asp_hangup(scb) ! 1782: asp_scb_t *scb; ! 1783: { ! 1784: int s; ! 1785: gbuf_t *m; ! 1786: ! 1787: /* ! 1788: * set the state to Close ! 1789: */ ! 1790: ATDISABLE(s, scb->lock); ! 1791: scb->state = ASPSTATE_Close; ! 1792: if (scb->tickle_tid) { ! 1793: atp_cancel_req(scb->gref, (unsigned int)scb->tickle_tid); ! 1794: scb->tickle_tid = 0; ! 1795: } ! 1796: ! 1797: /* ! 1798: * notify upstream of the hangup ! 1799: */ ! 1800: if (scb->rem_addr.node) { ! 1801: if (scb->get_wait) { ! 1802: #ifdef _AIX ! 1803: e_wakeup(&scb->event); ! 1804: #else ! 1805: thread_wakeup(&scb->event); ! 1806: #endif ! 1807: ATENABLE(s, scb->lock); ! 1808: } else ! 1809: ATENABLE(s, scb->lock); ! 1810: } else ! 1811: ATENABLE(s, scb->lock); ! 1812: } ! 1813: ! 1814: void ! 1815: asp_clock(arg) ! 1816: void *arg; ! 1817: { ! 1818: if (!asp_off_flag) ! 1819: asp_timer(arg, 0); ! 1820: } ! 1821: ! 1822: StaticProc void ! 1823: asp_iocack(gref, mioc) ! 1824: gref_t *gref; ! 1825: gbuf_t *mioc; ! 1826: { ! 1827: if (gbuf_cont(mioc)) ! 1828: ((ioc_t *)gbuf_rptr(mioc))->ioc_count = gbuf_msgsize(gbuf_cont(mioc)); ! 1829: else ! 1830: ((ioc_t *)gbuf_rptr(mioc))->ioc_count = 0; ! 1831: ! 1832: gbuf_type(mioc) = MSG_IOCACK; ! 1833: atalk_putnext(gref, mioc); ! 1834: } ! 1835: ! 1836: StaticProc void ! 1837: asp_iocnak(gref, mioc, err) ! 1838: gref_t *gref; ! 1839: gbuf_t *mioc; ! 1840: int err; ! 1841: { ! 1842: ((ioc_t *)gbuf_rptr(mioc))->ioc_count = 0; ! 1843: if (err == 0) ! 1844: err = ENXIO; ! 1845: ((ioc_t *)gbuf_rptr(mioc))->ioc_error = err; ! 1846: ((ioc_t *)gbuf_rptr(mioc))->ioc_rval = -1; ! 1847: if (gbuf_cont(mioc)) { ! 1848: gbuf_freem(gbuf_cont(mioc)); ! 1849: gbuf_cont(mioc) = 0; ! 1850: } ! 1851: ! 1852: gbuf_type(mioc) = MSG_IOCNAK; ! 1853: atalk_putnext(gref, mioc); ! 1854: } ! 1855: ! 1856: /* ! 1857: * the alloc scb routine ! 1858: */ ! 1859: StaticProc asp_scb_t * ! 1860: asp_scb_alloc() ! 1861: { ! 1862: int s, i; ! 1863: gbuf_t *m; ! 1864: asp_scb_t *scb, *scb_array; ! 1865: ! 1866: ATDISABLE(s, aspall_lock); ! 1867: if (scb_free_list == 0) { ! 1868: if ((m = gbuf_alloc(SCBS_PER_BLK*sizeof(asp_scb_t), PRI_MED)) == 0) ! 1869: { ! 1870: ATENABLE(s, aspall_lock); ! 1871: return (asp_scb_t *)0; ! 1872: } ! 1873: bzero((char *)gbuf_rptr(m), SCBS_PER_BLK*sizeof(asp_scb_t)); ! 1874: gbuf_cont(m) = scb_resource_m; ! 1875: scb_resource_m = m; ! 1876: scb_array = (asp_scb_t *)gbuf_rptr(m); ! 1877: for (i=0; i < SCBS_PER_BLK-1; i++) ! 1878: scb_array[i].next_scb = (asp_scb_t *)&scb_array[i+1]; ! 1879: scb_array[i].next_scb = 0; ! 1880: scb_free_list = (asp_scb_t *)&scb_array[0]; ! 1881: } ! 1882: ! 1883: scb = scb_free_list; ! 1884: scb_free_list = scb->next_scb; ! 1885: ATENABLE(s, aspall_lock); ! 1886: ATLOCKINIT(scb->lock); ! 1887: ATLOCKINIT(scb->delay_lock); ! 1888: ATEVENTINIT(scb->event); ! 1889: ATEVENTINIT(scb->delay_event); ! 1890: ! 1891: return scb; ! 1892: } ! 1893: ! 1894: /* ! 1895: * the free scb routine ! 1896: */ ! 1897: StaticProc void ! 1898: asp_scb_free(scb) ! 1899: asp_scb_t *scb; ! 1900: { ! 1901: int s; ! 1902: ! 1903: bzero((char *)scb, sizeof(asp_scb_t)); ! 1904: ATDISABLE(s, aspall_lock); ! 1905: scb->next_scb = scb_free_list; ! 1906: scb_free_list = scb; ! 1907: ATENABLE(s, aspall_lock); ! 1908: } ! 1909: ! 1910: /* ! 1911: * routine to pass up receive data ! 1912: */ ! 1913: StaticProc void ! 1914: asp_putnext(gref, mproto) ! 1915: gref_t *gref; ! 1916: gbuf_t *mproto; ! 1917: { ! 1918: int s; ! 1919: gbuf_t *m; ! 1920: asp_scb_t *scb; ! 1921: ! 1922: scb = (asp_scb_t *)gref->info; ! 1923: ! 1924: /* ! 1925: * queue the message. ! 1926: */ ! 1927: ATDISABLE(s, scb->lock); ! 1928: gbuf_next(mproto) = 0; ! 1929: if ((m = scb->sess_ioc) == 0) ! 1930: scb->sess_ioc = mproto; ! 1931: else { ! 1932: while (gbuf_next(m)) ! 1933: m = gbuf_next(m); ! 1934: gbuf_next(m) = mproto; ! 1935: } ! 1936: scb->rcv_cnt++; ! 1937: if (scb->rcv_cnt >= MAX_RCV_CNT) ! 1938: scb->snd_stop = 1; ! 1939: ! 1940: if (scb->get_wait) { ! 1941: #ifdef _AIX ! 1942: e_wakeup(&scb->event); ! 1943: #else ! 1944: thread_wakeup(&scb->event); ! 1945: #endif ! 1946: ATENABLE(s, scb->lock); ! 1947: } else if (scb->sel_on && (mproto == scb->sess_ioc)) { ! 1948: ATENABLE(s, scb->lock); ! 1949: atalk_notify_sel(gref); ! 1950: } else ! 1951: ATENABLE(s, scb->lock); ! 1952: } ! 1953: ! 1954: /* ! 1955: * The following two routines are direct entries from system ! 1956: * calls to allow fast sending and recving of ASP data. ! 1957: */ ! 1958: int ! 1959: ASPputmsg(gref, ctlptr, datptr, flags, errp) ! 1960: gref_t *gref; ! 1961: strbuf_t *ctlptr; ! 1962: strbuf_t *datptr; ! 1963: int flags; ! 1964: int *errp; ! 1965: { ! 1966: int s, err, len; ! 1967: gbuf_t *mproto, *mdata; ! 1968: strbuf_t ctlbuf; ! 1969: strbuf_t datbuf; ! 1970: asp_scb_t *scb; ! 1971: ! 1972: if ((scb = (asp_scb_t *)gref->info) == 0) { ! 1973: dPrintf(D_M_ASP,D_L_ERROR, "ASPputmsg: stale handle=%x, pid=%d\n", ! 1974: gref,gref->pid,0,0,0); ! 1975: *errp = EINVAL; ! 1976: return -1; ! 1977: } ! 1978: ! 1979: if (scb->state == ASPSTATE_Close) ! 1980: return 0; ! 1981: if (scb->snd_stop) { ! 1982: *errp = EAGAIN; ! 1983: return -1; ! 1984: } ! 1985: ! 1986: /* ! 1987: * copy in the control and data info ! 1988: */ ! 1989: if ((err = copyin((caddr_t)ctlptr, ! 1990: (caddr_t)&ctlbuf, sizeof(ctlbuf))) != 0) ! 1991: goto l_err; ! 1992: if ((err = copyin((caddr_t)datptr, ! 1993: (caddr_t)&datbuf, sizeof(datbuf))) != 0) ! 1994: goto l_err; ! 1995: ! 1996: /* ! 1997: * allocate buffer and copy in the control content ! 1998: */ ! 1999: while ((mproto = gbuf_alloc(ctlbuf.len, PRI_MED)) == 0) { ! 2000: ATDISABLE(s, scb->delay_lock); ! 2001: atalk_timeout(asp_wakeup, scb, 10); ! 2002: #ifdef _AIX ! 2003: err = e_sleep_thread(&scb->delay_event, &scb->delay_lock, LOCK_HANDLER|INTERRUPTIBLE); ! 2004: #else ! 2005: thread_sleep(&scb->delay_event, &scb->delay_lock, INTERRUPTIBLE); ! 2006: err = thread_wait_result(); ! 2007: #endif ! 2008: ATENABLE(s, scb->delay_lock); ! 2009: if (err != THREAD_AWAKENED) { ! 2010: *errp = EINTR; ! 2011: return -1; ! 2012: } ! 2013: } ! 2014: gbuf_type(mproto) = MSG_PROTO; ! 2015: gbuf_wset(mproto,ctlbuf.len); ! 2016: if ((err = copyin((caddr_t)ctlbuf.buf, ! 2017: (caddr_t)gbuf_rptr(mproto), ctlbuf.len)) != 0) { ! 2018: gbuf_freem(mproto); ! 2019: goto l_err; ! 2020: } ! 2021: ! 2022: len = (((union asp_primitives *)gbuf_rptr(mproto))->Primitive ! 2023: == ASPFUNC_CmdReply) ? 0 : aspCMDsize; ! 2024: ! 2025: /* ! 2026: * allocate buffer and copy in the data content ! 2027: */ ! 2028: if (datbuf.len) { ! 2029: l_again: ! 2030: #ifdef _AIX ! 2031: mdata = gbuf_alloc(datbuf.len+len, PRI_MED); ! 2032: if (mdata == 0) { ! 2033: #else ! 2034: if (datbuf.len <= 2048) ! 2035: mdata = gbuf_alloc(datbuf.len+len, PRI_MED); ! 2036: else { ! 2037: void *buf; ! 2038: if ((buf = atalk_kalloc(datbuf.len)) == 0) ! 2039: mdata = 0; ! 2040: else { ! 2041: if ((mdata = (gbuf_t *)gbuf_attach( ! 2042: buf, atalk_kfree, datbuf.len, 0)) == 0) ! 2043: atalk_kfree(buf); ! 2044: } ! 2045: } ! 2046: if (mdata == 0) { ! 2047: #endif ! 2048: ATDISABLE(s, scb->delay_lock); ! 2049: atalk_timeout(asp_wakeup, scb, 10); ! 2050: #ifdef _AIX ! 2051: err = e_sleep_thread(&scb->delay_event, &scb->delay_lock, LOCK_HANDLER|INTERRUPTIBLE); ! 2052: #else ! 2053: thread_sleep(&scb->delay_event, &scb->delay_lock, INTERRUPTIBLE); ! 2054: err = thread_wait_result(); ! 2055: #endif ! 2056: ATENABLE(s, scb->delay_lock); ! 2057: if (err != THREAD_AWAKENED) { ! 2058: gbuf_freem(mproto); ! 2059: *errp = EINTR; ! 2060: return -1; ! 2061: } ! 2062: goto l_again; ! 2063: } ! 2064: gbuf_wset(mdata,(datbuf.len+len)); ! 2065: gbuf_cont(mproto) = mdata; ! 2066: if ((err = copyin((caddr_t)datbuf.buf, ! 2067: (caddr_t)(gbuf_rptr(mdata)+len), datbuf.len)) != 0) { ! 2068: gbuf_freem(mproto); ! 2069: goto l_err; ! 2070: } ! 2071: } ! 2072: ! 2073: /* ! 2074: * call asp_wput to process the request ! 2075: */ ! 2076: return asp_wput(gref, mproto); ! 2077: ! 2078: l_err: ! 2079: *errp = err; ! 2080: return -1; ! 2081: } ! 2082: ! 2083: int ! 2084: ASPgetmsg(gref, ctlptr, datptr, flags, errp) ! 2085: gref_t *gref; ! 2086: strbuf_t *ctlptr; ! 2087: strbuf_t *datptr; ! 2088: int *flags; ! 2089: int *errp; ! 2090: { ! 2091: int lock, err, s, len, sum, rval; ! 2092: gbuf_t *mproto, *mdata, *m; ! 2093: strbuf_t ctlbuf; ! 2094: strbuf_t datbuf; ! 2095: asp_scb_t *scb; ! 2096: unsigned char get_wait; ! 2097: ! 2098: if ((scb = (asp_scb_t *)gref->info) == 0) { ! 2099: dPrintf(D_M_ASP,D_L_ERROR, "ASPgetmsg: stale handle=%x, pid=%d\n", ! 2100: gref,gref->pid,0,0,0); ! 2101: *errp = EINVAL; ! 2102: return -1; ! 2103: } ! 2104: ! 2105: ATDISABLE(s, scb->lock); ! 2106: if (scb->state == ASPSTATE_Close) { ! 2107: ATENABLE(s, scb->lock); ! 2108: return 0; ! 2109: } ! 2110: ! 2111: /* ! 2112: * get receive data ! 2113: */ ! 2114: while ((mproto = scb->sess_ioc) == 0) { ! 2115: scb->get_wait = 1; ! 2116: #ifdef _AIX ! 2117: err = e_sleep_thread(&scb->event, &scb->lock, LOCK_HANDLER|INTERRUPTIBLE); ! 2118: #else ! 2119: thread_sleep(&scb->event, &scb->lock, INTERRUPTIBLE); ! 2120: err = thread_wait_result(); ! 2121: #endif ! 2122: if (err != THREAD_AWAKENED) { ! 2123: scb->get_wait = 0; ! 2124: ATENABLE(s, scb->lock); ! 2125: *errp = EINTR; ! 2126: return -1; ! 2127: } ! 2128: if (scb->state == ASPSTATE_Close) { ! 2129: scb->get_wait = 0; ! 2130: ATENABLE(s, scb->lock); ! 2131: return 0; ! 2132: } ! 2133: } ! 2134: get_wait = scb->get_wait; ! 2135: scb->get_wait = 0; ! 2136: if ((ctlptr == 0) && (datptr == 0)) { ! 2137: ATENABLE(s, scb->lock); ! 2138: return 0; ! 2139: } ! 2140: scb->sess_ioc = gbuf_next(mproto); ! 2141: mdata = gbuf_cont(mproto); ! 2142: ATENABLE(s, scb->lock); ! 2143: ! 2144: if (gbuf_type(mproto) == MSG_ERROR) { ! 2145: err = (int)gbuf_rptr(mproto)[0]; ! 2146: goto l_err; ! 2147: } ! 2148: ! 2149: /* ! 2150: * copy in the control and data info ! 2151: */ ! 2152: if ((err = copyin((caddr_t)ctlptr, ! 2153: (caddr_t)&ctlbuf, sizeof(ctlbuf))) != 0) ! 2154: goto l_err; ! 2155: if ((err = copyin((caddr_t)datptr, ! 2156: (caddr_t)&datbuf, sizeof(datbuf))) != 0) ! 2157: goto l_err; ! 2158: if ((datbuf.maxlen < 0) || (datbuf.maxlen < gbuf_msgsize(mdata))) { ! 2159: ATDISABLE(s, scb->lock); ! 2160: gbuf_next(mproto) = scb->sess_ioc; ! 2161: scb->sess_ioc = mproto; ! 2162: ATENABLE(s, scb->lock); ! 2163: return MOREDATA; ! 2164: } ! 2165: ! 2166: if (scb->sel_on && (get_wait == 0)) { ! 2167: /* ! 2168: * this is a hack to support the select() call. ! 2169: * we're not supposed to dequeue messages in the Streams head's ! 2170: * read queue this way; but there is no better way. ! 2171: */ ! 2172: ATDISABLE(s, scb->lock); ! 2173: if (scb->sess_ioc == 0) { ! 2174: ATENABLE(s, scb->lock); ! 2175: } else { ! 2176: ATENABLE(s, scb->lock); ! 2177: atalk_notify_sel(gref); ! 2178: } ! 2179: } ! 2180: ! 2181: /* ! 2182: * copy out the control content and info ! 2183: */ ! 2184: ctlbuf.len = gbuf_len(mproto); ! 2185: if ((err = copyout((caddr_t)gbuf_rptr(mproto), ! 2186: (caddr_t)ctlbuf.buf, ctlbuf.len)) != 0) ! 2187: goto l_err; ! 2188: if ((err = copyout((caddr_t)&ctlbuf, ! 2189: (caddr_t)ctlptr, sizeof(ctlbuf))) != 0) ! 2190: goto l_err; ! 2191: ! 2192: /* ! 2193: * copy out the data content and info ! 2194: */ ! 2195: for (rval=0, sum=0; mdata && (rval == 0); mdata = gbuf_cont(mdata)) { ! 2196: len = gbuf_len(mdata); ! 2197: if (len) { ! 2198: if ((len + sum) > datbuf.maxlen) { ! 2199: len = datbuf.maxlen - sum; ! 2200: rval = MOREDATA; ! 2201: } ! 2202: if ((err = copyout((caddr_t)gbuf_rptr(mdata), ! 2203: (caddr_t)&datbuf.buf[sum], len)) != 0) ! 2204: goto l_err; ! 2205: sum += len; ! 2206: } ! 2207: } ! 2208: datbuf.len = sum; ! 2209: if ((err = copyout((caddr_t)&datbuf, ! 2210: (caddr_t)datptr, sizeof(datbuf))) != 0) ! 2211: goto l_err; ! 2212: ! 2213: gbuf_freem(mproto); ! 2214: ! 2215: ATDISABLE(s, scb->lock); ! 2216: if (scb->sess_ioc) ! 2217: scb->rcv_cnt--; ! 2218: else { ! 2219: scb->rcv_cnt = 0; ! 2220: scb->snd_stop = 0; ! 2221: } ! 2222: ATENABLE(s, scb->lock); ! 2223: return rval; ! 2224: ! 2225: l_err: ! 2226: ATDISABLE(s, scb->lock); ! 2227: gbuf_next(mproto) = scb->sess_ioc; ! 2228: scb->sess_ioc = mproto; ! 2229: ATENABLE(s, scb->lock); ! 2230: *errp = err; ! 2231: return -1; ! 2232: } ! 2233: StaticProc void ! 2234: asp_wakeup(scb) ! 2235: asp_scb_t *scb; ! 2236: { ! 2237: int s; ! 2238: ! 2239: ATDISABLE(s, scb->delay_lock); ! 2240: #ifdef _AIX ! 2241: e_wakeup(&scb->delay_event); ! 2242: #else ! 2243: thread_wakeup(&scb->delay_event); ! 2244: #endif ! 2245: ATENABLE(s, scb->delay_lock); ! 2246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.