Annotation of kernel/bsd/netat/sys_glue.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 Apple Computer, Inc. 
        !            27:  *
        !            28:  *     The information contained herein is subject to change without
        !            29:  *     notice and  should not be  construed as a commitment by Apple
        !            30:  *     Computer, Inc. Apple Computer, Inc. assumes no responsibility
        !            31:  *     for any errors that may appear.
        !            32:  *
        !            33:  *     Confidential and Proprietary to Apple Computer, Inc.
        !            34:  *
        !            35:  */
        !            36: #ifdef _AIX
        !            37: #include <sys/sleep.h>
        !            38: #include <sys/poll.h>
        !            39: #endif
        !            40: #include <sys/ioccom.h>
        !            41: #include <h/sysglue.h>
        !            42: #include <at/appletalk.h>
        !            43: #include <at/elap.h>
        !            44: #include <at/ddp.h>
        !            45: #include <at/at_lap.h>
        !            46: #include <at_elap.h>
        !            47: #include <h/at_ddp.h>
        !            48: #undef e_sleep_thread
        !            49: 
        !            50: /*definition of dbgBits moved here to avoid multiple redefinition */
        !            51: dbgBits_t      dbgBits;
        !            52: 
        !            53: int _ATsocket(proto, err, proc)
        !            54:        int proto;
        !            55:        int *err;
        !            56:        void *proc;
        !            57: {
        !            58:        int fd;
        !            59:        gref_t *gref;
        !            60: 
        !            61:        /* make sure the specified protocol id is valid */
        !            62:        switch (proto) {
        !            63:        case ATPROTO_DDP:
        !            64:        case ATPROTO_LAP:
        !            65:        case ATPROTO_ATP:
        !            66:        case ATPROTO_ASP:
        !            67:        case ATPROTO_AURP:
        !            68:        case ATPROTO_ADSP:
        !            69:                break;
        !            70:        default:
        !            71:                *err = EPROTOTYPE;
        !            72: #ifdef APPLETALK_DEBUG
        !            73:                kprintf("_ATsocket: error EPROTOTYPE =%d\n", *err);
        !            74: #endif
        !            75:                return -1;
        !            76:        }
        !            77: 
        !            78:        /* allocate a protocol channel */
        !            79:        if ((*err = gref_open(&gref)) != 0) {
        !            80: #ifdef APPLETALK_DEBUG
        !            81:                kprintf("_ATsocket: error gref_open =%d\n", *err);
        !            82: #endif
        !            83:                return -1;
        !            84:        }
        !            85:        gref->proto = proto;
        !            86: #ifdef NEXT
        !            87:        gref->pid = ((struct proc *)proc)->p_pid;
        !            88: #endif
        !            89: 
        !            90:        /* open the specified protocol */
        !            91:        switch (gref->proto) {
        !            92:        case ATPROTO_DDP:
        !            93:                *err = ddp_open(gref); break;
        !            94:        case ATPROTO_LAP:
        !            95:                *err = lap_open(gref); break;
        !            96:        case ATPROTO_ATP:
        !            97:                *err = atp_open(gref, 1); break;
        !            98:        case ATPROTO_ASP:
        !            99:                *err = asp_open(gref); break;
        !           100: #ifdef AURP_SUPPORT
        !           101:        case ATPROTO_AURP:
        !           102:                *err = aurp_open(gref); break;
        !           103: #endif
        !           104:        case ATPROTO_ADSP:
        !           105:                *err = adsp_open(gref); break;
        !           106:        }
        !           107: 
        !           108:        /* create the descriptor for the channel */
        !           109:        if (*err)
        !           110:                gref->proto = ATPROTO_NONE;
        !           111:        if (*err || (*err = atalk_openref(gref, &fd, proc))) {
        !           112: #ifdef APPLETALK_DEBUG
        !           113:                kprintf("_ATsocket: error atalk_openref =%d\n", *err);
        !           114: #endif
        !           115:                gref_close(gref);
        !           116:                return -1;
        !           117:        }
        !           118: /*
        !           119:        kprintf("_ATsocket: proto=%d return=%d fd=%d\n", proto, *err, fd);
        !           120: */
        !           121:        return fd;
        !           122: }
        !           123: 
        !           124: int _ATgetmsg(fd, ctlptr, datptr, flags, err, proc)
        !           125:        int fd;
        !           126:        strbuf_t *ctlptr;
        !           127:        strbuf_t *datptr;
        !           128:        int *flags;
        !           129:        int *err;
        !           130:        void *proc;
        !           131: {
        !           132:        int rc = -1;
        !           133:        gref_t *gref;
        !           134: 
        !           135:        if ((*err = atalk_getref(0, fd, &gref, proc)) == 0) {
        !           136:                switch (gref->proto) {
        !           137:                case ATPROTO_ASP:
        !           138:                        rc = ASPgetmsg(gref, ctlptr, datptr, flags, err); break;
        !           139:                case ATPROTO_AURP:
        !           140: #ifdef AURP_SUPPORT
        !           141:                        rc = AURPgetmsg(err); break;
        !           142: #endif
        !           143:                default:
        !           144:                        *err = EPROTONOSUPPORT; break;
        !           145:                }
        !           146:        }
        !           147: 
        !           148: 
        !           149: /*     kprintf("_ATgetmsg: return=%d\n", *err);*/
        !           150:        return rc;
        !           151: }
        !           152: 
        !           153: int _ATputmsg(fd, ctlptr, datptr, flags, err, proc)
        !           154:        int fd;
        !           155:        strbuf_t *ctlptr;
        !           156:        strbuf_t *datptr;
        !           157:        int flags;
        !           158:        int *err;
        !           159:        void *proc;
        !           160: {
        !           161:        int rc = -1;
        !           162:        gref_t *gref;
        !           163: 
        !           164:        if ((*err = atalk_getref(0, fd, &gref, proc)) == 0) {
        !           165:                switch (gref->proto) {
        !           166:                case ATPROTO_ASP:
        !           167:                        rc = ASPputmsg(gref, ctlptr, datptr, flags, err); break;
        !           168:                default:
        !           169:                        *err = EPROTONOSUPPORT; break;
        !           170:                }
        !           171:        }
        !           172: 
        !           173: /*     kprintf("_ATputmsg: return=%d\n", *err); */
        !           174:        return rc;
        !           175: }
        !           176: 
        !           177: int _ATclose(fp, proc)
        !           178:        void *fp;
        !           179:        void *proc;
        !           180: {
        !           181:        int err;
        !           182:        gref_t *gref;
        !           183: 
        !           184:        if ((err = atalk_closeref(fp, &gref)) != 0)
        !           185:                return err;
        !           186: 
        !           187:        gref_close(gref);
        !           188:        return 0;
        !           189: }
        !           190: 
        !           191: int _ATrw(fp, rw, uio, ext)
        !           192:        void *fp;
        !           193:        enum uio_rw rw;
        !           194:        struct uio *uio;
        !           195:        int ext;
        !           196: {
        !           197:        void gref_wput();
        !           198:        int s, err, len, rlen, clen, res;
        !           199:        gref_t *gref;
        !           200:        gbuf_t *m, *mhead, *mprev;
        !           201: 
        !           202:        if ((err = atalk_getref(fp, 0, &gref, 0)) != 0)
        !           203:                return err;
        !           204: 
        !           205:        if ((len = uio->uio_resid) == 0)
        !           206:                return 0;
        !           207: 
        !           208:        ATDISABLE(s, gref->lock);
        !           209:        if (gref->errno) {
        !           210:                ATENABLE(s, gref->lock);
        !           211:                return (int)gref->errno;
        !           212:        }
        !           213: 
        !           214:   if (rw == UIO_READ) {
        !           215:        while ((gref->errno == 0) && ((mhead = gref->rdhead) == 0)) {
        !           216:                gref->sevents |= POLLMSG;
        !           217:                err = tsleep(&gref->event, PSOCK | PCATCH, "AT read", 0);
        !           218:                gref->sevents &= ~POLLMSG;
        !           219:                if (err != 0) {
        !           220:                        ATENABLE(s, gref->lock);
        !           221:                        return err;
        !           222:                }
        !           223:        }
        !           224: 
        !           225:        if (gref->errno) {
        !           226:                ATENABLE(s, gref->lock);
        !           227:                return EPIPE;
        !           228:        }
        !           229:        if ((gref->rdhead = gbuf_next(mhead)) == 0)
        !           230:                gref->rdtail = 0;
        !           231: 
        !           232:        ATENABLE(s, gref->lock);
        !           233: 
        !           234:        gbuf_next(mhead) = 0;
        !           235: 
        !           236:        for (mprev=0, m=mhead, rlen=0; m && len; rlen+=clen, len-=clen) {
        !           237:                if ((clen = gbuf_len(m)) > 0) {
        !           238:                        if (clen > len)
        !           239:                                clen = len;
        !           240: #ifdef _AIX
        !           241:                        if (uiomove((caddr_t)gbuf_rptr(m), clen, UIO_READ, uio) == -1)
        !           242:                                break;
        !           243: #else
        !           244:                        uio->uio_rw = UIO_READ;
        !           245:                        res= uiomove((caddr_t)gbuf_rptr(m), clen, uio);
        !           246:                        /* kprintf("_ATrw: UIO_READ: res=%d\n", res); */
        !           247:                        if (res == -1)
        !           248:                                break;
        !           249: #endif
        !           250:                        if (gbuf_len(m) > len) {
        !           251:                                gbuf_rinc(m,clen);
        !           252:                                break;
        !           253:                        }
        !           254:                }
        !           255:                mprev = m;
        !           256:                m = gbuf_cont(m);
        !           257:        }
        !           258:        if (m) {
        !           259:                if (mprev)
        !           260:                        gbuf_cont(mprev) = 0;
        !           261:                else
        !           262:                        mhead = 0;
        !           263:                ATDISABLE(s, gref->lock);
        !           264:                if (gref->rdhead == 0)
        !           265:                        gref->rdtail = m;
        !           266:                gbuf_next(m) = gref->rdhead;
        !           267:                gref->rdhead = m;
        !           268:                ATENABLE(s, gref->lock);
        !           269:        }
        !           270:        if (mhead)
        !           271:                gbuf_freem(mhead);
        !           272: 
        !           273:   } else {
        !           274:        if (gref->writeable) {
        !           275:                while (!(*gref->writeable)(gref)) {
        !           276:                        /* flow control on, wait to be enabled to write */ 
        !           277:                        gref->sevents |= POLLSYNC;
        !           278:                        err = tsleep(&gref->event, PSOCK | PCATCH, "AT write", 0);
        !           279:                        gref->sevents &= ~POLLSYNC;
        !           280:                        if (err != 0) {
        !           281:                                ATENABLE(s, gref->lock);
        !           282:                                return err;
        !           283:                        }
        !           284:                }
        !           285:        }
        !           286: 
        !           287:        ATENABLE(s, gref->lock);
        !           288: 
        !           289:        /* allocate a buffer to copy in the write data */
        !           290:        if ((m = gbuf_alloc(AT_WR_OFFSET+len, PRI_MED)) == 0)
        !           291:                return ENOBUFS;
        !           292:        gbuf_rinc(m,AT_WR_OFFSET);
        !           293:        gbuf_wset(m,len);
        !           294: 
        !           295:        /* copy in the write data */
        !           296: #ifdef _AIX
        !           297:        if (uiomove((caddr_t)gbuf_rptr(m), len, UIO_WRITE, uio) == -1) {
        !           298: #else
        !           299:        uio->uio_rw = UIO_WRITE;
        !           300:        res= uiomove((caddr_t)gbuf_rptr(m), len, uio);
        !           301:        /* kprintf("_ATrw: UIO_WRITE: res=%d\n", res); */
        !           302:        if (res == -1) {
        !           303: #endif
        !           304:                gbuf_freeb(m);
        !           305:                return EIO;
        !           306:        }
        !           307: 
        !           308:        /* forward the write data to the appropriate protocol module */
        !           309:        gref_wput(gref, m);
        !           310:   }
        !           311: 
        !           312:        return 0;
        !           313: }
        !           314: 
        !           315: int _ATread(fp, uio, cred)
        !           316:        void *fp;
        !           317:        struct uio *uio;
        !           318:        void *cred;
        !           319: {
        !           320:        return _ATrw(fp, UIO_READ, uio, 0);
        !           321: }
        !           322: 
        !           323: int _ATwrite(fp, uio, cred)
        !           324:        void *fp;
        !           325:        struct uio *uio;
        !           326:        void *cred;
        !           327: {
        !           328:        return _ATrw(fp, UIO_WRITE, uio, 0);
        !           329: }
        !           330: /*
        !           331: struct at_ioctl_args {
        !           332:        int fdes;
        !           333:        u_long cmd;
        !           334:        caddr_t arg;
        !           335: };
        !           336: int _ATioctl(p, uap, retval)
        !           337:        struct proc *p;
        !           338:        register struct at_ioctl_args *uap;
        !           339:        register_t *retval;
        !           340: */
        !           341: int _ATioctl(fp, cmd, arg, proc)
        !           342:        void *fp;
        !           343:        u_long cmd;
        !           344:        register caddr_t arg;
        !           345:        void *proc;
        !           346: {
        !           347:        void gref_wput();
        !           348:        int s, err, len;
        !           349:        gref_t *gref;
        !           350:        gbuf_t *m, *mdata;
        !           351:        ioc_t *ioc;
        !           352:        ioccmd_t ioccmd;
        !           353: 
        !           354: 
        !           355:        if ((err = atalk_getref(fp, 0, &gref, 0)) != 0) {
        !           356: #ifdef APPLETALK_DEBUG
        !           357:                kprintf("_ATioctl: atalk_getref=%d\n", err);
        !           358: #endif
        !           359:                return err;
        !           360:        }
        !           361: 
        !           362:        /* error if not for us */
        !           363:        if ((cmd  & 0xffff) != 0xff99)
        !           364:                return EOPNOTSUPP;
        !           365: 
        !           366:        /* copy in ioc command info */
        !           367: /*
        !           368:        kprintf("_ATioctl: arg ioccmd.ic_cmd=%x ic_len=%x gref->lock=%x, gref->event=%x\n",
        !           369:                ((ioccmd_t *)arg)->ic_cmd, ((ioccmd_t *)arg)->ic_len, gref->lock, gref->event);
        !           370: */
        !           371:        if ((err = copyin((caddr_t)arg,
        !           372:                        (caddr_t)&ioccmd, sizeof(ioccmd_t))) != 0) { 
        !           373: #ifdef APPLETALK_DEBUG
        !           374:          kprintf("_ATioctl: err = %d, copyin(%x, %x, %d)\n", err, (caddr_t)arg,
        !           375:                  (caddr_t)&ioccmd, sizeof(ioccmd_t));
        !           376: #endif
        !           377:                return err;
        !           378:        } 
        !           379: 
        !           380:        /* allocate a buffer to create an ioc command */
        !           381:        if ((m = gbuf_alloc(sizeof(ioc_t), PRI_HI)) == 0)
        !           382:                return ENOBUFS;
        !           383:        gbuf_wset(m,sizeof(ioc_t));
        !           384:        gbuf_set_type(m, MSG_IOCTL);
        !           385: 
        !           386:        /* create the ioc command */
        !           387:        if (ioccmd.ic_len) {
        !           388:                if ((gbuf_cont(m) = gbuf_alloc(ioccmd.ic_len, PRI_HI)) == 0) {
        !           389:                        gbuf_freem(m);
        !           390: #ifdef APPLETALK_DEBUG
        !           391:                        kprintf("_ATioctl: gbuf_alloc err=%d\n",ENOBUFS);
        !           392: #endif
        !           393:                        return ENOBUFS;
        !           394:                }
        !           395:                gbuf_wset(gbuf_cont(m),ioccmd.ic_len);
        !           396:                if ((err = copyin((caddr_t)ioccmd.ic_dp,
        !           397:                                (caddr_t)gbuf_rptr(gbuf_cont(m)), ioccmd.ic_len)) != 0) { 
        !           398:                        gbuf_freem(m);
        !           399:                        return err;
        !           400:                }
        !           401:        }
        !           402:        ioc = (ioc_t *)gbuf_rptr(m);
        !           403:        ioc->ioc_cmd = ioccmd.ic_cmd;
        !           404:        ioc->ioc_count = ioccmd.ic_len;
        !           405:        ioc->ioc_error = 0;
        !           406:        ioc->ioc_rval = 0;
        !           407: 
        !           408:        /* send the ioc command to the appropriate recipient */
        !           409:        gref_wput(gref, m);
        !           410: 
        !           411:        /* wait for the ioc ack */
        !           412:        ATDISABLE(s, gref->lock);
        !           413:        while ((m = gref->ichead) == 0) {
        !           414:                gref->sevents |= POLLPRI;
        !           415:                err = tsleep(&gref->iocevent, PSOCK | PCATCH, "AT ioctl", 0);
        !           416:                gref->sevents &= ~POLLPRI;
        !           417:                if (err != 0) {
        !           418:                        ATENABLE(s, gref->lock);
        !           419: #ifdef APPLETALK_DEBUG
        !           420:                        kprintf("_ATioctl: EINTR\n");
        !           421: #endif
        !           422:                        return err;
        !           423:                }
        !           424:        }
        !           425: 
        !           426: /* PR-2224797 */
        !           427:        if (gbuf_next(m) == m)          /* error case */
        !           428:                gbuf_next(m) = 0; 
        !           429: 
        !           430:        gref->ichead = gbuf_next(m);
        !           431: 
        !           432:        ATENABLE(s, gref->lock);
        !           433: 
        !           434: 
        !           435: /*     kprintf("_ATioctl: woke up from tread sleep\n"); */
        !           436:        /* process the ioc response */
        !           437:        ioc = (ioc_t *)gbuf_rptr(m);
        !           438:        if ((err = ioc->ioc_error) == 0) {
        !           439:                ioccmd.ic_timout = ioc->ioc_rval;
        !           440:                ioccmd.ic_len = 0;
        !           441:                mdata = gbuf_cont(m);
        !           442:                if (mdata && ioccmd.ic_dp) {
        !           443:                        ioccmd.ic_len = gbuf_msgsize(mdata);
        !           444:                  for (len=0; mdata; mdata=gbuf_cont(mdata)) {
        !           445:                        if ((err = copyout((caddr_t)gbuf_rptr(mdata),
        !           446:                                        (caddr_t)&ioccmd.ic_dp[len], gbuf_len(mdata))) < 0) {
        !           447: #ifdef APPLETALK_DEBUG
        !           448:                                kprintf("_ATioctl: len=%d error copyout=%d from=%x to=%x gbuf_len=%x\n",
        !           449:                                         len, err, (caddr_t)gbuf_rptr(mdata), 
        !           450:                                         (caddr_t)&ioccmd.ic_dp[len], gbuf_len(mdata));
        !           451: #endif
        !           452:                                goto l_done;
        !           453:                        }
        !           454:                        len += gbuf_len(mdata);
        !           455:                  }
        !           456:                }
        !           457:                if ((err = copyout((caddr_t)&ioccmd,
        !           458:                                (caddr_t)arg, sizeof(ioccmd_t))) != 0) {
        !           459: #ifdef APPLETALK_DEBUG
        !           460:                                kprintf("_ATioctl: error copyout2=%d from=%x to=%x len=%d\n",
        !           461:                                         err, &ioccmd, arg, sizeof(ioccmd_t));
        !           462: #endif
        !           463:                        goto l_done;
        !           464:                }
        !           465:        }
        !           466: 
        !           467: l_done:
        !           468:        gbuf_freem(m);
        !           469:        /*kprintf("_ATioctl: I_done=%d\n", err);*/
        !           470:        return err;
        !           471: }
        !           472: 
        !           473: #ifndef _AIX
        !           474: int _ATselect(fp, which, proc)
        !           475:        void *fp;
        !           476:        int which;
        !           477:        void *proc;
        !           478: {
        !           479:        int s, err, rc = 0;
        !           480:        gref_t *gref;
        !           481: 
        !           482:        if ((err = atalk_getref(fp, 0, &gref, 0)) != 0)
        !           483:                return err;
        !           484: 
        !           485:        ATDISABLE(s, gref->lock);
        !           486:        if (which == FREAD) {
        !           487:                if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
        !           488:                        rc = 1;
        !           489:                else {
        !           490:                        gref->sevents |= POLLIN;
        !           491:                        selrecord(proc, &gref->si);
        !           492:                }
        !           493:        }
        !           494: 
        !           495:        else if (which == POLLOUT) {
        !           496:                if (gref->writeable) {
        !           497:                        if ((*gref->writeable)(gref))
        !           498:                                rc = 1;
        !           499:                        else {
        !           500:                                gref->sevents |= POLLOUT;
        !           501:                                selrecord(proc, &gref->si);
        !           502:                        }
        !           503:                } else
        !           504:                        rc = 1;
        !           505:        }
        !           506:        ATENABLE(s, gref->lock);
        !           507: 
        !           508:        return rc;
        !           509: }
        !           510: 
        !           511: #else  /* AIX code is no longer supported. */
        !           512: 
        !           513: int _ATselect(fp, corl, reqevents, retevents, notify)
        !           514:        void *fp;
        !           515:        int corl;
        !           516:        unsigned short reqevents;
        !           517:        unsigned short *retevents;
        !           518:        void (*notify)();
        !           519: {
        !           520:        int s, err, rc = 0;
        !           521:        gref_t *gref;
        !           522:        unsigned short sevents = 0;
        !           523: 
        !           524:        if ((err = atalk_getref(fp, 0, &gref, 0)) != 0)
        !           525:                return err;
        !           526: 
        !           527:        ATDISABLE(s, gref->lock);
        !           528:        if (reqevents & POLLIN) {
        !           529:                if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
        !           530:                        sevents |= POLLIN;
        !           531:        }
        !           532: 
        !           533:        if (reqevents & POLLOUT) {
        !           534:                if (gref->writeable) {
        !           535:                        if ((*gref->writeable)(gref))
        !           536:                                sevents |= POLLOUT;
        !           537:                } else
        !           538:                        sevents |= POLLOUT;
        !           539:        }
        !           540: 
        !           541:        if ((sevents == 0) && ((reqevents & POLLSYNC) == 0)) {
        !           542:                if (rc = selreg(corl, 99, gref, reqevents, notify)) {
        !           543:                        ATENABLE(s, gref->lock);
        !           544:                        goto l_done;
        !           545:                }
        !           546: 
        !           547:           if (reqevents & POLLIN) {
        !           548:                        if (gref->rdhead || (gref->readable && (*gref->readable)(gref)))
        !           549:                                sevents |= POLLIN;
        !           550:                        else
        !           551:                                gref->sevents |= POLLIN;
        !           552:           }
        !           553: 
        !           554:           if (reqevents & POLLOUT) {
        !           555:                        if (gref->writeable) {
        !           556:                                if ((*gref->writeable)(gref))
        !           557:                                        sevents |= POLLOUT;
        !           558:                                else
        !           559:                                        gref->sevents |= POLLOUT;
        !           560:                        } else
        !           561:                                sevents |= POLLOUT;
        !           562:           }
        !           563:      }
        !           564:        ATENABLE(s, gref->lock);
        !           565:      *retevents = sevents;
        !           566: 
        !           567: l_done:
        !           568:        return rc;
        !           569: }
        !           570: 
        !           571: int _ATstat()
        !           572: {
        !           573:        return 0;
        !           574: }
        !           575: #endif  /* end AIX section */
        !           576: 
        !           577: void atalk_putnext(gref, m)
        !           578:        gref_t *gref;
        !           579:        gbuf_t *m;
        !           580: {
        !           581:        int s;
        !           582: 
        !           583:        ATDISABLE(s, gref->lock);
        !           584: 
        !           585:        gbuf_next(m) = 0;
        !           586: 
        !           587:        if ((gbuf_type(m) == MSG_IOCACK) || (gbuf_type(m) == MSG_IOCNAK)) {
        !           588:                if (gref->ichead)
        !           589:                        gbuf_next(gref->ichead) = m;
        !           590:                else {
        !           591:                        gref->ichead = m;
        !           592:                        if (gref->sevents & POLLPRI) {
        !           593:                                /*kprintf("atalk_putnext: wake up gref->event=%x\n", &gref->event);*/
        !           594:                                thread_wakeup(&gref->iocevent);
        !           595:                        }
        !           596:                        atalk_notify_sel(gref);
        !           597:                }
        !           598: 
        !           599:        } else {
        !           600:          if (gref->errno == 0) {
        !           601:                if (gbuf_type(m) == MSG_ERROR) {
        !           602:                        gref->errno = *gbuf_rptr(m);
        !           603:                        if (gref->rdhead) {
        !           604:                                gbuf_freel(gref->rdhead);
        !           605:                                gref->rdhead = 0;
        !           606:                        }
        !           607:                        if (gref->sevents & POLLMSG) {
        !           608:                                gref->sevents &= ~POLLMSG;
        !           609:                                /*kprintf("atalk_putnext: wake up gref->event=%x\n", &gref->event);*/
        !           610:                                thread_wakeup(&gref->event);
        !           611:                        }
        !           612:                        if (gref->sevents & POLLIN) {
        !           613:                                gref->sevents &= ~POLLIN;
        !           614:                                /*kprintf("atalk_putnext: selwakeup gref->si=%x\n", &gref->si); */
        !           615:                                selwakeup(&gref->si);
        !           616:                        }
        !           617:                } else if (gref->rdhead) {
        !           618:                        gbuf_next(gref->rdtail) = m;
        !           619:                        gref->rdtail = m;
        !           620:                } else {
        !           621:                        gref->rdhead = m;
        !           622:                        if (gref->sevents & POLLMSG) {
        !           623:                                gref->sevents &= ~POLLMSG;
        !           624:                                /*kprintf("atalk_putnext: wake up2 gref->event=%x\n", &gref->event);*/
        !           625:                                thread_wakeup(&gref->event);
        !           626:                        }
        !           627:                        if (gref->sevents & POLLIN) {
        !           628:                                gref->sevents &= ~POLLIN;
        !           629:                                /*kprintf("atalk_putnext: selwakeup2 gref->si=%x\n", &gref->si);*/
        !           630:                                selwakeup(&gref->si);
        !           631:                        }
        !           632:                        gref->rdtail = m;
        !           633:                }
        !           634:          }
        !           635:        }
        !           636: 
        !           637:        ATENABLE(s, gref->lock);
        !           638: }
        !           639: 
        !           640: void atalk_enablew(gref)
        !           641:        gref_t *gref;
        !           642: {
        !           643:        if (gref->sevents & POLLSYNC)
        !           644: #ifdef _AIX
        !           645:                e_wakeup(&gref->event);
        !           646: #else
        !           647:                thread_wakeup(&gref->event);
        !           648: #endif
        !           649: }
        !           650: 
        !           651: void atalk_flush(gref)
        !           652:        gref_t *gref;
        !           653: {
        !           654:        int s;
        !           655: 
        !           656:        ATDISABLE(s, gref->lock);
        !           657:        if (gref->rdhead) {
        !           658:                gbuf_freel(gref->rdhead);
        !           659:                gref->rdhead = 0;
        !           660:        }
        !           661:        if (gref->ichead) {
        !           662:                gbuf_freel(gref->ichead);
        !           663:                gref->ichead = 0;
        !           664:        }
        !           665:        ATENABLE(s, gref->lock);
        !           666: }
        !           667: 
        !           668: void atalk_notify_sel(gref)
        !           669:        gref_t *gref;
        !           670: {
        !           671:        int s;
        !           672: 
        !           673:        ATDISABLE(s, gref->lock);
        !           674:        if (gref->sevents & POLLIN) {
        !           675:                gref->sevents &= ~POLLIN;
        !           676:                selwakeup(&gref->si);
        !           677:        }
        !           678:        ATENABLE(s, gref->lock);
        !           679: }
        !           680: 
        !           681: int atalk_peek(gref, event)
        !           682:        gref_t *gref;
        !           683:        unsigned char *event;
        !           684: {
        !           685:        int s, rc;
        !           686: 
        !           687:        ATDISABLE(s, gref->lock);
        !           688:        if (gref->rdhead) {
        !           689:                *event = *gbuf_rptr(gref->rdhead);
        !           690:                rc = 0;
        !           691:        } else
        !           692:                rc = -1;
        !           693:        ATENABLE(s, gref->lock);
        !           694: 
        !           695:        return rc;
        !           696: }
        !           697: 
        !           698: static gbuf_t *trace_msg;
        !           699: 
        !           700: void atalk_settrace(str, p1, p2, p3, p4, p5)
        !           701:        char *str;
        !           702: {
        !           703:        int len;
        !           704:        gbuf_t *m, *nextm;
        !           705:        char trace_buf[256];
        !           706: 
        !           707:        sprintf(trace_buf, str, p1, p2, p3, p4, p5);
        !           708:        len = strlen(trace_buf);
        !           709: #ifdef APPLETALK_DEBUG
        !           710:        kprintf("atalk_settrace: gbufalloc size=%d\n", len+1);
        !           711: #endif
        !           712:        if ((m = gbuf_alloc(len+1, PRI_MED)) == 0)
        !           713:                return;
        !           714:        gbuf_wset(m,len);
        !           715:        strcpy(gbuf_rptr(m), trace_buf);
        !           716:        if (trace_msg) {
        !           717:                for (nextm=trace_msg; gbuf_cont(nextm); nextm=gbuf_cont(nextm)) ;
        !           718:                gbuf_cont(nextm) = m;
        !           719:        } else
        !           720:                trace_msg = m;
        !           721: }
        !           722: 
        !           723: void atalk_gettrace(m)
        !           724:        gbuf_t *m;
        !           725: {
        !           726:        if (trace_msg) {
        !           727:                gbuf_cont(m) = trace_msg;
        !           728:                trace_msg = 0;
        !           729:        }
        !           730: }
        !           731: 
        !           732: #define GREF_PER_BLK 32
        !           733: static gref_t *gref_free_list = 0;
        !           734: atlock_t refall_lock;
        !           735: 
        !           736: void gref_init()
        !           737: {
        !           738:        ATLOCKINIT(refall_lock);
        !           739: }
        !           740: 
        !           741: gref_t *gref_alloc()
        !           742: {
        !           743:        extern gbuf_t *atp_resource_m;
        !           744:        int i, s;
        !           745:        gbuf_t *m;
        !           746:        gref_t *gref, *gref_array;
        !           747: 
        !           748:        ATDISABLE(s, refall_lock);
        !           749:        if (gref_free_list == 0) {
        !           750:                ATENABLE(s, refall_lock);
        !           751: #ifdef APPLETALK_DEBUG
        !           752:                kprintf("gref_alloc: gbufalloc size=%d\n", GREF_PER_BLK*sizeof(gref_t));
        !           753: #endif
        !           754:                if ((m = gbuf_alloc(GREF_PER_BLK*sizeof(gref_t),PRI_HI)) == 0)
        !           755:                        return (gref_t *)0;
        !           756:                bzero(gbuf_rptr(m), GREF_PER_BLK*sizeof(gref_t));
        !           757:                gref_array = (gref_t *)gbuf_rptr(m);
        !           758:                for (i=0; i < GREF_PER_BLK-1; i++)
        !           759:                        gref_array[i].next = (gref_t *)&gref_array[i+1];
        !           760:                ATDISABLE(s, refall_lock);
        !           761:                gbuf_cont(m) = atp_resource_m;
        !           762:                atp_resource_m = m;
        !           763:                gref_array[i].next = gref_free_list;
        !           764:                gref_free_list = (gref_t *)&gref_array[0];
        !           765:        }
        !           766: 
        !           767:        gref = gref_free_list;
        !           768:        gref_free_list = gref->next;
        !           769:        ATENABLE(s, refall_lock);
        !           770:        ATLOCKINIT(gref->lock);
        !           771:        ATEVENTINIT(gref->event);
        !           772:        ATEVENTINIT(gref->iocevent);
        !           773: 
        !           774:        return gref;
        !           775: }
        !           776: 
        !           777: void gref_free(gref)
        !           778:        gref_t *gref;
        !           779: {
        !           780:        int s;
        !           781: 
        !           782:        ATDISABLE(s, refall_lock);
        !           783:        bzero((char *)gref, sizeof(gref_t));
        !           784:        gref->next = gref_free_list;
        !           785:        gref_free_list = gref;
        !           786:        ATENABLE(s, refall_lock);
        !           787: }
        !           788: 
        !           789: int gref_open(grefp)
        !           790:        gref_t **grefp;
        !           791: {
        !           792:        gref_t *gref;
        !           793: 
        !           794:        /*
        !           795:         * if no gref structure available, return failure
        !           796:         */
        !           797:        if ((gref = (gref_t *)gref_alloc()) == 0)
        !           798:                return ENOBUFS;
        !           799: #ifndef NEXT
        !           800:        gref->pid = getpid();
        !           801: #endif
        !           802:        *grefp = gref;
        !           803: 
        !           804:        return 0;
        !           805: }
        !           806: 
        !           807: int gref_close(gref)
        !           808:        gref_t *gref;
        !           809: {
        !           810:        int rc;
        !           811: 
        !           812:        switch (gref->proto) {
        !           813:        case ATPROTO_DDP:
        !           814:                rc = ddp_close(gref); break;
        !           815:        case ATPROTO_LAP:
        !           816:                rc = lap_close(gref); break;
        !           817:        case ATPROTO_ATP:
        !           818:                rc = atp_close(gref, 1); break;
        !           819:        case ATPROTO_ASP:
        !           820:                rc = asp_close(gref); break;
        !           821: #ifdef AURP_SUPPORT
        !           822:        case ATPROTO_AURP:
        !           823:                rc = aurp_close(gref); break;
        !           824:                break;
        !           825: #endif
        !           826:        case ATPROTO_ADSP:
        !           827:                rc = adsp_close(gref); break;
        !           828:        default:
        !           829:                rc = 0;
        !           830:                break;
        !           831:        }
        !           832: 
        !           833:        if (rc == 0) {
        !           834:                atalk_flush(gref);
        !           835:                selthreadclear(&gref->si);
        !           836:                gref_free(gref);
        !           837:        }
        !           838: 
        !           839:        return rc;
        !           840: }
        !           841: 
        !           842: void gref_wput(gref, m)
        !           843:        gref_t *gref;
        !           844:        gbuf_t *m;
        !           845: {
        !           846: 
        !           847:        switch (gref->proto) {
        !           848:        case ATPROTO_DDP:
        !           849:                ddp_putmsg(gref, m); break;
        !           850:        case ATPROTO_LAP:
        !           851:                elap_wput(gref, m); break;
        !           852:        case ATPROTO_ATP:
        !           853:                atp_wput(gref, m); break;
        !           854:        case ATPROTO_ASP:
        !           855:                asp_wput(gref, m); break;
        !           856: #ifdef AURP_SUPPORT
        !           857:        case ATPROTO_AURP:
        !           858:                aurp_wput(gref, m); break;
        !           859: #endif
        !           860:        case ATPROTO_ADSP:
        !           861:                adsp_wput(gref, m); break;
        !           862:        case ATPROTO_NONE:
        !           863:                if (gbuf_type(m) == MSG_IOCTL) {
        !           864:                        gbuf_freem(gbuf_cont(m));
        !           865:                        gbuf_cont(m) = 0;
        !           866:                        ((ioc_t *)gbuf_rptr(m))->ioc_rval = -1;
        !           867:                        ((ioc_t *)gbuf_rptr(m))->ioc_error = EPROTO;
        !           868:                        gbuf_set_type(m, MSG_IOCNAK);
        !           869:                        atalk_putnext(gref, m);
        !           870:                } else
        !           871:                        gbuf_freem(m);
        !           872:                break;
        !           873:        default:
        !           874:                gbuf_freem(m);
        !           875:                break;
        !           876:        }
        !           877: }
        !           878: 
        !           879: int gbuf_msgsize(m)
        !           880:        gbuf_t *m;
        !           881: {
        !           882:        int size;
        !           883: 
        !           884:        for (size=0; m; m=gbuf_cont(m))
        !           885:                size += gbuf_len(m);
        !           886:        return size;
        !           887: }
        !           888: 
        !           889: /* Duplicate a single mbuf, attaching existing external storage. */
        !           890: gbuf_t *gbuf_dupb(m)
        !           891:      gbuf_t *m;
        !           892: {
        !           893:        return((gbuf_t *)m_copym(m, 0, gbuf_len(m), M_DONTWAIT));
        !           894: }
        !           895: 
        !           896: gbuf_t *gbuf_dupb_wait(m, wait)
        !           897:      gbuf_t *m;
        !           898:      int wait;
        !           899: {
        !           900:        return((gbuf_t *)m_copym(m, 0, gbuf_len(m), (wait)? M_WAIT: M_DONTWAIT));
        !           901: }
        !           902: 
        !           903: /* Duplicate an mbuf chain, attaching existing external storage. */
        !           904: gbuf_t *gbuf_dupm(mlist)
        !           905:      gbuf_t *mlist;
        !           906: {
        !           907:        return((gbuf_t *)m_copym(mlist, 0, M_COPYALL, M_DONTWAIT));
        !           908: }
        !           909: 
        !           910: gbuf_t *gbuf_copym(mlist)
        !           911:        gbuf_t *mlist;
        !           912: {
        !           913:        int len, offset;
        !           914:        gbuf_t *m, *mcurr, *mprev, *mhead;
        !           915: 
        !           916:        offset = AT_WR_OFFSET;
        !           917:        for (mhead = 0, m = mlist; m; m = gbuf_cont(m)) {
        !           918:                if ((len = gbuf_len(m)) == 0)
        !           919:                        continue;
        !           920:                if ((mcurr = gbuf_alloc(offset+len, PRI_MED)) == 0) {
        !           921:                        if (mhead)
        !           922:                                gbuf_freem(mhead);
        !           923:                        return (gbuf_t *)0;
        !           924:                }
        !           925:                gbuf_rinc(mcurr,offset);
        !           926:                gbuf_wset(mcurr,len);
        !           927:                gbuf_set_type(mcurr, gbuf_type(m));
        !           928:                bcopy(gbuf_rptr(m), gbuf_rptr(mcurr), len);
        !           929:                if (mhead)
        !           930:                        gbuf_cont(mprev) = mcurr;
        !           931:                else {
        !           932:                        mhead = mcurr;
        !           933:                        offset = 0;
        !           934:                }
        !           935:                mprev = mcurr;
        !           936:        }
        !           937: 
        !           938:        return (gbuf_t *)mhead;
        !           939: }
        !           940: 
        !           941: void gbuf_freem(mlist)
        !           942:        gbuf_t *mlist;
        !           943: {
        !           944:        m_freem((struct mbuf *)mlist);
        !           945: }
        !           946: 
        !           947: void gbuf_linkb(m1, m2)
        !           948:        gbuf_t *m1;
        !           949:        gbuf_t *m2;
        !           950: {
        !           951:        while (gbuf_cont(m1) != 0)
        !           952:                m1 = gbuf_cont(m1);
        !           953:        gbuf_cont(m1) = m2;
        !           954: }
        !           955: 
        !           956: /**************************************/
        !           957: 
        !           958: int ddp_adjmsg(m, len)
        !           959:        gbuf_t          *m;
        !           960:        int     len;
        !           961: {
        !           962:        int buf_len;
        !           963:        gbuf_t *curr_m, *prev_m;
        !           964: 
        !           965:        if (m == (gbuf_t *)0)
        !           966:                return 0;
        !           967: 
        !           968:        if (len > 0) {
        !           969:                for (curr_m=m; curr_m;) {
        !           970:                        buf_len = gbuf_len(curr_m);
        !           971:                        if (len < buf_len) {
        !           972:                                gbuf_rinc(curr_m,len);
        !           973:                                return 1;
        !           974:                        }
        !           975:                        len -= buf_len;
        !           976:                        gbuf_rinc(curr_m,buf_len);
        !           977:                        if ((curr_m = gbuf_cont(curr_m)) == 0) {
        !           978:                                gbuf_freem(m);
        !           979:                                return 0;
        !           980:                        }
        !           981:                }
        !           982: 
        !           983:        } else if (len < 0) {
        !           984:                len = -len;
        !           985: l_cont:        prev_m = 0;
        !           986:                for (curr_m=m; gbuf_cont(curr_m);
        !           987:                        prev_m=curr_m, curr_m=gbuf_cont(curr_m)) ;
        !           988:                buf_len = gbuf_len(curr_m);
        !           989:                if (len < buf_len) {
        !           990:                        gbuf_wdec(curr_m,len);
        !           991:                        return 1;
        !           992:                }
        !           993:                if (prev_m == 0)
        !           994:                        return 0;
        !           995:                gbuf_cont(prev_m) = 0;
        !           996:                gbuf_freeb(curr_m);
        !           997:                len -= buf_len;
        !           998:                goto l_cont;
        !           999: 
        !          1000:        } else
        !          1001:                return 1;
        !          1002: }
        !          1003: 
        !          1004: /*
        !          1005:  * The message chain, m is grown in size by len contiguous bytes.
        !          1006:  * If len is non-negative, len bytes are added to the
        !          1007:  * end of the gbuf_t chain.  If len is negative, the
        !          1008:  * bytes are added to the front. ddp_growmsg only adds bytes to 
        !          1009:  * message blocks of the same type.
        !          1010:  * It returns a pointer to the new gbuf_t on sucess, 0 on failure.
        !          1011:  */
        !          1012: 
        !          1013: gbuf_t *ddp_growmsg(mp, len)
        !          1014:        gbuf_t  *mp;
        !          1015:        int     len;
        !          1016: {
        !          1017:        gbuf_t  *m, *d;
        !          1018: 
        !          1019:        if ((m = mp) == (gbuf_t *) 0)
        !          1020:                return ((gbuf_t *) 0);
        !          1021: 
        !          1022:        if (len <= 0) {
        !          1023:                len = -len;
        !          1024:                if ((d = gbuf_alloc(len, PRI_MED)) == 0)
        !          1025:                        return ((gbuf_t *) 0);
        !          1026:                gbuf_set_type(d, gbuf_type(m));
        !          1027:                gbuf_wset(d,len);
        !          1028:                /* link in new gbuf_t */
        !          1029:                gbuf_cont(d) = m;
        !          1030:                return (d);
        !          1031: 
        !          1032:        } else {
        !          1033:                register int    count;
        !          1034:                /*
        !          1035:                 * Add to tail.
        !          1036:                 */
        !          1037:                if ((count = gbuf_msgsize(m)) < 0)
        !          1038:                        return ((gbuf_t *) 0);
        !          1039:                /* find end of chain */
        !          1040:                for ( ; m; m = gbuf_cont(m)) {
        !          1041:                        if (gbuf_len(m) >= count) 
        !          1042:                                break;
        !          1043:                        count -= gbuf_len(m);
        !          1044:                }
        !          1045:                /* m now points to gbuf_t to add to */
        !          1046:                if ((d = gbuf_alloc(len, PRI_MED)) == 0)
        !          1047:                        return ((gbuf_t *) 0);
        !          1048:                gbuf_set_type(d, gbuf_type(m));
        !          1049:                /* link in new gbuf_t */
        !          1050:                gbuf_cont(d) = gbuf_cont(m);
        !          1051:                gbuf_cont(m) = d;
        !          1052:                gbuf_wset(d,len);
        !          1053:                return (d);
        !          1054:        }
        !          1055: }
        !          1056: 
        !          1057: 
        !          1058: 
        !          1059: /*
        !          1060:  *     return an MSG_ERROR on the read stream. Note that the same message
        !          1061:  *     block that caused the problem is used as the vehicle. So chained 
        !          1062:  *     blocks to this message will be free'd; i.e. ASSUMES no multiple
        !          1063:  *     references.
        !          1064:  *     Used by other appletalk modules, so it is not static!
        !          1065:  */
        !          1066: 
        !          1067: void data_error(errno,mp,gref)
        !          1068: int            errno;
        !          1069: register gbuf_t        *mp;
        !          1070: register gref_t        *gref;
        !          1071: {
        !          1072: 
        !          1073:         gbuf_set_type(mp, MSG_ERROR);
        !          1074:        
        !          1075:        *gbuf_rptr(mp) = (unsigned char)errno;
        !          1076:        gbuf_wset(mp,1);
        !          1077:        if (gbuf_cont(mp)) {
        !          1078:                gbuf_freem(gbuf_cont(mp));
        !          1079:                gbuf_cont(mp) = 0;
        !          1080:        }
        !          1081: 
        !          1082:        atalk_putnext(gref, mp);
        !          1083: }
        !          1084: 
        !          1085: /*
        !          1086:  *     return the MSG_IOCACK/MSG_IOCNAK. Note that the same message
        !          1087:  *     block is used as the vehicle, and that if there is an error return,
        !          1088:  *     then linked blocks are lopped off. BEWARE of multiple references.
        !          1089:  *     Used by other appletalk modules, so it is not static!
        !          1090:  */
        !          1091: 
        !          1092: void ioc_ack(errno, m, gref)
        !          1093: int            errno;
        !          1094: register gbuf_t        *m;
        !          1095: register gref_t        *gref;
        !          1096: 
        !          1097: {
        !          1098:        ioc_t *iocbp = (ioc_t *)gbuf_rptr(m);
        !          1099:        
        !          1100:        /*kprintf("ioc_ack: m=%x gref=%x errno=%d\n", m, gref, errno);*/
        !          1101: 
        !          1102:        if (gref->info == NULL) {
        !          1103:                gbuf_freem(m);
        !          1104: #ifdef APPLETALK_DEBUG
        !          1105:                kprintf("ioc_ack: gref->info == NULL: free m\n");
        !          1106: #endif
        !          1107:                return;
        !          1108:        }
        !          1109:        if ((iocbp->ioc_error = errno) != 0)
        !          1110:        {       /* errno != 0, then there is an error, get rid of linked blocks! */
        !          1111: 
        !          1112:                if (gbuf_cont(m)) {
        !          1113:                        gbuf_freem(gbuf_cont(m));
        !          1114:                        gbuf_cont(m) = 0;
        !          1115:                }
        !          1116:                gbuf_set_type(m, MSG_IOCNAK);
        !          1117:                iocbp->ioc_count = 0;   /* only make zero length if error */
        !          1118:                iocbp->ioc_rval = -1;
        !          1119:        } else
        !          1120:                gbuf_set_type(m, MSG_IOCACK);
        !          1121: 
        !          1122:        atalk_putnext(gref, m);
        !          1123: }
        !          1124: 
        !          1125: /* Queue management functions */
        !          1126: 
        !          1127: void
        !          1128: ddp_remque(elem)
        !          1129:        register LIB_QELEM_T    *elem;
        !          1130: {
        !          1131:        elem->q_back->q_forw = elem->q_forw;
        !          1132:        elem->q_forw->q_back = elem->q_back;
        !          1133: }
        !          1134: 
        !          1135: void
        !          1136: ddp_insque(elem, prev)
        !          1137:        register LIB_QELEM_T    *elem, *prev;
        !          1138: { 
        !          1139:        elem->q_back = prev;
        !          1140:        elem->q_forw = prev->q_forw;
        !          1141:        prev->q_forw->q_back = elem;
        !          1142:        prev->q_forw = elem;
        !          1143: }

unix.superglobalmegacorp.com

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