|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.