Annotation of kernel/bsd/netat/adsp_stream.c, revision 1.1

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: }

unix.superglobalmegacorp.com

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