|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright (c) 1995-1998 Apple Computer, Inc. ! 27: * All Rights Reserved. ! 28: * ! 29: * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC. ! 30: * The copyright notice above does not evidence any actual or ! 31: * intended publication of such source code. ! 32: */ ! 33: ! 34: #include <h/adsp_local.h> ! 35: #include <h/adsp_ioctl.h> ! 36: #include <at/ddp.h> ! 37: #include <h/at_ddp.h> ! 38: #include <h/atlog.h> ! 39: ! 40: void SndMsgUp(); ! 41: void adsp_rput(); ! 42: static void adsp_stop(); ! 43: static void adsp_iocack(); ! 44: static void adsp_iocnak(); ! 45: static void adspgetcfg(); ! 46: void adsp_dequeue_ccb(); ! 47: unsigned char adspAssignSocket(); ! 48: int adspallocate(), adsprelease(); ! 49: static int adspInited = 0; ! 50: ! 51: at_ddp_cfg_t ddpcfg; ! 52: atlock_t adspall_lock; ! 53: atlock_t adspgen_lock; ! 54: GLOBAL adspGlobal; ! 55: ! 56: /**********/ ! 57: ! 58: int adsp_pidM[256]; ! 59: char adsp_inputC[256]; ! 60: CCB *adsp_inputQ[256]; ! 61: extern char ddp_off_flag; ! 62: extern int ot_protoCnt; ! 63: extern char ot_protoT[]; ! 64: extern char ot_adsp_socketM[]; ! 65: ! 66: static char adsp_off_flag; ! 67: static CCB *ccb_used_list; ! 68: ! 69: void adsp_input(mp) ! 70: gbuf_t *mp; ! 71: { ! 72: gref_t *gref; ! 73: CCBPtr sp; ! 74: at_ddp_t *p; ! 75: int s, l; ! 76: gbuf_t *mb; ! 77: ! 78: switch (gbuf_type(mp)) { ! 79: case MSG_DATA: ! 80: p = (at_ddp_t *)gbuf_rptr(mp); ! 81: ATDISABLE(s, adspall_lock); ! 82: sp = adsp_inputQ[p->dst_socket]; ! 83: if ((sp == 0) || adsp_off_flag || (sp->gref==0) || (sp->state==sClosed)) ! 84: { ! 85: ATENABLE(s, adspall_lock); ! 86: gbuf_freem(mp); ! 87: return; ! 88: } ! 89: else if (sp->otccbLink != 0) { ! 90: do { ! 91: if ((sp->remoteAddress.a.node == p->src_node) ! 92: && (sp->remoteAddress.a.socket == p->src_socket) ! 93: && (*(short *)sp->remoteAddress.a.net == *(short *)p->src_net)) ! 94: break; ! 95: } while ((sp = sp->otccbLink) != 0); ! 96: if (sp == 0) ! 97: { ! 98: ATENABLE(s, adspall_lock); ! 99: gbuf_freem(mp); ! 100: return; ! 101: } ! 102: } ! 103: if (sp->lockFlag) { ! 104: gbuf_next(mp) = 0; ! 105: if (sp->deferred_mb) { ! 106: for (mb=sp->deferred_mb; gbuf_next(mb); mb=gbuf_next(mb)) ; ! 107: gbuf_next(mb) = mp; ! 108: } else ! 109: sp->deferred_mb = mp; ! 110: ATENABLE(s, adspall_lock); ! 111: return; ! 112: } ! 113: ATDISABLE(l, sp->lockRemove); ! 114: sp->lockFlag = 1; ! 115: ATENABLE(l, adspall_lock); ! 116: while (mp) { ! 117: adsp_rput(sp->gref, mp); ! 118: if ((mp = sp->deferred_mb) != 0) { ! 119: sp->deferred_mb = gbuf_next(mp); ! 120: gbuf_next(mp) = 0; ! 121: } ! 122: } ! 123: sp->lockFlag = 0; ! 124: ATENABLE(s, sp->lockRemove); ! 125: return; ! 126: ! 127: case MSG_IOCACK: ! 128: case MSG_IOCNAK: ! 129: gref = (gref_t *)((ioc_t *)gbuf_rptr(mp))->ioc_private; ! 130: break; ! 131: ! 132: case MSG_IOCTL: ! 133: adsp_stop(mp, *gbuf_rptr(mp)); ! 134: gbuf_set_type(mp, MSG_IOCACK); ! 135: DDP_OUTPUT(mp); ! 136: return; ! 137: ! 138: default: ! 139: gbuf_freem(mp); ! 140: return; ! 141: } ! 142: ! 143: adsp_rput(gref, mp); ! 144: } ! 145: ! 146: /**********/ ! 147: int adsp_readable(gref) ! 148: gref_t *gref; ! 149: { ! 150: int rc; ! 151: CCBPtr sp; ! 152: ! 153: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 154: rc = sp->rData; ! 155: ! 156: return rc; ! 157: } ! 158: ! 159: int adsp_writeable(gref) ! 160: gref_t *gref; ! 161: { ! 162: int s, rc; ! 163: CCBPtr sp; ! 164: ! 165: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 166: ATDISABLE(s, sp->lock); ! 167: rc = CalcSendQFree(sp); ! 168: ATENABLE(s, sp->lock); ! 169: ! 170: return rc; ! 171: } ! 172: ! 173: void adsp_init() ! 174: { ! 175: adspInited++; ! 176: InitGlobals(); ! 177: ccb_used_list = 0; ! 178: adsp_off_flag = 0; ! 179: bzero(adsp_pidM, sizeof(adsp_pidM)); ! 180: bzero(adsp_inputC, sizeof(adsp_inputC)); ! 181: bzero(adsp_inputQ, sizeof(adsp_inputQ)); ! 182: } ! 183: ! 184: /* ! 185: * Description: ! 186: * ADSP open and close routines. These routines ! 187: * initalize and release the ADSP structures. They do not ! 188: * have anything to do with "connections" ! 189: */ ! 190: ! 191: int adsp_open(gref) ! 192: gref_t *gref; ! 193: { ! 194: register CCBPtr sp; ! 195: int s; ! 196: ! 197: if (!adspInited) ! 198: adsp_init(); ! 199: /* ! 200: * if not ready, return error ! 201: */ ! 202: if (adsp_off_flag) ! 203: return ENOTREADY; ! 204: ! 205: if (!adspAllocateCCB(gref)) ! 206: return(ENOBUFS); /* can't get buffers */ ! 207: ! 208: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 209: gref->readable = adsp_readable; ! 210: gref->writeable = adsp_writeable; ! 211: ATDISABLE(s, adspall_lock); ! 212: if ((sp->otccbLink = ccb_used_list) != 0) ! 213: sp->otccbLink->ccbLink = sp; ! 214: ccb_used_list = sp; ! 215: ATENABLE(s, adspall_lock); ! 216: return 0; ! 217: } ! 218: ! 219: int adsp_close(gref) ! 220: gref_t *gref; ! 221: { ! 222: int s, l; ! 223: unsigned char localSocket; ! 224: ! 225: /* make sure we've not yet removed the CCB (e.g., due to TrashSession) */ ! 226: ATDISABLE(l, adspgen_lock); ! 227: if (gref->info) { ! 228: CCBPtr sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 229: ATDISABLE(s, sp->lock); ! 230: ATENABLE(s, adspgen_lock); ! 231: if (sp->ioDone) ! 232: { ! 233: ATENABLE(l, sp->lock); ! 234: return 0; ! 235: } ! 236: localSocket = sp->localSocket; ! 237: ATENABLE(l, sp->lock); ! 238: if (localSocket) ! 239: adspRelease(gref); ! 240: else ! 241: { ! 242: adsp_dequeue_ccb(sp); ! 243: gbuf_freeb((gbuf_t *)gref->info); ! 244: } ! 245: } else ! 246: ATENABLE(l, adspgen_lock); ! 247: return 0; ! 248: } ! 249: ! 250: ! 251: /* ! 252: * Name: ! 253: * adsp_rput ! 254: * ! 255: * Description: ! 256: * ADSP streams read put and service routines. ! 257: */ ! 258: ! 259: void adsp_rput(gref, mp) ! 260: gref_t *gref; /* READ queue */ ! 261: gbuf_t *mp; ! 262: { ! 263: static first = 1; ! 264: ! 265: switch (gbuf_type(mp)) { ! 266: case MSG_ERROR: ! 267: case MSG_HANGUP: ! 268: case MSG_IOCACK: ! 269: case MSG_IOCNAK: ! 270: ! 271: /* ! 272: * ADSP needs to obtain the network number and node number ! 273: * for the Host it is running on. ! 274: * In the AUX implementation it "peeked" inside the ddp ! 275: * structure pointed to by at_ifDefault; ! 276: * In a strict streams module implementation "peeking" is ! 277: * neither kosher, nor permitted. ! 278: * adspgetcfg() sends a DDP_IOC_GET_CFG ioctl request to DDP. ! 279: * This code picks up the response from DDP. From this ! 280: * response, the ADSP streams module obtains the network ! 281: * and node number. ! 282: */ ! 283: ! 284: /* ! 285: ** Examine the first packet coming from DDP stream. ! 286: */ ! 287: if (first) { ! 288: first = 0; ! 289: if (gbuf_type(mp) == MSG_IOCACK) { ! 290: ioc_t *iocbp = (ioc_t *) gbuf_rptr(mp); ! 291: ! 292: if (iocbp->ioc_cmd == DDP_IOC_GET_CFG) { ! 293: if (gbuf_rptr(gbuf_cont(mp))) { ! 294: bcopy((caddr_t) gbuf_rptr(gbuf_cont(mp)), ! 295: (caddr_t) &ddpcfg, ! 296: sizeof(at_ddp_cfg_t)); ! 297: dPrintf(D_M_ADSP, D_L_INFO, ! 298: ("ADSP: Net = 0x%x, Node = 0x%x\n", ! 299: NET_VALUE(ddpcfg.node_addr.net), ! 300: ddpcfg.node_addr.node)); ! 301: } ! 302: gbuf_freem(mp); ! 303: return; ! 304: } ! 305: } ! 306: } ! 307: switch (adspReadHandler(gref, mp)) { ! 308: case STR_PUTNEXT: ! 309: atalk_putnext(gref, mp); ! 310: break; ! 311: case STR_IGNORE: ! 312: break; ! 313: } ! 314: break; ! 315: default: ! 316: CheckReadQueue(gbuf_rptr(((gbuf_t *)gref->info))); ! 317: CheckSend(gbuf_rptr(((gbuf_t *)gref->info))); ! 318: ! 319: switch (gbuf_type(mp)) { ! 320: case MSG_IOCTL: ! 321: case MSG_DATA: ! 322: case MSG_PROTO: ! 323: if (adspReadHandler(gref, mp) == STR_PUTNEXT) ! 324: atalk_putnext(gref, mp); ! 325: break; ! 326: default: ! 327: atalk_putnext(gref, mp); ! 328: break; ! 329: } ! 330: } ! 331: } ! 332: ! 333: /* ! 334: * Name: ! 335: * adsp_wput ! 336: * ! 337: * Description: ! 338: * ADSP streams write put and service routines. ! 339: * ! 340: */ ! 341: ! 342: int adsp_wput(gref, mp) ! 343: gref_t *gref; /* WRITE queue */ ! 344: gbuf_t *mp; ! 345: { ! 346: int rc; ! 347: int s; ! 348: gbuf_t *xm; ! 349: ioc_t *iocbp; ! 350: ! 351: if (gbuf_type(mp) == MSG_IOCTL) { ! 352: iocbp = (ioc_t *)gbuf_rptr(mp); ! 353: switch (iocbp->ioc_cmd) { ! 354: case AT_ADSP_LINK: ! 355: adsp_dequeue_ccb((CCBPtr)gbuf_rptr(((gbuf_t *)gref->info))); ! 356: ot_protoT[DDP_ADSP] = 1; ! 357: ot_protoCnt++; ! 358: ! 359: iocbp->ioc_rval = 0; ! 360: adsp_iocack(gref, mp); ! 361: return 0; ! 362: ! 363: case AT_ADSP_UNLINK: ! 364: ot_protoT[DDP_ADSP] = 0; ! 365: ot_protoCnt--; ! 366: ddp_off_flag = 0; /* why do this on an unlink? */ ! 367: ! 368: if (adspInited) { ! 369: CleanupGlobals(); /* for 2225395 */ ! 370: adspInited = 0; ! 371: } ! 372: iocbp->ioc_rval = 0; ! 373: adsp_iocack(gref, mp); ! 374: return 0; ! 375: ! 376: case ADSPBINDREQ: ! 377: { ! 378: unsigned char v; ! 379: CCBPtr sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 380: ! 381: if (gbuf_cont(mp) == NULL) { ! 382: iocbp->ioc_rval = -1; ! 383: adsp_iocnak(gref, mp, EINVAL); ! 384: } ! 385: v = *(unsigned char *)gbuf_rptr(gbuf_cont(mp)); ! 386: ATDISABLE(s, adspall_lock); ! 387: if ( (v != 0) ! 388: && ((v > DDP_SOCKET_LAST) || (v < 2) ! 389: || (adsp_inputQ[v] != 0) || (ot_adsp_socketM[v] != 0)) ) { ! 390: ATENABLE(s, adspall_lock); ! 391: iocbp->ioc_rval = -1; ! 392: adsp_iocnak(gref, mp, EINVAL); ! 393: } ! 394: else { ! 395: if (v == 0) { ! 396: ATENABLE(s, adspall_lock); ! 397: if ((v = adspAssignSocket(gref, 0)) == 0) { ! 398: iocbp->ioc_rval = -1; ! 399: adsp_iocnak(gref, mp, EINVAL); ! 400: return 0; ! 401: } ! 402: } else { ! 403: adsp_inputC[v] = 1; ! 404: adsp_inputQ[v] = sp; ! 405: adsp_pidM[v] = sp->pid; ! 406: ATENABLE(s, adspall_lock); ! 407: adsp_dequeue_ccb(sp); ! 408: } ! 409: *(unsigned char *)gbuf_rptr(gbuf_cont(mp)) = v; ! 410: sp->localSocket = v; ! 411: iocbp->ioc_rval = 0; ! 412: adsp_iocack(gref, mp); ! 413: } ! 414: return 0; ! 415: } ! 416: ! 417: case ADSPGETSOCK: ! 418: case ADSPGETPEER: ! 419: { ! 420: at_inet_t *addr; ! 421: CCBPtr sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 422: ! 423: if (((xm = gbuf_cont(mp)) == NULL) ! 424: && ((xm = gbuf_alloc(sizeof(at_inet_t), PRI_MED)) == NULL)) { ! 425: iocbp->ioc_rval = -1; ! 426: adsp_iocnak(gref, mp, ENOSR); ! 427: return 0; ! 428: } ! 429: gbuf_cont(mp) = xm; ! 430: gbuf_wset(xm,sizeof(at_inet_t)); ! 431: addr = (at_inet_t *)gbuf_rptr(xm); ! 432: if (iocbp->ioc_cmd == ADSPGETSOCK) { ! 433: adspgetcfg(gref); ! 434: *addr = ddpcfg.node_addr; ! 435: addr->socket = sp->localSocket; ! 436: } else ! 437: *addr = sp->remoteAddress.a; ! 438: iocbp->ioc_rval = 0; ! 439: adsp_iocack(gref, mp); ! 440: return 0; ! 441: } ! 442: } /* switch */ ! 443: } ! 444: ! 445: /* Obtain Network and Node Id's from DDP */ ! 446: adspgetcfg(gref); ! 447: ! 448: if (!gref->info) ! 449: gbuf_freem(mp); ! 450: else { ! 451: CCBPtr sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 452: ATDISABLE(s, sp->lockClose); ! 453: rc = adspWriteHandler(gref, mp); ! 454: ATENABLE(s, sp->lockClose); ! 455: ! 456: switch (rc) { ! 457: case STR_PUTNEXT: ! 458: if (gbuf_type(mp) == MSG_IOCTL) { ! 459: iocbp = (ioc_t *)gbuf_rptr(mp); ! 460: if (iocbp->ioc_cmd == DDP_IOC_GET_CFG) { ! 461: if ((xm = gbuf_alloc(sizeof(at_ddp_cfg_t), PRI_MED)) == NULL) { ! 462: adsp_iocnak(gref, mp, ENOBUFS); ! 463: break; ! 464: } ! 465: if (gbuf_cont(mp) != NULL) ! 466: gbuf_freem(gbuf_cont(mp)); ! 467: gbuf_cont(mp) = xm; ! 468: gbuf_wset(xm,sizeof(at_ddp_cfg_t)); ! 469: *(at_ddp_cfg_t *)gbuf_rptr(xm) = ddpcfg; ! 470: ((at_ddp_cfg_t *)gbuf_rptr(xm))->node_addr.socket = ! 471: ((CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)))->localSocket; ! 472: adsp_iocack(gref, mp); ! 473: break; ! 474: } ! 475: iocbp->ioc_private = (void *)gref; ! 476: } ! 477: DDP_OUTPUT(mp); ! 478: break; ! 479: case STR_IGNORE: ! 480: case STR_IGNORE+99: ! 481: break; ! 482: default: ! 483: gbuf_freem(mp); ! 484: break; ! 485: } ! 486: } ! 487: ! 488: return 0; ! 489: } /* adsp_wput */ ! 490: ! 491: void adspioc_ack(errno, m, gref) ! 492: int errno; ! 493: gbuf_t *m; ! 494: gref_t *gref; ! 495: { ! 496: ioc_t *iocbp; ! 497: ! 498: if (m == NULL) ! 499: return; ! 500: iocbp = (ioc_t *) gbuf_rptr(m); ! 501: ! 502: iocbp->ioc_error = errno; /* set the errno */ ! 503: iocbp->ioc_count = gbuf_msgsize(gbuf_cont(m)); ! 504: if (gbuf_type(m) == MSG_IOCTL) /* if an ioctl, this is an ack */ ! 505: gbuf_set_type(m, MSG_IOCACK); /* and ALWAYS update the user */ ! 506: /* ioctl structure */ ! 507: SndMsgUp(gref, m); ! 508: } ! 509: ! 510: static void adspgetcfg(gref) ! 511: gref_t *gref; ! 512: { ! 513: static adspgetcfgdone = 0; ! 514: register gbuf_t *mp; ! 515: ioc_t *iocbp; ! 516: ! 517: if (adspgetcfgdone) ! 518: return; ! 519: ! 520: if (gref && (mp = gbuf_alloc(sizeof(ioc_t), PRI_HI))) { ! 521: adspgetcfgdone = 1; ! 522: gbuf_set_type(mp, MSG_IOCTL); ! 523: gbuf_wset(mp,sizeof(ioc_t)); ! 524: iocbp = (ioc_t *) gbuf_rptr(mp); ! 525: iocbp->ioc_private = (void *)gref; ! 526: iocbp->ioc_count = ((CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)))->localSocket; ! 527: iocbp->ioc_error = 7; ! 528: ! 529: iocbp->ioc_cmd = DDP_IOC_GET_CFG; ! 530: DDP_OUTPUT(mp); ! 531: } ! 532: } ! 533: ! 534: static void adsp_iocack(gref, m) ! 535: gref_t *gref; ! 536: register gbuf_t *m; ! 537: { ! 538: if (gbuf_type(m) == MSG_IOCTL) ! 539: gbuf_set_type(m, MSG_IOCACK); ! 540: ! 541: if (gbuf_cont(m)) ! 542: ((ioc_t *)gbuf_rptr(m))->ioc_count = gbuf_msgsize(gbuf_cont(m)); ! 543: else ! 544: ((ioc_t *)gbuf_rptr(m))->ioc_count = 0; ! 545: ! 546: SndMsgUp(gref, m); ! 547: } ! 548: ! 549: ! 550: static void adsp_iocnak(gref, m, err) ! 551: gref_t *gref; ! 552: register gbuf_t *m; ! 553: register int err; ! 554: { ! 555: if (gbuf_type(m) == MSG_IOCTL) ! 556: gbuf_set_type(m, MSG_IOCNAK); ! 557: ((ioc_t *)gbuf_rptr(m))->ioc_count = 0; ! 558: ! 559: if (err == 0) ! 560: err = ENXIO; ! 561: ((ioc_t *)gbuf_rptr(m))->ioc_error = err; ! 562: ! 563: if (gbuf_cont(m)) { ! 564: gbuf_freem(gbuf_cont(m)); ! 565: gbuf_cont(m) = NULL; ! 566: } ! 567: SndMsgUp(gref, m); ! 568: } ! 569: ! 570: unsigned char ! 571: adspAssignSocket(gref, flag) ! 572: gref_t *gref; ! 573: int flag; ! 574: { ! 575: unsigned char sVal, sMax, sMin, sSav, inputC; ! 576: CCBPtr sp; ! 577: int s; ! 578: ! 579: sMax = flag ? DDP_SOCKET_LAST-46 : DDP_SOCKET_LAST-6; ! 580: sMin = DDP_SOCKET_1st_DYNAMIC-64; ! 581: ! 582: ATDISABLE(s, adspall_lock); ! 583: for (inputC=255, sVal=sMax; sVal >= sMin; sVal--) { ! 584: if (!ot_adsp_socketM[sVal]) { ! 585: if (!adsp_inputQ[sVal]) ! 586: break; ! 587: else if (flag) { ! 588: if ((adsp_inputC[sVal] < inputC) ! 589: && (adsp_inputQ[sVal]->state == sOpen)) { ! 590: inputC = adsp_inputC[sVal]; ! 591: sSav = sVal; ! 592: } ! 593: } ! 594: } ! 595: } ! 596: ! 597: if (sVal < sMin) { ! 598: if (!flag || (inputC == 255)) { ! 599: ATENABLE(s, adspall_lock); ! 600: return 0; ! 601: } ! 602: sVal = sSav; ! 603: } ! 604: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 605: ATENABLE(s, adspall_lock); ! 606: adsp_dequeue_ccb(sp); ! 607: ATDISABLE(s, adspall_lock); ! 608: adsp_inputC[sVal]++; ! 609: sp->otccbLink = adsp_inputQ[sVal]; ! 610: adsp_inputQ[sVal] = sp; ! 611: if (!flag) ! 612: adsp_pidM[sVal] = sp->pid; ! 613: ATENABLE(s, adspall_lock); ! 614: return sVal; ! 615: } ! 616: ! 617: int ! 618: adspDeassignSocket(sp) ! 619: CCBPtr sp; ! 620: { ! 621: unsigned char sVal; ! 622: CCBPtr curr_sp; ! 623: CCBPtr prev_sp; ! 624: int pid = 0; ! 625: int s, l; ! 626: ! 627: dPrintf(D_M_ADSP, D_L_TRACE, ("adspDeassignSocket: pid=%d,s=%d\n", ! 628: sp->pid, sp->localSocket)); ! 629: ATDISABLE(s, adspall_lock); ! 630: sVal = sp->localSocket; ! 631: if ((curr_sp = adsp_inputQ[sVal]) != 0) { ! 632: prev_sp = 0; ! 633: while (curr_sp != sp) { ! 634: prev_sp = curr_sp; ! 635: curr_sp = curr_sp->otccbLink; ! 636: } ! 637: if (curr_sp) { ! 638: ATDISABLE(l, sp->lockRemove); ! 639: if (prev_sp) ! 640: prev_sp->otccbLink = sp->otccbLink; ! 641: else ! 642: adsp_inputQ[sVal] = sp->otccbLink; ! 643: ATENABLE(l, sp->lockRemove); ! 644: if (adsp_inputQ[sVal]) ! 645: adsp_inputC[sVal]--; ! 646: else { ! 647: pid = adsp_pidM[sVal]; ! 648: adsp_inputC[sVal] = 0; ! 649: adsp_pidM[sVal] = 0; ! 650: } ! 651: sp->ccbLink = 0; ! 652: sp->otccbLink = 0; ! 653: sp->localSocket = 0; ! 654: ATENABLE(s, adspall_lock); ! 655: return pid ? 0 : 1; ! 656: } ! 657: } ! 658: ATENABLE(s, adspall_lock); ! 659: ! 660: dPrintf(D_M_ADSP, D_L_ERROR, ! 661: ("adspDeassignSocket: closing, no CCB block, trouble ahead\n")); ! 662: return -1; ! 663: } ! 664: ! 665: /* ! 666: * stop ADSP now ! 667: */ ! 668: static void ! 669: adsp_stop(m, flag) ! 670: gbuf_t *m; ! 671: int flag; ! 672: { ! 673: int k, s, *x_wptr; ! 674: CCB *sp; ! 675: ! 676: ATDISABLE(s, adspall_lock); ! 677: gbuf_rptr(m)[1]++; ! 678: ! 679: if (flag) ! 680: adsp_off_flag = 1; ! 681: ! 682: x_wptr = (int *)gbuf_wptr(m); ! 683: for (sp = ccb_used_list; sp; sp = sp->otccbLink) { ! 684: if (flag == 2) { ! 685: sp->ioDone = 1; ! 686: } else { ! 687: *(int *)gbuf_wptr(m) = sp->pid; ! 688: gbuf_winc(m,sizeof(int)); ! 689: } ! 690: } ! 691: ! 692: for (k=0; k < 256; k++) { ! 693: if ((sp = adsp_inputQ[k]) == 0) ! 694: continue; ! 695: do { ! 696: if (flag == 2) { ! 697: sp->ioDone = 1; ! 698: } else { ! 699: *(int *)gbuf_wptr(m) = sp->pid; ! 700: gbuf_winc(m,sizeof(int)); ! 701: } ! 702: } while ((sp = sp->otccbLink) != 0); ! 703: } ! 704: ATENABLE(s, adspall_lock); ! 705: ! 706: while (x_wptr != (int *)gbuf_wptr(m)) { ! 707: dPrintf(D_M_ADSP, D_L_TRACE, ("adsp_stop: pid=%d\n", *x_wptr)); ! 708: x_wptr++; ! 709: } ! 710: } ! 711: ! 712: /* ! 713: * remove CCB from the use list ! 714: */ ! 715: void ! 716: adsp_dequeue_ccb(sp) ! 717: CCB *sp; ! 718: { ! 719: int s; ! 720: ! 721: ATDISABLE(s, adspall_lock); ! 722: if (sp == ccb_used_list) { ! 723: if ((ccb_used_list = sp->otccbLink) != 0) ! 724: sp->otccbLink->ccbLink = 0; ! 725: } else if (sp->ccbLink) { ! 726: if ((sp->ccbLink->otccbLink = sp->otccbLink) != 0) ! 727: sp->otccbLink->ccbLink = sp->ccbLink; ! 728: } ! 729: ! 730: sp->otccbLink = 0; ! 731: sp->ccbLink = 0; ! 732: ATENABLE(s, adspall_lock); ! 733: } ! 734: ! 735: void SndMsgUp(gref, mp) ! 736: gref_t *gref; /* WRITE queue */ ! 737: gbuf_t *mp; ! 738: { ! 739: atalk_putnext(gref, mp); ! 740: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.