1: /* 2: * SCCS id @(#)prf.c 2.1 (Berkeley) 8/5/83 3: */ 4: 5: #include "param.h" 6: #include <sys/systm.h> 7: #include <sys/filsys.h> 8: #include <sys/mount.h> 9: #include <sys/seg.h> 10: #include <sys/buf.h> 11: #include <sys/conf.h> 12: #include <sys/inline.h> 13: #ifdef UCB_AUTOBOOT 14: #include <sys/reboot.h> 15: #endif 16: 17: /* 18: * In case console is off, 19: * panicstr contains argument to last 20: * call to panic. 21: */ 22: 23: char *panicstr; 24: 25: /* 26: * Scaled down version of C Library printf. 27: * Only %c %s %u %d (==%u) %o %x %D %O are recognized. 28: * Used to print diagnostic information directly on console tty. 29: * Since it is not interrupt driven, all system activities are 30: * suspended. Printf should not be used for chit-chat. 31: * 32: */ 33: #ifdef UCB_DEVERR 34: /* 35: * One additional format: %b is supported to decode error registers. 36: * Usage is: 37: * printf("reg=%b\n", regval, "<base><arg>*"); 38: * Where <base> is the output base expressed as a control character, 39: * e.g. \10 gives octal; \20 gives hex. Each arg is a sequence of 40: * characters, the first of which gives the bit number to be inspected 41: * (origin 1), and the next characters (up to a control character, i.e. 42: * a character <= 32), give the name of the register. Thus 43: * printf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); 44: * would produce output: 45: * reg=3<BITTWO,BITONE> 46: */ 47: #endif UCB_DEVERR 48: 49: /*VARARGS1*/ 50: printf(fmt, x1) 51: register char *fmt; 52: unsigned x1; 53: { 54: prf(fmt, &x1, 0); 55: } 56: 57: #ifdef UCB_UPRINTF 58: /* 59: * Uprintf prints to the current user's terminal, 60: * guarantees not to sleep (so could be called by interrupt routines; 61: * but prints on the tty of the current process) 62: * and does no watermark checking - (so no verbose messages). 63: * NOTE: with current kernel mapping scheme, the user structure is 64: * not guaranteed to be accessible at interrupt level (see seg.h); 65: * a savemap/restormap would be needed here or in putchar if uprintf 66: * was to be used at interrupt time. 67: */ 68: /*VARARGS1*/ 69: uprintf(fmt, x1) 70: char *fmt; 71: unsigned x1; 72: { 73: prf(fmt, &x1, 2); 74: } 75: #else 76: 77: /*VARARGS1*/ 78: uprintf(fmt, x1) 79: char *fmt; 80: unsigned x1; 81: { 82: prf(fmt, &x1, 0); 83: } 84: 85: #endif UCB_PRINTF 86: 87: prf(fmt, adx, touser) 88: register char *fmt; 89: register unsigned int *adx; 90: { 91: register c; 92: char *s; 93: #ifdef UCB_DEVERR 94: int i, any; 95: unsigned b; 96: #endif 97: 98: loop: 99: while((c = *fmt++) != '%') { 100: if(c == '\0') 101: return; 102: putchar(c, touser); 103: } 104: c = *fmt++; 105: if(c == 'd' || c == 'u' || c == 'o' || c == 'x') 106: printn((long)*adx, c=='o'? 8: (c=='x'? 16:10), touser); 107: else if(c == 'c') 108: putchar(*adx, touser); 109: else if(c == 's') { 110: s = (char *)*adx; 111: while(c = *s++) 112: putchar(c, touser); 113: } else if (c == 'D' || c == 'O' || c == 'X') { 114: printn(*(long *)adx, c=='D'?10:c=='O'?8:16, touser); 115: adx += (sizeof(long) / sizeof(int)) - 1; 116: } 117: #ifdef UCB_DEVERR 118: else if (c == 'b') { 119: b = *adx++; 120: s = (char *) *adx; 121: printn((long) b, *s++, touser); 122: any = 0; 123: if (b) { 124: putchar('<', touser); 125: while (i = *s++) { 126: if (b & (1 << (i - 1))) { 127: if (any) 128: putchar(',', touser); 129: any = 1; 130: for (; (c = *s) > 32; s++) 131: putchar(c, touser); 132: } else 133: for (; *s > 32; s++) 134: ; 135: } 136: putchar('>', touser); 137: } 138: } 139: #endif 140: adx++; 141: goto loop; 142: } 143: 144: /* 145: * Print an unsigned integer in base b, avoiding recursion. 146: */ 147: printn(n, b, touser) 148: long n; 149: { 150: long a; 151: char prbuf[12]; 152: register char *cp; 153: 154: if (b == 10 && n < 0) { 155: putchar('-', touser); 156: n = -n; 157: } 158: cp = prbuf; 159: do { 160: *cp++ = "0123456789ABCDEF"[(int)(n%b)]; 161: } while (n = n/b); /* Avoid n /= b, since that requires alrem */ 162: do 163: putchar(*--cp, touser); 164: while (cp > prbuf); 165: } 166: 167: /* 168: * Panic is called on fatal errors. 169: * It prints "panic: mesg", syncs, and then reboots if possible. 170: * If we are called twice, then we avoid trying to 171: * sync the disks as this often leads to recursive panics. 172: */ 173: panic(s) 174: register char *s; 175: { 176: #ifdef UCB_AUTOBOOT 177: int bootopt = (panicstr == NULL) ? RB_DUMP : (RB_DUMP | RB_NOSYNC); 178: 179: if (panicstr == NULL) 180: panicstr = s; 181: printf("panic: %s\n", s); 182: (void) _spl0(); 183: boot(rootdev,bootopt); 184: /*NOTREACHED*/ 185: #else 186: printf("panic: %s\n", s); 187: if (panicstr == NULL) { 188: panicstr = s; 189: if (bfreelist.b_forw) 190: update(); 191: } 192: for(;;) 193: idle(); 194: #endif 195: } 196: 197: /* 198: * Warn that a system table is full. 199: */ 200: tablefull(tab) 201: char *tab; 202: { 203: printf("%s: table is full\n", tab); 204: } 205: 206: /* 207: * Hard error is the preface to plaintive error messages 208: * about failing disk tranfers. 209: */ 210: harderr(bp, cp) 211: struct buf *bp; 212: char *cp; 213: { 214: printf("%s%d%c: hard error bn %D ", cp, 215: dkunit(bp), 'a' + (minor(bp->b_dev) & 07), bp->b_blkno); 216: } 217: 218: /* 219: * Fserr prints the name of a file system 220: * with an error diagnostic, in the form 221: * filsys: error message 222: */ 223: fserr(fp, cp) 224: struct filsys *fp; 225: char *cp; 226: { 227: printf("%s: %s\n", fp->s_fsmnt, cp); 228: } 229: 230: #ifndef UCB_DEVERR 231: /* 232: * deverr prints a diagnostic from 233: * a device driver. 234: * It prints the device, block number, 235: * and 2 octal words (usually some error 236: * status registers) passed as argument. 237: */ 238: deverror(bp, o1, o2) 239: register struct buf *bp; 240: { 241: register struct mount *mp; 242: register struct filsys *fp; 243: 244: for(mp = mount; mp < mountNMOUNT; mp++) 245: if(mp->m_inodp != NULL) 246: if(bp->b_dev == mp->m_dev) { 247: fp = &mp->m_filsys; 248: fserr(fp, "err"); 249: } 250: printf("err on dev %u/%u\n", major(bp->b_dev), minor(bp->b_dev)); 251: printf("bn=%D er=%o,%o\n", bp->b_blkno, o1, o2); 252: } 253: #endif UCB_DEVERR