Annotation of kernel/bsd/netat/sys_glue.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 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.