Annotation of XNU/bsd/netat/adsp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * Change log:
        !            24:  *   06/29/95 - Modified to handle flow control for writing (Tuyen Nguyen)
        !            25:  *    Modified for MP, 1996 by Tuyen Nguyen
        !            26:  *   Modified, April 9, 1997 by Tuyen Nguyen for MacOSX.
        !            27:  */
        !            28: #define RESOLVE_DBG
        !            29: #include <sys/errno.h>
        !            30: #include <sys/types.h>
        !            31: #include <sys/param.h>
        !            32: #include <machine/spl.h>
        !            33: #include <sys/systm.h>
        !            34: #include <sys/kernel.h>
        !            35: #include <sys/proc.h>
        !            36: #include <sys/filedesc.h>
        !            37: #include <sys/fcntl.h>
        !            38: #include <sys/mbuf.h>
        !            39: #include <sys/socket.h>
        !            40: 
        !            41: #include <netat/sysglue.h>
        !            42: #include <netat/appletalk.h>
        !            43: #include <netat/at_pcb.h>
        !            44: #include <netat/ddp.h>
        !            45: #include <netat/adsp.h>
        !            46: #include <netat/adsp_internal.h>
        !            47: 
        !            48: #ifdef notdefn
        !            49: struct adsp_debug adsp_dtable[1025];
        !            50: int ad_entry = 0;
        !            51: #endif
        !            52: 
        !            53: extern atlock_t adspgen_lock;
        !            54: 
        !            55: adspAllocateCCB(gref)
        !            56:     register gref_t *gref;     /* READ queue */
        !            57: {
        !            58:     gbuf_t *ccb_mp;
        !            59:     register CCBPtr sp;
        !            60: 
        !            61:     if (!(ccb_mp = gbuf_alloc(sizeof(CCB), PRI_LO))) {
        !            62:         return (0);
        !            63:     }
        !            64:     bzero((caddr_t) gbuf_rptr(ccb_mp), sizeof(CCB));
        !            65:     gbuf_wset(ccb_mp,sizeof(CCB));
        !            66:     gref->info = (caddr_t) ccb_mp;
        !            67:     sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
        !            68: 
        !            69:     sp->pid = gref->pid; /* save the caller process pointer */
        !            70:     sp->gref = gref;           /* save a back pointer to the WRITE queue */
        !            71:     sp->sp_mp = ccb_mp;                /* and its message block */
        !            72:     ATLOCKINIT(sp->lock);
        !            73:     ATLOCKINIT(sp->lockClose);
        !            74:     ATLOCKINIT(sp->lockRemove);
        !            75:     return 1;
        !            76: }
        !            77: 
        !            78: adspRelease(gref)
        !            79:     register gref_t *gref;     /* READ queue */
        !            80: {
        !            81:     register CCBPtr sp;
        !            82:     int s, l;
        !            83: 
        !            84:     ATDISABLE(l, adspgen_lock);
        !            85:     if (gref->info) {
        !            86:        sp = (CCBPtr)gbuf_rptr(((gbuf_t *)gref->info));
        !            87:        ATDISABLE(s, sp->lock);
        !            88:        ATENABLE(s, adspgen_lock);
        !            89:                                /* Tells completion routine of close */
        !            90:                                /* packet to remove us. */
        !            91: 
        !            92:        if (sp->state == sPassive || sp->state == sClosed || 
        !            93:            sp->state == sOpening || sp->state == sListening) {
        !            94:            ATENABLE(l, sp->lock);
        !            95:            if (sp->state == sListening)
        !            96:                CompleteQueue(&sp->opb, errAborted);
        !            97:            sp->removing = 1;   /* Prevent allowing another dspClose. */
        !            98:            DoClose(sp, errAborted, 0); /* will remove CCB */
        !            99:            return 0;
        !           100:        } else {                        /* sClosing & sOpen */
        !           101:            sp->state = sClosing;
        !           102:        }
        !           103:        ATENABLE(l, sp->lock);
        !           104: 
        !           105:        if (CheckOkToClose(sp)) { /* going to close */
        !           106:            sp->sendCtl = B_CTL_CLOSE; /* Send close advice */
        !           107:        } else {
        !           108:                CheckSend(sp);  /* try one more time to send out data */
        !           109:                if (sp->state != sClosed)
        !           110:                    sp->sendCtl = B_CTL_CLOSE; /* Setup to send close advice */
        !           111:        }
        !           112:        CheckSend(sp);          /* and force out the close */
        !           113:        ATDISABLE(s, sp->lock);
        !           114:            sp->removing = 1;   /* Prevent allowing another dspClose. */
        !           115:            sp->state = sClosed;
        !           116:        ATENABLE(s, sp->lock);
        !           117:            DoClose(sp, errAborted, 0);  /* to closed and remove CCB */
        !           118:     } else
        !           119:        ATENABLE(l, adspgen_lock);
        !           120: }
        !           121: 
        !           122: 
        !           123: 
        !           124: 
        !           125: adspWriteHandler(gref, mp)
        !           126:     gref_t *gref;                      /* WRITE queue */
        !           127:     gbuf_t *mp;
        !           128: {
        !           129: 
        !           130:     register ioc_t *iocbp;
        !           131:     register struct adspcmd *ap;
        !           132:     int error, flag;
        !           133:        void *sp;
        !           134: 
        !           135:     switch(gbuf_type(mp)) {
        !           136:     case MSG_DATA:
        !           137:        if (gref->info == 0) {
        !           138:            gbuf_freem(mp);
        !           139:            return(STR_IGNORE);
        !           140:         }
        !           141:        /*
        !           142:         * Fill in the global stuff
        !           143:         */
        !           144:        ap = (struct adspcmd *)gbuf_rptr(mp);
        !           145:        ap->gref = gref;
        !           146:        ap->ioc = 0;
        !           147:        ap->mp = mp;
        !           148:        sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
        !           149:        switch(ap->csCode) {
        !           150:        case dspWrite:
        !           151:            if ((error = adspWrite(sp, ap)))
        !           152:                gbuf_freem(mp);
        !           153:            return(STR_IGNORE);
        !           154:        case dspAttention:
        !           155:            if ((error = adspAttention(sp, ap)))
        !           156:                gbuf_freem(mp);
        !           157:            return(STR_IGNORE);
        !           158:        }
        !           159:     case MSG_IOCTL:
        !           160:        if (gref->info == 0) {
        !           161:            adspioc_ack(EPROTO, mp, gref);
        !           162:            return(STR_IGNORE);
        !           163:         }
        !           164:        iocbp = (ioc_t *) gbuf_rptr(mp);
        !           165:        if (ADSP_IOCTL(iocbp->ioc_cmd)) {
        !           166:            iocbp->ioc_count = sizeof(*ap) - 1;
        !           167:            if (gbuf_cont(mp) == 0) {
        !           168:                adspioc_ack(EINVAL, mp, gref);
        !           169:                return(STR_IGNORE);
        !           170:            }
        !           171:            ap = (struct adspcmd *) gbuf_rptr(gbuf_cont(mp));
        !           172:            ap->gref = gref;
        !           173:            ap->ioc = (caddr_t) mp;
        !           174:            ap->mp = gbuf_cont(mp); /* request head */
        !           175:            ap->ioResult = 0;
        !           176: 
        !           177:            if ((gref->info == 0) && ((iocbp->ioc_cmd != ADSPOPEN) &&
        !           178:                                    (iocbp->ioc_cmd != ADSPCLLISTEN))) {
        !           179:                ap->ioResult = errState;
        !           180: 
        !           181:                adspioc_ack(EINVAL, mp, gref);
        !           182:                return(STR_IGNORE);
        !           183:            }
        !           184:        }       
        !           185:        sp = (void *)gbuf_rptr(((gbuf_t *)gref->info));
        !           186:        switch(iocbp->ioc_cmd) {
        !           187:        case ADSPOPEN:
        !           188:        case ADSPCLLISTEN:
        !           189:                ap->socket = ((CCBPtr)sp)->localSocket;
        !           190:                flag = (adspMode(ap) == ocAccept) ? 1 : 0;
        !           191:                if (flag && ap->socket) {
        !           192:                        if (adspDeassignSocket((CCBPtr)sp) >= 0)
        !           193:                                ap->socket = 0;
        !           194:                }
        !           195:                if ((ap->socket == 0) &&
        !           196:                        ((ap->socket = (at_socket)adspAssignSocket(gref, flag)) == 0)) {
        !           197:                    adspioc_ack(EADDRNOTAVAIL, mp, gref);
        !           198:                return(STR_IGNORE);
        !           199:                }
        !           200:            ap->csCode = iocbp->ioc_cmd == ADSPOPEN ? dspInit : dspCLInit;
        !           201:            if ((error = adspInit(sp, ap)) == 0) {
        !           202:                switch(ap->csCode) {
        !           203:                case dspInit:
        !           204:                    /* and open the connection */
        !           205:                    ap->csCode = dspOpen;
        !           206:                    error = adspOpen(sp, ap);
        !           207:                    break;
        !           208:                case dspCLInit:
        !           209:                    /* ADSPCLLISTEN */
        !           210:                    ap->csCode = dspCLListen;
        !           211:                    error = adspCLListen(sp, ap);
        !           212:                    break;
        !           213:                }
        !           214:            }
        !           215:            if (error) 
        !           216:                adspioc_ack(error, mp, gref); /* if this failed req complete */
        !           217:            return(STR_IGNORE);
        !           218:        case ADSPCLOSE:
        !           219:            ap->csCode = dspClose;
        !           220:            if ((error = adspClose(sp, ap))) {
        !           221:                adspioc_ack(error, mp, gref);
        !           222:                break;
        !           223:            }
        !           224:            break;
        !           225:        case ADSPCLREMOVE:
        !           226:            ap->csCode = dspCLRemove;
        !           227:            error = adspClose(sp, ap);
        !           228:            adspioc_ack(error, mp, gref);
        !           229:            return(STR_IGNORE);
        !           230:        case ADSPCLDENY:
        !           231:            ap->csCode = dspCLDeny;
        !           232:            if ((error = adspCLDeny(sp, ap))) {
        !           233:                adspioc_ack(error, mp, gref);
        !           234:            }
        !           235:            return(STR_IGNORE);
        !           236:        case ADSPSTATUS:
        !           237:            ap->csCode = dspStatus;
        !           238:            if ((error = adspStatus(sp, ap))) {
        !           239:                adspioc_ack(error, mp, gref);
        !           240:            }
        !           241:            return(STR_IGNORE);
        !           242:        case ADSPREAD:
        !           243:            ap->csCode = dspRead;
        !           244:            if ((error = adspRead(sp, ap))) {
        !           245:                adspioc_ack(error, mp, gref);
        !           246:            }
        !           247:            return(STR_IGNORE);
        !           248:        case ADSPATTENTION:
        !           249:            ap->csCode = dspAttention;
        !           250:            if ((error = adspReadAttention(sp, ap))) {
        !           251:                adspioc_ack(error, mp, gref);
        !           252:            }
        !           253:            return(STR_IGNORE);
        !           254:        case ADSPOPTIONS:
        !           255:            ap->csCode = dspOptions;
        !           256:            if ((error = adspOptions(sp, ap))) {
        !           257:                adspioc_ack(error, mp, gref);
        !           258:            }
        !           259:            return(STR_IGNORE);
        !           260:        case ADSPRESET:
        !           261:            ap->csCode = dspReset;
        !           262:            if ((error = adspReset(sp, ap))) {
        !           263:                adspioc_ack(error, mp, gref);
        !           264:            }
        !           265:            return(STR_IGNORE);
        !           266:        case ADSPNEWCID:
        !           267:            ap->csCode = dspNewCID;
        !           268:            if ((error = adspNewCID(sp, ap))) {
        !           269:                adspioc_ack(error, mp, gref);
        !           270:            }
        !           271:            return(STR_IGNORE);
        !           272:        default:
        !           273:            return(STR_PUTNEXT);        /* pass it on down */
        !           274:        }
        !           275:        return(STR_IGNORE);
        !           276:     case MSG_PROTO:
        !           277:     default:
        !           278:        gbuf_freem(mp);
        !           279:     }
        !           280: }
        !           281: 
        !           282: 
        !           283: adspReadHandler(gref, mp)
        !           284:     gref_t *gref;
        !           285:     gbuf_t *mp;
        !           286: {
        !           287:     int error;
        !           288: 
        !           289:     switch(gbuf_type(mp)) {
        !           290:     case MSG_DATA:
        !           291:        if ((error = adspPacket(gref, mp))) {
        !           292:            gbuf_freem(mp);
        !           293:        }
        !           294:        break;
        !           295:        
        !           296:     case MSG_IOCTL:
        !           297:     default:
        !           298:        return(STR_PUTNEXT);
        !           299:        break;
        !           300:     }
        !           301:     return(STR_IGNORE);
        !           302: }
        !           303: 
        !           304: /*
        !           305:  * adsp_sendddp()
        !           306:  *
        !           307:  * Description:
        !           308:  *      This procedure a formats a DDP datagram header and calls the
        !           309:  *      DDP module to queue it for routing and transmission according to
        !           310:  *      the DDP parameters.  We always take control of the datagram;
        !           311:  *      if there is an error we free it, otherwise we pass it to the next
        !           312:  *      layer.  We don't need to set the src address fileds because the
        !           313:  *      DDP layer fills these in for us.
        !           314:  *
        !           315:  * Calling Sequence:
        !           316:  *      ret_status = adsp_sendddp(q, sp, mp, length, dstnetaddr, ddptype);
        !           317:  *
        !           318:  * Formal Parameters:
        !           319:  *     sp              Caller stream pointer
        !           320:  *      mp              gbuf_t chain containing the datagram to transmit
        !           321:  *                     The first mblk contains the ADSP header and space
        !           322:  *                     for the DDP header.
        !           323:  *      length          size of data portion of datagram
        !           324:  *      dstnetaddr      address of 4-byte destination internet address
        !           325:  *      ddptype         DDP protocol to assign to the datagram
        !           326:  *
        !           327:  * Completion Status:
        !           328:  *      0               Procedure successful completed.
        !           329:  *      EMSGSIZE        Specified datagram length is too big.
        !           330:  *
        !           331:  * Side Effects:
        !           332:  *      NONE
        !           333:  */
        !           334: 
        !           335: adsp_sendddp(sp, mp, length, dstnetaddr, ddptype)
        !           336:    CCBPtr sp;
        !           337:    gbuf_t *mp;
        !           338:    int length;
        !           339:    AddrUnion *dstnetaddr;
        !           340:    int ddptype;
        !           341: {
        !           342:    DDPX_FRAME   *ddp;
        !           343:    gbuf_t *mlist = mp;
        !           344: 
        !           345:    if (mp == 0)
        !           346:        return EINVAL;
        !           347: 
        !           348:    if (length > DDP_DATA_SIZE) {
        !           349:        gbuf_freel(mlist);
        !           350:        return EMSGSIZE;
        !           351:    }
        !           352: 
        !           353:   while (mp) {
        !           354: 
        !           355:    if (length == 0)
        !           356:        length = gbuf_msgsize(mp) - DDPL_FRAME_LEN;
        !           357:    /* Set up the DDP header */
        !           358: 
        !           359:    ddp = (DDPX_FRAME *) gbuf_rptr(mp);
        !           360:    UAS_ASSIGN(ddp->ddpx_length, (length + DDPL_FRAME_LEN));
        !           361:    UAS_ASSIGN(ddp->ddpx_cksm, 0);
        !           362:    if (sp) {
        !           363:        if (sp->useCheckSum)
        !           364:           UAS_ASSIGN(ddp->ddpx_cksm, 1);
        !           365:    }
        !           366: 
        !           367:    NET_ASSIGN(ddp->ddpx_dnet, dstnetaddr->a.net);
        !           368:    ddp->ddpx_dnode = dstnetaddr->a.node;
        !           369:    ddp->ddpx_source = sp ? sp->localSocket : ddp->ddpx_dest;
        !           370:    ddp->ddpx_dest = dstnetaddr->a.socket;
        !           371: 
        !           372:    ddp->ddpx_type = ddptype;
        !           373:    length = 0;
        !           374:    mp = gbuf_next(mp);
        !           375: 
        !           376:   }
        !           377:           
        !           378:    DDP_OUTPUT(mlist);
        !           379:    return 0;
        !           380: }
        !           381: 
        !           382: void NotifyUser(sp)
        !           383:     register CCBPtr sp;
        !           384: 
        !           385: {
        !           386: /*
        !           387:     pidsig(sp->pid, SIGIO);
        !           388: */
        !           389: }
        !           390: 
        !           391: void UrgentUser(sp)
        !           392:     register CCBPtr sp;
        !           393: {
        !           394: /*
        !           395:     pidsig(sp->pid, SIGURG);
        !           396: */
        !           397: }

unix.superglobalmegacorp.com

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