Annotation of XNU/bsd/netat/adsp.c, revision 1.1.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.