Annotation of cci/sys/bsc/bsctr.c, revision 1.1.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.