Annotation of cci/sys/bsc/bsctr.c, revision 1.1

1.1     ! root        1: /*     D.L.Buck and Associates, Inc. - 8/27/84
        !             2:  *
        !             3:  *     COPYRIGHT NOTICE:
        !             4:  *             Copyright c 8/27/84 - An unpublished work by 
        !             5:  *             D.L.Buck and Associates, Inc.
        !             6:  *
        !             7:  *     PROPRIETARY RIGHTS NOTICE:
        !             8:  *             All rights reserved. This document and program contains
        !             9:  *             proprietary information of D.L.Buck and Associates,Inc.
        !            10:  *             of San Jose, California, U.S.A., embodying confidential
        !            11:  *             information,  ideas, and expressions,  no part of which
        !            12:  *             may be reproduced, or transmitted in any form or by any
        !            13:  *             means,  electronic,  mechanical,  or otherwise, without
        !            14:  *             the written permission of D.L.Buck and Associates, Inc.
        !            15:  *
        !            16:  * NAME
        !            17:  *     bsctr - BISYNC TRACE Driver
        !            18:  *
        !            19:  * DESCRIPTION
        !            20:  *     This trace module represents a pseudo-device to Unix. It has
        !            21:  *     the usual open, close, read, and ioctl routines for a read-only
        !            22:  *     device. As well, it has a trace event logging routine which is
        !            23:  *     called from the other portions of the bisync driver to log state
        !            24:  *     changes, received information, transmitted information, and errors.
        !            25:  *     Trace events are stored in a trace buffer until read by a user-level
        !            26:  *     routine.
        !            27:  */
        !            28: 
        !            29: #ifndef lint
        !            30: static char bsctr_c[] = "@(#)bsctr.c   1.7 REL";
        !            31: #endif
        !            32: 
        !            33: #include        "../bsc/local.h"
        !            34: #include        "../bsc/bscio.h"
        !            35: #include       "../bsc/bsc.h"
        !            36: #include        "../bsc/bsctr.h"
        !            37: 
        !            38: #if defined BSD42
        !            39: #define ERRRET(x)      return x
        !            40: #define        UCOUNT  uio->uio_resid
        !            41: #else
        !            42: #define        ERRRET(x)       u.u_error = x; return
        !            43: #define        UCOUNT  u.u_count
        !            44: #endif
        !            45: 
        !            46: #define SIZEMASK 0x03ff
        !            47: 
        !            48: extern struct bsc bsc[];       /* device information */
        !            49: char bsctbuf[TBUFSIZE];        /* circular trace buffer */
        !            50: char *bsctbin, *bsctbout;      /* ptrs to next write, read locations */
        !            51: char *lastpkt;                 /* pts to len field of last pkt if 'y' */
        !            52: char bscbw;                    /* someone's waiting on the trace buffer */
        !            53: unsigned char bsclost;         /* number of lost trace events */
        !            54: int bsctlock = -1;             /* Trace lock */
        !            55: #if defined BSD42
        !            56: extern struct timeval time;
        !            57: #define TRTIME time.tv_sec
        !            58: #else
        !            59: extern long time;
        !            60: #define TRTIME time
        !            61: #endif
        !            62: 
        !            63: #define INSERT(x)      {*bsctbin = (x);\
        !            64:                        if (++bsctbin == &bsctbuf[TBUFSIZE]) bsctbin = bsctbuf;}
        !            65: #define ZERO    0      /* dummy insert value for odd byte receive packets */
        !            66: 
        !            67: /*
        !            68:  * NAME
        !            69:  *     bsctr - trace an event for Bisync Drivers
        !            70:  * SYNOPSIS
        !            71:  *     bsctr (dev, state, type [, len, dptr])
        !            72:  *     dev_t dev;      Device number
        !            73:  *     unsigned state; State number (bscpsm) or other info (bscll)
        !            74:  *     char type;      Trace Packet type
        !            75:  *     short len;      (Optional) Length of data section of packet
        !            76:  *     char *dptr;     (Optional) Pointer to data section (kernel space)
        !            77:  * ALGORITHM
        !            78:  *     1. Check for trace buffer overflow
        !            79:  *     2. If we can't insert next trace packet, count
        !            80:  *        trace buffer overruns. Otherwise, insert
        !            81:  *        packet into trace buffer.
        !            82:  *     3. If the last packet was of type 'y' and this packet is the
        !            83:  *        same, combine the packets by merging the data from the
        !            84:  *        second into the first.
        !            85:  *     4. If the last packet was type 'y' and the data length was
        !            86:  *        odd, make it even by adding a dummy data byte.
        !            87:  *     5. Add the new data packet by inserting the time (a long),
        !            88:  *        state, type, and if type 'x' or 'y', the length and
        !            89:  *        data.
        !            90:  * MACHINE DEPENDENCIES
        !            91:  *     This algorithm assumes a 'normal' byte ordering within a short.
        !            92:  *     If the length needs to be increased ((3) above), the low-order
        !            93:  *     byte address is computed and incremented, and any carry
        !            94:  *     added to the computed high-order address.
        !            95:  *     On Intel and PDP-11's, for example, this algorithm will need
        !            96:  *     to be modified.
        !            97:  */    
        !            98: 
        !            99: bsctr(dev,state,type,len,dptr)
        !           100: dev_t dev;             /* bsc device minor number */
        !           101: unsigned state;        /* current state number, or other info */
        !           102: char type;             /* current state's type */
        !           103: register short int len;        /* length of data in dptr */
        !           104: register char *dptr;   /* data to be logged */
        !           105: {
        !           106:        register int avail;     /* number of trace buffer bytes available */
        !           107:        short int givenlen;
        !           108: 
        !           109:        /* 1. check for trace buffer overflow */
        !           110:        avail = (bsctbin >= bsctbout) ? TBUFSIZE - (bsctbin - bsctbout):
        !           111:                                      bsctbout - bsctbin;
        !           112:        --avail;        /* don't allow in to catch out */
        !           113: 
        !           114:        /* 2. if we can't insert next trace packet, count
        !           115:         *      trace buffer overruns. Otherwise, insert
        !           116:         *      packet into trace buffer.
        !           117:         */
        !           118:        givenlen = (type < 'x') ? 0 : (len & SIZEMASK);
        !           119: 
        !           120:        if (avail < givenlen+8) {       /* we will lose data */
        !           121:                ++bsclost;
        !           122:                return;
        !           123:        }
        !           124: 
        !           125: /*
        !           126:  *   3.        If it is a 'y' type (receive) then the characters will be
        !           127:  *     sent here one at a time.  In order to store them similarly to
        !           128:  *     'x' types (transmit), each character is added to the end of the
        !           129:  *     list of received characters and the length is incremented by one
        !           130:  *     instead of storing each of the characters as an individual packet.
        !           131:  *     The first receive character is stored just as a transmit packet
        !           132:  *     with a length of one.  The next packet, if a 'y', is stored as 
        !           133:  *     noted above.
        !           134:  */
        !           135: 
        !           136:        if (type == 'y' && lastpkt) {
        !           137:                INSERT(*dptr);
        !           138:                lastpkt[0]++;           /* Incr. length */
        !           139:                if (*lastpkt == 0) {    /* Overflow? */
        !           140:                        if (lastpkt == bsctbuf)
        !           141:                                bsctbuf[TBUFSIZE-1]++;
        !           142:                        else    lastpkt[-1]++;
        !           143:                }
        !           144:        } else  {
        !           145:                /*
        !           146:                 * Check to see if the last character stored was a receive type
        !           147:                 * and whether the length was odd.  If it was, a 
        !           148:                 * dummy character must be added to force an even boundary
        !           149:                 * as with transmit characters
        !           150:                 */
        !           151:                if (lastpkt && (*lastpkt & 1))
        !           152:                                INSERT(ZERO);
        !           153:                lastpkt = (char *)0;
        !           154:                
        !           155:                INSERT(TRTIME>>24);
        !           156:                INSERT(TRTIME>>16);
        !           157:                INSERT(TRTIME>>8);
        !           158:                INSERT(TRTIME);
        !           159:                INSERT(state);
        !           160:                INSERT(type);
        !           161:                if (type >= 'x') {      /* we will log data */
        !           162:                        INSERT(givenlen>>8);
        !           163:                        if (type == 'y')
        !           164:                                lastpkt = bsctbin;
        !           165:                        INSERT(givenlen);
        !           166:                        if (type == 'x' && (givenlen & 1)) ++givenlen;
        !           167:                        while (--givenlen >= 0)
        !           168:                                INSERT(*dptr++);
        !           169:                }
        !           170:        }
        !           171:        if (bscbw) {            /* someone waiting */
        !           172:                bscbw = 0;
        !           173:                wakeup (bsctbuf);
        !           174:        }
        !           175: }
        !           176: 
        !           177: #if defined BSD42
        !           178: bstread(dev,uio)       /* user request to read trace buffer */
        !           179: register dev_t dev;
        !           180: struct uio *uio;
        !           181: #else
        !           182: bstread(dev)   /* user request to read trace buffer */
        !           183: register dev_t dev;
        !           184: #endif
        !           185: {
        !           186:        register int x, diff;
        !           187:        int errcode = 0;
        !           188: 
        !           189:        dev = minor(dev);
        !           190:        x = spl8();
        !           191:        while (bsctbin == bsctbout) {   /* buffer empty */
        !           192:                if (bsc[dev].b_mode == BSC_CLOSED){
        !           193:                        splx(x);
        !           194: #if defined BSD42
        !           195:                        return 0;
        !           196: #else
        !           197:                        return;
        !           198: #endif
        !           199:                }
        !           200:                ++bscbw;                /* indicate we'll sleep for trace buf*/
        !           201:                sleep(bsctbuf, BSCPRI);/* sleep for it */
        !           202:        }
        !           203:        if (lastpkt && (*lastpkt & 1))
        !           204:                INSERT(ZERO);
        !           205:        lastpkt = (char *)0;
        !           206:        diff = (bsctbin > bsctbout) ? bsctbin - bsctbout :
        !           207:                        TBUFSIZE - (bsctbout - bsctbin);
        !           208:        splx(x);
        !           209:        if (diff > UCOUNT) diff = UCOUNT;
        !           210:        if (&bsctbout[diff] >= &bsctbuf[TBUFSIZE])  {
        !           211:                x = &bsctbuf[TBUFSIZE] - bsctbout;
        !           212: #if defined BSD42
        !           213:                errcode = uiomove(bsctbout, x, UIO_READ, uio);
        !           214:                if (!errcode)
        !           215:                        errcode = uiomove (bsctbuf, diff - x, UIO_READ, uio);
        !           216: #else
        !           217:                if (iomove (bsctbout, x, B_READ) ||
        !           218:                    iomove (bsctbuf, diff - x, B_READ))
        !           219:                        errcode = EFAULT;
        !           220: #endif
        !           221:                bsctbout = &bsctbuf[diff - x];
        !           222:        } else {
        !           223: #if defined BSD42
        !           224:                errcode = uiomove(bsctbout, diff, UIO_READ, uio);
        !           225: #else
        !           226:                if (iomove(bsctbout, diff, B_READ))
        !           227:                        errcode = EFAULT;
        !           228: #endif
        !           229:                bsctbout += diff;
        !           230:        }
        !           231:        /* ?. If trace events were lost, add loss event to next buffer */
        !           232:        if (bsclost) {  /* # trace events lost */
        !           233:                x = spl8();
        !           234:                bsctr(dev, bsclost, 'o');       /* overrun event */
        !           235:                bsclost = 0;
        !           236:                splx(x);
        !           237:        }
        !           238: #ifdef BSD42
        !           239:        return errcode;
        !           240: #else
        !           241:        if (errcode)
        !           242:                u.u_error = errcode;
        !           243: #endif
        !           244: }
        !           245: 
        !           246: bstopen(dev, flag)
        !           247: dev_t dev;
        !           248: {
        !           249:        if (bsctlock != -1) {
        !           250:                ERRRET(EBUSY);
        !           251:        }
        !           252:        bsctlock = dev = minor(dev);
        !           253:        bsc[dev].b_trace = 1;           /* indicate tracing activated */
        !           254:        bsctbin = bsctbout = bsctbuf;   /* initialize in, out pointers */
        !           255:        lastpkt = (char *)0;
        !           256:        while (bsc[dev].b_mode == BSC_CLOSED) /* wait till open */
        !           257:                sleep (&bsc[dev].b_trace, BSCPRI);
        !           258: #ifdef BSD42
        !           259:        return 0;
        !           260: #endif
        !           261: }
        !           262: 
        !           263: bstclose(dev)
        !           264: dev_t dev;
        !           265: {
        !           266:        wakeup(bsctbuf);
        !           267:        bsc[minor(dev)].b_trace = 0;
        !           268:        bsctlock = -1;
        !           269: #if defined BSD42
        !           270:        return 0;
        !           271: #endif
        !           272: }
        !           273: 
        !           274: bstioctl(dev,cmd,arg)          /* ioctl entry */
        !           275: dev_t dev;
        !           276: {
        !           277:        bsc[minor(dev)].b_trace = (cmd&0xf) + 1;
        !           278: #if defined BSD42
        !           279:        return 0;
        !           280: #endif
        !           281: }

unix.superglobalmegacorp.com

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