|
|
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: #define RESOLVE_DBG ! 26: #include <adsp_local.h> ! 27: #include "adsp_ioctl.h" ! 28: ! 29: #ifdef notdefn ! 30: struct adsp_debug adsp_dtable[1025]; ! 31: int ad_entry = 0; ! 32: #endif ! 33: ! 34: extern atlock_t adspgen_lock; ! 35: ! 36: adspAllocateCCB(gref) ! 37: register gref_t *gref; /* READ queue */ ! 38: { ! 39: gbuf_t *ccb_mp; ! 40: register CCBPtr sp; ! 41: ! 42: if (!(ccb_mp = gbuf_alloc(sizeof(CCB), PRI_LO))) { ! 43: return (0); ! 44: } ! 45: bzero((caddr_t) gbuf_rptr(ccb_mp), sizeof(CCB)); ! 46: gbuf_wset(ccb_mp,sizeof(CCB)); ! 47: gref->info = (caddr_t) ccb_mp; ! 48: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 49: ! 50: sp->pid = gref->pid; /* save the caller process pointer */ ! 51: sp->gref = gref; /* save a back pointer to the WRITE queue */ ! 52: sp->sp_mp = ccb_mp; /* and its message block */ ! 53: ATLOCKINIT(sp->lock); ! 54: ATLOCKINIT(sp->lockClose); ! 55: ATLOCKINIT(sp->lockRemove); ! 56: return 1; ! 57: } ! 58: ! 59: adspRelease(gref) ! 60: register gref_t *gref; /* READ queue */ ! 61: { ! 62: register CCBPtr sp; ! 63: register gbuf_t *mp; ! 64: int s, l; ! 65: ! 66: ATDISABLE(l, adspgen_lock); ! 67: if (gref->info) { ! 68: sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info)); ! 69: ATDISABLE(s, sp->lock); ! 70: ATENABLE(s, adspgen_lock); ! 71: /* Tells completion routine of close */ ! 72: /* packet to remove us. */ ! 73: ! 74: if (sp->state == sPassive || sp->state == sClosed || ! 75: sp->state == sOpening || sp->state == sListening) { ! 76: ATENABLE(l, sp->lock); ! 77: if (sp->state == sListening) ! 78: CompleteQueue(&sp->opb, errAborted); ! 79: sp->removing = 1; /* Prevent allowing another dspClose. */ ! 80: DoClose(sp, errAborted, 0); /* will remove CCB */ ! 81: return 0; ! 82: } else { /* sClosing & sOpen */ ! 83: sp->state = sClosing; ! 84: } ! 85: ATENABLE(l, sp->lock); ! 86: ! 87: if (CheckOkToClose(sp)) { /* going to close */ ! 88: sp->sendCtl = B_CTL_CLOSE; /* Send close advice */ ! 89: } else { ! 90: CheckSend(sp); /* try one more time to send out data */ ! 91: if (sp->state != sClosed) ! 92: sp->sendCtl = B_CTL_CLOSE; /* Setup to send close advice */ ! 93: } ! 94: CheckSend(sp); /* and force out the close */ ! 95: ATDISABLE(s, sp->lock); ! 96: sp->removing = 1; /* Prevent allowing another dspClose. */ ! 97: sp->state = sClosed; ! 98: ATENABLE(s, sp->lock); ! 99: DoClose(sp, errAborted, 0); /* to closed and remove CCB */ ! 100: } else ! 101: ATENABLE(l, adspgen_lock); ! 102: } ! 103: ! 104: ! 105: ! 106: ! 107: adspWriteHandler(gref, mp) ! 108: gref_t *gref; /* WRITE queue */ ! 109: gbuf_t *mp; ! 110: { ! 111: ! 112: register ioc_t *iocbp; ! 113: register struct adspcmd *ap; ! 114: int error, flag; ! 115: void *sp; ! 116: ! 117: switch(gbuf_type(mp)) { ! 118: case MSG_DATA: ! 119: if (gref->info == 0) { ! 120: gbuf_freem(mp); ! 121: return(STR_IGNORE); ! 122: } ! 123: /* ! 124: * Fill in the global stuff ! 125: */ ! 126: ap = (struct adspcmd *)gbuf_rptr(mp); ! 127: ap->gref = gref; ! 128: ap->ioc = 0; ! 129: ap->mp = mp; ! 130: sp = (void *)gbuf_rptr(((gbuf_t *)gref->info)); ! 131: switch(ap->csCode) { ! 132: case dspWrite: ! 133: if (error = adspWrite(sp, ap)) ! 134: gbuf_freem(mp); ! 135: return(STR_IGNORE); ! 136: case dspAttention: ! 137: if (error = adspAttention(sp, ap)) ! 138: gbuf_freem(mp); ! 139: return(STR_IGNORE); ! 140: } ! 141: case MSG_IOCTL: ! 142: if (gref->info == 0) { ! 143: adspioc_ack(EPROTO, mp, gref); ! 144: return(STR_IGNORE); ! 145: } ! 146: iocbp = (ioc_t *) gbuf_rptr(mp); ! 147: if (ADSP_IOCTL(iocbp->ioc_cmd)) { ! 148: iocbp->ioc_count = sizeof(*ap) - 1; ! 149: if (gbuf_cont(mp) == 0) { ! 150: adspioc_ack(EINVAL, mp, gref); ! 151: return(STR_IGNORE); ! 152: } ! 153: ap = (struct adspcmd *) gbuf_rptr(gbuf_cont(mp)); ! 154: ap->gref = gref; ! 155: ap->ioc = (caddr_t) mp; ! 156: ap->mp = gbuf_cont(mp); /* request head */ ! 157: ap->ioResult = 0; ! 158: ! 159: if ((gref->info == 0) && ((iocbp->ioc_cmd != ADSPOPEN) && ! 160: (iocbp->ioc_cmd != ADSPCLLISTEN))) { ! 161: ap->ioResult = errState; ! 162: ! 163: adspioc_ack(EINVAL, mp, gref); ! 164: return(STR_IGNORE); ! 165: } ! 166: } ! 167: sp = (void *)gbuf_rptr(((gbuf_t *)gref->info)); ! 168: switch(iocbp->ioc_cmd) { ! 169: case ADSPOPEN: ! 170: case ADSPCLLISTEN: ! 171: ap->socket = ((CCBPtr)sp)->localSocket; ! 172: flag = (adspMode(ap) == ocAccept) ? 1 : 0; ! 173: if (flag && ap->socket) { ! 174: if (adspDeassignSocket((CCBPtr)sp) >= 0) ! 175: ap->socket = 0; ! 176: } ! 177: if ((ap->socket == 0) && ! 178: ((ap->socket = (at_socket)adspAssignSocket(gref, flag)) == 0)) { ! 179: adspioc_ack(EADDRNOTAVAIL, mp, gref); ! 180: return(STR_IGNORE); ! 181: } ! 182: ap->csCode = iocbp->ioc_cmd == ADSPOPEN ? dspInit : dspCLInit; ! 183: if ((error = ! 184: adspInit(sp, ap)) == 0) { ! 185: switch(ap->csCode) { ! 186: case dspInit: ! 187: /* and open the connection */ ! 188: ap->csCode = dspOpen; ! 189: error = adspOpen(sp, ap); ! 190: break; ! 191: case dspCLInit: ! 192: /* ADSPCLLISTEN */ ! 193: ap->csCode = dspCLListen; ! 194: error = adspCLListen(sp, ap); ! 195: break; ! 196: } ! 197: } ! 198: if (error) ! 199: adspioc_ack(error, mp, gref); /* if this failed req complete */ ! 200: return(STR_IGNORE); ! 201: case ADSPCLOSE: ! 202: ap->csCode = dspClose; ! 203: if (error = adspClose(sp, ap)) { ! 204: adspioc_ack(error, mp, gref); ! 205: break; ! 206: } ! 207: break; ! 208: case ADSPCLREMOVE: ! 209: ap->csCode = dspCLRemove; ! 210: error = adspClose(sp, ap); ! 211: adspioc_ack(error, mp, gref); ! 212: return(STR_IGNORE); ! 213: case ADSPCLDENY: ! 214: ap->csCode = dspCLDeny; ! 215: if (error = adspCLDeny(sp, ap)) { ! 216: adspioc_ack(error, mp, gref); ! 217: } ! 218: return(STR_IGNORE); ! 219: case ADSPSTATUS: ! 220: ap->csCode = dspStatus; ! 221: if (error = adspStatus(sp, ap)) { ! 222: adspioc_ack(error, mp, gref); ! 223: } ! 224: return(STR_IGNORE); ! 225: case ADSPREAD: ! 226: ap->csCode = dspRead; ! 227: if (error = adspRead(sp, ap)) { ! 228: adspioc_ack(error, mp, gref); ! 229: } ! 230: return(STR_IGNORE); ! 231: case ADSPATTENTION: ! 232: ap->csCode = dspAttention; ! 233: if (error = adspReadAttention(sp, ap)) { ! 234: adspioc_ack(error, mp, gref); ! 235: } ! 236: return(STR_IGNORE); ! 237: case ADSPOPTIONS: ! 238: ap->csCode = dspOptions; ! 239: if (error = adspOptions(sp, ap)) { ! 240: adspioc_ack(error, mp, gref); ! 241: } ! 242: return(STR_IGNORE); ! 243: case ADSPRESET: ! 244: ap->csCode = dspReset; ! 245: if (error = adspReset(sp, ap)) { ! 246: adspioc_ack(error, mp, gref); ! 247: } ! 248: return(STR_IGNORE); ! 249: case ADSPNEWCID: ! 250: ap->csCode = dspNewCID; ! 251: if (error = adspNewCID(sp, ap)) { ! 252: adspioc_ack(error, mp, gref); ! 253: } ! 254: return(STR_IGNORE); ! 255: default: ! 256: return(STR_PUTNEXT); /* pass it on down */ ! 257: } ! 258: return(STR_IGNORE); ! 259: case MSG_PROTO: ! 260: default: ! 261: gbuf_freem(mp); ! 262: } ! 263: } ! 264: ! 265: ! 266: adspReadHandler(gref, mp) ! 267: gref_t *gref; ! 268: gbuf_t *mp; ! 269: { ! 270: int error; ! 271: ! 272: switch(gbuf_type(mp)) { ! 273: case MSG_DATA: ! 274: if (error = adspPacket(gref, mp)) { ! 275: gbuf_freem(mp); ! 276: } ! 277: break; ! 278: ! 279: case MSG_IOCTL: ! 280: default: ! 281: return(STR_PUTNEXT); ! 282: break; ! 283: } ! 284: return(STR_IGNORE); ! 285: } ! 286: ! 287: /* ! 288: * adsp_sendddp() ! 289: * ! 290: * Description: ! 291: * This procedure a formats a DDP datagram header and calls the ! 292: * DDP module to queue it for routing and transmission according to ! 293: * the DDP parameters. We always take control of the datagram; ! 294: * if there is an error we free it, otherwise we pass it to the next ! 295: * layer. We don't need to set the src address fileds because the ! 296: * DDP layer fills these in for us. ! 297: * ! 298: * Calling Sequence: ! 299: * ret_status = adsp_sendddp(q, sp, mp, length, dstnetaddr, ddptype); ! 300: * ! 301: * Formal Parameters: ! 302: * sp Caller stream pointer ! 303: * mp gbuf_t chain containing the datagram to transmit ! 304: * The first mblk contains the ADSP header and space ! 305: * for the DDP header. ! 306: * length size of data portion of datagram ! 307: * dstnetaddr address of 4-byte destination internet address ! 308: * ddptype DDP protocol to assign to the datagram ! 309: * ! 310: * Completion Status: ! 311: * 0 Procedure successful completed. ! 312: * EMSGSIZE Specified datagram length is too big. ! 313: * ! 314: * Side Effects: ! 315: * NONE ! 316: */ ! 317: ! 318: adsp_sendddp(sp, mp, length, dstnetaddr, ddptype) ! 319: CCBPtr sp; ! 320: gbuf_t *mp; ! 321: int length; ! 322: AddrUnion *dstnetaddr; ! 323: int ddptype; ! 324: { ! 325: DDPX_FRAME *ddp; ! 326: gbuf_t *mlist = mp; ! 327: ! 328: if (mp == 0) ! 329: return EINVAL; ! 330: ! 331: if (length > DDP_DATA_SIZE) { ! 332: gbuf_freel(mlist); ! 333: return EMSGSIZE; ! 334: } ! 335: ! 336: while (mp) { ! 337: ! 338: if (length == 0) ! 339: length = gbuf_msgsize(mp) - DDPL_FRAME_LEN; ! 340: /* Set up the DDP header */ ! 341: ! 342: ddp = (DDPX_FRAME *) gbuf_rptr(mp); ! 343: UAS_ASSIGN(ddp->ddpx_length, (length + DDPL_FRAME_LEN)); ! 344: UAS_ASSIGN(ddp->ddpx_cksm, 0); ! 345: if (sp) { ! 346: if (sp->useCheckSum) ! 347: UAS_ASSIGN(ddp->ddpx_cksm, 1); ! 348: } ! 349: ! 350: NET_NET(ddp->ddpx_dnet, dstnetaddr->a.net); ! 351: ddp->ddpx_dnode = dstnetaddr->a.node; ! 352: ddp->ddpx_source = sp ? sp->localSocket : ddp->ddpx_dest; ! 353: ddp->ddpx_dest = dstnetaddr->a.socket; ! 354: ! 355: ddp->ddpx_type = ddptype; ! 356: length = 0; ! 357: mp = gbuf_next(mp); ! 358: ! 359: } ! 360: ! 361: DDP_OUTPUT(mlist); ! 362: return 0; ! 363: } ! 364: ! 365: void NotifyUser(sp) ! 366: register CCBPtr sp; ! 367: ! 368: { ! 369: /* ! 370: pidsig(sp->pid, SIGIO); ! 371: */ ! 372: } ! 373: ! 374: void UrgentUser(sp) ! 375: register CCBPtr sp; ! 376: { ! 377: /* ! 378: pidsig(sp->pid, SIGURG); ! 379: */ ! 380: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.