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