|
|
1.1 ! root 1: # To unbundle, sh this file ! 2: echo LL.c 1>&2 ! 3: mkdir scsi scsi/osanity scsi/scsi scsi/inc scsi/generic scsi/sony scsi/wren ! 4: sed 's/.//' >LL.c <<'//GO.SYSIN DD LL.c' ! 5: -#include <sys/param.h> ! 6: - ! 7: -/* ! 8: - * long-long support ! 9: - */ ! 10: - ! 11: -#define M 0x80000000 ! 12: - ! 13: -unsigned ! 14: -Lshift(ll, l) ! 15: -llong_t ll; ! 16: -long l; ! 17: -{ ! 18: - return (ll.hi<<(32-l)) | (ll.lo>>l); ! 19: -} ! 20: - ! 21: -llong_t ! 22: -ltoL(l) ! 23: -long l; ! 24: -{ ! 25: - llong_t t; ! 26: - ! 27: - t.hi = 0; ! 28: - t.lo = l; ! 29: - return t; ! 30: -} ! 31: - ! 32: -llong_t ! 33: -Lladd(ll, l) ! 34: -llong_t ll; ! 35: -long l; ! 36: -{ ! 37: - llong_t t; ! 38: - long cin; ! 39: - ! 40: - t = ll; ! 41: - t.lo += l; ! 42: - cin = ll.lo^t.lo; ! 43: - if (l>=0) { ! 44: - if ((ll.lo&cin)&M) ! 45: - t.hi++; ! 46: - } else { ! 47: - if ((~ll.lo&cin)&M) ! 48: - t.hi--; ! 49: - } ! 50: - return t; ! 51: -} ! 52: - ! 53: -llong_t ! 54: -Luadd(ll, u) ! 55: -llong_t ll; ! 56: -unsigned long u; ! 57: -{ ! 58: - llong_t t; ! 59: - long cin; ! 60: - ! 61: - t = ll; ! 62: - t.lo += u; ! 63: - cin = ll.lo^t.lo; ! 64: - if ((ll.lo&cin)&M) ! 65: - t.hi++; ! 66: - return t; ! 67: -} ! 68: - ! 69: -llong_t ! 70: -LLadd(lla, llb) ! 71: -llong_t lla, llb; ! 72: -{ ! 73: - llong_t t; ! 74: - ! 75: - t.hi = lla.hi+llb.hi; ! 76: - t.lo = lla.lo+llb.lo; ! 77: - if ((lla.lo&llb.lo | lla.lo&~t.lo | llb.lo&~t.lo)&M) ! 78: - t.hi++; ! 79: - return t; ! 80: -} ! 81: - ! 82: -llong_t ! 83: -Llmul(a, b) ! 84: - llong_t a; ! 85: - unsigned long b; ! 86: -{ ! 87: - llong_t r; ! 88: - ! 89: - r = ltoL(0); ! 90: - while(b){ ! 91: - if(b&1) ! 92: - r = LLadd(r, a); ! 93: - b >>= 1; ! 94: - a = LLadd(a, a); ! 95: - } ! 96: - return(r); ! 97: -} ! 98: //GO.SYSIN DD LL.c ! 99: echo btree.c 1>&2 ! 100: sed 's/.//' >btree.c <<'//GO.SYSIN DD btree.c' ! 101: -#include <libc.h> ! 102: -#include <cbt.h> ! 103: -#undef nfree ! 104: -#include "worm.h" ! 105: -#include "sym.h" ! 106: -#include <sys/types.h> ! 107: -#include <sys/stat.h> ! 108: - ! 109: -static char *inonames; ! 110: -static bfile *bf; ! 111: -static dirlk(), wormdir(); ! 112: - ! 113: -char * ! 114: -cbtinit(s, blk, doinodes) ! 115: - register Superblock *s; ! 116: - long blk; ! 117: -{ ! 118: - static char buf[64]; ! 119: - char name[256], buf1[256]; ! 120: - ! 121: - if(s->magic != SMAGIC){ ! 122: - fprint(2, "bad Superblock at %ld\n", blk); ! 123: - exit(1); ! 124: - } ! 125: - numinodes = s->ninodes; ! 126: - if(doinodes){ ! 127: - inonames = malloc(s->blocksize*(int)NBLKS(s, s->ninochars)); ! 128: - if(inonames == 0){ ! 129: - sprint(buf, "cbtinit: can't malloc %d\n", s->blocksize*(int)NBLKS(s, s->ninochars)); ! 130: - return(buf); ! 131: - } ! 132: - if(dirlk(s) == 0) ! 133: - wormdir(s); ! 134: - } else ! 135: - inonames = 0; ! 136: - return((char *)0); ! 137: -} ! 138: - ! 139: -static ! 140: -dirlk(s) ! 141: - register Superblock *s; ! 142: -{ ! 143: - char name[256], buf1[256]; ! 144: - struct stat sbuf; ! 145: - int fd; ! 146: - ! 147: - sprint(name, "/usr/worm/dirs/%s", s->vol_id); ! 148: - sprint(buf1, "%s.I", name); ! 149: - if(stat(buf1, &sbuf) < 0) ! 150: - return(0); ! 151: - if(sbuf.st_mtime < s->ctime) ! 152: - return(0); /* worm is more recent than disk */ ! 153: - if((bf = bopen(name, 0)) == 0) ! 154: - return(0); ! 155: - sprint(buf1, "%s.I", name); ! 156: - if((fd = open(buf1, 0)) < 0){ ! 157: - fprint(2, "%s: btree but no inodes\n", name); ! 158: - return(0); ! 159: - } ! 160: - if(read(fd, inonames, (int)s->ninochars) != s->ninochars){ ! 161: - fprint(2, "%s: expected %d chars\n", buf1, s->ninochars); ! 162: - close(fd); ! 163: - return(0); ! 164: - } ! 165: - close(fd); ! 166: - return(1); ! 167: -} ! 168: - ! 169: -static ! 170: -wormdir(s) ! 171: - register Superblock *s; ! 172: -{ ! 173: - char name[256], buf1[256]; ! 174: - ! 175: - sprint(name, "/tmp/worm%d", getpid()); ! 176: - Seek(s, s->binodes); ! 177: - sprint(buf1, "%s.F", name); ! 178: - copyout(s, buf1, s->nF, 0, 0); ! 179: - sprint(buf1, "%s.T", name); ! 180: - copyout(s, buf1, s->nT, 0, 0); ! 181: - if(Read(s, inonames, NBLKS(s, s->ninochars))) ! 182: - return(0); ! 183: - if((bf = bopen(name, 0)) == 0){ ! 184: - fprint(2, "can't bopen %s", name); ! 185: - return(0); ! 186: - } ! 187: - sprint(buf1, "%s.F", name); unlink(buf1); ! 188: - sprint(buf1, "%s.T", name); unlink(buf1); ! 189: - return(1); ! 190: -} ! 191: - ! 192: -copyout(s, name, len, overwrite, verbose) ! 193: - register Superblock *s; ! 194: - char *name; ! 195: - long len; ! 196: -{ ! 197: - int fd, l; ! 198: - char *buf; ! 199: - ! 200: - if(access(name, 0) == 0){ ! 201: - if(!overwrite){ ! 202: - fprint(2, "%s already exists!\n", name); ! 203: - exit(1); ! 204: - } ! 205: - if(verbose) ! 206: - fprint(2, "overwriting %s\n", name); ! 207: - } ! 208: - if((fd = creat(name, 0666)) < 0){ ! 209: - perror(name); ! 210: - exit(1); ! 211: - } ! 212: - if((buf = malloc(l = (BIGBLOCK/1024)*s->blocksize)) == 0){ ! 213: - fprint(2, "can't malloc %d\n", l); ! 214: - exit(1); ! 215: - } ! 216: - if(verbose) ! 217: - print("%s: %d bytes\n", name, len); ! 218: - while(len >= l){ ! 219: - if(Read(s, buf, NBLKS(s, l))) ! 220: - exit(1); ! 221: - if(write(fd, buf, l) != l){ ! 222: - perror(name); ! 223: - exit(2); ! 224: - } ! 225: - len -= l; ! 226: - } ! 227: - if(Read(s, buf, NBLKS(s, len))) ! 228: - exit(2); ! 229: - if(write(fd, buf, (int)len) != len){ ! 230: - perror(name); ! 231: - exit(2); ! 232: - } ! 233: - free(buf); ! 234: -} ! 235: - ! 236: -Inode * ! 237: -binodefn(s) ! 238: - char *s; ! 239: -{ ! 240: - static Inode i; ! 241: - mbuf key; ! 242: - ! 243: - if(inonames == 0) ! 244: - return((Inode *)0); ! 245: - key.mdata = s; ! 246: - key.mlen = strlen(s); ! 247: - if(bseek(bf, key) != 1) ! 248: - return((Inode *)0); ! 249: - key.mdata = (char *)&i; ! 250: - if(bread(bf, (mbuf *)0, &key)){ ! 251: - perror("inode read"); ! 252: - return((Inode *)0); ! 253: - } ! 254: - i.name.n = i.name.o+inonames; ! 255: - return(&i); ! 256: -} ! 257: - ! 258: -void ! 259: -btraverse(fn) ! 260: - void (*fn)(); ! 261: -{ ! 262: - static Inode i; ! 263: - mbuf key; ! 264: - ! 265: - if(inonames == 0) ! 266: - return; ! 267: - bfirst(bf); ! 268: - key.mdata = (char *)&i; ! 269: - while(bread(bf, (mbuf *)0, &key) == 0){ ! 270: - i.name.n = i.name.o+inonames; ! 271: - (*fn)(&i); ! 272: - } ! 273: -} ! 274: //GO.SYSIN DD btree.c ! 275: echo c.c 1>&2 ! 276: sed 's/.//' >c.c <<'//GO.SYSIN DD c.c' ! 277: -#include <sys/param.h> ! 278: -main(argc, argv) ! 279: - char **argv; ! 280: -{ ! 281: - Long off; ! 282: - long a, b; ! 283: - ! 284: - a = atoi(argv[1]); ! 285: - b = atoi(argv[2]); ! 286: - off = Llmul(ltoL(a), b); ! 287: - print("%d(#%x) x %d(#%x) = #%ux%0.8ux(%.0f)\n", a, a, b, b, off.hi, off.lo, ! 288: - ((float)off.lo) + 65536.0*65536.0*off.hi); ! 289: - if(llseek(open("/dev/null", 0), off, 0) < 0) ! 290: - perror("seek"); ! 291: -} ! 292: //GO.SYSIN DD c.c ! 293: echo crap 1>&2 ! 294: sed 's/.//' >crap <<'//GO.SYSIN DD crap' ! 295: -#include <libc.h> ! 296: -#include "sym.h" ! 297: -#include "worm.h" ! 298: - ! 299: -main(argc, argv) ! 300: - char **argv; ! 301: -{ ! 302: - Superblock s; ! 303: - char *e; ! 304: - Inode *i; ! 305: - int c; ! 306: - char *dev = "/dev/worm0"; ! 307: - extern char *optarg; ! 308: - extern int optind; ! 309: - ! 310: - while((c = getopt(argc, argv, "f:")) != -1) ! 311: - switch(c) ! 312: - { ! 313: - case 'f': dev = optarg; break; ! 314: - case '?': usage(); ! 315: - } ! 316: - if(optind+2 != argc) ! 317: - usage(); ! 318: - dev = mapdev(dev); ! 319: - if((s.fd = open(dev, 0)) < 0){ ! 320: - perror(dev); ! 321: - exit(1); ! 322: - } ! 323: - if(e = openinode(&s, DO_INODE|SPIN_DOWN)){ ! 324: - fprint(2, "%s: %s\n", dev, e); ! 325: - exit(1); ! 326: - } ! 327: - if(strcmp(s.vol_id, argv[optind])){ ! 328: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id); ! 329: - exit(1); ! 330: - } ! 331: - if(i = inodeof(argv[++optind])) ! 332: - c = pr(&s, i); ! 333: - else { ! 334: - fprint(2, "wcat: can't find %s\n", argv[optind]); ! 335: - c = 1; ! 336: - } ! 337: - exit(c); ! 338: -} ! 339: - ! 340: -usage() ! 341: -{ ! 342: - fprint(2, "Usage: worm cat [-fdevice] vol_id file\n"); ! 343: - exit(1); ! 344: -} ! 345: - ! 346: -pr(s, i) ! 347: - Superblock *s; ! 348: - register Inode *i; ! 349: -{ ! 350: - char b[BIGBLOCK]; ! 351: - register long len, n; ! 352: - long nb; ! 353: - int fd; ! 354: - ! 355: - fd = 1; ! 356: - nb = sizeof b / s->blocksize; ! 357: - Seek(s, i->block); ! 358: - for(n = i->nbytes, len = nb*s->blocksize; n > 0;){ ! 359: - if(len > n){ ! 360: - len = n; ! 361: - nb = (len+s->blocksize-1)/s->blocksize; ! 362: - } ! 363: - Read(s, b, nb); ! 364: - if(write(fd, b, (int)len) != len){ ! 365: - perror("write"); ! 366: - return(1); ! 367: - } ! 368: - n -= len; ! 369: - } ! 370: - close(fd); ! 371: - return(0); ! 372: -} ! 373: //GO.SYSIN DD crap ! 374: echo flink.c 1>&2 ! 375: sed 's/.//' >flink.c <<'//GO.SYSIN DD flink.c' ! 376: -#include <libc.h> ! 377: -#include "worm.h" ! 378: - ! 379: -static Inode *inodebase; ! 380: -static char *namebase; ! 381: -static long nnames, ninodes; ! 382: -static char *expanded; ! 383: -static readinodes; ! 384: -static ifd; ! 385: - ! 386: -static Inode *diskinode(); ! 387: - ! 388: -static Inode * ! 389: -finode(s) ! 390: - char *s; ! 391: -{ ! 392: - register lo, hi, m; ! 393: - register Inode *i; ! 394: - ! 395: - if(readinodes == 0) ! 396: - return(diskinode(s)); ! 397: -#define EXPAND(in) (i = inodebase+(in), expanded[in]?0:(i->name.n=i->name.o+namebase, expanded[in]=1)) ! 398: -#define CMP(str, in) (EXPAND(in), strcmp(str, i->name.n)) ! 399: - ! 400: - if(CMP(s, lo = 0) < 0) ! 401: - return(0); ! 402: - if(CMP(s, (hi = ninodes)-1) > 0) ! 403: - return(0); ! 404: - while(lo < hi-1){ ! 405: - m = (lo+hi)/2; ! 406: - if(CMP(s, m) < 0) ! 407: - hi = m; ! 408: - else ! 409: - lo = m; ! 410: - } ! 411: - if(CMP(s, lo) == 0) ! 412: - return(inodebase+lo); ! 413: - else ! 414: - return(0); ! 415: -} ! 416: - ! 417: -static void ! 418: -ftraverse(fn) ! 419: - void (*fn)(); ! 420: -{ ! 421: - register Inode *i; ! 422: - register n; ! 423: - ! 424: - if(readinodes == 0){ ! 425: - readinodes = 1; ! 426: - lseek(ifd, 8L, 0); ! 427: - read(ifd, (char *)inodebase, (int)ninodes*sizeof(Inode)); ! 428: - } ! 429: - for(n = 0; n < ninodes; n++){ ! 430: - EXPAND(n); ! 431: - (*fn)(i); ! 432: - } ! 433: -} ! 434: - ! 435: -fastlink(s, msg, ifn, tfn) ! 436: - Superblock *s; ! 437: - char **msg; ! 438: - Inode *(**ifn)(); ! 439: - void (**tfn)(); ! 440: -{ ! 441: - int n; ! 442: - long t; ! 443: - static char buf[256]; ! 444: - ! 445: - *msg = 0; ! 446: - *ifn = finode; ! 447: - *tfn = ftraverse; ! 448: - sprint(buf, "/usr/worm/tmp/%s", s->vol_id); ! 449: - if((ifd = open(buf, 0)) < 0) ! 450: - return(0); ! 451: - read(ifd, (char *)&t, 4); ! 452: - if(t != s->ctime) ! 453: - return(0); ! 454: - read(ifd, (char *)&ninodes, 4); ! 455: - inodebase = (Inode *)malloc(n = ninodes*sizeof(Inode)); ! 456: - expanded = malloc((int)ninodes); ! 457: - memset(expanded, 0, (int)ninodes); ! 458: - lseek(ifd, (long)n, 1); ! 459: - readinodes = 0; ! 460: - read(ifd, (char *)&nnames, 4); ! 461: - namebase = malloc((int)nnames); ! 462: - read(ifd, namebase, (int)nnames); ! 463: - numinodes = ninodes; ! 464: - numnamechars = nnames; ! 465: - return(1); ! 466: -} ! 467: - ! 468: -static ! 469: -readi(ino, ip) ! 470: - Inode *ip; ! 471: -{ ! 472: - static myino = -1; ! 473: - static Inode myi; ! 474: - ! 475: - if(ino != myino){ ! 476: - myino = ino; ! 477: - lseek(ifd, 8L+myino*sizeof(Inode), 0); ! 478: - read(ifd, (char *)&myi, sizeof myi); ! 479: - myi.name.n = myi.name.o+namebase; ! 480: - } ! 481: - *ip = myi; ! 482: -} ! 483: - ! 484: -static Inode * ! 485: -diskinode(s) ! 486: - char *s; ! 487: -{ ! 488: - register lo, hi, m; ! 489: - static Inode ii; ! 490: - register Inode *i = ⅈ ! 491: - ! 492: -#define READ(in) readi(in, i) ! 493: -#undef CMP ! 494: -#define CMP(str, in) (READ(in), strcmp(str, i->name.n)) ! 495: - ! 496: - if(ninodes <= 0) ! 497: - return(0); ! 498: - if(CMP(s, lo = 0) < 0) ! 499: - return(0); ! 500: - if(CMP(s, (hi = ninodes)-1) > 0) ! 501: - return(0); ! 502: - while(lo < hi-1){ ! 503: - m = (lo+hi)/2; ! 504: - if(CMP(s, m) < 0) ! 505: - hi = m; ! 506: - else ! 507: - lo = m; ! 508: - } ! 509: - if(CMP(s, lo) == 0) ! 510: - return(i); ! 511: - else ! 512: - return(0); ! 513: -} ! 514: //GO.SYSIN DD flink.c ! 515: echo getopt.c 1>&2 ! 516: sed 's/.//' >getopt.c <<'//GO.SYSIN DD getopt.c' ! 517: -#define ERR(str, chr) if(opterr){fprint(2, "%s%s%c\n", argv[0], str, chr);} ! 518: -int opterr = 1; ! 519: -int optind = 1; ! 520: -int optopt; ! 521: -char *optarg; ! 522: -char *strchr(); ! 523: - ! 524: -int ! 525: -getopt (argc, argv, opts) ! 526: -char **argv, *opts; ! 527: -{ ! 528: - static int sp = 1; ! 529: - register c; ! 530: - register char *cp; ! 531: - ! 532: - if (sp == 1) ! 533: - if (optind >= argc || ! 534: - argv[optind][0] != '-' || argv[optind][1] == '\0') ! 535: - return -1; ! 536: - else if (strcmp(argv[optind], "--") == 0) { ! 537: - optind++; ! 538: - return -1; ! 539: - } ! 540: - optopt = c = argv[optind][sp]; ! 541: - if (c == ':' || (cp=strchr(opts, c)) == 0) { ! 542: - ERR (": illegal option -- ", c); ! 543: - if (argv[optind][++sp] == '\0') { ! 544: - optind++; ! 545: - sp = 1; ! 546: - } ! 547: - return '?'; ! 548: - } ! 549: - if (*++cp == ':') { ! 550: - if (argv[optind][sp+1] != '\0') ! 551: - optarg = &argv[optind++][sp+1]; ! 552: - else if (++optind >= argc) { ! 553: - ERR (": option requires an argument -- ", c); ! 554: - sp = 1; ! 555: - return '?'; ! 556: - } else ! 557: - optarg = argv[optind++]; ! 558: - sp = 1; ! 559: - } else { ! 560: - if (argv[optind][++sp] == '\0') { ! 561: - sp = 1; ! 562: - optind++; ! 563: - } ! 564: - optarg = 0; ! 565: - } ! 566: - return c; ! 567: -} ! 568: //GO.SYSIN DD getopt.c ! 569: echo in.c 1>&2 ! 570: sed 's/.//' >in.c <<'//GO.SYSIN DD in.c' ! 571: -#include <libc.h> ! 572: -#include <fio.h> ! 573: -#include "worm.h" ! 574: - ! 575: -int bad = 0; ! 576: -long nbytes; ! 577: -long blkdone; ! 578: -long nfiles; ! 579: -char *argout; ! 580: - ! 581: -static Inode *inodes; ! 582: -static long ip; ! 583: -static long ninodes = 0; ! 584: -static char *nameb; ! 585: -static long np; ! 586: -static long nnameb = 0; ! 587: -static long nblocks; ! 588: -#define IINC 1024 ! 589: -#define NINC (64*IINC) ! 590: - ! 591: -ininit() ! 592: -{ ! 593: - if(nnameb == 0){ ! 594: - nameb = malloc((unsigned)(nnameb = NINC)); ! 595: - if(nameb == 0){ ! 596: - fprint(2, "wwrite: malloc fail, %d bytes\n", nnameb); ! 597: - exit(1); ! 598: - } ! 599: - } ! 600: - np = 0; ! 601: - if(ninodes == 0){ ! 602: - inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC)); ! 603: - if(inodes == 0){ ! 604: - fprint(2, "wwrite: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 605: - exit(1); ! 606: - } ! 607: - } ! 608: - ip = 0; ! 609: - nblocks = 0; ! 610: -} ! 611: - ! 612: -inadd(s, i) ! 613: - Superblock *s; ! 614: - register Inode *i; ! 615: -{ ! 616: - register long len; ! 617: - ! 618: - len = strlen(i->name.n)+1; ! 619: - if(np+len > nnameb){ ! 620: - while(np+len > nnameb) ! 621: - nnameb += NINC; ! 622: - nameb = realloc(nameb, (unsigned)nnameb); ! 623: - if(nameb == 0){ ! 624: - fprint(2, "wwrite: realloc fail, %d bytes\n", nnameb); ! 625: - exit(1); ! 626: - } ! 627: - } ! 628: - strcpy(nameb+np, i->name.n); ! 629: - i->name.o = np; ! 630: - np += len; ! 631: - i->block = s->nextffree + nblocks; ! 632: - if(ip == ninodes){ ! 633: - ninodes += IINC; ! 634: - inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode)); ! 635: - if(inodes == 0){ ! 636: - fprint(2, "wwrite: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 637: - exit(1); ! 638: - } ! 639: - } ! 640: - inodes[ip++] = *i; ! 641: - nblocks += (i->nbytes+s->blocksize-1)/s->blocksize; ! 642: - return(0); ! 643: -} ! 644: - ! 645: -inwrite(s, arg) ! 646: - Superblock *s; ! 647: - void *arg; ! 648: -{ ! 649: - int i, j; ! 650: - long next = s->nextffree; ! 651: - char *e; ! 652: - ! 653: - if(e = lkwri(s, inodes, ip, nameb, np, nblocks)){ ! 654: - fprint(2, "%s\n", e); ! 655: - bad = 1; ! 656: - return; ! 657: - } ! 658: - Seek(s, next); ! 659: - argout[2] = ' '; ! 660: - for(i = 0; i < ip; i++){ ! 661: - inodes[i].block = next; ! 662: - inodes[i].name.n = inodes[i].name.o + nameb; ! 663: - writeout(s, &inodes[i], &next, arg); ! 664: - j = (blkdone*100)/nblocks; ! 665: - argout[0] = j/10+'0'; ! 666: - argout[1] = j%10+'0'; ! 667: - } ! 668: -} ! 669: //GO.SYSIN DD in.c ! 670: echo inode.c 1>&2 ! 671: sed 's/.//' >inode.c <<'//GO.SYSIN DD inode.c' ! 672: -#include <libc.h> ! 673: -#include "worm.h" ! 674: -#include <sys/types.h> ! 675: -#include <sys/udaioc.h> ! 676: - ! 677: -Inode *(*inodefn)(); ! 678: -void (*traversefn)(); ! 679: -extern Inode *vinodefn(), *binodefn(); ! 680: -extern void vtraverse(), btraverse(); ! 681: -extern char *lkopi(), *cbtinit(); ! 682: -long numinodes; ! 683: -long numnamechars; ! 684: - ! 685: -char * ! 686: -openinode(s, flags) ! 687: - register Superblock *s; ! 688: -{ ! 689: - short fd = s->fd; ! 690: - char *b, *z; ! 691: - long blk; ! 692: - unsigned short ibuf[3]; ! 693: - static char buf[64]; ! 694: - extern char *getenv(); ! 695: - extern long atol(); ! 696: -int goo; extern errno; int ntry; ! 697: - ! 698: - if(z = getenv("WORMZERO")) ! 699: - blk = atol(z); ! 700: - else ! 701: - blk = 0; ! 702: - ntry = 0; ! 703: -loop: ! 704: - bigseek(s->fd, blk, 1024, 0); ! 705: - if(((goo = read(s->fd, (char *)ibuf, sizeof ibuf)) != sizeof ibuf) || ! 706: - ((((long)ibuf[1])<<16|ibuf[0]) != SMAGIC)){ ! 707: - if((goo < 0) && (errno == ENXIO)) ! 708: - blk++; /* blank check (unwritten), try next blk */ ! 709: - else if((goo == sizeof ibuf) && (ibuf[0] == 0) && (ibuf[1] == 0)) ! 710: - blk++; /* zeroes(??), try next blk */ ! 711: - else { ! 712: - fprint(2, "DEBUGGING[%d]: read=%d magic=0x%lx errno=%d\n", ! 713: - ntry, goo, (((long)ibuf[1])<<16|ibuf[0]), errno); ! 714: - if(ntry++ < 3) ! 715: - goto loop; ! 716: - } ! 717: - bigseek(s->fd, blk, 1024, 0); ! 718: - if(read(s->fd, (char *)ibuf, sizeof ibuf) < sizeof ibuf) ! 719: - return("no block size"); ! 720: - } ! 721: - if(flags&SPIN_DOWN) ! 722: - ioctl(s->fd, UIOSPDW); ! 723: - s->blocksize = ibuf[2]; /* magic is 0-1 */ ! 724: - if((b = malloc(s->blocksize)) == 0){ ! 725: - sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 726: - return(buf); ! 727: - } ! 728: - bigseek(s->fd, blk, 1024, 0); ! 729: - if(read(s->fd, b, s->blocksize) != s->blocksize) ! 730: - return("superblock read error"); ! 731: - *s = *((Superblock *)b); ! 732: - free(b); ! 733: - s->fd = fd; ! 734: - if(s->myblock == 0) ! 735: - s->myblock = blk; ! 736: - switch(s->version) ! 737: - { ! 738: - case VLINK: ! 739: - if(flags&DO_INODE){ ! 740: - Superblock tmpsb; ! 741: - ! 742: - tmpsb = *s; ! 743: - if(b = lkopi(s, blk, 0)) ! 744: - return(b); ! 745: - if(fastlink(s, &b, &inodefn, &traversefn)) ! 746: - return(b); ! 747: - *s = tmpsb; ! 748: - } ! 749: - inodefn = vinodefn; ! 750: - traversefn = vtraverse; ! 751: - return(lkopi(s, blk, flags&DO_INODE)); ! 752: - case VBTREE: ! 753: - inodefn = binodefn; ! 754: - traversefn = btraverse; ! 755: - return(cbtinit(s, blk, flags&DO_INODE)); ! 756: - default: ! 757: - sprint(buf, "unknown version %d@%ld", s->version, blk); ! 758: - return(buf); ! 759: - } ! 760: -} ! 761: //GO.SYSIN DD inode.c ! 762: echo io.c 1>&2 ! 763: sed 's/.//' >io.c <<'//GO.SYSIN DD io.c' ! 764: -#include <libc.h> ! 765: -#include "worm.h" ! 766: - ! 767: -Read(s, buf, n) ! 768: - register Superblock *s; ! 769: - char *buf; ! 770: - long n; ! 771: -{ ! 772: - register k; ! 773: - int len; ! 774: - ! 775: - n *= s->blocksize; ! 776: - if(n != (int)n){ ! 777: - fprint(2, "bad arg to Read n=%ld\n", n); ! 778: - abort(); ! 779: - } ! 780: - len = BIGBLOCK; ! 781: - while(n){ ! 782: - if(n < len) len = n; ! 783: - if((k = read(s->fd, buf, len)) != len){ ! 784: - if(k && (errno != ENXIO)){ ! 785: - perror("Read"); ! 786: - exit(1); ! 787: - } ! 788: - return(1); ! 789: - } ! 790: - n -= len; ! 791: - buf += len; ! 792: - } ! 793: - return(0); ! 794: -} ! 795: - ! 796: -Write(s, buf, n) ! 797: - register Superblock *s; ! 798: - char *buf; ! 799: - long n; ! 800: -{ ! 801: - register k; ! 802: - int len; ! 803: - char msg[256]; ! 804: - ! 805: - n *= s->blocksize; ! 806: - if(n != (int)n){ ! 807: - fprint(2, "bad arg to Write n=%d\n", n); ! 808: - abort(); ! 809: - } ! 810: - len = BIGBLOCK; ! 811: - while(n){ ! 812: - if(n < len) len = n; ! 813: - if((k = write(s->fd, buf, len)) != len){ ! 814: - sprint(msg, "Write %d blks (%dB)", n/s->blocksize, n); ! 815: - perror(msg); ! 816: - return(1); ! 817: - } ! 818: - n -= len; ! 819: - buf += len; ! 820: - } ! 821: - return(0); ! 822: -} ! 823: - ! 824: -Seek(s, blk) ! 825: - register Superblock *s; ! 826: - long blk; ! 827: -{ ! 828: - bigseek(s->fd, blk, s->blocksize, 0); ! 829: -} ! 830: - ! 831: -bigseek(fd, a, b, ptr) ! 832: -{ ! 833: -#define SEEK64 /**/ ! 834: -#ifdef SEEK64 ! 835: -#include <sys/param.h> ! 836: - llong_t off; ! 837: - extern llong_t Llmul(), ltoL(); ! 838: - ! 839: - off = Llmul(ltoL(a), b); ! 840: - llseek(fd, off, ptr); ! 841: -#else ! 842: - lseek(fd, a*(long)b, ptr); ! 843: -#endif ! 844: -} ! 845: //GO.SYSIN DD io.c ! 846: echo mapdev.c 1>&2 ! 847: sed 's/.//' >mapdev.c <<'//GO.SYSIN DD mapdev.c' ! 848: -char * ! 849: -mapdev(s) ! 850: - char *s; ! 851: -{ ! 852: - static char buf[128]; ! 853: - ! 854: - if((s[1] == 0) && (*s >= '0') && (*s <= '9')){ ! 855: - sprint(buf, "/dev/worm%c", *s); ! 856: - s = buf; ! 857: - } ! 858: - return(s); ! 859: -} ! 860: //GO.SYSIN DD mapdev.c ! 861: echo mkfile 1>&2 ! 862: sed 's/.//' >mkfile <<'//GO.SYSIN DD mkfile' ! 863: -CFLAGS=-g -I. ! 864: -CC=cc ! 865: -LIB=worm.a ! 866: -BIN=/usr/lib/worm ! 867: -L=io inode vlink flink sym getopt mapdev btree LL in timenow ! 868: -OBJ=${L:%=$LIB(%.o)} ! 869: -NPROC=2 ! 870: -# remember to change /usr/bin/worm if you add programs ! 871: -ALL=wmkfs wstat wwrite wread wls woffline wcat wbtree wrm\ ! 872: - wdir wreset wmv wtmpdir wmount wcopy jukebox scsish ! 873: -BALL=${ALL:%=$BIN/%} ! 874: - ! 875: -all:V: $ALL ! 876: - ! 877: -scsish jukebox:Pexit 1: /unix ! 878: - cd scsi; mk both ! 879: - ! 880: -$LIB:Q: $OBJ ! 881: - names=`membername $newprereq` ! 882: - ar rv $LIB $names && rm $names ! 883: - ranlib $LIB ! 884: - ! 885: -'^(w[^.]*)$':R: \\1.o $LIB #O/\\1 ! 886: - $CC $CFLAGS -o $target $stem1.o $LIB -lcbt ! 887: - ! 888: -'^(poot)$':R: \\1.o $LIB #O/\\1 ! 889: - $CC $CFLAGS -o $target $stem1.o $LIB -lcbt ! 890: - ! 891: -'^(O/w[^.]*)$':R: \\1.O $COBJ ! 892: - cyntax $prereq && > $target ! 893: - ! 894: -$BIN/'(w[^.]*)$':R: \\1 ! 895: - cp $stem1 $target && strip $target; chmod 775 $target ! 896: -$BIN/'(scsish|jukebox)':R: \\1 ! 897: - cp $stem1 $target && strip $target; chmod 775 $target ! 898: - ! 899: -sym.o wtree.o thing.o: sym.h ! 900: -wtree.o thing.o: thing.h ! 901: - ! 902: -$LIB(%.o):N: %.o ! 903: -%.o: worm.h ! 904: -O/%.O: %.c ! 905: - cyntax -c $stem.c && mv $stem.O O ! 906: -O/%.O: worm.h ! 907: - ! 908: -pp: ! 909: - smallpr mkfile worm.h *.c ! 910: - ! 911: -clean:V: ! 912: - rm -f *.o *.a $ALL core O/* ! 913: - ! 914: -install:V: $BALL ! 915: - ! 916: -ship:V: shipped ! 917: -shipped: $BALL /usr/bin/worm ! 918: - ship $newprereq && touch $target ! 919: - ! 920: -goo:V: wmv wls wwrite wmkfs ! 921: - set +e ! 922: - > temp ! 923: - wmkfs -ftemp testa ! 924: - wwrite -ftemp testa w*.[ch] ! 925: - wls -ftemp -l wreset.c; wls -ftemp -b wreset.c ! 926: - wmv -ftemp testa wreset.c xxx ! 927: - wls -ftemp -l wreset.c xxx; wls -ftemp -b xxx ! 928: - ! 929: -wild: $BALL ! 930: - dest=wild ship $newprereq && touch $target ! 931: - ! 932: -poot:V: wcopy wls wstat wmkfs ! 933: - > temp1 ! 934: - wmkfs -ftemp1 -n300 test7a; wstat -v -ftemp1 ! 935: - wls -ftemp | wcopy -ftemp -v -m0 testa temp1 test7a ! 936: - wstat -v -ftemp; wls -ftemp -b | sort | mc ! 937: - wstat -v -ftemp1; wls -ftemp1 -b | sort | mc ! 938: - #wstat -v -ftemp; wstat -v -ftemp1 ! 939: - wls -ftemp | wcopy -ftemp -v -m0 testa temp1 test7a ! 940: - wstat -v -ftemp1; wls -ftemp1 -b | sort | mc ! 941: - set +e;(wls -ftemp; echo; wls -ftemp; echo; wls -ftemp)| tee temp2 | wcopy -ftemp -v -m100 testa temp1 test7a ! 942: - wstat -v -ftemp1; wls -ftemp1 -b | sort | mc ! 943: - ! 944: -goop:V: wmkfs wstat wwrite ! 945: - > temp ! 946: - wmkfs -ftemp -n1000 testa; wstat -vftemp ! 947: - wmkfs -n666 -ftemp testa; wstat -vftemp ! 948: //GO.SYSIN DD mkfile ! 949: echo owcopy.c 1>&2 ! 950: sed 's/.//' >owcopy.c <<'//GO.SYSIN DD owcopy.c' ! 951: -#include <libc.h> ! 952: -#include "worm.h" ! 953: -#include "sym.h" ! 954: -#include <sys/types.h> ! 955: -#include <sys/stat.h> ! 956: -#include <pwd.h> ! 957: -#include <grp.h> ! 958: - ! 959: -char *timenow(); ! 960: -long minfree = 40000; ! 961: -int verbose = 0; ! 962: -static char *copy(); ! 963: - ! 964: -main(argc, argv) ! 965: - char **argv; ! 966: -{ ! 967: - char *e; ! 968: - char *dev = "/dev/worm0"; ! 969: - char *dest = 0; ! 970: - Superblock in, out; ! 971: - long start = 1; ! 972: - long count = 1000000L; ! 973: - int c; ! 974: - extern char *optarg; ! 975: - extern int optind; ! 976: - void pr(); ! 977: - ! 978: - while((c = getopt(argc, argv, "vc:m:s:f:")) != -1) ! 979: - switch(c) ! 980: - { ! 981: - case 'c': count = atol(optarg); break; ! 982: - case 'f': dev = optarg; break; ! 983: - case 'm': minfree = atol(optarg); break; ! 984: - case 's': start = atol(optarg); break; ! 985: - case 'v': verbose = 1; break; ! 986: - case '?': usage(); ! 987: - } ! 988: - dev = mapdev(dev); ! 989: - if((in.fd = open(dev, 0)) < 0){ ! 990: - perror(dev); ! 991: - exit(1); ! 992: - } ! 993: - if(optind+3 != argc) ! 994: - usage(); ! 995: - ! 996: - if(e = openinode(&in, SPIN_DOWN)){ ! 997: - fprint(2, "worm copy: %s: %s\n", dev, e); ! 998: - exit(1); ! 999: - } ! 1000: - if(strcmp(argv[optind], in.vol_id)){ ! 1001: - fprint(2, "src vol_id mismatch: expected %s, got %s\n", ! 1002: - argv[optind], in.vol_id); ! 1003: - exit(1); ! 1004: - } ! 1005: - dest = mapdev(argv[optind+1]); ! 1006: - if((out.fd = open(dest, 2)) < 0){ ! 1007: - perror(dest); ! 1008: - exit(1); ! 1009: - } ! 1010: - if(e = openinode(&out, SPIN_DOWN)){ ! 1011: - fprint(2, "worm copy: %s: %s\n", dest, e); ! 1012: - exit(1); ! 1013: - } ! 1014: - if(strcmp(argv[optind+2], out.vol_id)){ ! 1015: - fprint(2, "destination vol_id mismatch: expected %s, got %s\n", ! 1016: - argv[optind+2], out.vol_id); ! 1017: - exit(1); ! 1018: - } ! 1019: - if(e = copy(&in, start, count, &out)){ ! 1020: - fprint(2, "worm copy: %s: %s\n", dest, e); ! 1021: - exit(1); ! 1022: - } ! 1023: - exit(0); ! 1024: -} ! 1025: - ! 1026: -usage() ! 1027: -{ ! 1028: - fprint(2, "Usage: worm copy [-v] [-fdevice] [-s startblk] [-c count] [-m minfree] srcvolid destdev destvolid\n"); ! 1029: - exit(2); ! 1030: -} ! 1031: - ! 1032: -static char * ! 1033: -copy(in, blk, count, out) ! 1034: - register Superblock *in, *out; ! 1035: - long blk, count; ! 1036: -{ ! 1037: - register Inode *i; ! 1038: - short fd = in->fd; ! 1039: - char *b, *err; ! 1040: - long nb, ndata; ! 1041: - char *nameb; ! 1042: - Inode *inodes = 0; ! 1043: - Inode *iend; ! 1044: - long delta; ! 1045: - static char buf[64]; ! 1046: - extern char *lkwri(); ! 1047: - ! 1048: - in->blocksize = 1024; ! 1049: - if((b = malloc(in->blocksize)) == 0){ ! 1050: - sprint(buf, "couldn't malloc buffer (%d bytes)", in->blocksize); ! 1051: - return(buf); ! 1052: - } ! 1053: - Seek(in, blk); ! 1054: - if(Read(in, b, 1)){ ! 1055: - fprint(2, "worm copy: unexpected read error\n"); ! 1056: - exit(1); ! 1057: - } ! 1058: - *in = *((Superblock *)b); ! 1059: - in->fd = fd; ! 1060: - while(count-- > 0){ ! 1061: - if(in->magic != SMAGIC){ ! 1062: - fprint(2, "bad Superblock at %ld\n", blk); ! 1063: - exit(1); ! 1064: - } ! 1065: - if(in->ninodes){ ! 1066: - if(verbose) ! 1067: - fprint(2, "%s reading chunk %s:%ld (%.1f%%)\n", ! 1068: - timenow(), in->vol_id, in->myblock, ! 1069: - in->myblock*100./(float)in->nblocks); ! 1070: - if(out->nfree < minfree){ ! 1071: - fprint(2, "worm copy: disk %s has < %d free at input %d\n", ! 1072: - out->vol_id, minfree, in->myblock); ! 1073: - exit(1); ! 1074: - } ! 1075: - nb = (in->ninodes+(in->blocksize/sizeof(Inode))-1)/(in->blocksize/sizeof(Inode)); ! 1076: - inodes = (Inode *)malloc((unsigned)(in->blocksize*nb)); ! 1077: - if(inodes == 0){ ! 1078: - sprint(buf, "inode malloc(%d) fail, sbrk=%d\n", ! 1079: - (in->blocksize*nb), sbrk(0)); ! 1080: - return(buf); ! 1081: - } ! 1082: - Seek(in, in->binodes); ! 1083: - if(Read(in, (char *)inodes, nb)) ! 1084: - goto skip; ! 1085: - delta = out->nextffree - inodes->block; ! 1086: -print("%d inodes; delta=%d\n", in->ninodes, delta); ! 1087: - for(i = inodes, iend = inodes+in->ninodes; i < iend; i++) ! 1088: - if(i->block > 0) ! 1089: - i->block += delta; ! 1090: - nb = (in->ninochars+in->blocksize-1)/in->blocksize; ! 1091: - nameb = malloc((unsigned)(in->blocksize*nb)); ! 1092: - if(nameb == 0){ ! 1093: - sprint(buf, "name buffer malloc(%d) fail, sbrk=%d\n", ! 1094: - (in->blocksize*nb), sbrk(0)); ! 1095: - return(buf); ! 1096: - } ! 1097: - if(Read(in, nameb, nb)) ! 1098: - goto skip; ! 1099: - ndata = in->binodes - in->myblock - 1; ! 1100: - if(err = lkwri(out, inodes, in->ninodes, nameb, in->ninochars, ndata)){ ! 1101: - fprint(2, "wcopy: lkwri: %s at input %d\n", err, in->myblock); ! 1102: - exit(1); ! 1103: - } ! 1104: - dcopy(in, out, ndata); ! 1105: - } ! 1106: - skip: ! 1107: - blk = in->nextsb; ! 1108: - Seek(in, blk); ! 1109: - if(Read(in, b, 1L)) ! 1110: - break; ! 1111: - *in = *((Superblock *)b); ! 1112: - in->fd = fd; ! 1113: - if(in->myblock == 0) ! 1114: - in->myblock = blk; ! 1115: - } ! 1116: - free(b); ! 1117: - if(verbose) ! 1118: - fprint(2, "%s copy done, %s is %.1f%% full\n", timenow(), out->vol_id, ! 1119: - out->myblock*100.0/(float)out->nblocks); ! 1120: - return((char *)0); ! 1121: -} ! 1122: - ! 1123: -dcopy(in, out, n) ! 1124: - Superblock *in, *out; ! 1125: - long n; ! 1126: -{ ! 1127: - char buf[BIGBLOCK]; ! 1128: - long bs; ! 1129: - ! 1130: - bs = BIGBLOCK/in->blocksize; ! 1131: - Seek(in, in->myblock+1); ! 1132: - Seek(out, out->myblock+1); ! 1133: - while(n > 0){ ! 1134: - if(bs > n) bs = n; ! 1135: - if(Read(in, buf, bs)){ ! 1136: - fprint(2, "wcopy: warning: data read error at %d\n", in->myblock); ! 1137: - } ! 1138: - if(Write(out, buf, bs)){ ! 1139: - fprint(2, "wcopy: dcopy write error\n"); ! 1140: - exit(1); ! 1141: - } ! 1142: - n -= bs; ! 1143: - } ! 1144: -} ! 1145: - ! 1146: -char * ! 1147: -timenow() ! 1148: -{ ! 1149: - long tim; ! 1150: - char *tims; ! 1151: - ! 1152: - time(&tim); ! 1153: - tims = ctime(&tim); ! 1154: - tims[19] = 0; ! 1155: - return(tims); ! 1156: -} ! 1157: //GO.SYSIN DD owcopy.c ! 1158: echo partial.news 1>&2 ! 1159: sed 's/.//' >partial.news <<'//GO.SYSIN DD partial.news' ! 1160: -the worm programs now only run properly on systems ! 1161: -with llseek in the kernel. the three systems that matter ! 1162: //GO.SYSIN DD partial.news ! 1163: echo poot.c 1>&2 ! 1164: sed 's/.//' >poot.c <<'//GO.SYSIN DD poot.c' ! 1165: -#include <libc.h> ! 1166: -#include "sym.h" ! 1167: -#include "worm.h" ! 1168: - ! 1169: -main(argc, argv) ! 1170: - char **argv; ! 1171: -{ ! 1172: - Superblock s; ! 1173: - char buf[1024]; ! 1174: - char *e; ! 1175: - Inode *i; ! 1176: - int c; ! 1177: - char *com = 0; ! 1178: - char *dev = "/dev/worm0"; ! 1179: - extern char *optarg; ! 1180: - extern int optind; ! 1181: - ! 1182: - while((c = getopt(argc, argv, "f:c:")) != -1) ! 1183: - switch(c) ! 1184: - { ! 1185: - case 'c': com = optarg; break; ! 1186: - case 'f': dev = optarg; break; ! 1187: - case '?': usage(); ! 1188: - } ! 1189: - if(optind+2 != argc) ! 1190: - usage(); ! 1191: - dev = mapdev(dev); ! 1192: - if((s.fd = open(dev, 2)) < 0){ ! 1193: - perror(dev); ! 1194: - exit(1); ! 1195: - } ! 1196: - if(e = openinode(&s, SPIN_DOWN)){ ! 1197: - fprint(2, "%s: %s\n", dev, e); ! 1198: - exit(1); ! 1199: - } ! 1200: - if(strcmp(s.vol_id, argv[optind])){ ! 1201: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id); ! 1202: - exit(1); ! 1203: - } ! 1204: - if(s.version != VBTREE){ ! 1205: - fprint(2, "poot: %s must be a btree disk\n", s.vol_id); ! 1206: - exit(1); ! 1207: - } ! 1208: - memset(buf, sizeof buf, 0); ! 1209: - memset(s.vol_id, sizeof s.vol_id, 0); ! 1210: - strcpy(s.vol_id, argv[++optind]); ! 1211: - if(com){ ! 1212: - memset(s.comment, sizeof s.comment, 0); ! 1213: - strcpy(s.comment, com); ! 1214: - } ! 1215: - memcpy(buf, &s, 1024); ! 1216: - lseek(s.fd, 0, 0); ! 1217: - if(write(s.fd, buf, 1024) != 1024){ ! 1218: - perror("write of new superblock"); ! 1219: - exit(1); ! 1220: - } ! 1221: - exit(0); ! 1222: -} ! 1223: - ! 1224: -usage() ! 1225: -{ ! 1226: - fprint(2, "Usage: poot [-fdevice] [-ccnewcomment] vol_id new_vol_id\n"); ! 1227: - exit(1); ! 1228: -} ! 1229: //GO.SYSIN DD poot.c ! 1230: echo scsi/mkfile 1>&2 ! 1231: sed 's/.//' >scsi/mkfile <<'//GO.SYSIN DD scsi/mkfile' ! 1232: -SYS=research ! 1233: -< $SYS.mk ! 1234: -JL=juke.a ! 1235: -X=allocate cold getstatus ioshelves iodr_sh lib load nlun warm ! 1236: -JLIB=${X:%=$JL(%.o)} ! 1237: -JSRC=${X:%=%.c} ! 1238: - ! 1239: -SL=scsi.a ! 1240: -X=s_$IO ge_sense s_volid s_pperror s_fixedstr s_longat s_xd ! 1241: -SLIB=${X:%=$SL(%.o)} ! 1242: - ! 1243: -SHL=scsish.a ! 1244: -GENERIC=ge_dev ge_inq ge_stop ge_start ge_capacity ge_display\ ! 1245: - ge_reset ge_tur ge_scsi ge_readt ge_copy # ge_sense in $SL ! 1246: -SONY=so_dev so_inq so_alt so_config so_status so_eject so_rel so_set\ ! 1247: - so_shelfside so_diskid so_internal so_media so_readid so_copy\ ! 1248: - so_i0.tab so_i1.tab so_scsi.tab so_sense so_nesd.tab ! 1249: -WREN=wr_dev wr_inq wr_rmode wr_wmode wr_diag ! 1250: -X=$GENERIC $SONY $WREN ! 1251: -SHLIB=${X:%=$SHL(%.o)} ! 1252: - ! 1253: -all:V: jukebox scsish ! 1254: - ! 1255: -both:V: ../jukebox ../scsish ! 1256: - ! 1257: -../%: % ! 1258: - cp $prereq $target ! 1259: - ! 1260: -jukebox: jukebox.o $JL $SHL $SL ! 1261: - $CC $CFLAGS -o $target $prereq $LDFLAGS ! 1262: - ! 1263: -scsish: scsish.o $SHL $SL ! 1264: - $CC $CFLAGS -o $target $prereq $LDFLAGS ! 1265: - ! 1266: -jpp:V: ! 1267: - pr mkfile juke.h scsi.h jukebox.c $JSRC | lp -ddp -n2 ! 1268: - ! 1269: -poot:V: scsish ! 1270: - echo 'dev scsi ! 1271: - copy 4 0 10 5 0 1' | scsish ! 1272: - ! 1273: -scsi.cpio:V: inc/scsi.h ! 1274: - find * -print | sed -e '/\.[oa]$/d' -e '/\.cpio$/d' | cpio -oc > $target ! 1275: -inc/scsi.h:Pcmp -s: /usr/include/scsi.h ! 1276: - cp $prereq $target ! 1277: - ! 1278: - ! 1279: -# below is just magic; believe it. ! 1280: - ! 1281: -$JL(%.o):N: %.o ! 1282: -$JL:Q: $JLIB ! 1283: - names=`membername $newprereq` ! 1284: - ar rv $JL $names && rm $names ! 1285: - $RANLIB $JL ! 1286: - ! 1287: -$SL(%.o):N: %.o ! 1288: -$SL:Q: $SLIB ! 1289: - names=`membername $newprereq` ! 1290: - ar rv $SL $names && rm $names ! 1291: - $RANLIB $SL ! 1292: - ! 1293: -$SHL(%.o):N: %.o ! 1294: -$SHL:Q: $SHLIB ! 1295: - names=`membername $newprereq` ! 1296: - ar rv $SHL $names && rm $names ! 1297: - $RANLIB $SHL ! 1298: - ! 1299: -s_%.o: scsi/%.c ! 1300: - cd scsi; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target ! 1301: -so_%.o: sony/%.c ! 1302: - cd sony; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target ! 1303: -so_%.o: sony/fns.h ! 1304: -ge_%.o: generic/%.c ! 1305: - cd generic; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target ! 1306: -ge_%.o: generic/fns.h ! 1307: -wr_%.o: wren/%.c ! 1308: - cd wren; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target ! 1309: -wr_%.o: wren/fns.h ! 1310: -so_%.o wr_%.o ge_%.o: scsish.h scsi.h ! 1311: - ! 1312: -so_%.tab.o:Q: sony/%.tab ! 1313: - cd sony ! 1314: - echo generating $target ! 1315: - p=$stem.tab ! 1316: - awk -F' ' ' ! 1317: - BEGIN { h["0"]=0;h["1"]=1;h["2"]=2;h["3"]=3;h["4"]=4;h["5"]=5;h["6"]=6;h["7"]=7; ! 1318: - h["8"]=8;h["9"]=9;h["a"]=10;h["b"]=11;h["c"]=12;h["d"]=13;h["e"]=14;h["f"]=15; ! 1319: - } ! 1320: - function done( i){ ! 1321: - for(i = 0; i < 256; i++) if(x[i]){ ! 1322: - print "\t\"" x[i] "\"," ! 1323: - x[i] = "" ! 1324: - } else printf "\t\"<#%x>\",\n", i ! 1325: - print "};" ! 1326: - } ! 1327: - function hex(n, i){ ! 1328: - return(h[substr(n, 1, 1)]*16+h[substr(n, 2, 1)]); ! 1329: - } ! 1330: - NF == 1 { if(NR > 1) done(); print "char *" $1 "[] = {" } ! 1331: - NF > 1 { x[hex($1)] = $2; } ! 1332: - END { done(); }' < $p > $p.c && $CC $CFLAGS -c $p.c && mv $p.o ../$target ! 1333: - rm $p.c ! 1334: //GO.SYSIN DD scsi/mkfile ! 1335: echo scsi/cold.c 1>&2 ! 1336: sed 's/.//' >scsi/cold.c <<'//GO.SYSIN DD scsi/cold.c' ! 1337: -#include <stddef.h> ! 1338: -#include <stdio.h> ! 1339: -#include <string.h> ! 1340: -#include "scsi.h" ! 1341: -#include "juke.h" ! 1342: - ! 1343: -static sort(char *buf); ! 1344: - ! 1345: -cold_inv(char type, char *buf) ! 1346: -{ ! 1347: - Side side; ! 1348: - int drive, sh, nsh; ! 1349: - int n; ! 1350: - char vol_id[512]; ! 1351: - int didit[NSHELF]; ! 1352: - ! 1353: - if(j_getstatus(buf)) /* get the jukebox status */ ! 1354: - return(-1); ! 1355: -printf("getstatus done\n"); ! 1356: - /* first clear out nonexistent labels */ ! 1357: - n = 0; ! 1358: - for(sh = 0; sh < NSHELF; sh++){ ! 1359: - if((j_status.shelf[sh]&0xC0) == 0xC0){ ! 1360: - n++; ! 1361: - j_shelf[sh] = "there"; ! 1362: - } else ! 1363: - j_shelf[sh] = 0; ! 1364: - didit[sh] = 0; ! 1365: - } ! 1366: - printf("%d disks in shelves.\n", n); ! 1367: - /* second, clear the drives */ ! 1368: - for(sh = 0; sh < NSHELF; sh++) ! 1369: - if(j_shelf[sh] == 0) ! 1370: - break; ! 1371: - for(drive = 0; drive < 8; drive++){ ! 1372: - if(!j_status.lun[drive].diskin) ! 1373: - continue; /* no disk in drive */ ! 1374: -printf("clearing drive %d:\n", drive); ! 1375: - if(j_status.lun[drive].diskindrive && !j_status.lun[drive].shelfvalid){ ! 1376: - if(j_drive_to_shelf(drive, sh, SIDEA, buf)) ! 1377: - return(-1); ! 1378: - for(sh++; sh < NSHELF; sh++) ! 1379: - if(j_shelf[sh] == 0) ! 1380: - break; ! 1381: - n++; ! 1382: - } else ! 1383: - if(j_drive_to_shelf(drive, -1, SIDEA, buf)) ! 1384: - return(-1); ! 1385: - printf("\n"); ! 1386: - } ! 1387: - printf("reloading %d disks.\n", n); ! 1388: - side = SIDEA; ! 1389: - drive = min(nlun+1, NLUN-1); ! 1390: - j_wrshelf = 1; ! 1391: - for(sh = 0; sh < NSHELF; sh++){ ! 1392: - if(didit[sh]) ! 1393: - continue; ! 1394: - j_shelf[sh] = 0; ! 1395: - /* the C0 means disk properly present (not temp) */ ! 1396: - if((j_status.shelf[sh]&0xC0) == 0xC0){ ! 1397: - if(getvol(sh, drive, vol_id, &side)) ! 1398: - errexit(vol_id); ! 1399: - switch(type) ! 1400: - { ! 1401: - case 'c': ! 1402: - for(nsh = 0; j_shelf[nsh]; nsh++) ! 1403: - ; ! 1404: - break; ! 1405: - case 's': ! 1406: - case 'r': ! 1407: - while(j_shelf[nsh = nrand(NSHELF)]) ! 1408: - ; ! 1409: - break; ! 1410: - case 'u': ! 1411: - default: ! 1412: - nsh = sh; ! 1413: - break; ! 1414: - } ! 1415: - printf("%s@%d -> %d\n", vol_id, sh, nsh); ! 1416: - if(j_drive_to_shelf(drive, nsh, side, buf) < 0) ! 1417: - return(-1); ! 1418: - j_shelf[nsh] = strdup(vol_id); ! 1419: - didit[nsh] = 1; ! 1420: - sleep(2); ! 1421: - } ! 1422: - } ! 1423: - printf("process any new disks.\n"); ! 1424: - if(warm_inv(buf)) ! 1425: - return(-1); ! 1426: - if(type == 's') ! 1427: - return(sort(buf)); ! 1428: - return(0); ! 1429: -} ! 1430: - ! 1431: -getvol(int sh, int drive, char *vol_id, int *side) ! 1432: -{ ! 1433: - int i; ! 1434: - char buf[512]; ! 1435: - ! 1436: - if(j_shelf_to_drive(sh, SIDEA, drive, vol_id) < 0) ! 1437: - return(-1); ! 1438: - if((i = j_rvolid(drive, buf)) < 0) ! 1439: - goto softerr; ! 1440: - if(i == 0) ! 1441: - *side = SIDEA; ! 1442: - else { ! 1443: - *side = SIDEB; ! 1444: - if(j_drive_to_shelf(drive, sh, SIDEA, vol_id) < 0) ! 1445: - return(-1); ! 1446: - if(j_shelf_to_drive(sh, SIDEB, drive, vol_id) < 0) ! 1447: - return(-1); ! 1448: - if((i = j_rvolid(drive, buf)) < 0) ! 1449: - goto softerr; ! 1450: - } ! 1451: - if(i > 0) ! 1452: - strcpy(vol_id, UNALLOCATED); ! 1453: - else { ! 1454: - strcpy(vol_id, buf); ! 1455: - i = strlen(vol_id)-1; ! 1456: - if(i < 0){ ! 1457: - sprintf(buf, "apparently good superblock but null vol_id"); ! 1458: - goto softerr; ! 1459: - } else if(vol_id[i] == 'a') ! 1460: - vol_id[i] = 0; ! 1461: - else if(vol_id[i] == 'b'){ ! 1462: - vol_id[i] = 0; ! 1463: - *side = !*side; ! 1464: - } else { ! 1465: - sprintf(buf, "vol_id '%s' must end in a or b", vol_id); ! 1466: - strcpy(vol_id, buf); ! 1467: - return(-1); ! 1468: - } ! 1469: - } ! 1470: - return(0); ! 1471: -softerr: ! 1472: - *side = SIDEA; ! 1473: - fprintf(stderr, "error in reading shelf %d: %s; proceeding\n", sh, buf); ! 1474: - sprintf(vol_id, "DISK_ERROR%d", sh); ! 1475: - gen_reset(0, (int *)0, 0, (char **)0, buf); ! 1476: - return(0); ! 1477: -} ! 1478: - ! 1479: -static int index[NSHELF]; ! 1480: -static ! 1481: -cmp(int *a, int *b) ! 1482: -{ ! 1483: - char *sa = j_shelf[*a], *sb = j_shelf[*b]; ! 1484: - ! 1485: - if((sa == 0) && (sb == 0)) return(0); ! 1486: - if(sa == 0) return(-1); ! 1487: - if(sb == 0) return(1); ! 1488: - return(strcmp(sa, sb)); ! 1489: -} ! 1490: - ! 1491: -static char *disk[8]; ! 1492: - ! 1493: -static ! 1494: -sd(int a, int b, char *err) ! 1495: -{ ! 1496: - disk[b] = j_shelf[a]; ! 1497: - return(j_shelf_to_drive(a, SIDEB, b, err)); ! 1498: -} ! 1499: -static ! 1500: -ds(int a, int b, char *err) ! 1501: -{ ! 1502: - j_shelf[b] = disk[a]; ! 1503: - return(j_drive_to_shelf(a, b, SIDEB, err)); ! 1504: -} ! 1505: - ! 1506: -static ! 1507: -sort(char *errbuf) ! 1508: -{ ! 1509: - int i, j, org; ! 1510: - ! 1511: - for(i = 0; i < NSHELF; i++) ! 1512: - index[i] = i; ! 1513: - qsort(index, NSHELF, sizeof index[0], cmp); ! 1514: - for(i = 0; i < NSHELF; i++){ ! 1515: - if(index[i] < 0) continue; ! 1516: - if(sd(org = i, NLUN-1, errbuf) < 0) ! 1517: - return(-1); ! 1518: - j = index[i]; ! 1519: - index[i] = -1; ! 1520: - while(j != org){ ! 1521: - if(sd(j, NLUN-2, errbuf) < 0) ! 1522: - return(-1); ! 1523: - if(ds(NLUN-2, i, errbuf) < 0) ! 1524: - return(-1); ! 1525: - i = j; ! 1526: - if(index[i] < 0) ! 1527: - break; ! 1528: - j = index[i]; ! 1529: - index[i] = -1; ! 1530: - } ! 1531: - if(ds(NLUN-1, i, errbuf) < 0) ! 1532: - return(-1); ! 1533: - } ! 1534: - return(0); ! 1535: -} ! 1536: //GO.SYSIN DD scsi/cold.c ! 1537: echo scsi/osanity/tstfill.c 1>&2 ! 1538: sed 's/.//' >scsi/osanity/tstfill.c <<'//GO.SYSIN DD scsi/osanity/tstfill.c' ! 1539: -short pat[][8] = ! 1540: -{ ! 1541: - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, ! 1542: - 0xb6db, 0xeb6d, 0xb6db, 0xeb6d, 0xb6db, 0xeb6d, 0xb6db, 0xeb6d, ! 1543: - 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, ! 1544: - 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, ! 1545: - 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, ! 1546: -}; ! 1547: - ! 1548: -fillbuf(buf, n) ! 1549: - char *buf; ! 1550: -{ ! 1551: - int i = 0; ! 1552: - register j; ! 1553: - ! 1554: - while(n > 0){ ! 1555: - if(i >= sizeof(pat)/sizeof(pat[0])) ! 1556: - i = 0; ! 1557: - for(j = 0; j < 64; j++, buf += 16) ! 1558: - memcpy(buf, pat[i], 16); ! 1559: - n--; ! 1560: - i++; ! 1561: - } ! 1562: -} ! 1563: //GO.SYSIN DD scsi/osanity/tstfill.c ! 1564: echo scsi/osanity/tstrd.c 1>&2 ! 1565: sed 's/.//' >scsi/osanity/tstrd.c <<'//GO.SYSIN DD scsi/osanity/tstrd.c' ! 1566: -main(argc, argv) ! 1567: - char **argv; ! 1568: -{ ! 1569: - long first, last, t; ! 1570: - char buf[32768], buf1[32768], *bufp; ! 1571: - int fd, n; ! 1572: - char *worm = "/dev/worm0"; ! 1573: - ! 1574: - if((argc < 3) || (argc > 4)){ ! 1575: - print("Usage: tstrd [device] firstblock firstnonblock\n"); ! 1576: - exit(1); ! 1577: - } ! 1578: - if(argc > 3) ! 1579: - worm = *++argv; ! 1580: - if((fd = open(worm, 0)) < 0){ ! 1581: - perror(worm); ! 1582: - exit(1); ! 1583: - } ! 1584: - first = atol(argv[1]); ! 1585: - last = atol(argv[2]); ! 1586: - if((first < 0) || (last <= first)){ ! 1587: - print("bad first=%ld last=%ld\n", first, last); ! 1588: - exit(1); ! 1589: - } ! 1590: - print("reading blocks %ld - %ld inclusive on %s\n", first, last-1, worm); ! 1591: - fillbuf(buf, 32); ! 1592: - bufp = &buf[1024*(first%5)]; ! 1593: - lseek(fd, first*1024, 0); ! 1594: - while(first < last){ ! 1595: - n = last-first; ! 1596: - if(n > 25) n = 25; ! 1597: - if(read(fd, buf1, n*1024) != n*1024){ ! 1598: - print("block %ld: ", first); ! 1599: - perror("read"); ! 1600: - exit(1); ! 1601: - } ! 1602: - if(memcmp(bufp, buf1, n*1024)){ ! 1603: - print("block %ld: bytes differ\n", first); ! 1604: - exit(1); ! 1605: - } ! 1606: - if((first%5000) == 0){ ! 1607: - t = time((long *)0); ! 1608: - print("done block %ld: %s", first, ctime(&t)); ! 1609: - } ! 1610: - first += n; ! 1611: - } ! 1612: - exit(0); ! 1613: -} ! 1614: //GO.SYSIN DD scsi/osanity/tstrd.c ! 1615: echo scsi/osanity/tstsk.c 1>&2 ! 1616: sed 's/.//' >scsi/osanity/tstsk.c <<'//GO.SYSIN DD scsi/osanity/tstsk.c' ! 1617: -main(argc, argv) ! 1618: - char **argv; ! 1619: -{ ! 1620: - long first, last, t; ! 1621: - char buf[32768], buf1[32768], *bufp; ! 1622: - int fd, n, i; ! 1623: - char *worm = "/dev/worm0"; ! 1624: - long bands[50][2]; ! 1625: - int nbands; ! 1626: - long loop; ! 1627: - double tseek, tbl; ! 1628: - float floop; ! 1629: - ! 1630: - if(argc < 3){ ! 1631: - print("Usage: tstsk [device] firstblock firstnonblock ...\n"); ! 1632: - exit(1); ! 1633: - } ! 1634: - if((argc&1) == 0) ! 1635: - worm = *++argv; ! 1636: - if((fd = open(worm, 0)) < 0){ ! 1637: - perror(worm); ! 1638: - exit(1); ! 1639: - } ! 1640: - nbands = 0; ! 1641: - while(*++argv){ ! 1642: - first = atol(*argv); ! 1643: - last = atol(*++argv); ! 1644: - if((first < 0) || (last <= first)){ ! 1645: - print("bad first=%ld last=%ld\n", first, last); ! 1646: - exit(1); ! 1647: - } ! 1648: - bands[nbands][0] = first; ! 1649: - bands[nbands][1] = last; ! 1650: - nbands++; ! 1651: - } ! 1652: - tseek = tbl = 0; ! 1653: - last = 0; ! 1654: - fillbuf(buf, 32); ! 1655: - for(loop = 0;; loop++){ ! 1656: - i = nrand(nbands); ! 1657: - first = bands[i][0] + lrand()%(bands[i][1]-bands[i][0]); ! 1658: - n = 20; ! 1659: - if(first+n > bands[i][1]) ! 1660: - first = bands[i][1]-n; ! 1661: - if(first < bands[i][0]) ! 1662: - first = bands[i][0], n = bands[i][1]-first; ! 1663: - tbl += n; ! 1664: - lseek(fd, first*1024, 0); ! 1665: - last -= first; ! 1666: - if(last < 0) last = -last; ! 1667: - tseek += last; ! 1668: - bufp = &buf[1024*(first%5)]; ! 1669: - if(read(fd, buf1, n*1024) != n*1024){ ! 1670: - print("block %ld: ", first); ! 1671: - perror("read"); ! 1672: - exit(1); ! 1673: - } ! 1674: - if(memcmp(bufp, buf1, n*1024)){ ! 1675: - print("block %ld: bytes differ\n", first); ! 1676: - exit(1); ! 1677: - } ! 1678: - if(loop && ((loop%100) == 0)){ ! 1679: - t = time((long *)0); ! 1680: - floop = loop+1; ! 1681: - print("loop %ld: ave blocks=%.1f, ave seek=%.1fk at %s", ! 1682: - loop, tbl/floop, tseek/floop, ctime(&t)); ! 1683: - } ! 1684: - last = first+n; ! 1685: - } ! 1686: -} ! 1687: //GO.SYSIN DD scsi/osanity/tstsk.c ! 1688: echo scsi/osanity/tstwr.c 1>&2 ! 1689: sed 's/.//' >scsi/osanity/tstwr.c <<'//GO.SYSIN DD scsi/osanity/tstwr.c' ! 1690: -main(argc, argv) ! 1691: - char **argv; ! 1692: -{ ! 1693: - long first, last, t; ! 1694: - char buf[32768], buf1[32768], *bufp; ! 1695: - int fd, n; ! 1696: - char *worm = "/dev/worm0"; ! 1697: - ! 1698: - if((argc < 3) || (argc > 4)){ ! 1699: - print("Usage: tstwr [device] firstblock firstnonblock\n"); ! 1700: - exit(1); ! 1701: - } ! 1702: - if(argc > 3) ! 1703: - worm = *++argv; ! 1704: - if((fd = open(worm, 1)) < 0){ ! 1705: - perror(worm); ! 1706: - exit(1); ! 1707: - } ! 1708: - first = atol(argv[1]); ! 1709: - last = atol(argv[2]); ! 1710: - if((first < 0) || (last <= first)){ ! 1711: - print("bad first=%ld last=%ld\n", first, last); ! 1712: - exit(1); ! 1713: - } ! 1714: - print("writing blocks %ld - %ld inclusive on %s\n", first, last-1, worm); ! 1715: - fillbuf(buf, 32); ! 1716: - bufp = &buf[1024*(first%5)]; ! 1717: - lseek(fd, first*1024, 0); ! 1718: - while(first < last){ ! 1719: - n = last-first; ! 1720: - if(n > 25) n = 25; ! 1721: - if(write(fd, bufp, n*1024) != n*1024){ ! 1722: - print("block %ld: ", first); ! 1723: - perror("write"); ! 1724: - exit(1); ! 1725: - } ! 1726: - if((first%5000) == 0){ ! 1727: - t = time((long *)0); ! 1728: - print("done block %ld: %s", first, ctime(&t)); ! 1729: - } ! 1730: - first += n; ! 1731: - } ! 1732: - exit(0); ! 1733: -} ! 1734: //GO.SYSIN DD scsi/osanity/tstwr.c ! 1735: echo scsi/osanity/mkfile 1>&2 ! 1736: sed 's/.//' >scsi/osanity/mkfile <<'//GO.SYSIN DD scsi/osanity/mkfile' ! 1737: -CFLAGS=-g ! 1738: -NPROC=2 ! 1739: -ALL=tstwr tstrd tstsk ! 1740: - ! 1741: -all:V: $ALL ! 1742: - ! 1743: -tst%: tst%.o tstfill.o ! 1744: - $CC $CFLAGS -o $target $prereq ! 1745: - ! 1746: -clean:V: ! 1747: - rm -f *.o $ALL core ! 1748: //GO.SYSIN DD scsi/osanity/mkfile ! 1749: echo scsi/osanity/seek 1>&2 ! 1750: sed 's/.//' >scsi/osanity/seek <<'//GO.SYSIN DD scsi/osanity/seek' ! 1751: -tstsk 5 100000 400000 500000 800000 900000 1200000 1300000 1500000 1600000 ! 1752: //GO.SYSIN DD scsi/osanity/seek ! 1753: echo scsi/juke.3 1>&2 ! 1754: sed 's/.//' >scsi/juke.3 <<'//GO.SYSIN DD scsi/juke.3' ! 1755: -.TH INTERNAL 3 ! 1756: -.CT 2 file_io ! 1757: -.SH NAME ! 1758: -jukebox routines ! 1759: -.tr %" ! 1760: -.SH SYNOPSIS ! 1761: -.B "#include %hdr.h%" ! 1762: -.PP ! 1763: -.tr %% ! 1764: -.B "int j_shelf_to_drive(int sh, Side side, int dr, char *err)" ! 1765: -.PP ! 1766: -.B "int j_drive_to_shelf(int dr, int sh, Side side, char *err)" ! 1767: -.PP ! 1768: -.B "int j_empty_drive(int tlim, char *buf)" ! 1769: -.PP ! 1770: -.B "void j_rdshelves(char *buf)" ! 1771: -.PP ! 1772: -.B "int j_getstatus(char *buf)" ! 1773: -.PP ! 1774: -.B "int j_scsiio(struct scsi_cmd *cmd, int ncmd," ! 1775: -.br ! 1776: -.B "\ \ \ \ \ \ struct scsi_return *ret, int nret, char *err)" ! 1777: -.PP ! 1778: -.B "int j_shelfof(char *vol_id)" ! 1779: -.PP ! 1780: -.B "int j_volid(int dr, char *err)" ! 1781: -.PP ! 1782: -.B "extern char *j_shelf[NSHELF];" ! 1783: -.PP ! 1784: -.B "extern void pperror(char *buf, char *mesg); ! 1785: -.SH DESCRIPTION ! 1786: -.I J_shelf_to_drive ! 1787: -places the disk in shelf ! 1788: -.I sh ! 1789: -in logical drive ! 1790: -.IR dr . ! 1791: -It returns 0 on success; ! 1792: -otherwise an error message is placed in ! 1793: -.I err . ! 1794: -.PP ! 1795: -.I J_drive_to_shelf ! 1796: -places the disk ! 1797: -in logical drive ! 1798: -.IR dr ! 1799: -in shelf ! 1800: -.IR sh . ! 1801: -If ! 1802: -.I sh ! 1803: -is negative, ! 1804: -the disk is returned to its home shelf. ! 1805: -It returns 0 on success; ! 1806: -otherwise an error message is placed in ! 1807: -.IR err . ! 1808: -.PP ! 1809: -.I J_rdshelves ! 1810: -initializes each element of ! 1811: -.I j_shelf ! 1812: -to the volid of the disk on that shelf. ! 1813: -A zero pointer means there is no disk; ! 1814: -a name of ! 1815: -.B UNALLOCATED ! 1816: -means the disk has not been allocated a name yet. ! 1817: -It returns 0 on success; ! 1818: -otherwise an error message is placed in ! 1819: -.IR err . ! 1820: -.PP ! 1821: -.I J_getstatus ! 1822: -initializes ! 1823: -.B j_status ! 1824: -which include the following fields: ! 1825: -.EX ! 1826: - struct Lunstatus lun[NLUN]; /* disk status */ ! 1827: - uchar shelf[NSHELF]; /* shelf status */ ! 1828: - uchar iounit; /* I/O unit status */ ! 1829: - uchar carrier; /* carrier status */ ! 1830: - uchar udrive; /* upper drive status */ ! 1831: - uchar ldrive; /* lower drive status */ ! 1832: -.EE ! 1833: -A return value of 0 implies success; ! 1834: -otherwise \-1 is returned and an error message is placed in ! 1835: -.IR err . ! 1836: -.PP ! 1837: -.I J_scsiio ! 1838: -performs a SCSI transaction. ! 1839: -It sends the command in ! 1840: -.I cmd ! 1841: -and ! 1842: -.I ncmd ! 1843: -data bytes and stores the return status in ! 1844: -.IR ret . ! 1845: -A return value of 0 implies success; ! 1846: -otherwise \-1 is returned and an error message is placed in ! 1847: -.IR err . ! 1848: -.PP ! 1849: -.I J_shelfof ! 1850: -returns the shelf number of the disk labelled ! 1851: -.IR vol_id . ! 1852: -If there is no such disk, ! 1853: -\-1 is returned. ! 1854: -.PP ! 1855: -.I J_volid ! 1856: -returns the volid of the disk on drive ! 1857: -.I dr ! 1858: -in ! 1859: -.IR err . ! 1860: -A return value of 0 implies success; ! 1861: -otherwise \-1 is returned and an error message is placed in ! 1862: -.IR err . ! 1863: -.PP ! 1864: -.I Pperror ! 1865: -returns an error message that is contained in ! 1866: -.IR buf. ! 1867: -.PP ! 1868: -.SH "SEE ALSO" ! 1869: -.SH DIAGNOSTICS ! 1870: //GO.SYSIN DD scsi/juke.3 ! 1871: echo scsi/warm.c 1>&2 ! 1872: sed 's/.//' >scsi/warm.c <<'//GO.SYSIN DD scsi/warm.c' ! 1873: -#include <stddef.h> ! 1874: -#include <stdio.h> ! 1875: -#include <string.h> ! 1876: -#include "scsi.h" ! 1877: -#include "juke.h" ! 1878: - ! 1879: -warm_inv(char *buf) ! 1880: -{ ! 1881: - Side side; ! 1882: - int drive, sh; ! 1883: - char vol_id[512]; ! 1884: - ! 1885: - if(j_rdshelves(buf)) /* read in shelf names */ ! 1886: - return(-1); ! 1887: - side = SIDEA; ! 1888: - drive = min(nlun+1, NLUN-1); ! 1889: - for(;;){ ! 1890: - if(j_getstatus(buf)) /* get the jukebox status */ ! 1891: - return(-1); ! 1892: - for(sh = 0; sh < NSHELF; sh++) ! 1893: - if(j_status.shelf[sh]&0x10) break; ! 1894: - if(sh >= NSHELF) ! 1895: - break; ! 1896: - if(getvol(127, drive, vol_id, &side)){ ! 1897: - strcpy(buf, vol_id); ! 1898: - return(-1); ! 1899: - } ! 1900: - for(sh = 0; j_shelf[sh]; sh++) ! 1901: - ; ! 1902: - printf("%s -> %d\n", vol_id, sh); ! 1903: - if(j_drive_to_shelf(drive, sh, side, buf) < 0) ! 1904: - return(-1); ! 1905: - j_wrshelf = 1; ! 1906: - j_shelf[sh] = strdup(vol_id); ! 1907: - sleep(1); ! 1908: - } ! 1909: - return(0); ! 1910: -} ! 1911: //GO.SYSIN DD scsi/warm.c ! 1912: echo scsi/juke.h 1>&2 ! 1913: sed 's/.//' >scsi/juke.h <<'//GO.SYSIN DD scsi/juke.h' ! 1914: -#define NLUN 8 ! 1915: -#define NSHELF 50 ! 1916: -extern int nlun; ! 1917: -extern void setnlun(void); ! 1918: -extern char *j_shelf[NSHELF]; ! 1919: -extern int j_wrshelf; /* need to write out shelves */ ! 1920: -extern j_rdshelves(char *err); ! 1921: -extern j_wrshelves(char *err); ! 1922: -extern j_inventory(char cold, int tlim, char *err); ! 1923: - ! 1924: -typedef enum { SIDEA = 0, SIDEB = 1 } Side; ! 1925: - ! 1926: -struct Lunstatus ! 1927: -{ ! 1928: - unsigned int poweron:1; /* is power on ? */ ! 1929: - unsigned int diskin:1; /* is disk in drive? */ ! 1930: - unsigned int ready:1; /* is disk spun up or spun down? */ ! 1931: - unsigned int writeprotect:1; /* is disk write protected? */ ! 1932: - unsigned int diskindrive:1; /* is driveshelf a drive number? */ ! 1933: - unsigned int shelfvalid:1; /* is retshelf valid? */ ! 1934: - uchar driveshelf; /* drive number */ ! 1935: - uchar retshelf; /* return shelf */ ! 1936: -}; ! 1937: - ! 1938: -struct Jstatus ! 1939: -{ ! 1940: - struct Lunstatus lun[NLUN]; /* disk status */ ! 1941: - uchar shelf[NSHELF]; /* shelf status */ ! 1942: - uchar iounit; /* I/O unit status */ ! 1943: - uchar carrier; /* carrier status */ ! 1944: - uchar udrive; /* upper drive status */ ! 1945: - uchar ldrive; /* lower drive status */ ! 1946: -}; ! 1947: -extern struct Jstatus j_status; ! 1948: -extern int j_getstatus(char *err); ! 1949: -extern int j_shelfof(char *vol_id); ! 1950: -extern int j_driveof(char *vol_id); ! 1951: - ! 1952: -extern char *strdup(char *); ! 1953: -extern int j_shelf_to_drive(int, Side, int, char *); ! 1954: -extern int j_drive_to_shelf(int, int, Side, char *); ! 1955: -extern int j_empty_drive(long, char *); ! 1956: -extern int j_rvolid(int, char *); ! 1957: -extern int j_wvolid(int, char *, char *); ! 1958: -extern void pperror(char *buf, char *mesg); ! 1959: -extern int reserve_drive(int, char *); ! 1960: -extern int release_drive(int, char *); ! 1961: -extern int cold_inv(char, char *); ! 1962: -extern int warm_inv(char *); ! 1963: -extern int j_load(char *vol_id, char *buf, long tlim); ! 1964: -extern int j_unload(char *vol_id, char *buf); ! 1965: - ! 1966: -#define JUKEDIR "/usr/worm/jukedir" ! 1967: -#define UNALLOCATED "<unallocated>" ! 1968: //GO.SYSIN DD scsi/juke.h ! 1969: echo scsi/scsi.h 1>&2 ! 1970: sed 's/.//' >scsi/scsi.h <<'//GO.SYSIN DD scsi/scsi.h' ! 1971: -typedef unsigned char uchar; ! 1972: - ! 1973: -struct scsi_cmd ! 1974: -{ ! 1975: - unsigned long id; ! 1976: - uchar bus_id; /* SCSI id of destination device */ ! 1977: - uchar flags; ! 1978: - uchar cmd[10]; /* SCSI command */ ! 1979: - uchar data[4096]; /* optional data */ ! 1980: -}; ! 1981: - ! 1982: -struct scsi_return ! 1983: -{ ! 1984: - unsigned long id; ! 1985: - uchar scsi_stat; /* scsi status byte */ ! 1986: - uchar scsi_msg; /* scsi message byte */ ! 1987: - uchar flags; ! 1988: - uchar type; /* 1=td 2=us */ ! 1989: - unsigned short reg1; /* td=sa, us=per */ ! 1990: - unsigned short reg2; /* td=mscp, us=per */ ! 1991: - unsigned char sense[22]; ! 1992: - char pad[2]; ! 1993: - uchar data[4096]; /* any data */ ! 1994: - uchar nread; /* chars read(-8) if ret count was -ve */ ! 1995: -}; ! 1996: - ! 1997: -#define set6(x,a,b,c,d,e,f) (x).flags=0,(x).cmd[0]=(a),(x).cmd[1]=(b),(x).cmd[2]=(c),\ ! 1998: - (x).cmd[3]=(d),(x).cmd[4]=(e),(x).cmd[5]=(f) ! 1999: -#define set10(x,a,b,c,d,e,f,g,h,i,j) (x).flags=0,(x).cmd[0]=(a),(x).cmd[1]=(b),(x).cmd[2]=(c),\ ! 2000: - (x).cmd[3]=(d),(x).cmd[4]=(e),(x).cmd[5]=(f),(x).cmd[6]=(g),(x).cmd[7]=(h),\ ! 2001: - (x).cmd[8]=(i),(x).cmd[9]=(j) ! 2002: -#define setdiag(x,lun,n) (x).flags=0,(x).cmd[0]=0x1C,(x).cmd[1]=(lun)<<5,(x).cmd[2] = 0,\ ! 2003: - (x).cmd[3]=(n)>>8,(x).cmd[4]=(n),(x).cmd[5]=0 ! 2004: - ! 2005: -extern s_io(int, struct scsi_cmd *, int, struct scsi_return *, int, char *);/* return 0 on no error, does sense on error */ ! 2006: -extern ss_io(int, struct scsi_cmd *, int, struct scsi_return *, int, char *);/* return 0 on no error */ ! 2007: -extern int s_ignua; /* should s_io ignore unit attentions? */ ! 2008: -extern void (*ss_extsense)(uchar *, char *, int); ! 2009: -extern int s_start(int, char *); ! 2010: -extern int s_stop(int, char *); ! 2011: -extern int s_eject(int, char *); ! 2012: -extern int s_id; ! 2013: -extern unsigned long longat(uchar *); ! 2014: //GO.SYSIN DD scsi/scsi.h ! 2015: echo scsi/jukebox.c 1>&2 ! 2016: sed 's/.//' >scsi/jukebox.c <<'//GO.SYSIN DD scsi/jukebox.c' ! 2017: -#include <stdio.h> ! 2018: -#include <limits.h> ! 2019: -#include "scsi.h" ! 2020: -#include "juke.h" ! 2021: - ! 2022: -main(int argc, char *argv[]) ! 2023: -{ ! 2024: - int c; ! 2025: - int aflag = 0, eflag = 0, mflag = 0, pflag = 0; ! 2026: - int rflag = 0, sflag = 0, uflag = 0, Uflag = 0; ! 2027: - long secs = 3600L*24*183; /* half a year is enough */ ! 2028: - char *vol_id; ! 2029: - char errbuf[1024]; ! 2030: - extern int optind; ! 2031: - extern char *optarg; ! 2032: - ! 2033: - setbuf(stdout, (char *)0); /* turn off buffering */ ! 2034: - while((c = getopt(argc, argv, "aemprsuUw:")) != -1) ! 2035: - switch (c) ! 2036: - { ! 2037: - case 'a': aflag = 1; break; ! 2038: - case 'e': eflag = 1; break; ! 2039: - case 'm': mflag = 1; break; ! 2040: - case 'p': pflag = 1; break; ! 2041: - case 'r': rflag = 1; break; ! 2042: - case 's': sflag = 1; break; ! 2043: - case 'u': uflag = 1; break; ! 2044: - case 'U': Uflag = 1; break; ! 2045: - case 'w': secs = atol(optarg); break; ! 2046: - default: usage(); break; ! 2047: - } ! 2048: - s_id = 2; ! 2049: - setnlun(); ! 2050: - if(!aflag&&!eflag&&!mflag&&!pflag&&!rflag&&!uflag&&!Uflag) ! 2051: - sflag = 1; ! 2052: - vol_id = (optind < argc)? argv[optind] : 0; ! 2053: - if(uflag || Uflag) ! 2054: - unload(Uflag); ! 2055: - if(eflag){ ! 2056: - if(vol_id == 0){ ! 2057: - strcpy(errbuf, "-e needs a vol_id"); ! 2058: - goto scram; ! 2059: - } ! 2060: - if(eject(vol_id, errbuf)) ! 2061: - goto scram; ! 2062: - } ! 2063: - if(rflag){ ! 2064: - unload(1); ! 2065: - sleep(1); ! 2066: - if(cold_inv(vol_id? *vol_id : 'u', errbuf) < 0) ! 2067: - goto scram; ! 2068: - } ! 2069: - if(aflag){ ! 2070: - if(vol_id == 0){ ! 2071: - strcpy(errbuf, "-a needs a vol_id"); ! 2072: - goto scram; ! 2073: - } ! 2074: - if(allocate(vol_id, errbuf)) ! 2075: - goto scram; ! 2076: - } ! 2077: - if(mflag){ ! 2078: - if((c = j_load(vol_id, errbuf, secs)) < 0) ! 2079: - goto scram; ! 2080: - if(s_start(c, errbuf) < 0) ! 2081: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2082: - if(s_stop(c, errbuf) < 0) ! 2083: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2084: - printf("%d\n", c); ! 2085: - } ! 2086: - if(sflag) ! 2087: - prstatus(); ! 2088: - if(pflag){ ! 2089: - if(j_rdshelves(errbuf) < 0) ! 2090: - goto scram; ! 2091: - for(c = 0; c < NSHELF; c++) ! 2092: - if(j_shelf[c]) ! 2093: - printf("%d: %s\n", c, j_shelf[c]); ! 2094: - } ! 2095: - if(j_wrshelf) ! 2096: - if(j_wrshelves(errbuf)) ! 2097: - errexit(errbuf); ! 2098: - exit(0); ! 2099: -scram: ! 2100: - if(j_wrshelf) ! 2101: - j_wrshelves(errbuf); ! 2102: - errexit(errbuf); ! 2103: -} ! 2104: - ! 2105: -usage() ! 2106: -{ ! 2107: - fprintf(stderr, "Usage: jukebox [-aemprsuU] [-w secs] [vol_id\n"); ! 2108: - exit(1); ! 2109: -} ! 2110: - ! 2111: -errexit(char *errbuf) ! 2112: -{ ! 2113: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2114: - exit(1); ! 2115: -} ! 2116: - ! 2117: -prstatus() ! 2118: -{ ! 2119: - struct Lunstatus *l; ! 2120: - int c; ! 2121: - char errbuf[1024]; ! 2122: - static char *spin[2] = { "offline", "online" }; ! 2123: - ! 2124: - if(j_getstatus(errbuf)){ ! 2125: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2126: - exit(1); ! 2127: - } ! 2128: - if(j_rdshelves(errbuf)){ ! 2129: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2130: - exit(1); ! 2131: - } ! 2132: - for(c = 0; c < 8; c++){ ! 2133: - l = &j_status.lun[c]; ! 2134: - if(!l->diskin) ! 2135: - continue; ! 2136: - printf("lun %d(", c); ! 2137: - if(j_status.udrive == (0x80|c)) ! 2138: - printf("upper,%s", spin[l->ready]); ! 2139: - else if(j_status.ldrive == (0x80|c)) ! 2140: - printf("lower,%s", spin[l->ready]); ! 2141: - else ! 2142: - printf("in shelf"); ! 2143: - printf("): "); ! 2144: - if(l->shelfvalid){ ! 2145: - if(j_shelf[l->retshelf>>1]) ! 2146: - printf("%s%c", j_shelf[l->retshelf>>1], "ab"[l->retshelf&1]); ! 2147: - else ! 2148: - printf("unallocated shelf number %d??", l->retshelf); ! 2149: - } else ! 2150: - printf("<unknown shelf??>"); ! 2151: - printf("\n"); ! 2152: - } ! 2153: -} ! 2154: - ! 2155: -unload(int force) ! 2156: -{ ! 2157: - struct Lunstatus *l; ! 2158: - int c; ! 2159: - char errbuf[1024]; ! 2160: - ! 2161: - if(j_getstatus(errbuf)){ ! 2162: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2163: - exit(1); ! 2164: - } ! 2165: - if(j_rdshelves(errbuf)){ ! 2166: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2167: - exit(1); ! 2168: - } ! 2169: - for(c = 0; c < 8; c++){ ! 2170: - l = &j_status.lun[c]; ! 2171: - if(!l->diskin) ! 2172: - continue; ! 2173: - if(force || !l->ready) ! 2174: - if(j_drive_to_shelf(c, -1, SIDEA, errbuf)) ! 2175: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2176: - } ! 2177: -} ! 2178: - ! 2179: -eject(char *vol_id, char *errbuf) ! 2180: -{ ! 2181: - int sh; ! 2182: - int dr; ! 2183: - ! 2184: - if(j_rdshelves(errbuf)){ ! 2185: - fprintf(stderr, "jukebox: %s\n", errbuf); ! 2186: - exit(1); ! 2187: - } ! 2188: - sh = j_shelfof(vol_id); ! 2189: - if(sh < 0){ ! 2190: - sprintf(errbuf, "xcan't find vol_id %s", vol_id); ! 2191: - return(-1); ! 2192: - } ! 2193: - j_wrshelf = 1; ! 2194: - if((dr = j_driveof(vol_id)) >= 0){ ! 2195: - j_shelf[sh] = 0; ! 2196: - return(s_eject(dr, errbuf)); ! 2197: - } ! 2198: - dr = NLUN-1; ! 2199: - if(j_shelf_to_drive(sh, SIDEA, dr, errbuf) < 0) ! 2200: - return(-1); ! 2201: - if(s_eject(dr, errbuf)) ! 2202: - return(-1); ! 2203: - j_shelf[sh] = 0; ! 2204: - return(0); ! 2205: -} ! 2206: //GO.SYSIN DD scsi/jukebox.c ! 2207: echo scsi/getstatus.c 1>&2 ! 2208: sed 's/.//' >scsi/getstatus.c <<'//GO.SYSIN DD scsi/getstatus.c' ! 2209: -#include <stddef.h> ! 2210: -#include <stdio.h> ! 2211: -#include "scsi.h" ! 2212: -#include "juke.h" ! 2213: - ! 2214: -struct Jstatus j_status; ! 2215: - ! 2216: -static ! 2217: -dolun(struct Lunstatus *lun, uchar *u) ! 2218: -{ ! 2219: - lun->poweron = ((*u)&0x80) == 0; ! 2220: - lun->diskin = ((*u)&0x40) != 0; ! 2221: - lun->ready = ((*u)&0x01) != 0; ! 2222: - u++; ! 2223: - lun->diskindrive = ((*u)&0x80) != 0; ! 2224: - lun->driveshelf = (*u)&0x7F; ! 2225: - u++; ! 2226: - lun->shelfvalid = ((*u)&0x80) != 0; ! 2227: - lun->retshelf = (*u)&0x7F; ! 2228: -} ! 2229: - ! 2230: -j_getstatus(char *err) ! 2231: -{ ! 2232: - struct scsi_cmd cmd; ! 2233: - struct scsi_return ret; ! 2234: - int i; ! 2235: - ! 2236: - set6(cmd, 0x1D, 0, 0, 0, 10, 0); ! 2237: - memset(cmd.data, 0, 10); ! 2238: - cmd.data[0] = 0xE2; ! 2239: - if(s_io(1, &cmd, 10, &ret, 0, err)) ! 2240: - return(-1); ! 2241: - set6(cmd, 0x1C, 0, 0, 0, 128, 0); ! 2242: - if(s_io(0, &cmd, 0, &ret, 128, err)) ! 2243: - return(-1); ! 2244: - for(i = 0; i < 8; i++) ! 2245: - dolun(&j_status.lun[i], &ret.data[16+4*i]); ! 2246: - for(i = 0; i < NSHELF; i++) ! 2247: - j_status.shelf[i] = ret.data[48+i]; ! 2248: - j_status.iounit = ret.data[98]; ! 2249: - j_status.carrier = ret.data[99]; ! 2250: - j_status.udrive = ret.data[100]; ! 2251: - j_status.ldrive = ret.data[101]; ! 2252: - return(0); ! 2253: -} ! 2254: //GO.SYSIN DD scsi/getstatus.c ! 2255: echo scsi/nlun.c 1>&2 ! 2256: sed 's/.//' >scsi/nlun.c <<'//GO.SYSIN DD scsi/nlun.c' ! 2257: -#include <stdio.h> ! 2258: -#include "scsi.h" ! 2259: -#include "juke.h" ! 2260: - ! 2261: -int nlun = 1; ! 2262: - ! 2263: -void ! 2264: -setnlun(void) ! 2265: -{ ! 2266: - char buf[512]; ! 2267: - ! 2268: - for(nlun = 0; nlun < NLUN; nlun++){ ! 2269: - sprintf(buf, "/dev/worm%d", nlun); ! 2270: - if(access(buf, 0) < 0) ! 2271: - return; ! 2272: - } ! 2273: -} ! 2274: //GO.SYSIN DD scsi/nlun.c ! 2275: echo scsi/allocate.c 1>&2 ! 2276: sed 's/.//' >scsi/allocate.c <<'//GO.SYSIN DD scsi/allocate.c' ! 2277: -#include <stddef.h> ! 2278: -#include <stdio.h> ! 2279: -#include <string.h> ! 2280: -#include "scsi.h" ! 2281: -#include "juke.h" ! 2282: - ! 2283: -allocate(char *vol_id, char *buf) ! 2284: -{ ! 2285: - int drive, sh; ! 2286: - char nbuf[512]; ! 2287: - ! 2288: - if(j_rdshelves(buf)) /* read in shelf names */ ! 2289: - return(-1); ! 2290: - if(j_getstatus(buf)) /* get the jukebox status */ ! 2291: - return(-1); ! 2292: - sh = j_shelfof(vol_id); ! 2293: - if(sh >= 0){ ! 2294: - sprintf(buf, "there is an existing '%s' on shelf %d", vol_id, sh); ! 2295: - return(-1); ! 2296: - } ! 2297: - sh = j_shelfof(UNALLOCATED); ! 2298: - if(sh < 0){ ! 2299: - sprintf(buf, "no unallocated disks"); ! 2300: - return(-1); ! 2301: - } ! 2302: - printf("using unallocated disk from shelf %d\n", sh); ! 2303: - drive = min(nlun+1, NLUN-1); ! 2304: - if(j_shelf_to_drive(sh, SIDEB, drive, buf) < 0) ! 2305: - return(-1); ! 2306: - sprintf(nbuf, "%sb", vol_id); ! 2307: - if(j_wvolid(drive, nbuf, buf)) ! 2308: - return(-1); ! 2309: - j_wrshelf = 1; ! 2310: - j_shelf[sh] = strdup(vol_id); ! 2311: - if(j_drive_to_shelf(drive, sh, SIDEB, buf) < 0) ! 2312: - return(-1); ! 2313: - if(j_shelf_to_drive(sh, SIDEA, drive, buf) < 0) ! 2314: - return(-1); ! 2315: - sprintf(nbuf, "%sa", vol_id); ! 2316: - if(j_wvolid(drive, nbuf, buf)) ! 2317: - return(-1); ! 2318: - if(j_drive_to_shelf(drive, sh, SIDEA, buf) < 0) ! 2319: - return(-1); ! 2320: - return(0); ! 2321: -} ! 2322: //GO.SYSIN DD scsi/allocate.c ! 2323: echo scsi/scsi/dslib.c 1>&2 ! 2324: sed 's/.//' >scsi/scsi/dslib.c <<'//GO.SYSIN DD scsi/scsi/dslib.c' ! 2325: -/* ! 2326: -|| dslib.c - library routines for /dev/scsi ! 2327: -|| ! 2328: -|| Copyright 1988, 1989, by ! 2329: -|| Gene Dronek (Vulcan Laboratory) and ! 2330: -|| Rich Morin (Canta Forda Computer Laboratory). ! 2331: -|| All rights reserved. ! 2332: -*/ ! 2333: -#ident "dslib.c: $Revision: 1.4 $" ! 2334: - ! 2335: -#include <stdio.h> ! 2336: -#include <sys/types.h> ! 2337: - ! 2338: -#include "dslib.h" ! 2339: -#ifdef aux ! 2340: -#include <sys/vio.h> ! 2341: -#include <sys/scsireq.h> ! 2342: -#endif aux ! 2343: - ! 2344: -int dsdebug=0; ! 2345: -long dsreqflags; /* flag bits always set by filldsreq */ ! 2346: - ! 2347: -#define min(i,j) ( (i) < (j) ? (i) : (j) ) ! 2348: - ! 2349: - ! 2350: -/* ! 2351: -|| Startup/shutdown ----------------------------------------------- ! 2352: -*/ ! 2353: - ! 2354: -static struct context *dsc[FDSIZ]; ! 2355: - ! 2356: - ! 2357: -/* ! 2358: -|| dsopen - open device, set up structures ! 2359: -*/ ! 2360: - ! 2361: -struct dsreq * ! 2362: -dsopen(opath, oflags) ! 2363: - char *opath; ! 2364: - int oflags; ! 2365: -{ ! 2366: - ! 2367: - struct dsreq *dsp; ! 2368: - struct context *cp; ! 2369: - int fd; ! 2370: - DSDBG(fprintf(stderr,"dsopen(%s,%x) ", opath, oflags)); ! 2371: - ! 2372: - fd = open(opath, oflags); ! 2373: - if (fd < 0) ! 2374: - return NULL; /* can't open */ ! 2375: - if (dsc[fd] != NULL) /* already in use */ ! 2376: - ds_zot("dsopen: fd already in use"); ! 2377: - ! 2378: - cp = (struct context *) calloc(1, sizeof(struct context)); ! 2379: - if (cp == NULL) /* can't allocate */ ! 2380: - ds_zot("dsopen: can't allocate space"); ! 2381: - dsc[fd] = cp; ! 2382: - cp->dsc_fd = fd; ! 2383: - dsp = &(cp->dsc_dsreq); ! 2384: - ! 2385: - dsp->ds_flags = 0; ! 2386: - dsp->ds_time = 10 * 1000; /* 10 second default timeout */ ! 2387: - dsp->ds_private = (ulong) cp; /* pointer back to context */ ! 2388: - dsp->ds_cmdbuf = cp->dsc_cmd; ! 2389: - dsp->ds_cmdlen = sizeof cp->dsc_cmd; ! 2390: - dsp->ds_databuf = 0; ! 2391: - dsp->ds_datalen = 0; ! 2392: - dsp->ds_sensebuf = cp->dsc_sense; ! 2393: - dsp->ds_senselen = sizeof cp->dsc_sense; ! 2394: - DSDBG(fprintf(stderr,"=>cp %x, dsp %x\n", cp, dsp)); ! 2395: - return dsp; ! 2396: -} ! 2397: - ! 2398: - ! 2399: -/* ! 2400: -|| dsclose - close device, release context struct. ! 2401: -*/ ! 2402: - ! 2403: -dsclose(dsp) ! 2404: - struct dsreq *dsp; ! 2405: -{ ! 2406: - int fd; ! 2407: - struct context *cp; ! 2408: - ! 2409: - if (dsp == NULL) ! 2410: - ds_zot("dsclose: dsp is NULL"); ! 2411: - ! 2412: - cp = (struct context *)dsp->ds_private; ! 2413: - fd = getfd(dsp); ! 2414: - if ( cp == NULL ) ! 2415: - ds_zot("dsclose: private is NULL"); ! 2416: - ! 2417: - cfree(cp); ! 2418: - dsc[fd] = (struct context *)NULL; ! 2419: - return; ! 2420: -} ! 2421: - ! 2422: - ! 2423: -/* ! 2424: -|| Generic SCSI CCS Command functions ------------------------------------ ! 2425: -|| ! 2426: -|| dsp dsreq pointer ! 2427: -|| data data buffer pointer ! 2428: -|| datalen data buffer length ! 2429: -|| lba logical block address ! 2430: -|| vu vendor unique bits ! 2431: -*/ ! 2432: - ! 2433: -/* ! 2434: -|| testunitready00 - issue group 0 "Test Unit Ready" command (0x00) ! 2435: -*/ ! 2436: - ! 2437: -testunitready00(dsp) ! 2438: - struct dsreq *dsp; ! 2439: -{ ! 2440: - fillg0cmd(dsp, CMDBUF(dsp), G0_TEST, 0, 0, 0, 0, 0); ! 2441: - filldsreq(dsp, 0, 0, DSRQ_READ|DSRQ_SENSE); ! 2442: - return(doscsireq(getfd(dsp), dsp)); ! 2443: -} ! 2444: - ! 2445: - ! 2446: -/* ! 2447: -|| requestsense03 - issue group 0 "Request Sense" command (0x03) ! 2448: -*/ ! 2449: - ! 2450: -requestsense03(dsp, data, datalen, vu) ! 2451: - struct dsreq *dsp; ! 2452: - caddr_t data; ! 2453: - long datalen; ! 2454: - char vu; ! 2455: -{ ! 2456: - fillg0cmd(dsp, CMDBUF(dsp), G0_REQU, 0, 0, 0, B1(datalen), B1(vu<<6)); ! 2457: - filldsreq(dsp, data, datalen, DSRQ_READ); ! 2458: - return(doscsireq(getfd(dsp), dsp)); ! 2459: -} ! 2460: - ! 2461: - ! 2462: -/* ! 2463: -|| write0a - issue group 0 "Write" command (0x0a) ! 2464: -*/ ! 2465: - ! 2466: -write0a(dsp, data, datalen, lba, vu) ! 2467: - struct dsreq *dsp; ! 2468: - caddr_t data; ! 2469: - long datalen, lba; ! 2470: - char vu; ! 2471: -{ ! 2472: - fillg0cmd(dsp, CMDBUF(dsp), G0_WRIT, B3(lba), B1(datalen), B1(vu<<6)); ! 2473: - filldsreq(dsp, data, datalen, DSRQ_READ); ! 2474: - return(doscsireq(getfd(dsp), dsp)); ! 2475: -} ! 2476: - ! 2477: - ! 2478: -/* ! 2479: -|| inquiry12 - issue group 0 "Inquiry" command (0x12) ! 2480: -*/ ! 2481: - ! 2482: -inquiry12(dsp, data, datalen, vu) ! 2483: - struct dsreq *dsp; ! 2484: - caddr_t data; ! 2485: - long datalen; ! 2486: - char vu; ! 2487: -{ ! 2488: - fillg0cmd(dsp, CMDBUF(dsp), G0_INQU, 0, 0, 0, B1(datalen), B1(vu<<6)); ! 2489: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE); ! 2490: - return(doscsireq(getfd(dsp), dsp)); ! 2491: -} ! 2492: - ! 2493: - ! 2494: -/* ! 2495: -|| modeselect15 - issue group 0 "Mode Select" command (0x15) ! 2496: -|| ! 2497: -|| save 0 - don't save saveable pages ! 2498: -|| 1 - save saveable pages ! 2499: -*/ ! 2500: - ! 2501: -modeselect15(dsp, data, datalen, save, vu) ! 2502: - struct dsreq *dsp; ! 2503: - caddr_t data; ! 2504: - long datalen; ! 2505: - char save, vu; ! 2506: -{ ! 2507: - fillg0cmd(dsp, CMDBUF(dsp), G0_MSEL, save&1, 0, 0, B1(datalen), B1(vu<<6)); ! 2508: - filldsreq(dsp, data, datalen, DSRQ_WRITE|DSRQ_SENSE); ! 2509: - return(doscsireq(getfd(dsp), dsp)); ! 2510: -} ! 2511: - ! 2512: - ! 2513: -/* ! 2514: -|| modesense1a - issue group 0 "Mode Sense" command (0x1a) ! 2515: -|| ! 2516: -|| pagectrl 0 - current values ! 2517: -|| 1 - changeable values ! 2518: -|| 2 - default values ! 2519: -|| 3 - saved values ! 2520: -|| ! 2521: -|| pagecode 0 - vendor unique ! 2522: -|| 1 - error recovery ! 2523: -|| 2 - disconnect/reconnect ! 2524: -|| 3 - direct access dev. fmt. ! 2525: -|| 4 - rigid disk geometry ! 2526: -|| 5 - flexible disk ! 2527: -|| 6-9 - see specific dev. types ! 2528: -|| 0a - implemented options ! 2529: -|| 0b - medium types supported ! 2530: -|| 3f - return all pages ! 2531: -*/ ! 2532: - ! 2533: -modesense1a(dsp, data, datalen, pagectrl, pagecode, vu) ! 2534: - struct dsreq *dsp; ! 2535: - caddr_t data; ! 2536: - long datalen; ! 2537: - char pagectrl, pagecode, vu; ! 2538: -{ ! 2539: - fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN, 0x10, ! 2540: - ((pagectrl&3)<<6) | (pagecode&0x3F), ! 2541: - 0, B1(datalen), B1(vu<<6)); ! 2542: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE); ! 2543: - return(doscsireq(getfd(dsp), dsp)); ! 2544: -} ! 2545: - ! 2546: - ! 2547: -/* ! 2548: -|| senddiagnostic1d - issue group 0 "Send Diagnostic" command (0x1d) ! 2549: -|| ! 2550: -|| self 0 - run test, hold results ! 2551: -|| 1 - run test, return status ! 2552: -|| ! 2553: -|| dofl 0 - device online ! 2554: -|| 1 - device offline ! 2555: -|| ! 2556: -|| uofl 0 - unit online ! 2557: -|| 1 - unit offline ! 2558: -*/ ! 2559: - ! 2560: -senddiagnostic1d(dsp, data, datalen, self, dofl, uofl, vu) ! 2561: - struct dsreq *dsp; ! 2562: - caddr_t data; ! 2563: - long datalen; ! 2564: - char self, dofl, uofl, vu; ! 2565: -{ ! 2566: - fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN, ! 2567: - (self&1)<<2 | (dofl&1)<<1 | (uofl&1), ! 2568: - 0, B2(datalen), B1(vu<<6)); ! 2569: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE); ! 2570: - return(doscsireq(getfd(dsp), dsp)); ! 2571: -} ! 2572: - ! 2573: - ! 2574: -/* ! 2575: -|| readcapacity25 - issue group 1 "Read Capacity" command (0x25) ! 2576: -|| ! 2577: -|| pmi 0 - return last logical block, entire unit ! 2578: -|| 1 - return last logical block, current track ! 2579: -*/ ! 2580: - ! 2581: -readcapacity25(dsp, data, datalen, lba, pmi, vu) ! 2582: - struct dsreq *dsp; ! 2583: - caddr_t data; ! 2584: - long datalen, lba; ! 2585: - char pmi, vu; ! 2586: -{ ! 2587: - fillg1cmd(dsp, CMDBUF(dsp), G1_RCAP, 0, B4(lba), 0, 0, pmi&1, B1(vu<<6)); ! 2588: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE ! 2589: - /* |DSRQ_CTRL2 */ ); ! 2590: - /* dsp->ds_time = 100; /* often takes a while */ ! 2591: - return(doscsireq(getfd(dsp), dsp)); ! 2592: -} ! 2593: - ! 2594: - ! 2595: -/* ! 2596: -|| readextended28 - issue group 1 "Read Extended" command (0x28) ! 2597: -*/ ! 2598: - ! 2599: -readextended28(dsp, data, datalen, lba, vu) ! 2600: - struct dsreq *dsp; ! 2601: - caddr_t data; ! 2602: - long datalen, lba; ! 2603: - char vu; ! 2604: -{ ! 2605: - fillg1cmd(dsp, CMDBUF(dsp), G1_READ, 0, B4(lba), 0, B2(datalen), B1(vu<<6)); ! 2606: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE ! 2607: - /* |DSRQ_CTRL2 */ ); ! 2608: - /* dsp->ds_time = 100; /* often takes a while */ ! 2609: - return(doscsireq(getfd(dsp), dsp)); ! 2610: -} ! 2611: - ! 2612: - ! 2613: -/* ! 2614: -|| writeextended2a - issue group 1 "Write Extended" command (0x2a) ! 2615: -*/ ! 2616: - ! 2617: -writeextended2a(dsp, data, datalen, lba, vu) ! 2618: - struct dsreq *dsp; ! 2619: - caddr_t data; ! 2620: - long datalen, lba; ! 2621: - char vu; ! 2622: -{ ! 2623: - fillg1cmd(dsp, CMDBUF(dsp), G1_WRIT, 0, B4(lba), 0, B2(datalen), B1(vu<<6)); ! 2624: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE ! 2625: - /* |DSRQ_CTRL2 */ ); ! 2626: - /* dsp->ds_time = 100; /* often takes a while */ ! 2627: - return(doscsireq(getfd(dsp), dsp)); ! 2628: -} ! 2629: - ! 2630: - ! 2631: -/* ! 2632: -|| Support functions ---------------------------------------------------- ! 2633: -*/ ! 2634: - ! 2635: -/* ! 2636: -|| fillg0cmd - Fill a Group 0 command buffer ! 2637: -*/ ! 2638: - ! 2639: -fillg0cmd(dsp, cmd, b0,b1,b2,b3,b4,b5) ! 2640: - struct dsreq *dsp; ! 2641: - uchar_t *cmd, b0,b1,b2,b3,b4,b5; ! 2642: -{ ! 2643: - uchar_t *c = cmd; ! 2644: - DSDBG(fprintf(stderr,"fillg0cmd(%x,%x, %02x %02x %02x %02x %02x %02x)\n", ! 2645: - dsp, cmd, b0,b1,b2,b3,b4,b5)); ! 2646: - *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5; ! 2647: - ! 2648: - CMDBUF(dsp) = (caddr_t) cmd; ! 2649: - CMDLEN(dsp) = 6; ! 2650: -} ! 2651: - ! 2652: - ! 2653: -/* ! 2654: -|| fillg1cmd - Fill a Group 1 command buffer ! 2655: -*/ ! 2656: - ! 2657: -fillg1cmd(dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) ! 2658: - struct dsreq *dsp; ! 2659: - uchar_t *cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9; ! 2660: -{ ! 2661: - uchar_t *c = cmd; ! 2662: - DSDBG(fprintf(stderr, ! 2663: - "fillg1cmd(%x,%x, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)\n", ! 2664: - dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)); ! 2665: - ! 2666: - *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5; ! 2667: - *c++ = b6, *c++ = b7, *c++ = b8, *c++ = b9; ! 2668: - ! 2669: - CMDBUF(dsp) = (caddr_t) cmd; ! 2670: - CMDLEN(dsp) = 10; ! 2671: -} ! 2672: - ! 2673: - ! 2674: -/* ! 2675: -|| filldsreq - Fill a dsreq structure ! 2676: -*/ ! 2677: - ! 2678: -filldsreq(dsp,data,datalen,flags) ! 2679: - struct dsreq *dsp; ! 2680: - uchar_t *data; ! 2681: -{ ! 2682: - DSDBG(fprintf(stderr,"filldsreq(%x,%x,%d,%x) cmdlen %d\n", ! 2683: - dsp,data,datalen,flags,CMDLEN(dsp))); ! 2684: - dsp->ds_flags = flags | dsreqflags | ! 2685: - (((dsdebug&1) ? DSRQ_TRACE : 0) | ! 2686: - ((dsdebug&2) ? DSRQ_PRINT : 0)); ! 2687: - dsp->ds_time = 10 * 1000; /* default to 10 seconds */ ! 2688: - dsp->ds_link = 0; ! 2689: - dsp->ds_synch = 0; ! 2690: - dsp->ds_ret = 0; ! 2691: - ! 2692: - DATABUF(dsp) = (caddr_t) data; ! 2693: - DATALEN(dsp) = datalen; ! 2694: -} ! 2695: - ! 2696: - ! 2697: -/* ! 2698: -|| bprint - print array of bytes, in hex. ! 2699: -*/ ! 2700: - ! 2701: -#define hex(x) "0123456789ABCDEF" [ (x) & 0xF ] ! 2702: - ! 2703: -bprint(s,n,nperline,space) ! 2704: - char *s; ! 2705: -{ ! 2706: - int i, x; ! 2707: - char *sp = (space) ? " ": ""; ! 2708: - ! 2709: - for(i=0;i<n;i++) { ! 2710: - x = s[i]; ! 2711: - fprintf(stderr,((i%4==3)?"%c%c%s%s":"%c%c%s"), ! 2712: - hex(x>>4), hex(x), sp, sp); ! 2713: - if ( i%nperline == (nperline - 1) ) ! 2714: - fprintf(stderr,"\n"); ! 2715: - } ! 2716: - if ( space ) ! 2717: - fprintf(stderr,"\n"); ! 2718: -} ! 2719: - ! 2720: - ! 2721: -/* ! 2722: -|| doscsireq - issue scsi command, return status or -1 error. ! 2723: -*/ ! 2724: - ! 2725: -doscsireq( fd, dsp) ! 2726: - int fd; /* ioctl file descriptor */ ! 2727: - struct dsreq *dsp; /* devscsi request packet */ ! 2728: -{ ! 2729: - int cc; ! 2730: - int retries = 4; ! 2731: - uchar_t sbyte; ! 2732: - ! 2733: - DSDBG(fprintf(stderr,"doscsireq(%d,%x) %x ---- %s\n",fd,dsp, ! 2734: - (CMDBUF(dsp))[0], ! 2735: - ds_vtostr( (CMDBUF(dsp))[0], cmdnametab))); ! 2736: - ! 2737: - /* ! 2738: - * loop, issuing command ! 2739: - * until done, or further retry pointless ! 2740: - */ ! 2741: - ! 2742: - while ( --retries > 0 ) { ! 2743: - ! 2744: - caddr_t sp; ! 2745: - ! 2746: - sp = SENSEBUF(dsp); ! 2747: - DSDBG(fprintf(stderr,"cmdbuf = "); ! 2748: - bprint(CMDBUF(dsp),CMDLEN(dsp),16,1)); ! 2749: - if ( (dsp->ds_flags & DSRQ_WRITE) ) ! 2750: - DSDBG(bprint( DATABUF(dsp), min(50,DATALEN(dsp)),16,1 )); ! 2751: - ! 2752: -DSDBG(fprintf(stderr,"databuf datalen %x %d\n",DATABUF(dsp), DATALEN(dsp))); ! 2753: - cc = ioctl( fd, DS_ENTER, dsp); ! 2754: - if ( cc < 0) { ! 2755: - ds_panic(dsp, "cannot ioctl fd %d\n",fd); ! 2756: - } ! 2757: - ! 2758: - DSDBG(fprintf(stderr,"cmdlen after ioctl=%d\n",CMDLEN(dsp))); ! 2759: - DSDBG(fprintf(stderr,"ioctl=%d ret=%x %s", ! 2760: - cc, RET(dsp), ! 2761: - RET(dsp) ? ds_vtostr(RET(dsp),dsrtnametab) : "")); ! 2762: - DSDBG(if (SENSESENT(dsp)) fprintf(stderr," sensesent=%d", ! 2763: - SENSESENT(dsp))); ! 2764: - ! 2765: - DSDBG(fprintf(stderr, ! 2766: - " cmdsent=%d datasent=%d sbyte=%x %s\n", ! 2767: - CMDSENT(dsp), DATASENT(dsp), STATUS(dsp), ! 2768: - ds_vtostr(STATUS(dsp), cmdstatustab))); ! 2769: - DSDBG(if ( FLAGS(dsp) & DSRQ_READ ) ! 2770: - bprint( DATABUF(dsp), min(16*16,DATASENT(dsp)), 16,1)); ! 2771: - ! 2772: -#ifdef aux ! 2773: - /* ! 2774: - * check for AUX bus-error ! 2775: - * we retry with poll-dma ! 2776: - */ ! 2777: - if ( RET(dsp) == DSRT_AGAIN ) { ! 2778: - int n = SDC_RDPOLL|SDC_WRPOLL; ! 2779: - DSDBG(fprintf(stderr,"setting rd/wr-poll")); ! 2780: - cc = ioctl( fd, DS_SET, n); /* set bits */ ! 2781: - if ( cc != 0 ) ! 2782: - return -1; ! 2783: - } ! 2784: -#endif aux ! 2785: - ! 2786: - if ( RET(dsp) == DSRT_NOSEL ) ! 2787: - continue; /* retry noselect 3X */ ! 2788: - ! 2789: - /* decode sense data returned */ ! 2790: - if ( SENSESENT(dsp) ) { ! 2791: - DSDBG( ! 2792: - fprintf(stderr, "sense key %x - %s\n", ! 2793: - SENSEKEY(sp), ! 2794: - ds_vtostr( SENSEKEY(sp), sensekeytab)); ! 2795: - bprint( SENSEBUF(dsp), ! 2796: - min(100, SENSESENT(dsp)), ! 2797: - 16,1); ! 2798: - ); ! 2799: - } ! 2800: - DSDBG(fprintf(stderr, "sbyte %x\n", STATUS(dsp))); ! 2801: - ! 2802: - /* decode scsi command status byte */ ! 2803: - sbyte = STATUS(dsp); ! 2804: - switch (sbyte) { ! 2805: - case 0x08: /* BUSY */ ! 2806: - case 0x18: /* RESERV CONFLICT */ ! 2807: - sleep(2); ! 2808: - continue; ! 2809: - case 0x00: /* GOOD */ ! 2810: - case 0x02: /* CHECK CONDITION */ ! 2811: - case 0x10: /* INTERM/GOOD */ ! 2812: - default: ! 2813: - return sbyte; ! 2814: - } ! 2815: - } ! 2816: - return -1; /* fail retry limit */ ! 2817: -} ! 2818: - ! 2819: - ! 2820: -/* ! 2821: -|| opttovar - lookup option in table, return var addr (NULL if fail) ! 2822: -*/ ! 2823: - ! 2824: -int * ! 2825: -opttovar( ostr, table) ! 2826: - char *ostr; ! 2827: - struct opttab{ ! 2828: - char *opt; ! 2829: - int *var; ! 2830: - } *table; ! 2831: -{ ! 2832: - register struct opttab *tp; ! 2833: - ! 2834: - for (tp=table; (tp->var); tp++) ! 2835: - if ( strncmp( ostr, tp->opt, 3) == 0 ) ! 2836: - break; ! 2837: - ! 2838: - if ( !tp->var ) ! 2839: - fprintf(stderr,"unknown option %s", ostr); ! 2840: - ! 2841: - return (tp->var); ! 2842: -} ! 2843: - ! 2844: - ! 2845: -/* ! 2846: -|| ds_vtostr - lookup value in table to return string pointer ! 2847: -*/ ! 2848: - ! 2849: -char * ! 2850: -ds_vtostr( v, table) ! 2851: - long v; ! 2852: - struct vtab *table; ! 2853: -{ ! 2854: - register struct vtab *tp; ! 2855: - ! 2856: - for (tp=table; (tp->string); tp++) ! 2857: - if ( v == tp->val ) ! 2858: - break; ! 2859: - ! 2860: - return (tp->string) ? tp->string : ""; ! 2861: -} ! 2862: - ! 2863: - ! 2864: -/* ! 2865: -|| ds_panic - yelp, leave... ! 2866: -*/ ! 2867: - ! 2868: -ds_panic( fmt, v) ! 2869: - char *fmt; ! 2870: - int v; ! 2871: -{ ! 2872: - extern errno; ! 2873: - ! 2874: - fprintf(stderr,fmt,v); ! 2875: - fprintf(stderr,"\nerrno = %d\n",errno); ! 2876: - exit(1); ! 2877: -} ! 2878: - ! 2879: - ! 2880: -/* ! 2881: -|| ds_zot - go away, with a message. ! 2882: -*/ ! 2883: - ! 2884: -ds_zot(message) ! 2885: - char *message; ! 2886: -{ ! 2887: - fprintf(stderr, "%s\n", message); ! 2888: - exit(1); ! 2889: -} ! 2890: //GO.SYSIN DD scsi/scsi/dslib.c ! 2891: echo scsi/scsi/volid.c 1>&2 ! 2892: sed 's/.//' >scsi/scsi/volid.c <<'//GO.SYSIN DD scsi/scsi/volid.c' ! 2893: -#include <stddef.h> ! 2894: -#include <stdio.h> ! 2895: -#include "../scsi.h" ! 2896: -#include "../juke.h" ! 2897: - ! 2898: -static ! 2899: -myread(int drive, long block, struct scsi_return *ret, char *err) ! 2900: -{ ! 2901: - struct scsi_cmd cmd; ! 2902: - ! 2903: - cmd.bus_id = s_id; ! 2904: - set10(cmd, 0x28, drive<<5, block>>24, block>>16, block>>8, block, 0, 0, 1, 0); ! 2905: - return(s_io(0, &cmd, 0, ret, 1024, err)); ! 2906: -} ! 2907: - ! 2908: -j_rvolid(int drive, char *err) ! 2909: -{ ! 2910: - struct scsi_return ret; ! 2911: - long b, lastb; ! 2912: - char buf[1024]; ! 2913: - int debug = 0; ! 2914: - ! 2915: - err[0] = 0; ! 2916: - if(s_start(drive, err) < 0) ! 2917: - return(-1); ! 2918: - if(myread(drive, 0L, &ret, err) == 0){ ! 2919: - memset(buf, 0, 1024); ! 2920: - if(memcmp(buf, ret.data, 1024)){ ! 2921: - if(debug) ! 2922: - fprintf(stderr, "superblok at 0\n"); ! 2923: - goto done; /* found a superblock at 0 */ ! 2924: - } ! 2925: - } ! 2926: - for(b = 1, lastb = -1;;){ ! 2927: -hack: ! 2928: - if(debug) ! 2929: - fprintf(stderr, "read block %d\n", b); ! 2930: - if(myread(drive, b, &ret, err)) ! 2931: - break; ! 2932: - lastb = b; ! 2933: - b = ((long *)ret.data)[9]; ! 2934: - } ! 2935: - if(lastb < 0){ ! 2936: - if(b == 1){ /* for disks with a bad block 1 */ ! 2937: - b = 2; ! 2938: - goto hack; ! 2939: - } ! 2940: - if(debug) ! 2941: - fprintf(stderr, "tried for superblock at blocks 1,2\n"); ! 2942: - sprintf(err, "no superblock"); ! 2943: - s_stop(drive, buf); ! 2944: - return(1); ! 2945: - } ! 2946: - if(myread(drive, lastb, &ret, err) < 0){ ! 2947: - s_stop(drive, buf); ! 2948: - fprintf(stderr, "read fail on block %d (b=%d)\n", lastb, b);/**/ ! 2949: - return(-1); ! 2950: - } ! 2951: - if(debug) ! 2952: - fprintf(stderr, "superblock at %d\n", lastb); ! 2953: -done: ! 2954: - strncpy(err, (char *)&ret.data[42], 128); ! 2955: - err[127] = 0; ! 2956: - s_stop(drive, buf); ! 2957: - return(0); ! 2958: -} ! 2959: - ! 2960: -static ! 2961: -mywrite(int drive, long block, struct scsi_cmd *cmd, struct scsi_return *ret, char *err) ! 2962: -{ ! 2963: - set10((*cmd), 0x2A, drive<<5, block>>24, block>>16, block>>8, block, 0, 0, 1, 0); ! 2964: - return(s_io(0, cmd, 1024, ret, 0, err)); ! 2965: -} ! 2966: - ! 2967: -j_wvolid(int drive, char *vol_id, char *err) ! 2968: -{ ! 2969: - char tmpfile[L_tmpnam]; ! 2970: - char buf[512]; ! 2971: - struct scsi_return ret; ! 2972: - struct scsi_cmd cmd; ! 2973: - FILE *fp; ! 2974: - int n; ! 2975: - ! 2976: - printf("mkfs %s\n", vol_id); ! 2977: - /* first get the capacity/size for mkfs to make a valid superblock */ ! 2978: - tmpnam(tmpfile); ! 2979: - if((fp = fopen(tmpfile, "w+r")) == NULL){ ! 2980: - pperror(err, tmpfile); ! 2981: - return(-1); ! 2982: - } ! 2983: - if(s_start(drive, err) < 0) ! 2984: - return(-1); ! 2985: - set10(cmd, 0x25, drive<<5, 0, 0, 0, 0, 0, 0, 0, 0); ! 2986: - if(n = s_io(0, &cmd, 0, &ret, 8, err)) ! 2987: - return(n); ! 2988: - switch(longat(&ret.data[0])) ! 2989: - { ! 2990: - case 1637999: /* sony 12in clv single density */ ! 2991: - sprintf(buf, "worm mkfs -n %d -f %s %s", 1600000, tmpfile, vol_id); ! 2992: - break; ! 2993: - case 3275999: /* sony 12in clv double density */ ! 2994: - sprintf(buf, "worm mkfs -n %d -f %s %s", 3250000, tmpfile, vol_id); ! 2995: - break; ! 2996: - default: ! 2997: - fprintf(stderr, "warning: bad capacity %d\n", longat(&ret.data[0])); ! 2998: - sprintf(buf, "worm mkfs -f %s %s", tmpfile, vol_id); ! 2999: - break; ! 3000: - } ! 3001: - if(system(buf)){ ! 3002: - sprintf(err, "%s: error", buf); ! 3003: - return(-1); ! 3004: - } ! 3005: - unlink(tmpfile); ! 3006: - fseek(fp, 1024L, 0); ! 3007: - if(fread(cmd.data, 1, 1024, fp) == 0){ ! 3008: - pperror(err, "mkfs read"); ! 3009: - return(-1); ! 3010: - } ! 3011: - fclose(fp); ! 3012: - if(mywrite(drive, 1L, &cmd, &ret, err)) ! 3013: - return(-1); ! 3014: - unlink(tmpfile); ! 3015: - s_stop(drive, err); ! 3016: - return(0); ! 3017: -} ! 3018: //GO.SYSIN DD scsi/scsi/volid.c ! 3019: echo scsi/scsi/pperror.c 1>&2 ! 3020: sed 's/.//' >scsi/scsi/pperror.c <<'//GO.SYSIN DD scsi/scsi/pperror.c' ! 3021: -#include "../scsi.h" ! 3022: - ! 3023: -void ! 3024: -pperror(char *buf, char *mesg) ! 3025: -{ ! 3026: - extern int sys_nerr; ! 3027: - extern char *sys_errlist[]; ! 3028: - extern int errno; ! 3029: - ! 3030: - if((errno < 0) || (errno >= sys_nerr)) ! 3031: - sprintf(buf, "%s: unknown errno %d", mesg, errno); ! 3032: - else ! 3033: - sprintf(buf, "%s: %s", mesg, sys_errlist[errno]); ! 3034: -} ! 3035: //GO.SYSIN DD scsi/scsi/pperror.c ! 3036: echo scsi/scsi/fixedstr.c 1>&2 ! 3037: sed 's/.//' >scsi/scsi/fixedstr.c <<'//GO.SYSIN DD scsi/scsi/fixedstr.c' ! 3038: -#include "../scsi.h" ! 3039: - ! 3040: -void ! 3041: -fixedstr(uchar *src, int len, char *dest) ! 3042: -{ ! 3043: - uchar *s; ! 3044: - ! 3045: - while((*src == ' ') && (len > 0)) ! 3046: - src++, len--; ! 3047: - for(s = src+len-1; s >= src; s--) ! 3048: - if(*s != ' ') ! 3049: - break; ! 3050: - memcpy(dest, (char *)src, len = s-src+1); ! 3051: - dest[len] = 0; ! 3052: -} ! 3053: //GO.SYSIN DD scsi/scsi/fixedstr.c ! 3054: echo scsi/scsi/longat.c 1>&2 ! 3055: sed 's/.//' >scsi/scsi/longat.c <<'//GO.SYSIN DD scsi/scsi/longat.c' ! 3056: -#include "../scsi.h" ! 3057: - ! 3058: -unsigned long ! 3059: -longat(uchar *src) ! 3060: -{ ! 3061: - unsigned long n; ! 3062: - ! 3063: - n = *src++; ! 3064: - n = (n<<8) | *src++; ! 3065: - n = (n<<8) | *src++; ! 3066: - n = (n<<8) | *src; ! 3067: - return(n); ! 3068: -} ! 3069: //GO.SYSIN DD scsi/scsi/longat.c ! 3070: echo scsi/scsi/xd.c 1>&2 ! 3071: sed 's/.//' >scsi/scsi/xd.c <<'//GO.SYSIN DD scsi/scsi/xd.c' ! 3072: -#include <stdio.h> ! 3073: -#include "../scsi.h" ! 3074: -#include "../scsish.h" ! 3075: - ! 3076: -#define WIDTH 32 ! 3077: - ! 3078: -void ! 3079: -xd(uchar *p, int n, FILE *fp) ! 3080: -{ ! 3081: - register i, nd, l; ! 3082: - unsigned char buf[WIDTH]; ! 3083: - int didstar; ! 3084: - unsigned char *s; ! 3085: - ! 3086: - for(nd = 0; n > 0; n -= l, nd += l){ ! 3087: - l = min(WIDTH, n); ! 3088: - if(nd && (l == WIDTH) && (memcmp(buf, p, l) == 0)){ ! 3089: - p += WIDTH; ! 3090: - if(didstar++ == 0) ! 3091: - fprintf(fp, "*\n"); ! 3092: - continue; ! 3093: - } ! 3094: - memcpy(buf, p, l); ! 3095: - didstar = 0; ! 3096: - fprintf(fp, "%5.5d", nd); ! 3097: - s = p; ! 3098: - for(i = 0; i < l; i++){ ! 3099: - if((i%4) == 0) putc(' ', fp); ! 3100: - fprintf(fp, "%2.2x", *p++); ! 3101: - } ! 3102: - putc('\n', fp); ! 3103: - fprintf(fp, " "); ! 3104: - for(i = 0; i < l; i++){ ! 3105: - if((i%4) == 0) putc(' ', fp); ! 3106: - if((*s >= ' ') && (*s < 0177)) ! 3107: - fprintf(fp, " %c", *s++); ! 3108: - else switch(*s++) ! 3109: - { ! 3110: - case '\n': fprintf(fp, "\\n"); break; ! 3111: - case '\t': fprintf(fp, "\\t"); break; ! 3112: - default: fprintf(fp, ".."); break; ! 3113: - } ! 3114: - } ! 3115: - putc('\n', fp); ! 3116: - } ! 3117: - fprintf(fp, "%5.5d\n", nd); ! 3118: -} ! 3119: //GO.SYSIN DD scsi/scsi/xd.c ! 3120: echo scsi/scsi/md_io.c 1>&2 ! 3121: sed 's/.//' >scsi/scsi/md_io.c <<'//GO.SYSIN DD scsi/scsi/md_io.c' ! 3122: -#include <stdio.h> ! 3123: -#include "../scsi.h" ! 3124: -#include "../scsish.h" ! 3125: -#include <sys/types.h> ! 3126: -#include <sys/dsreq.h> ! 3127: - ! 3128: -#define DEV(buf, target, lun) sprintf(buf, "/dev/scsi/sc0d%dl%d", target, lun) ! 3129: - ! 3130: -static fd = -1; ! 3131: -int s_id; ! 3132: -void (*ss_extsense)(uchar *, char *, int); ! 3133: - ! 3134: -ss_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err) ! 3135: -{ ! 3136: - int retv; ! 3137: - dsreq_t ds; ! 3138: - char dev[512]; ! 3139: - ! 3140: - err[0] = 0; ! 3141: - retv = -1; ! 3142: - if(ncmd && nret){ ! 3143: - sprintf(err, "both input (%d bytes) and output (%d bytes) expected", ncmd, nret); ! 3144: - return(retv); ! 3145: - } ! 3146: - if(cmd->bus_id & 0x8000){ ! 3147: - sprintf(err, "reset not supported"); ! 3148: - return(retv); ! 3149: - } ! 3150: - if(fd < 0){ ! 3151: - DEV(dev, cmd->bus_id, ((cmd->cmd[1]>>5)&7)); ! 3152: - if((fd = open(dev, 2)) < 0){ ! 3153: - pperror(err, dev); ! 3154: - return(-1); ! 3155: - } ! 3156: - } ! 3157: - ds.ds_flags = DSRQ_SENSE; ! 3158: - ds.ds_time = 30000; ! 3159: - ds.ds_cmdbuf = (char *)cmd->cmd; ! 3160: - ds.ds_cmdlen = 10; ! 3161: - if(ncmd){ ! 3162: - ds.ds_databuf = (char *)cmd->data; ! 3163: - ds.ds_datalen = ncmd; ! 3164: - ds.ds_flags |= DSRQ_WRITE; ! 3165: - } else { ! 3166: - ds.ds_databuf = (char *)ret->data; ! 3167: - ds.ds_datalen = nret; ! 3168: - ds.ds_flags |= DSRQ_READ; ! 3169: - } ! 3170: - ds.ds_sensebuf = (char *)ret->sense; ! 3171: - ds.ds_senselen = sizeof ret->sense; ! 3172: - ds.ds_iovbuf = 0; ! 3173: - ds.ds_link = 0; ! 3174: - if(ioctl(fd, DS_ENTER, &ds) < 0){ ! 3175: - pperror(err, "DS_ENTER ioctl"); ! 3176: -err_ret: ! 3177: - close(fd); ! 3178: - fd = -1; ! 3179: - return(retv); ! 3180: - } ! 3181: - if(ds.ds_ret ! 3182: - && (ds.ds_ret != DSRT_SHORT) ! 3183: - && (ds.ds_ret != DSRT_OK) ! 3184: - ) /* an error */ ! 3185: - fprintf(stderr, "ds_ret = #%x\n", ds.ds_ret); ! 3186: - ret->type = 3; ! 3187: - ret->scsi_stat = ds.ds_status; ! 3188: - ret->scsi_msg = ds.ds_msg; ! 3189: - ret->reg1 = ret->reg2 = 0; ! 3190: - if(nret >= 0){ ! 3191: - if(ds.ds_datasent != nret){ ! 3192: - if(ds.ds_datasent == 0) ! 3193: - retv = 1; ! 3194: - else ! 3195: - sprintf(err, "data transfer error; wanted %d, got %d", nret, ds.ds_datasent); ! 3196: - goto err_ret; ! 3197: - } ! 3198: - } else { ! 3199: - ret->nread = ds.ds_datasent; ! 3200: - } ! 3201: - if(!preserve){ ! 3202: - close(fd); ! 3203: - fd = -1; ! 3204: - } ! 3205: - return(0); ! 3206: -} ! 3207: - ! 3208: -static char *smsg[16] = ! 3209: -{ ! 3210: - "good", "check condition", "met/good", "reserved", ! 3211: - "busy", "reserved", "reserved", "reserved", ! 3212: - "intermediate good", "reserved", "intermediate good/met", "reserved", ! 3213: - "reservation conflict", "reserved", "reserved", "reserved", ! 3214: -}; ! 3215: - ! 3216: -s_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err) ! 3217: -{ ! 3218: - int n; ! 3219: - int status; ! 3220: - char buf[512]; ! 3221: - char ioerr[512]; ! 3222: - ! 3223: - cmd->bus_id = s_id; ! 3224: - if(n = ss_io(preserve, cmd, ncmd, ret, nret, err)){ ! 3225: - if(n < 0) ! 3226: - return(n); ! 3227: - strcpy(ioerr, err); ! 3228: - err[0] = 0; ! 3229: - } else ! 3230: - ioerr[0] = 0; ! 3231: - if(status = ret->scsi_stat){ ! 3232: - (*ss_extsense)(ret->data, buf, sizeof buf); ! 3233: - sprintf(err, "%s; %s", ioerr[0]? ioerr : smsg[(status>>1)&0xF], buf); ! 3234: - return(1); ! 3235: - } ! 3236: - return(0); ! 3237: -} ! 3238: //GO.SYSIN DD scsi/scsi/md_io.c ! 3239: echo scsi/scsi/h_io.c 1>&2 ! 3240: sed 's/.//' >scsi/scsi/h_io.c <<'//GO.SYSIN DD scsi/scsi/h_io.c' ! 3241: -#include <stdio.h> ! 3242: -#include "../scsi.h" ! 3243: -#include "../scsish.h" ! 3244: -#include <scsi.h> ! 3245: - ! 3246: -#define DEV "/dev/scsi" ! 3247: - ! 3248: -static fd = -1; ! 3249: -int s_id; ! 3250: -int s_ignua = 1; ! 3251: -void (*ss_extsense)(uchar *, char *, int); ! 3252: - ! 3253: -ss_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err) ! 3254: -{ ! 3255: - int n; ! 3256: - int retv; ! 3257: - ! 3258: - err[0] = 0; ! 3259: - retv = -1; ! 3260: - if(fd < 0){ ! 3261: - if((fd = open(DEV, 2)) < 0){ ! 3262: - pperror(err, DEV); ! 3263: - return(-1); ! 3264: - } ! 3265: - } ! 3266: - cmd->flags |= (ncmd == 0)? SCSI_RD:SCSI_WR; ! 3267: - if((n = write(fd, cmd, 16+ncmd)) != 16+ncmd){ ! 3268: - pperror(err, "scsiio write"); ! 3269: -err_ret: ! 3270: - close(fd); ! 3271: - fd = -1; ! 3272: - return(retv); ! 3273: - } ! 3274: - if(nret >= 0){ ! 3275: - if((n = read(fd, ret, 36+nret)) != 36+nret){ ! 3276: - if(n == 36) ! 3277: - retv = 1; ! 3278: - else ! 3279: - pperror(err, "scsiio read"); ! 3280: - goto err_ret; ! 3281: - } ! 3282: - } else { ! 3283: - if((n = read(fd, ret, 36-nret)) < 0){ ! 3284: - pperror(err, "scsiio read"); ! 3285: - goto err_ret; ! 3286: - } ! 3287: - ret->nread = n-36; ! 3288: - } ! 3289: - if(!preserve){ ! 3290: - close(fd); ! 3291: - fd = -1; ! 3292: - } ! 3293: - return(0); ! 3294: -} ! 3295: - ! 3296: -static char *smsg[16] = ! 3297: -{ ! 3298: - "good", "check condition", "met/good", "reserved", ! 3299: - "busy", "reserved", "reserved", "reserved", ! 3300: - "intermediate good", "reserved", "intermediate good/met", "reserved", ! 3301: - "reservation conflict", "reserved", "reserved", "reserved", ! 3302: -}; ! 3303: - ! 3304: -s_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err) ! 3305: -{ ! 3306: - int n; ! 3307: - int status; ! 3308: - char buf[512]; ! 3309: - char ioerr[512]; ! 3310: - struct scsi_cmd mycmd; ! 3311: - int ignoredua = 0; ! 3312: - ! 3313: - cmd->bus_id = s_id; ! 3314: -again: ! 3315: - if(n = ss_io(preserve, cmd, ncmd, ret, nret, err)){ ! 3316: - if(n < 0) ! 3317: - return(n); ! 3318: - strcpy(ioerr, err); ! 3319: - err[0] = 0; ! 3320: - } else ! 3321: - ioerr[0] = 0; ! 3322: - if(status = ret->scsi_stat){ ! 3323: - mycmd.bus_id = s_id; ! 3324: - set6(mycmd, 0x03, cmd->cmd[1]&0xE0, 0, 0, 100, 0); ! 3325: - if(n = ss_io(0, &mycmd, 0, ret, -100, err)) ! 3326: - return(n); ! 3327: - if(s_ignua){ /* ignore unit attention ?? */ ! 3328: - if((ret->data[2]&0xF) == 6){ /* it is */ ! 3329: - if(ignoredua++ == 0){ /* but only ignore once */ ! 3330: - mycmd.bus_id = s_id; ! 3331: - set6(mycmd, 0x12, cmd->cmd[1]&0xE0, 0, 0, 5, 0); ! 3332: - if(n = ss_io(0, &mycmd, 0, ret, 5, err)) ! 3333: - return(n); ! 3334: - goto again; ! 3335: - } ! 3336: - } ! 3337: - } ! 3338: - if(ss_extsense == 0) ! 3339: - ss_extsense = gen_extsense; ! 3340: - (*ss_extsense)(ret->data, buf, sizeof buf); ! 3341: - sprintf(err, "%s; %s", ioerr[0]? ioerr : smsg[(status>>1)&0xF], buf); ! 3342: - return(1); ! 3343: - } ! 3344: - return(0); ! 3345: -} ! 3346: //GO.SYSIN DD scsi/scsi/h_io.c ! 3347: echo scsi/scsi/gendev 1>&2 ! 3348: sed 's/.//' >scsi/scsi/gendev <<'//GO.SYSIN DD scsi/scsi/gendev' ! 3349: -awk 'END { for(t = 1; t < 8; t++) for(l=0; l < 8; l++){ ! 3350: - printf "/etc/mknod sc0d%dl%d c 43 %d\n", t, l, l*8+t ! 3351: - } ! 3352: - print "chmod 600 *; chown andrew *" ! 3353: - }' < /dev/null ! 3354: //GO.SYSIN DD scsi/scsi/gendev ! 3355: echo scsi/iodr_sh.c 1>&2 ! 3356: sed 's/.//' >scsi/iodr_sh.c <<'//GO.SYSIN DD scsi/iodr_sh.c' ! 3357: -#include "scsi.h" ! 3358: -#include "juke.h" ! 3359: - ! 3360: -j_shelf_to_drive(int sh, Side side, int dr, char *err) ! 3361: -{ ! 3362: - struct scsi_cmd cmd; ! 3363: - struct scsi_return ret; ! 3364: - ! 3365: - set6(cmd, 0xD6, dr<<5, 0, (sh<<1)|side, 0, 0); ! 3366: - return(s_io(0, &cmd, 0, &ret, 0, err)); ! 3367: -} ! 3368: - ! 3369: -j_drive_to_shelf(int dr, int sh, Side side, char *err) ! 3370: -{ ! 3371: - struct scsi_cmd cmd; ! 3372: - struct scsi_return ret; ! 3373: - ! 3374: - if(sh < 0) ! 3375: - set6(cmd, 0xD7, dr<<5, 0, 0, 0, 0); ! 3376: - else ! 3377: - set6(cmd, 0xD7, (dr<<5)|1, 0, (sh<<1)|side, 0, 0); ! 3378: - return(s_io(0, &cmd, 0, &ret, 0, err)); ! 3379: -} ! 3380: - ! 3381: -int ! 3382: -j_empty_drive(long tlimit, char *buf) ! 3383: -{ ! 3384: - int i, tstop; ! 3385: - ! 3386: - tstop = time((long *)0) + tlimit; ! 3387: - while(time((long *)0) <= tstop){ ! 3388: - setnlun(); /* in case it changes */ ! 3389: - /* look for empty drives */ ! 3390: - for(i = 0; i < nlun; i++) ! 3391: - if(!j_status.lun[i].diskin) ! 3392: - return(i); ! 3393: - /* look for spun down drives */ ! 3394: - for(i = 0; i < nlun; i++){ ! 3395: - if(!j_status.lun[i].ready){ ! 3396: - if(j_drive_to_shelf(i, -1, SIDEA, buf)) ! 3397: - return(-1); ! 3398: - else ! 3399: - return(i); ! 3400: - } ! 3401: - } ! 3402: - sleep(10); ! 3403: - if(j_getstatus(buf)) /* get the jukebox status */ ! 3404: - return(-1); ! 3405: - } ! 3406: - return(-1); ! 3407: -} ! 3408: //GO.SYSIN DD scsi/iodr_sh.c ! 3409: echo scsi/ioshelves.c 1>&2 ! 3410: sed 's/.//' >scsi/ioshelves.c <<'//GO.SYSIN DD scsi/ioshelves.c' ! 3411: -#include <stddef.h> ! 3412: -#include <stdio.h> ! 3413: -#include <string.h> ! 3414: -#include "scsi.h" ! 3415: -#include "juke.h" ! 3416: - ! 3417: -char *j_shelf[NSHELF]; ! 3418: -int j_wrshelf = 0; ! 3419: - ! 3420: -j_rdshelves(char *err) ! 3421: -{ ! 3422: - FILE *fp; ! 3423: - static haveread = 0; ! 3424: - int shno; ! 3425: - char vname[256]; ! 3426: - ! 3427: - if(haveread) ! 3428: - return(0); ! 3429: - for(shno = 0; shno < NSHELF; shno++) ! 3430: - j_shelf[shno] = 0; ! 3431: - if((fp = fopen(JUKEDIR, "r")) == NULL){ ! 3432: - pperror(err, JUKEDIR); ! 3433: - return(-1); ! 3434: - } ! 3435: - while(fscanf(fp, "%d %s\n", &shno, vname) == 2){ ! 3436: - if((shno < 0) || (shno >= NSHELF)){ ! 3437: - fprintf(stderr, "Warning: bad shelf number in %s: %d (vol_id=%s)\n", ! 3438: - JUKEDIR, shno, vname); ! 3439: - continue; ! 3440: - ! 3441: - } ! 3442: - j_shelf[shno] = strdup(vname); ! 3443: - } ! 3444: - fclose(fp); ! 3445: - haveread = 1; ! 3446: - return(0); ! 3447: -} ! 3448: - ! 3449: -j_wrshelves(char *err) ! 3450: -{ ! 3451: - FILE *fp; ! 3452: - int shno; ! 3453: - ! 3454: - if((fp = fopen(JUKEDIR, "w")) == NULL){ ! 3455: - pperror(err, JUKEDIR); ! 3456: - return(-1); ! 3457: - } ! 3458: - for(shno = 0; shno < NSHELF; shno++) ! 3459: - if(j_shelf[shno]) ! 3460: - fprintf(fp, "%d %s\n", shno, j_shelf[shno]); ! 3461: - fclose(fp); ! 3462: - return(0); ! 3463: -} ! 3464: - ! 3465: -int ! 3466: -j_shelfof(char *vol_id) ! 3467: -{ ! 3468: - int i; ! 3469: - char buf[512]; ! 3470: - ! 3471: - for(;;){ ! 3472: - for(i = 0; i < NSHELF; i++) ! 3473: - if(j_shelf[i] && (strcmp(j_shelf[i], vol_id) == 0)) ! 3474: - return(i); ! 3475: - if((i = warm_inv(buf)) <= 0) ! 3476: - break; ! 3477: - } ! 3478: - if(i < 0) ! 3479: - fprintf(stderr, "jukebox: %s\n", buf); ! 3480: - return(-1); ! 3481: -} ! 3482: - ! 3483: -int ! 3484: -j_driveof(char *vol_id) ! 3485: -{ ! 3486: - int i, sh; ! 3487: - ! 3488: - if((sh = j_shelfof(vol_id)) < 0) ! 3489: - return(-1); ! 3490: - for(i = 0; i < NLUN; i++) ! 3491: - if(j_status.lun[i].shelfvalid && (j_status.lun[i].retshelf == sh)) ! 3492: - return(i); ! 3493: - return(-1); ! 3494: -} ! 3495: //GO.SYSIN DD scsi/ioshelves.c ! 3496: echo scsi/scsish.c 1>&2 ! 3497: sed 's/.//' >scsi/scsish.c <<'//GO.SYSIN DD scsi/scsish.c' ! 3498: -#include <stddef.h> ! 3499: -#include <stdio.h> ! 3500: -#include <string.h> ! 3501: -#include "scsi.h" ! 3502: -#include "scsish.h" ! 3503: - ! 3504: -extern Device genericdev; ! 3505: -static Device *dev = 0; ! 3506: -static Function *function(char *, Device **); ! 3507: -static void parse(FILE *); ! 3508: - ! 3509: -main() ! 3510: -{ ! 3511: - setbuf(stdout, (char *)0); ! 3512: - scsi_target(2); ! 3513: - set_sony(); ! 3514: - printf("dev=%s, target=%d:\n", dev? dev->name:genericdev.name, s_id); ! 3515: - parse(stdin); ! 3516: - exit(0); ! 3517: -} ! 3518: - ! 3519: -static void ! 3520: -parse(FILE *fp) ! 3521: -{ ! 3522: - int i, n; ! 3523: - char *param; ! 3524: - char buf[4096]; ! 3525: - char *ptrs[100], *cargs[20]; ! 3526: - int iargs[20]; ! 3527: - int nc, ni; ! 3528: - Function *fn; ! 3529: - Device *thatdev; ! 3530: - char err[512]; ! 3531: - ! 3532: - for(;;){ ! 3533: - printf("> "); ! 3534: - fflush(stdout); ! 3535: - if(fgets(buf, sizeof buf, fp) == NULL) ! 3536: - break; ! 3537: - if(param = strchr(buf, '\n')) ! 3538: - *param = 0; ! 3539: - n = getmfields(buf, ptrs, sizeof ptrs/sizeof ptrs[0]); ! 3540: - if(n < 1) ! 3541: - continue; ! 3542: - if((fn = function(ptrs[0], &thatdev)) == 0){ ! 3543: - fprintf(stderr, "can't find cmd '%s'\n", ptrs[0]); ! 3544: - continue; ! 3545: - } ! 3546: - ni = nc = 0; ! 3547: - param = fn->param; ! 3548: - for(i = 1; i < n; i++){ ! 3549: - switch(*param++) ! 3550: - { ! 3551: - case 'I': ! 3552: - iargs[ni++] = atoi(ptrs[i]); ! 3553: - break; ! 3554: - case 'L': ! 3555: - iargs[ni++] = atoi(ptrs[i]); ! 3556: - if((iargs[ni-1] < 0) || (iargs[ni-1] > 7)){ ! 3557: - fprintf(stderr, "%s: lun %d out of range\n", ptrs[0], iargs[ni-1]); ! 3558: - continue; ! 3559: - } ! 3560: - break; ! 3561: - case 'S': ! 3562: - cargs[nc++] = ptrs[i]; ! 3563: - break; ! 3564: - default: ! 3565: - break; ! 3566: - } ! 3567: - if(*param == '?') ! 3568: - param++; ! 3569: - } ! 3570: - while(param[0] && param[1] && (param[1] == '?')) ! 3571: - param += 2; ! 3572: - if((i == n) != (*param == 0)){ ! 3573: - printf("param mismatch: %s: i=%d/n=%d param='%s'\n", ! 3574: - ptrs[0], i, n, param); ! 3575: - printf("device %s: %s\n", thatdev->name, fn->help); ! 3576: - continue; ! 3577: - } ! 3578: - if((*fn->fn)(ni, iargs, nc, cargs, err)) ! 3579: - fprintf(stderr, "error in '%s': %s\n", fn->name, err); ! 3580: - } ! 3581: -} ! 3582: - ! 3583: -static Function * ! 3584: -flook(Function *f, char *name) ! 3585: -{ ! 3586: - for(; f->help; f++) ! 3587: - if(strncmp(f->name, name, strlen(f->name)) == 0) ! 3588: - return(f); ! 3589: - return(0); ! 3590: -} ! 3591: - ! 3592: -static Function * ! 3593: -function(char *name, Device **devptr) ! 3594: -{ ! 3595: - Function *f = 0; ! 3596: - ! 3597: - if(dev && dev->fns && (f = flook(dev->fns, name))) ! 3598: - *devptr = dev; ! 3599: - else if(f = flook(genericdev.fns, name)) ! 3600: - *devptr = &genericdev; ! 3601: - return(f); ! 3602: -} ! 3603: - ! 3604: -void ! 3605: -setdevice(Device *d) ! 3606: -{ ! 3607: - dev = d; ! 3608: - ss_extsense = dev->extsense; ! 3609: -} ! 3610: - ! 3611: -static ! 3612: -help(Device *d, char *cmd, Device *prec) ! 3613: -{ ! 3614: - Function *f; ! 3615: - Function *base; ! 3616: - ! 3617: - base = (prec && prec->fns)? prec->fns:0; ! 3618: - if(cmd == 0){ ! 3619: - printf("device %s(%s):\n", d->name, d->verbose); ! 3620: - if(f = d->fns) ! 3621: - while(f->name){ ! 3622: - if((base == 0) || (flook(base, f->name) == 0)) ! 3623: - printf("\t%s\n", f->help); ! 3624: - f++; ! 3625: - } ! 3626: - return(0); ! 3627: - } else { ! 3628: - if(f = d->fns) ! 3629: - while(f->name) ! 3630: - if(strcmp(f->name, cmd) == 0){ ! 3631: - printf("(%s) %s\n", d->name, f->help); ! 3632: - return(1); ! 3633: - } else ! 3634: - f++; ! 3635: - return(0); ! 3636: - } ! 3637: -} ! 3638: - ! 3639: -int ! 3640: -gen_help(int niargs, int *iargs, int ncargs, char **cargs) ! 3641: -{ ! 3642: -#pragma ref niargs ! 3643: -#pragma ref iargs ! 3644: - ! 3645: - if(dev) ! 3646: - if(help(dev, ncargs == 0? 0:cargs[0], (Device *)0)) ! 3647: - return(0); ! 3648: - help(&genericdev, ncargs == 0? 0:cargs[0], dev); ! 3649: - return(0); ! 3650: -} ! 3651: - ! 3652: -extern Device sonydev; ! 3653: -extern Device wrendev; ! 3654: -static Device *devs[] = { ! 3655: - &genericdev, ! 3656: - &sonydev, ! 3657: - &wrendev, ! 3658: - 0 ! 3659: -}; ! 3660: - ! 3661: -int ! 3662: -gen_dev(int niargs, int *iargs, int ncargs, char **cargs) ! 3663: -{ ! 3664: - Device **d; ! 3665: - ! 3666: -#pragma ref niargs ! 3667: -#pragma ref iargs ! 3668: - ! 3669: - if(ncargs == 0) ! 3670: - printf("dev=%s\n", dev? dev->name : genericdev.name); ! 3671: - else if(strcmp(cargs[0], "?") == 0){ ! 3672: - printf("available devices:\n"); ! 3673: - for(d = devs; *d; d++) ! 3674: - printf("\t%s(%s)\n", (*d)->name, (*d)->verbose); ! 3675: - } else { ! 3676: - for(d = devs; *d; d++) ! 3677: - if(strcmp(cargs[0], (*d)->name) == 0) ! 3678: - break; ! 3679: - if(*d) ! 3680: - setdevice(*d); ! 3681: - else ! 3682: - fprintf(stderr, "device '%s' unknown\n", cargs[0]); ! 3683: - } ! 3684: - return(0); ! 3685: -} ! 3686: - ! 3687: -void ! 3688: -scsi_target(int n) ! 3689: -{ ! 3690: - if((n < 0) || (n >= 8)) ! 3691: - fprintf(stderr, "%d is an invalid target\n", n); ! 3692: - else ! 3693: - s_id = n; ! 3694: -} ! 3695: - ! 3696: -set_sony() ! 3697: -{ ! 3698: - int iargs[1]; ! 3699: - char *cargs[1]; ! 3700: - ! 3701: - cargs[0] = "sony"; ! 3702: - gen_dev(0, iargs, 1, cargs); ! 3703: -} ! 3704: //GO.SYSIN DD scsi/scsish.c ! 3705: echo scsi/dslib.c 1>&2 ! 3706: sed 's/.//' >scsi/dslib.c <<'//GO.SYSIN DD scsi/dslib.c' ! 3707: -/* ! 3708: -|| dslib.c - library routines for /dev/scsi ! 3709: -|| ! 3710: -|| Copyright 1988, 1989, by ! 3711: -|| Gene Dronek (Vulcan Laboratory) and ! 3712: -|| Rich Morin (Canta Forda Computer Laboratory). ! 3713: -|| All rights reserved. ! 3714: -*/ ! 3715: -#ident "dslib.c: $Revision: 1.4 $" ! 3716: - ! 3717: -#include <stdio.h> ! 3718: -#include <sys/types.h> ! 3719: - ! 3720: -#include "dslib.h" ! 3721: -#ifdef aux ! 3722: -#include <sys/vio.h> ! 3723: -#include <sys/scsireq.h> ! 3724: -#endif aux ! 3725: - ! 3726: -int dsdebug=0; ! 3727: -long dsreqflags; /* flag bits always set by filldsreq */ ! 3728: - ! 3729: -#define min(i,j) ( (i) < (j) ? (i) : (j) ) ! 3730: - ! 3731: - ! 3732: -/* ! 3733: -|| Startup/shutdown ----------------------------------------------- ! 3734: -*/ ! 3735: - ! 3736: -static struct context *dsc[FDSIZ]; ! 3737: - ! 3738: - ! 3739: -/* ! 3740: -|| dsopen - open device, set up structures ! 3741: -*/ ! 3742: - ! 3743: -struct dsreq * ! 3744: -dsopen(opath, oflags) ! 3745: - char *opath; ! 3746: - int oflags; ! 3747: -{ ! 3748: - ! 3749: - struct dsreq *dsp; ! 3750: - struct context *cp; ! 3751: - int fd; ! 3752: - DSDBG(fprintf(stderr,"dsopen(%s,%x) ", opath, oflags)); ! 3753: - ! 3754: - fd = open(opath, oflags); ! 3755: - if (fd < 0) ! 3756: - return NULL; /* can't open */ ! 3757: - if (dsc[fd] != NULL) /* already in use */ ! 3758: - ds_zot("dsopen: fd already in use"); ! 3759: - ! 3760: - cp = (struct context *) calloc(1, sizeof(struct context)); ! 3761: - if (cp == NULL) /* can't allocate */ ! 3762: - ds_zot("dsopen: can't allocate space"); ! 3763: - dsc[fd] = cp; ! 3764: - cp->dsc_fd = fd; ! 3765: - dsp = &(cp->dsc_dsreq); ! 3766: - ! 3767: - dsp->ds_flags = 0; ! 3768: - dsp->ds_time = 10 * 1000; /* 10 second default timeout */ ! 3769: - dsp->ds_private = (ulong) cp; /* pointer back to context */ ! 3770: - dsp->ds_cmdbuf = cp->dsc_cmd; ! 3771: - dsp->ds_cmdlen = sizeof cp->dsc_cmd; ! 3772: - dsp->ds_databuf = 0; ! 3773: - dsp->ds_datalen = 0; ! 3774: - dsp->ds_sensebuf = cp->dsc_sense; ! 3775: - dsp->ds_senselen = sizeof cp->dsc_sense; ! 3776: - DSDBG(fprintf(stderr,"=>cp %x, dsp %x\n", cp, dsp)); ! 3777: - return dsp; ! 3778: -} ! 3779: - ! 3780: - ! 3781: -/* ! 3782: -|| dsclose - close device, release context struct. ! 3783: -*/ ! 3784: - ! 3785: -dsclose(dsp) ! 3786: - struct dsreq *dsp; ! 3787: -{ ! 3788: - int fd; ! 3789: - struct context *cp; ! 3790: - ! 3791: - if (dsp == NULL) ! 3792: - ds_zot("dsclose: dsp is NULL"); ! 3793: - ! 3794: - cp = (struct context *)dsp->ds_private; ! 3795: - fd = getfd(dsp); ! 3796: - if ( cp == NULL ) ! 3797: - ds_zot("dsclose: private is NULL"); ! 3798: - ! 3799: - cfree(cp); ! 3800: - dsc[fd] = (struct context *)NULL; ! 3801: - return; ! 3802: -} ! 3803: - ! 3804: - ! 3805: -/* ! 3806: -|| Generic SCSI CCS Command functions ------------------------------------ ! 3807: -|| ! 3808: -|| dsp dsreq pointer ! 3809: -|| data data buffer pointer ! 3810: -|| datalen data buffer length ! 3811: -|| lba logical block address ! 3812: -|| vu vendor unique bits ! 3813: -*/ ! 3814: - ! 3815: -/* ! 3816: -|| testunitready00 - issue group 0 "Test Unit Ready" command (0x00) ! 3817: -*/ ! 3818: - ! 3819: -testunitready00(dsp) ! 3820: - struct dsreq *dsp; ! 3821: -{ ! 3822: - fillg0cmd(dsp, CMDBUF(dsp), G0_TEST, 0, 0, 0, 0, 0); ! 3823: - filldsreq(dsp, 0, 0, DSRQ_READ|DSRQ_SENSE); ! 3824: - return(doscsireq(getfd(dsp), dsp)); ! 3825: -} ! 3826: - ! 3827: - ! 3828: -/* ! 3829: -|| requestsense03 - issue group 0 "Request Sense" command (0x03) ! 3830: -*/ ! 3831: - ! 3832: -requestsense03(dsp, data, datalen, vu) ! 3833: - struct dsreq *dsp; ! 3834: - caddr_t data; ! 3835: - long datalen; ! 3836: - char vu; ! 3837: -{ ! 3838: - fillg0cmd(dsp, CMDBUF(dsp), G0_REQU, 0, 0, 0, B1(datalen), B1(vu<<6)); ! 3839: - filldsreq(dsp, data, datalen, DSRQ_READ); ! 3840: - return(doscsireq(getfd(dsp), dsp)); ! 3841: -} ! 3842: - ! 3843: - ! 3844: -/* ! 3845: -|| write0a - issue group 0 "Write" command (0x0a) ! 3846: -*/ ! 3847: - ! 3848: -write0a(dsp, data, datalen, lba, vu) ! 3849: - struct dsreq *dsp; ! 3850: - caddr_t data; ! 3851: - long datalen, lba; ! 3852: - char vu; ! 3853: -{ ! 3854: - fillg0cmd(dsp, CMDBUF(dsp), G0_WRIT, B3(lba), B1(datalen), B1(vu<<6)); ! 3855: - filldsreq(dsp, data, datalen, DSRQ_READ); ! 3856: - return(doscsireq(getfd(dsp), dsp)); ! 3857: -} ! 3858: - ! 3859: - ! 3860: -/* ! 3861: -|| inquiry12 - issue group 0 "Inquiry" command (0x12) ! 3862: -*/ ! 3863: - ! 3864: -inquiry12(dsp, data, datalen, vu) ! 3865: - struct dsreq *dsp; ! 3866: - caddr_t data; ! 3867: - long datalen; ! 3868: - char vu; ! 3869: -{ ! 3870: - fillg0cmd(dsp, CMDBUF(dsp), G0_INQU, 0, 0, 0, B1(datalen), B1(vu<<6)); ! 3871: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE); ! 3872: - return(doscsireq(getfd(dsp), dsp)); ! 3873: -} ! 3874: - ! 3875: - ! 3876: -/* ! 3877: -|| modeselect15 - issue group 0 "Mode Select" command (0x15) ! 3878: -|| ! 3879: -|| save 0 - don't save saveable pages ! 3880: -|| 1 - save saveable pages ! 3881: -*/ ! 3882: - ! 3883: -modeselect15(dsp, data, datalen, save, vu) ! 3884: - struct dsreq *dsp; ! 3885: - caddr_t data; ! 3886: - long datalen; ! 3887: - char save, vu; ! 3888: -{ ! 3889: - fillg0cmd(dsp, CMDBUF(dsp), G0_MSEL, save&1, 0, 0, B1(datalen), B1(vu<<6)); ! 3890: - filldsreq(dsp, data, datalen, DSRQ_WRITE|DSRQ_SENSE); ! 3891: - return(doscsireq(getfd(dsp), dsp)); ! 3892: -} ! 3893: - ! 3894: - ! 3895: -/* ! 3896: -|| modesense1a - issue group 0 "Mode Sense" command (0x1a) ! 3897: -|| ! 3898: -|| pagectrl 0 - current values ! 3899: -|| 1 - changeable values ! 3900: -|| 2 - default values ! 3901: -|| 3 - saved values ! 3902: -|| ! 3903: -|| pagecode 0 - vendor unique ! 3904: -|| 1 - error recovery ! 3905: -|| 2 - disconnect/reconnect ! 3906: -|| 3 - direct access dev. fmt. ! 3907: -|| 4 - rigid disk geometry ! 3908: -|| 5 - flexible disk ! 3909: -|| 6-9 - see specific dev. types ! 3910: -|| 0a - implemented options ! 3911: -|| 0b - medium types supported ! 3912: -|| 3f - return all pages ! 3913: -*/ ! 3914: - ! 3915: -modesense1a(dsp, data, datalen, pagectrl, pagecode, vu) ! 3916: - struct dsreq *dsp; ! 3917: - caddr_t data; ! 3918: - long datalen; ! 3919: - char pagectrl, pagecode, vu; ! 3920: -{ ! 3921: - fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN, 0x10, ! 3922: - ((pagectrl&3)<<6) | (pagecode&0x3F), ! 3923: - 0, B1(datalen), B1(vu<<6)); ! 3924: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE); ! 3925: - return(doscsireq(getfd(dsp), dsp)); ! 3926: -} ! 3927: - ! 3928: - ! 3929: -/* ! 3930: -|| senddiagnostic1d - issue group 0 "Send Diagnostic" command (0x1d) ! 3931: -|| ! 3932: -|| self 0 - run test, hold results ! 3933: -|| 1 - run test, return status ! 3934: -|| ! 3935: -|| dofl 0 - device online ! 3936: -|| 1 - device offline ! 3937: -|| ! 3938: -|| uofl 0 - unit online ! 3939: -|| 1 - unit offline ! 3940: -*/ ! 3941: - ! 3942: -senddiagnostic1d(dsp, data, datalen, self, dofl, uofl, vu) ! 3943: - struct dsreq *dsp; ! 3944: - caddr_t data; ! 3945: - long datalen; ! 3946: - char self, dofl, uofl, vu; ! 3947: -{ ! 3948: - fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN, ! 3949: - (self&1)<<2 | (dofl&1)<<1 | (uofl&1), ! 3950: - 0, B2(datalen), B1(vu<<6)); ! 3951: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE); ! 3952: - return(doscsireq(getfd(dsp), dsp)); ! 3953: -} ! 3954: - ! 3955: - ! 3956: -/* ! 3957: -|| readcapacity25 - issue group 1 "Read Capacity" command (0x25) ! 3958: -|| ! 3959: -|| pmi 0 - return last logical block, entire unit ! 3960: -|| 1 - return last logical block, current track ! 3961: -*/ ! 3962: - ! 3963: -readcapacity25(dsp, data, datalen, lba, pmi, vu) ! 3964: - struct dsreq *dsp; ! 3965: - caddr_t data; ! 3966: - long datalen, lba; ! 3967: - char pmi, vu; ! 3968: -{ ! 3969: - fillg1cmd(dsp, CMDBUF(dsp), G1_RCAP, 0, B4(lba), 0, 0, pmi&1, B1(vu<<6)); ! 3970: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE ! 3971: - /* |DSRQ_CTRL2 */ ); ! 3972: - /* dsp->ds_time = 100; /* often takes a while */ ! 3973: - return(doscsireq(getfd(dsp), dsp)); ! 3974: -} ! 3975: - ! 3976: - ! 3977: -/* ! 3978: -|| readextended28 - issue group 1 "Read Extended" command (0x28) ! 3979: -*/ ! 3980: - ! 3981: -readextended28(dsp, data, datalen, lba, vu) ! 3982: - struct dsreq *dsp; ! 3983: - caddr_t data; ! 3984: - long datalen, lba; ! 3985: - char vu; ! 3986: -{ ! 3987: - fillg1cmd(dsp, CMDBUF(dsp), G1_READ, 0, B4(lba), 0, B2(datalen), B1(vu<<6)); ! 3988: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE ! 3989: - /* |DSRQ_CTRL2 */ ); ! 3990: - /* dsp->ds_time = 100; /* often takes a while */ ! 3991: - return(doscsireq(getfd(dsp), dsp)); ! 3992: -} ! 3993: - ! 3994: - ! 3995: -/* ! 3996: -|| writeextended2a - issue group 1 "Write Extended" command (0x2a) ! 3997: -*/ ! 3998: - ! 3999: -writeextended2a(dsp, data, datalen, lba, vu) ! 4000: - struct dsreq *dsp; ! 4001: - caddr_t data; ! 4002: - long datalen, lba; ! 4003: - char vu; ! 4004: -{ ! 4005: - fillg1cmd(dsp, CMDBUF(dsp), G1_WRIT, 0, B4(lba), 0, B2(datalen), B1(vu<<6)); ! 4006: - filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE ! 4007: - /* |DSRQ_CTRL2 */ ); ! 4008: - /* dsp->ds_time = 100; /* often takes a while */ ! 4009: - return(doscsireq(getfd(dsp), dsp)); ! 4010: -} ! 4011: - ! 4012: - ! 4013: -/* ! 4014: -|| Support functions ---------------------------------------------------- ! 4015: -*/ ! 4016: - ! 4017: -/* ! 4018: -|| fillg0cmd - Fill a Group 0 command buffer ! 4019: -*/ ! 4020: - ! 4021: -fillg0cmd(dsp, cmd, b0,b1,b2,b3,b4,b5) ! 4022: - struct dsreq *dsp; ! 4023: - uchar_t *cmd, b0,b1,b2,b3,b4,b5; ! 4024: -{ ! 4025: - uchar_t *c = cmd; ! 4026: - DSDBG(fprintf(stderr,"fillg0cmd(%x,%x, %02x %02x %02x %02x %02x %02x)\n", ! 4027: - dsp, cmd, b0,b1,b2,b3,b4,b5)); ! 4028: - *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5; ! 4029: - ! 4030: - CMDBUF(dsp) = (caddr_t) cmd; ! 4031: - CMDLEN(dsp) = 6; ! 4032: -} ! 4033: - ! 4034: - ! 4035: -/* ! 4036: -|| fillg1cmd - Fill a Group 1 command buffer ! 4037: -*/ ! 4038: - ! 4039: -fillg1cmd(dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9) ! 4040: - struct dsreq *dsp; ! 4041: - uchar_t *cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9; ! 4042: -{ ! 4043: - uchar_t *c = cmd; ! 4044: - DSDBG(fprintf(stderr, ! 4045: - "fillg1cmd(%x,%x, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)\n", ! 4046: - dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)); ! 4047: - ! 4048: - *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5; ! 4049: - *c++ = b6, *c++ = b7, *c++ = b8, *c++ = b9; ! 4050: - ! 4051: - CMDBUF(dsp) = (caddr_t) cmd; ! 4052: - CMDLEN(dsp) = 10; ! 4053: -} ! 4054: - ! 4055: - ! 4056: -/* ! 4057: -|| filldsreq - Fill a dsreq structure ! 4058: -*/ ! 4059: - ! 4060: -filldsreq(dsp,data,datalen,flags) ! 4061: - struct dsreq *dsp; ! 4062: - uchar_t *data; ! 4063: -{ ! 4064: - DSDBG(fprintf(stderr,"filldsreq(%x,%x,%d,%x) cmdlen %d\n", ! 4065: - dsp,data,datalen,flags,CMDLEN(dsp))); ! 4066: - dsp->ds_flags = flags | dsreqflags | ! 4067: - (((dsdebug&1) ? DSRQ_TRACE : 0) | ! 4068: - ((dsdebug&2) ? DSRQ_PRINT : 0)); ! 4069: - dsp->ds_time = 10 * 1000; /* default to 10 seconds */ ! 4070: - dsp->ds_link = 0; ! 4071: - dsp->ds_synch = 0; ! 4072: - dsp->ds_ret = 0; ! 4073: - ! 4074: - DATABUF(dsp) = (caddr_t) data; ! 4075: - DATALEN(dsp) = datalen; ! 4076: -} ! 4077: - ! 4078: - ! 4079: -/* ! 4080: -|| bprint - print array of bytes, in hex. ! 4081: -*/ ! 4082: - ! 4083: -#define hex(x) "0123456789ABCDEF" [ (x) & 0xF ] ! 4084: - ! 4085: -bprint(s,n,nperline,space) ! 4086: - char *s; ! 4087: -{ ! 4088: - int i, x; ! 4089: - char *sp = (space) ? " ": ""; ! 4090: - ! 4091: - for(i=0;i<n;i++) { ! 4092: - x = s[i]; ! 4093: - fprintf(stderr,((i%4==3)?"%c%c%s%s":"%c%c%s"), ! 4094: - hex(x>>4), hex(x), sp, sp); ! 4095: - if ( i%nperline == (nperline - 1) ) ! 4096: - fprintf(stderr,"\n"); ! 4097: - } ! 4098: - if ( space ) ! 4099: - fprintf(stderr,"\n"); ! 4100: -} ! 4101: - ! 4102: - ! 4103: -/* ! 4104: -|| doscsireq - issue scsi command, return status or -1 error. ! 4105: -*/ ! 4106: - ! 4107: -doscsireq( fd, dsp) ! 4108: - int fd; /* ioctl file descriptor */ ! 4109: - struct dsreq *dsp; /* devscsi request packet */ ! 4110: -{ ! 4111: - int cc; ! 4112: - int retries = 4; ! 4113: - uchar_t sbyte; ! 4114: - ! 4115: - DSDBG(fprintf(stderr,"doscsireq(%d,%x) %x ---- %s\n",fd,dsp, ! 4116: - (CMDBUF(dsp))[0], ! 4117: - ds_vtostr( (CMDBUF(dsp))[0], cmdnametab))); ! 4118: - ! 4119: - /* ! 4120: - * loop, issuing command ! 4121: - * until done, or further retry pointless ! 4122: - */ ! 4123: - ! 4124: - while ( --retries > 0 ) { ! 4125: - ! 4126: - caddr_t sp; ! 4127: - ! 4128: - sp = SENSEBUF(dsp); ! 4129: - DSDBG(fprintf(stderr,"cmdbuf = "); ! 4130: - bprint(CMDBUF(dsp),CMDLEN(dsp),16,1)); ! 4131: - if ( (dsp->ds_flags & DSRQ_WRITE) ) ! 4132: - DSDBG(bprint( DATABUF(dsp), min(50,DATALEN(dsp)),16,1 )); ! 4133: - ! 4134: -DSDBG(fprintf(stderr,"databuf datalen %x %d\n",DATABUF(dsp), DATALEN(dsp))); ! 4135: - cc = ioctl( fd, DS_ENTER, dsp); ! 4136: - if ( cc < 0) { ! 4137: - ds_panic(dsp, "cannot ioctl fd %d\n",fd); ! 4138: - } ! 4139: - ! 4140: - DSDBG(fprintf(stderr,"cmdlen after ioctl=%d\n",CMDLEN(dsp))); ! 4141: - DSDBG(fprintf(stderr,"ioctl=%d ret=%x %s", ! 4142: - cc, RET(dsp), ! 4143: - RET(dsp) ? ds_vtostr(RET(dsp),dsrtnametab) : "")); ! 4144: - DSDBG(if (SENSESENT(dsp)) fprintf(stderr," sensesent=%d", ! 4145: - SENSESENT(dsp))); ! 4146: - ! 4147: - DSDBG(fprintf(stderr, ! 4148: - " cmdsent=%d datasent=%d sbyte=%x %s\n", ! 4149: - CMDSENT(dsp), DATASENT(dsp), STATUS(dsp), ! 4150: - ds_vtostr(STATUS(dsp), cmdstatustab))); ! 4151: - DSDBG(if ( FLAGS(dsp) & DSRQ_READ ) ! 4152: - bprint( DATABUF(dsp), min(16*16,DATASENT(dsp)), 16,1)); ! 4153: - ! 4154: -#ifdef aux ! 4155: - /* ! 4156: - * check for AUX bus-error ! 4157: - * we retry with poll-dma ! 4158: - */ ! 4159: - if ( RET(dsp) == DSRT_AGAIN ) { ! 4160: - int n = SDC_RDPOLL|SDC_WRPOLL; ! 4161: - DSDBG(fprintf(stderr,"setting rd/wr-poll")); ! 4162: - cc = ioctl( fd, DS_SET, n); /* set bits */ ! 4163: - if ( cc != 0 ) ! 4164: - return -1; ! 4165: - } ! 4166: -#endif aux ! 4167: - ! 4168: - if ( RET(dsp) == DSRT_NOSEL ) ! 4169: - continue; /* retry noselect 3X */ ! 4170: - ! 4171: - /* decode sense data returned */ ! 4172: - if ( SENSESENT(dsp) ) { ! 4173: - DSDBG( ! 4174: - fprintf(stderr, "sense key %x - %s\n", ! 4175: - SENSEKEY(sp), ! 4176: - ds_vtostr( SENSEKEY(sp), sensekeytab)); ! 4177: - bprint( SENSEBUF(dsp), ! 4178: - min(100, SENSESENT(dsp)), ! 4179: - 16,1); ! 4180: - ); ! 4181: - } ! 4182: - DSDBG(fprintf(stderr, "sbyte %x\n", STATUS(dsp))); ! 4183: - ! 4184: - /* decode scsi command status byte */ ! 4185: - sbyte = STATUS(dsp); ! 4186: - switch (sbyte) { ! 4187: - case 0x08: /* BUSY */ ! 4188: - case 0x18: /* RESERV CONFLICT */ ! 4189: - sleep(2); ! 4190: - continue; ! 4191: - case 0x00: /* GOOD */ ! 4192: - case 0x02: /* CHECK CONDITION */ ! 4193: - case 0x10: /* INTERM/GOOD */ ! 4194: - default: ! 4195: - return sbyte; ! 4196: - } ! 4197: - } ! 4198: - return -1; /* fail retry limit */ ! 4199: -} ! 4200: - ! 4201: - ! 4202: -/* ! 4203: -|| opttovar - lookup option in table, return var addr (NULL if fail) ! 4204: -*/ ! 4205: - ! 4206: -int * ! 4207: -opttovar( ostr, table) ! 4208: - char *ostr; ! 4209: - struct opttab{ ! 4210: - char *opt; ! 4211: - int *var; ! 4212: - } *table; ! 4213: -{ ! 4214: - register struct opttab *tp; ! 4215: - ! 4216: - for (tp=table; (tp->var); tp++) ! 4217: - if ( strncmp( ostr, tp->opt, 3) == 0 ) ! 4218: - break; ! 4219: - ! 4220: - if ( !tp->var ) ! 4221: - fprintf(stderr,"unknown option %s", ostr); ! 4222: - ! 4223: - return (tp->var); ! 4224: -} ! 4225: - ! 4226: - ! 4227: -/* ! 4228: -|| ds_vtostr - lookup value in table to return string pointer ! 4229: -*/ ! 4230: - ! 4231: -char * ! 4232: -ds_vtostr( v, table) ! 4233: - long v; ! 4234: - struct vtab *table; ! 4235: -{ ! 4236: - register struct vtab *tp; ! 4237: - ! 4238: - for (tp=table; (tp->string); tp++) ! 4239: - if ( v == tp->val ) ! 4240: - break; ! 4241: - ! 4242: - return (tp->string) ? tp->string : ""; ! 4243: -} ! 4244: - ! 4245: - ! 4246: -/* ! 4247: -|| ds_panic - yelp, leave... ! 4248: -*/ ! 4249: - ! 4250: -ds_panic( fmt, v) ! 4251: - char *fmt; ! 4252: - int v; ! 4253: -{ ! 4254: - extern errno; ! 4255: - ! 4256: - fprintf(stderr,fmt,v); ! 4257: - fprintf(stderr,"\nerrno = %d\n",errno); ! 4258: - exit(1); ! 4259: -} ! 4260: - ! 4261: - ! 4262: -/* ! 4263: -|| ds_zot - go away, with a message. ! 4264: -*/ ! 4265: - ! 4266: -ds_zot(message) ! 4267: - char *message; ! 4268: -{ ! 4269: - fprintf(stderr, "%s\n", message); ! 4270: - exit(1); ! 4271: -} ! 4272: //GO.SYSIN DD scsi/dslib.c ! 4273: echo scsi/load.c 1>&2 ! 4274: sed 's/.//' >scsi/load.c <<'//GO.SYSIN DD scsi/load.c' ! 4275: -#include <stdio.h> ! 4276: -#include <stddef.h> ! 4277: -#include <string.h> ! 4278: -#include "scsi.h" ! 4279: -#include "juke.h" ! 4280: - ! 4281: -j_load(char *vol_id, char *buf, long tlimit) ! 4282: -{ ! 4283: - Side side; ! 4284: - int n, sh, dr; ! 4285: - char disk_to_load[256]; ! 4286: - struct Lunstatus *l; ! 4287: - ! 4288: - if(j_rdshelves(buf)) /* read in shelf names */ ! 4289: - return(-1); ! 4290: - if(j_getstatus(buf)) /* get the jukebox status */ ! 4291: - return(-1); ! 4292: - /* now check which side we want */ ! 4293: - n = strlen(vol_id); ! 4294: - strcpy(disk_to_load, vol_id); ! 4295: - if(disk_to_load[n-1] == 'a') ! 4296: - side = SIDEA; ! 4297: - else if(disk_to_load[n-1] == 'b') ! 4298: - side = SIDEB; ! 4299: - else { ! 4300: - sprintf(buf, "vol_id '%s' must end in a or b", vol_id); ! 4301: - return(-1); ! 4302: - } ! 4303: - disk_to_load[n-1] = 0; ! 4304: - /* which shelf is that? */ ! 4305: - sh = j_shelfof(disk_to_load); ! 4306: - if(sh < 0){ ! 4307: - sprintf(buf, "can't find vol_id %s", disk_to_load); ! 4308: - return(-1); ! 4309: - } ! 4310: - while(tlimit >= 0){ ! 4311: - for(n = 0; n < NLUN; n++){ ! 4312: - l = &j_status.lun[n]; ! 4313: - if(l->diskin && l->shelfvalid && (sh == (l->retshelf>>1))){ ! 4314: - if(((l->retshelf&1) == side) && (n < nlun)) ! 4315: - return(n); ! 4316: - if(l->ready) ! 4317: - goto await; ! 4318: - if(j_drive_to_shelf(n, -1, 0, buf)) ! 4319: - return(-1); ! 4320: - if(j_getstatus(buf)) /* get the jukebox status */ ! 4321: - return(-1); ! 4322: - break; ! 4323: - } ! 4324: - } ! 4325: - /* disk is available */ ! 4326: - dr = j_empty_drive(tlimit, buf); ! 4327: - if(dr < 0){ ! 4328: - sprintf(buf, "can't find a free drive"); ! 4329: - return(-1); ! 4330: - } ! 4331: - if(j_shelf_to_drive(sh, side, dr, buf) < 0) ! 4332: - return(-1); ! 4333: - return(dr); ! 4334: -await: ! 4335: - sleep(10); ! 4336: - tlimit -= 10; ! 4337: - if(j_getstatus(buf)) /* get the jukebox status */ ! 4338: - return(-1); ! 4339: - } ! 4340: - sprintf(buf, "disk '%s' busy", disk_to_load); ! 4341: - return(-1); ! 4342: -} ! 4343: //GO.SYSIN DD scsi/load.c ! 4344: echo scsi/main.c 1>&2 ! 4345: sed 's/.//' >scsi/main.c <<'//GO.SYSIN DD scsi/main.c' ! 4346: -#include <stdio.h> ! 4347: -#include "jukebox.h" ! 4348: -#include "hdr.h" ! 4349: - ! 4350: -main(int argc, char *argv[]) ! 4351: -{ ! 4352: - int c; ! 4353: - int err = 0, cold = 0, warm = 0; ! 4354: - char *toload = 0, *uload = 0; ! 4355: - char *drive = 0; ! 4356: - char buf[256]; ! 4357: - extern int optind; ! 4358: - extern char *optarg; ! 4359: - ! 4360: - setbuf(stdout, (char *)0); /* turn off buffering */ ! 4361: - /* gather options */ ! 4362: - while ((c = getopt(argc,argv,"cn:l:wu:")) != -1) ! 4363: - switch (c) ! 4364: - { ! 4365: - case 'l': toload = optarg; break; ! 4366: - case 'c': cold = 1; break; ! 4367: - case 'w': warm = 1; break; ! 4368: - case 'u': uload = optarg ; break; ! 4369: - case 'n': drive = optarg ; break; ! 4370: - default: err = 1; break; ! 4371: - } ! 4372: - if(err) ! 4373: - exit(1); ! 4374: - /* now actually do some work */ ! 4375: - if (toload){ ! 4376: - if (j_load(toload, buf, 30)) ! 4377: - printf("load %s failed: %s\n", toload, buf); ! 4378: - else ! 4379: - printf("loaded %s on %s\n", toload, buf); ! 4380: - } ! 4381: - if(drive){ ! 4382: - if(j_volid(atoi(drive), buf)) ! 4383: - printf("j_volid(%s) failed: %s\n", drive, buf); ! 4384: - else ! 4385: - printf("%s is mounted on drive %d\n", buf, atoi(drive)); ! 4386: - } ! 4387: - if(cold){ ! 4388: - printf("invent cold: %d\n", cold); ! 4389: - cold_inventory(30, buf); ! 4390: - ! 4391: - } ! 4392: - if (warm) { ! 4393: - printf("invent warm: %d\n", warm); ! 4394: - warm_inventory(buf); ! 4395: - ! 4396: - } ! 4397: - ! 4398: - ! 4399: - if (uload){ ! 4400: - if (j_unload(uload, buf)) ! 4401: - printf("unload %s failed: %s\n", uload, buf); ! 4402: - else ! 4403: - printf("unloaded %s from %s\n", uload, buf); ! 4404: - ! 4405: - ! 4406: - } ! 4407: - exit(0); ! 4408: -} ! 4409: //GO.SYSIN DD scsi/main.c ! 4410: echo scsi/inc/scsi.h 1>&2 ! 4411: sed 's/.//' >scsi/inc/scsi.h <<'//GO.SYSIN DD scsi/inc/scsi.h' ! 4412: -#define SCSI_WR 0x80 ! 4413: -#define SCSI_RD 0x40 ! 4414: -#define SCSI_BRESET 0x20 ! 4415: -#define SCSI_RESET 0x10 ! 4416: -#define SCSI_SENSE 0x08 ! 4417: -#define SCSI_LTMOUT 0x04 ! 4418: - ! 4419: - ! 4420: -#define SCSI_CERR 0x01 ! 4421: //GO.SYSIN DD scsi/inc/scsi.h ! 4422: echo scsi/research.mk 1>&2 ! 4423: sed 's/.//' >scsi/research.mk <<'//GO.SYSIN DD scsi/research.mk' ! 4424: -# config stuff: research unix ! 4425: -CC=lcc ! 4426: -CFLAGS=-g ! 4427: -RANLIB=ranlib ! 4428: -LDFLAGS= ! 4429: -IO=h_io ! 4430: -NPROC=2 ! 4431: //GO.SYSIN DD scsi/research.mk ! 4432: echo scsi/sgi.mk 1>&2 ! 4433: sed 's/.//' >scsi/sgi.mk <<'//GO.SYSIN DD scsi/sgi.mk' ! 4434: -# config stuff: sgi; system v with moran/droneck /dev/scsi ! 4435: -CC=pcc # must be ansi ! 4436: -RANLIB=: ! 4437: -LDFLAGS= -lds ! 4438: -IO=md_io ! 4439: -CFLAGS=-g -I../inc ! 4440: -NPROC=4 ! 4441: //GO.SYSIN DD scsi/sgi.mk ! 4442: echo scsi/unload.c 1>&2 ! 4443: sed 's/.//' >scsi/unload.c <<'//GO.SYSIN DD scsi/unload.c' ! 4444: -#include <stdio.h> ! 4445: -#include <stddef.h> ! 4446: -#include <string.h> ! 4447: -#include "scsi.h" ! 4448: -#include "juke.h" ! 4449: - ! 4450: -j_unload(char *vol_id, char *buf) ! 4451: -{ ! 4452: - Side side; ! 4453: - int i, sh, dr; ! 4454: - char disk_to_unload[256]; ! 4455: - ! 4456: - if(j_rdshelves(buf)) /* read in shelf names */ ! 4457: - return(-1); ! 4458: - if(j_getstatus(buf)) /* get the jukebox status */ ! 4459: - return(-1); ! 4460: - /* now check which side we want */ ! 4461: - ! 4462: - strcpy(disk_to_unload, vol_id); ! 4463: - side = SIDEA; ! 4464: - sh = j_shelfof(disk_to_unload); ! 4465: - if(sh < 0){ ! 4466: - sprintf(buf, "can not find vol_id %s", disk_to_unload); ! 4467: - return(-1); ! 4468: - } ! 4469: - dr = -1; ! 4470: - for(i = 0; i < NLUN; i++){ ! 4471: - printf("dr:.. %d ", i); ! 4472: - printf(" rtsh: %d\n", j_status.lun[i].retshelf); ! 4473: - ! 4474: - /* is sh = retshelf? */ ! 4475: - ! 4476: - if( (j_status.lun[i].retshelf>>1 == sh) || ! 4477: - (j_status.lun[i].retshelf == sh*2+1) ){ dr = i; ! 4478: - break; ! 4479: - } } ! 4480: - printf("dr: %d, sh: %d, side: %d, i: %d\n", dr, sh, side, i); ! 4481: - if (dr == -1){ ! 4482: - sprintf(buf, "no drive has vol_id %s", disk_to_unload); ! 4483: - return(-1); ! 4484: - } ! 4485: - /* put vol_id in it's shelf*/ ! 4486: - if (j_drive_to_shelf(dr, sh, side, buf) >= 0){ ! 4487: - sprintf(buf,"/dev/worm%d\n", dr); ! 4488: - return(0); ! 4489: - } ! 4490: - return(-1); ! 4491: -} ! 4492: //GO.SYSIN DD scsi/unload.c ! 4493: echo scsi/README 1>&2 ! 4494: sed 's/.//' >scsi/README <<'//GO.SYSIN DD scsi/README' ! 4495: - This is a simple extensible shell (scsish) for poking at scsi ! 4496: -devices, particularly the simpler kinds commonly called toasters. ! 4497: -it is supposed to be self-documenting in use; try the help command. ! 4498: -my use of the moran-dronek /dev/scsi library is still imperfect; ! 4499: -there is still some some debugging showing. ! 4500: - ! 4501: - To compile, you first need mk. you then have to pick a system type ! 4502: -to set some flags; currently we support research and sgi. ! 4503: -yours may differ, particularly as no one else has our ansi C compiler for the sgi. ! 4504: -the only problem i would expect is the normal header file crap you get ! 4505: -mixing ansi and non-ansi files. i recommend setting NPROC=1 while debugging hdr files. ! 4506: -if you change (header) files, try putting them in the directory inc ! 4507: -(then others may benefit). To support a new system (say sgi-gcc), just create ! 4508: -a new file sgi-gcc.mk and so on. you may be missing some devices in ! 4509: -your /dev/scsi; the script scsi/gendev may help (but check the major/minor ! 4510: -numbers and permissions). ! 4511: - ! 4512: - As for modifying/extending scsish, it has been designed to be not too hard. ! 4513: -Adding a new device means adding a new set of rules (like the other rules) ! 4514: -to mkfile and creating a new directory (say exabyte) and at least two files in it ! 4515: -(dev.c and fns.h). The wren directory is a small example you can clone. ! 4516: -Adding new functions to any device means updating a file list in mkfile, ! 4517: -updating dev.c and fns.h in the device directory. The argument syntax ! 4518: -scheme is arguably pokey, but liveable. at some future point we should probably ! 4519: -switch over to osterhout's tcl. ! 4520: - ! 4521: - as always, i invite you send extensions/fixes etc back to ! 4522: [email protected] ! 4523: //GO.SYSIN DD scsi/README ! 4524: echo scsi/TODO 1>&2 ! 4525: sed 's/.//' >scsi/TODO <<'//GO.SYSIN DD scsi/TODO' ! 4526: - | COPY drive NUMBER NUMBER drive NUMBER {/*:COPY sdrive sstart nblocks ddrive dstart:: */ ! 4527: - s_copy($2, $3, $4, $5, $6); ! 4528: - } ! 4529: - | READ drive NUMBER { ! 4530: - struct scsi_ret output; ! 4531: - s_read($2, $3, 1, &output); ! 4532: - scsiodump(output.data, 1024); ! 4533: - } ! 4534: - | WRITE drive NUMBER { s_write($2, $3, 1); } ! 4535: - | WRITE drive NUMBER NUMBER { s_write($2, $3, $4); } /*:WRITE drive start n:: */ ! 4536: //GO.SYSIN DD scsi/TODO ! 4537: echo scsi/scsish.h 1>&2 ! 4538: sed 's/.//' >scsi/scsish.h <<'//GO.SYSIN DD scsi/scsish.h' ! 4539: -typedef int (*Functionfn)(int, int *, int, char **, char *); ! 4540: - ! 4541: -typedef struct ! 4542: -{ ! 4543: - char *name; ! 4544: - char *help; ! 4545: - char *param; ! 4546: - Functionfn fn; ! 4547: -} Function; ! 4548: - ! 4549: -typedef struct ! 4550: -{ ! 4551: - char *name; ! 4552: - char *verbose; ! 4553: - void (*extsense)(uchar *, char *, int); ! 4554: - Function *fns; ! 4555: -} Device; ! 4556: -extern void setdevice(Device *); ! 4557: - ! 4558: -extern void scsi_target(int); ! 4559: -extern void fixedstr(uchar *src, int len, char *dest); ! 4560: -extern void gen_extsense(uchar *, char *, int); ! 4561: -extern int shelfside(char *arg, char *err); ! 4562: -extern void xd(uchar *base, int, FILE *fp); ! 4563: //GO.SYSIN DD scsi/scsish.h ! 4564: echo scsi/generic/dev.c 1>&2 ! 4565: sed 's/.//' >scsi/generic/dev.c <<'//GO.SYSIN DD scsi/generic/dev.c' ! 4566: -#include <stdio.h> ! 4567: -#include "../scsi.h" ! 4568: -#include "../scsish.h" ! 4569: -#include "fns.h" ! 4570: - ! 4571: -static int gen_id(int, int *, int, char **, char *); ! 4572: - ! 4573: -static Function fns[] = { ! 4574: - { "capacity", "capacity [lun=0]", "L?", gen_capacity }, ! 4575: - { "copy", "copy srclun start n destlun dest", "LIILII?", gen_copy }, ! 4576: - { "display", "display", "", gen_display }, ! 4577: - { "dev", "dev [type] # dev ? for list", "S?", gen_dev }, ! 4578: - { "help", "help [cmd]", "S?", gen_help }, ! 4579: - { "id", "id [target=0]", "L?", gen_id }, ! 4580: - { "inq", "inq [lun=0]", "L?", gen_inq }, ! 4581: - { "readt", "readt count [lun=0]", "IL?", gen_readt }, ! 4582: - { "reset", "reset", "", gen_reset }, ! 4583: - { "scsi", "scsi bytes... # 6 or 10", "I?I?I?I?I?I?I?I?I?I?", gen_scsi }, ! 4584: - { "sense", "sense [lun=0]", "L?", gen_sense }, ! 4585: - { "start", "start [lun=0]", "L?", gen_start }, ! 4586: - { "stop", "stop [lun=0]", "L?", gen_stop }, ! 4587: - { "testunit", "testunit [lun=0", "L?", gen_tur }, ! 4588: - { 0 } ! 4589: -}; ! 4590: - ! 4591: -Device genericdev = { ! 4592: - "scsi", "generic scsi", ! 4593: - gen_extsense, ! 4594: - fns ! 4595: -}; ! 4596: - ! 4597: -static int ! 4598: -gen_id(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4599: -{ ! 4600: -#pragma ref ncargs ! 4601: -#pragma ref cargs ! 4602: -#pragma ref err ! 4603: - ! 4604: - if(niargs == 0) ! 4605: - printf("current SCSI id = %d\n", s_id); ! 4606: - else ! 4607: - scsi_target(iargs[0]); ! 4608: - return(0); ! 4609: -} ! 4610: //GO.SYSIN DD scsi/generic/dev.c ! 4611: echo scsi/generic/inq.c 1>&2 ! 4612: sed 's/.//' >scsi/generic/inq.c <<'//GO.SYSIN DD scsi/generic/inq.c' ! 4613: -#include <stdio.h> ! 4614: -#include "../scsi.h" ! 4615: -#include "../scsish.h" ! 4616: -#include "fns.h" ! 4617: - ! 4618: -char *gen_rmb[2] = { "nonremovable", "removable" }; ! 4619: -char *gen_devtype[256] = { ! 4620: - "direct access", ! 4621: - "sequential access", ! 4622: - "printer", ! 4623: - "processor", ! 4624: - "worm", ! 4625: - "cd-rom" ! 4626: -}; ! 4627: - ! 4628: -int ! 4629: -gen_inq(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4630: -{ ! 4631: - struct scsi_cmd cmd; ! 4632: - struct scsi_return ret; ! 4633: - int n, i; ! 4634: - ! 4635: -#pragma ref ncargs ! 4636: -#pragma ref cargs ! 4637: - ! 4638: - if(niargs == 0) ! 4639: - for(niargs = 0; niargs < 8; niargs++) ! 4640: - iargs[niargs] = niargs; ! 4641: - for(i = 0; i < niargs; i++){ ! 4642: - set6(cmd, 0x12, iargs[i]<<5, 0, 0, 36, 0); ! 4643: - if(n = s_io(0, &cmd, 0, &ret, -36, err)) ! 4644: - return(n); ! 4645: - printf("inq(%d,%d): %s %s;", s_id, iargs[i], ! 4646: - gen_rmb[ret.data[1]>>7], gen_devtype[ret.data[0]]); ! 4647: - if(ret.data[4] >= 16){ ! 4648: - char buf[256]; ! 4649: - ! 4650: - fixedstr(&ret.data[8], 8, buf); ! 4651: - printf(" %s", buf); ! 4652: - if(ret.data[4] >= 32){ ! 4653: - fixedstr(&ret.data[16], 16, buf); ! 4654: - printf("/%s", buf); ! 4655: - if(ret.data[4] >= 36){ ! 4656: - fixedstr(&ret.data[32], 4, buf); ! 4657: - printf(" rev=%s", buf); ! 4658: - } ! 4659: - } ! 4660: - } ! 4661: - printf(" [%d bytes]\n", ret.data[4]); ! 4662: - } ! 4663: - return(0); ! 4664: -} ! 4665: //GO.SYSIN DD scsi/generic/inq.c ! 4666: echo scsi/generic/sense.c 1>&2 ! 4667: sed 's/.//' >scsi/generic/sense.c <<'//GO.SYSIN DD scsi/generic/sense.c' ! 4668: -#include <stdio.h> ! 4669: -#include "../scsi.h" ! 4670: -#include "../scsish.h" ! 4671: -#include "fns.h" ! 4672: - ! 4673: -int ! 4674: -gen_sense(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4675: -{ ! 4676: - struct scsi_cmd cmd; ! 4677: - struct scsi_return ret; ! 4678: - int n; ! 4679: - ! 4680: -#pragma ref ncargs ! 4681: -#pragma ref cargs ! 4682: - ! 4683: - if(niargs == 0) ! 4684: - iargs[0] = 0; ! 4685: - set6(cmd, 0x03, iargs[0]<<5, 0, 0, 4, 0); ! 4686: - if(n = s_io(0, &cmd, 0, &ret, 4, err)) ! 4687: - return(n); ! 4688: - printf("sense(%d,%d): ", s_id, iargs[0]); ! 4689: - if((ret.data[0]&0x7F) == 0) ! 4690: - printf("no error\n"); ! 4691: - else { ! 4692: - printf("error class=0x%x, code=0x%x, sense=0x%x", ! 4693: - (ret.data[0]>>4)&7, ret.data[0]&0xF, ret.data[2]&0xF); ! 4694: - if(ret.data[0]&0x80) ! 4695: - printf(", addr=0x%x", ret.data[3]+256L*ret.data[2]+256L*256*ret.data[1]); ! 4696: - printf("\n"); ! 4697: - } ! 4698: - return(0); ! 4699: -} ! 4700: - ! 4701: -static char *exstab[16] = ! 4702: -{ ! 4703: - "no sense", ! 4704: - "recovered error", ! 4705: - "not ready", ! 4706: - "medium error", ! 4707: - "hardware error", ! 4708: - "illegal request", ! 4709: - "unit attention", ! 4710: - "data protect", ! 4711: - "blank check", ! 4712: - "vendor specific (#9)", ! 4713: - "copy aborted", ! 4714: - "aborted command", ! 4715: - "equal", ! 4716: - "volume overflow", ! 4717: - "miscompare", ! 4718: - "reserved (#f)", ! 4719: -}; ! 4720: - ! 4721: -void ! 4722: -gen_extsense(uchar *data, char *dest, int ndata) ! 4723: -{ ! 4724: - int class; ! 4725: - ! 4726: - class = (data[0]>>4)&7; ! 4727: - if(class == 7){ ! 4728: - if(data[0]&0x80) ! 4729: - sprintf(dest, "extended sense: %s info=#%2.2x#%2.2x#%2.2x#%2.2x", exstab[data[2]&0xF], data[3], data[4], data[5], data[6]); ! 4730: - else ! 4731: - sprintf(dest, "extended sense: %s", exstab[data[2]&0xF]); ! 4732: - } else { ! 4733: - sprintf(dest, "sense: class=#%x, code=#%x", class, data[0]&0xF); ! 4734: - } ! 4735: -} ! 4736: //GO.SYSIN DD scsi/generic/sense.c ! 4737: echo scsi/generic/start.c 1>&2 ! 4738: sed 's/.//' >scsi/generic/start.c <<'//GO.SYSIN DD scsi/generic/start.c' ! 4739: -#include <stdio.h> ! 4740: -#include "../scsi.h" ! 4741: -#include "../scsish.h" ! 4742: -#include "fns.h" ! 4743: - ! 4744: -int ! 4745: -gen_start(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4746: -{ ! 4747: - struct scsi_cmd cmd; ! 4748: - struct scsi_return ret; ! 4749: - int n; ! 4750: - ! 4751: -#pragma ref ncargs ! 4752: -#pragma ref cargs ! 4753: - ! 4754: - if(niargs == 0) ! 4755: - iargs[0] = 0; ! 4756: - set6(cmd, 0x1B, iargs[0]<<5, 0, 0, 1, 0); ! 4757: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 4758: - return(n); ! 4759: - return(0); ! 4760: -} ! 4761: //GO.SYSIN DD scsi/generic/start.c ! 4762: echo scsi/generic/stop.c 1>&2 ! 4763: sed 's/.//' >scsi/generic/stop.c <<'//GO.SYSIN DD scsi/generic/stop.c' ! 4764: -#include <stdio.h> ! 4765: -#include "../scsi.h" ! 4766: -#include "../scsish.h" ! 4767: -#include "fns.h" ! 4768: - ! 4769: -int ! 4770: -gen_stop(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4771: -{ ! 4772: - struct scsi_cmd cmd; ! 4773: - struct scsi_return ret; ! 4774: - int n; ! 4775: - ! 4776: -#pragma ref ncargs ! 4777: -#pragma ref cargs ! 4778: - ! 4779: - if(niargs == 0) ! 4780: - iargs[0] = 0; ! 4781: - set6(cmd, 0x1B, iargs[0]<<5, 0, 0, 0, 0); ! 4782: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 4783: - return(n); ! 4784: - return(0); ! 4785: -} ! 4786: //GO.SYSIN DD scsi/generic/stop.c ! 4787: echo scsi/generic/capacity.c 1>&2 ! 4788: sed 's/.//' >scsi/generic/capacity.c <<'//GO.SYSIN DD scsi/generic/capacity.c' ! 4789: -#include <stdio.h> ! 4790: -#include "../scsi.h" ! 4791: -#include "../scsish.h" ! 4792: -#include "fns.h" ! 4793: - ! 4794: -int ! 4795: -gen_capacity(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4796: -{ ! 4797: - struct scsi_cmd cmd; ! 4798: - struct scsi_return ret; ! 4799: - int n; ! 4800: - unsigned long ns, ss; ! 4801: - ! 4802: -#pragma ref ncargs ! 4803: -#pragma ref cargs ! 4804: - ! 4805: - if(niargs == 0) ! 4806: - iargs[0] = 0; ! 4807: - set10(cmd, 0x25, iargs[0]<<5, 0, 0, 0, 0, 0, 0, 0, 0); ! 4808: - if(n = s_io(0, &cmd, 0, &ret, 8, err)) ! 4809: - return(n); ! 4810: - ns = longat(&ret.data[0]); ! 4811: - ss = longat(&ret.data[4]); ! 4812: - printf("capacity(%d,%d): %ld blocks of %ld bytes (#%xx#%x)\n", s_id, iargs[0], ! 4813: - ns, ss, ns, ss); ! 4814: - return(0); ! 4815: -} ! 4816: //GO.SYSIN DD scsi/generic/capacity.c ! 4817: echo scsi/generic/display.c 1>&2 ! 4818: sed 's/.//' >scsi/generic/display.c <<'//GO.SYSIN DD scsi/generic/display.c' ! 4819: -#include <stdio.h> ! 4820: -#include "../scsi.h" ! 4821: -#include "../scsish.h" ! 4822: -#include "fns.h" ! 4823: - ! 4824: -extern char *gen_rmb[2]; ! 4825: -extern char *gen_devtype[256]; ! 4826: - ! 4827: -int ! 4828: -gen_display(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4829: -{ ! 4830: - struct scsi_cmd cmd; ! 4831: - struct scsi_return ret; ! 4832: - int n, i, old_id; ! 4833: - int retv = 0; ! 4834: - char rev[100], vendor[100], product[100]; ! 4835: - ! 4836: -#pragma ref niargs ! 4837: -#pragma ref iargs ! 4838: -#pragma ref ncargs ! 4839: -#pragma ref cargs ! 4840: - ! 4841: - old_id = s_id; ! 4842: - for(s_id = 0; s_id < 8; s_id++){ ! 4843: - printf("target %d:\n"); ! 4844: - set6(cmd, 0x00, 0, 0, 0, 0, 0); ! 4845: - if(s_io(0, &cmd, 0, &ret, 0, err)) ! 4846: - continue; ! 4847: - printf("responded to test unit ready\n"); ! 4848: - continue; ! 4849: - for(i = 0; i < 8; i++){ ! 4850: - set6(cmd, 0x12, i<<5, 0, 0, 36, 0); ! 4851: - if(n = s_io(0, &cmd, 0, &ret, -36, err)){ ! 4852: - retv = n; ! 4853: - break; ! 4854: - } ! 4855: - if(ret.nread >= 16) ! 4856: - fixedstr(&ret.data[8], 8, vendor); ! 4857: - else ! 4858: - sprintf(vendor, "??"); ! 4859: - if(ret.nread >= 32) ! 4860: - fixedstr(&ret.data[16], 16, product); ! 4861: - else ! 4862: - sprintf(product, "??"); ! 4863: - if(ret.nread >= 16) ! 4864: - fixedstr(&ret.data[32], 4, rev); ! 4865: - else ! 4866: - sprintf(vendor, "??"); ! 4867: - printf("\tlun(%d): %s %s, %s/%s rev=%s\n", i, ! 4868: - gen_rmb[ret.data[1]>>7], gen_devtype[ret.data[0]], ! 4869: - vendor, product, rev); ! 4870: - } ! 4871: - } ! 4872: - s_id = old_id; ! 4873: - return(retv); ! 4874: -} ! 4875: //GO.SYSIN DD scsi/generic/display.c ! 4876: echo scsi/generic/reset.c 1>&2 ! 4877: sed 's/.//' >scsi/generic/reset.c <<'//GO.SYSIN DD scsi/generic/reset.c' ! 4878: -#include <stdio.h> ! 4879: -#include "../scsi.h" ! 4880: -#include "../scsish.h" ! 4881: -#include "fns.h" ! 4882: -#include <scsi.h> ! 4883: - ! 4884: -int ! 4885: -gen_reset(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4886: -{ ! 4887: - struct scsi_cmd cmd; ! 4888: - struct scsi_return ret; ! 4889: - ! 4890: -#pragma ref niargs ! 4891: -#pragma ref iargs ! 4892: -#pragma ref ncargs ! 4893: -#pragma ref cargs ! 4894: - ! 4895: - set6(cmd, 0, 0, 0, 0, 0, 0); ! 4896: - cmd.bus_id = s_id; ! 4897: - cmd.flags |= SCSI_RESET | SCSI_BRESET; ! 4898: - /* should probably test for some kind of error... */ ! 4899: - ss_io(0, &cmd, 0, &ret, 0, err); ! 4900: - return(0); ! 4901: -} ! 4902: //GO.SYSIN DD scsi/generic/reset.c ! 4903: echo scsi/generic/tur.c 1>&2 ! 4904: sed 's/.//' >scsi/generic/tur.c <<'//GO.SYSIN DD scsi/generic/tur.c' ! 4905: -#include <stdio.h> ! 4906: -#include "../scsi.h" ! 4907: -#include "../scsish.h" ! 4908: -#include "fns.h" ! 4909: - ! 4910: -int ! 4911: -gen_tur(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4912: -{ ! 4913: - struct scsi_cmd cmd; ! 4914: - struct scsi_return ret; ! 4915: - int n; ! 4916: - ! 4917: -#pragma ref ncargs ! 4918: -#pragma ref cargs ! 4919: - ! 4920: - if(niargs == 0) ! 4921: - iargs[0] = 0; ! 4922: - set6(cmd, 0x00, iargs[0]<<5, 0, 0, 0, 0); ! 4923: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 4924: - return(n); ! 4925: - printf("(%d,%d): good status\n", s_id, iargs[0]); ! 4926: - return(0); ! 4927: -} ! 4928: //GO.SYSIN DD scsi/generic/tur.c ! 4929: echo scsi/generic/scsi.c 1>&2 ! 4930: sed 's/.//' >scsi/generic/scsi.c <<'//GO.SYSIN DD scsi/generic/scsi.c' ! 4931: -#include <stdio.h> ! 4932: -#include "../scsi.h" ! 4933: -#include "../scsish.h" ! 4934: -#include "fns.h" ! 4935: - ! 4936: -int ! 4937: -gen_scsi(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4938: -{ ! 4939: - struct scsi_cmd cmd; ! 4940: - struct scsi_return ret; ! 4941: - int n; ! 4942: - ! 4943: -#pragma ref ncargs ! 4944: -#pragma ref cargs ! 4945: - ! 4946: - switch(niargs) ! 4947: - { ! 4948: - case 6: ! 4949: - set6(cmd, iargs[0], iargs[1], iargs[2], iargs[3], iargs[4], iargs[5]); ! 4950: - break; ! 4951: - case 10: ! 4952: - set10(cmd, iargs[0], iargs[1], iargs[2], iargs[3], iargs[4], iargs[5], iargs[6], iargs[7], iargs[8], iargs[9]); ! 4953: - break; ! 4954: - default: ! 4955: - sprintf(err, "number of bytes (%d) must be 6 or 10\n", niargs); ! 4956: - return(1); ! 4957: - } ! 4958: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 4959: - return(n); ! 4960: - return(0); ! 4961: -} ! 4962: //GO.SYSIN DD scsi/generic/scsi.c ! 4963: echo scsi/generic/fns.h 1>&2 ! 4964: sed 's/.//' >scsi/generic/fns.h <<'//GO.SYSIN DD scsi/generic/fns.h' ! 4965: -extern int gen_inq(int, int *, int, char **, char *); ! 4966: -extern int gen_dev(int, int *, int, char **, char *); ! 4967: -extern int gen_help(int, int *, int, char **, char *); ! 4968: -extern int gen_sense(int, int *, int, char **, char *); ! 4969: -extern int gen_start(int, int *, int, char **, char *); ! 4970: -extern int gen_stop(int, int *, int, char **, char *); ! 4971: -extern int gen_capacity(int, int *, int, char **, char *); ! 4972: -extern int gen_display(int, int *, int, char **, char *); ! 4973: -extern int gen_reset(int, int *, int, char **, char *); ! 4974: -extern int gen_tur(int, int *, int, char **, char *); ! 4975: -extern int gen_scsi(int, int *, int, char **, char *); ! 4976: -extern int gen_readt(int, int *, int, char **, char *); ! 4977: -extern int gen_copy(int, int *, int, char **, char *); ! 4978: //GO.SYSIN DD scsi/generic/fns.h ! 4979: echo scsi/generic/readt.c 1>&2 ! 4980: sed 's/.//' >scsi/generic/readt.c <<'//GO.SYSIN DD scsi/generic/readt.c' ! 4981: -#include <stdio.h> ! 4982: -#include "../scsi.h" ! 4983: -#include "../scsish.h" ! 4984: -#include "fns.h" ! 4985: - ! 4986: -int ! 4987: -gen_readt(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 4988: -{ ! 4989: - struct scsi_cmd cmd; ! 4990: - struct scsi_return ret; ! 4991: - int n, i; ! 4992: - unsigned long ns, ss; ! 4993: - long bs, addr; ! 4994: - long t1, t2; ! 4995: - ! 4996: -#pragma ref ncargs ! 4997: -#pragma ref cargs ! 4998: - ! 4999: - if(niargs == 1) ! 5000: - iargs[1] = 0; ! 5001: - set10(cmd, 0x25, iargs[1]<<5, 0, 0, 0, 0, 0, 0, 0, 0); ! 5002: - if(n = s_io(0, &cmd, 0, &ret, 8, err)) ! 5003: - return(n); ! 5004: - ns = longat(&ret.data[0]); ! 5005: - ss = longat(&ret.data[4]); ! 5006: - bs = ss? sizeof(ret.data)/ss : 1; ! 5007: - time(&t1); ! 5008: - srand(t1); ! 5009: - addr = nrand(ns-iargs[0])-1; ! 5010: - printf("read(%d,%d): %d blocks @%d (chunk=%dx%d),", s_id, iargs[1], iargs[0], addr, bs, ss); ! 5011: - fflush(stdout); ! 5012: - time(&t1); ! 5013: - for(i = iargs[0]; i > 0; i -= bs){ ! 5014: - set10(cmd, 0x28, iargs[1]<<5, addr>>24, addr>>16, addr>>8, addr, ! 5015: - 0, 0, bs*0, 0); ! 5016: - if(n = s_io(0, &cmd, 0, &ret, bs*ss, err)) ! 5017: - return(n); ! 5018: - addr += bs; ! 5019: - } ! 5020: - time(&t2); ! 5021: - printf(" t=%ds (%.0fKB/s)\n", t2-t1, (iargs[0]*(float)ss/1024.)/((t1 == t2)? 1:t2-t1)); ! 5022: - return(0); ! 5023: -} ! 5024: //GO.SYSIN DD scsi/generic/readt.c ! 5025: echo scsi/generic/copy.c 1>&2 ! 5026: sed 's/.//' >scsi/generic/copy.c <<'//GO.SYSIN DD scsi/generic/copy.c' ! 5027: -#include <stdio.h> ! 5028: -#include "../scsi.h" ! 5029: -#include "../scsish.h" ! 5030: -#include "fns.h" ! 5031: - ! 5032: -#define PROGRESS \ ! 5033: - if(sbase/TALK != goo){\ ! 5034: - goo = sbase/TALK;\ ! 5035: - time(&t2);\ ! 5036: - printf("\tdoing block %ld at %s", goo*TALK, ctime(&t2));\ ! 5037: - } ! 5038: - ! 5039: -static int copy1(int, int, int, int, int, int, int, char *); ! 5040: - ! 5041: -int ! 5042: -gen_copy(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5043: -{ ! 5044: - int n; ! 5045: - int sdr = 0; ! 5046: - int sbase = iargs[1]; ! 5047: - int nblocks = iargs[2]; ! 5048: - int ddr = 0; ! 5049: - int dbase = iargs[4]; ! 5050: - int starget = iargs[0]; ! 5051: - int dtarget = iargs[3]; ! 5052: - int block = 256; ! 5053: - long nb = nblocks; ! 5054: - long t1, t2; ! 5055: - long goo; ! 5056: - ! 5057: -#define TALK 10000 ! 5058: - extern char *ctime(); ! 5059: - ! 5060: -#pragma ref ncargs ! 5061: -#pragma ref cargs ! 5062: - ! 5063: - if(niargs == 6) ! 5064: - block = iargs[5]; ! 5065: - printf("copying drive (%d,%d)[%d-%d] to drive (%d,%d)[%d-%d] blk=%dK\n", ! 5066: - starget, sdr, sbase, sbase+nblocks-1, ! 5067: - dtarget, ddr, dbase, dbase+nblocks-1, block); ! 5068: - time(&t1); ! 5069: - goo = -1; ! 5070: - while(nblocks > 0){ ! 5071: - n = min(block, nblocks); ! 5072: - printf("writing %d-%d\n", sbase, sbase+n-1);/**/ ! 5073: - if(copy1(starget, sdr, sbase, n, dtarget, ddr, dbase, err)) ! 5074: - break; ! 5075: - sbase += n; ! 5076: - dbase += n; ! 5077: - nblocks -= n; ! 5078: - PROGRESS ! 5079: - } ! 5080: - time(&t2); ! 5081: - t2 -= t1; ! 5082: - if(t2 == 0) t2 = 1; ! 5083: - printf("%ds: ", t2); ! 5084: - if(nblocks){ ! 5085: - printf("copy buggered up: sbase=%d nblks=%d dbase=%d\n", ! 5086: - sbase, nblocks, dbase); ! 5087: - return(1); ! 5088: - } ! 5089: - printf("%d blocks at %.1fKB/s\n", nb, nb/(float)t2); ! 5090: - return(0); ! 5091: -} ! 5092: - ! 5093: -static int ! 5094: -copy1(int st, int sd, int sb, int n, int dt, int dd, int db, char *err) ! 5095: -{ ! 5096: - struct scsi_cmd cmd; ! 5097: - struct scsi_return ret; ! 5098: - ! 5099: - set6(cmd, 0x18, sd<<5, 0, 0, 20, 0); ! 5100: - cmd.data[0] = 0x10; /* copy */ ! 5101: - cmd.data[1] = 0; ! 5102: - cmd.data[2] = 0; ! 5103: - cmd.data[3] = 0; ! 5104: - cmd.data[4] = (st<<5)|sd; ! 5105: - cmd.data[5] = (dt<<5)|dd; ! 5106: - cmd.data[6] = 0; ! 5107: - cmd.data[7] = 0; ! 5108: - cmd.data[8] = n>>24; ! 5109: - cmd.data[9] = n>>16; ! 5110: - cmd.data[10] = n>>8; ! 5111: - cmd.data[11] = n; ! 5112: - cmd.data[12] = sb>>24; ! 5113: - cmd.data[13] = sb>>16; ! 5114: - cmd.data[14] = sb>>8; ! 5115: - cmd.data[15] = sb; ! 5116: - cmd.data[16] = db>>24; ! 5117: - cmd.data[17] = db>>16; ! 5118: - cmd.data[18] = db>>8; ! 5119: - cmd.data[19] = db; ! 5120: - return(s_io(0, &cmd, 20, &ret, 0, err)); ! 5121: -} ! 5122: //GO.SYSIN DD scsi/generic/copy.c ! 5123: echo scsi/sony/dev.c 1>&2 ! 5124: sed 's/.//' >scsi/sony/dev.c <<'//GO.SYSIN DD scsi/sony/dev.c' ! 5125: -#include <stdio.h> ! 5126: -#include "../scsi.h" ! 5127: -#include "../scsish.h" ! 5128: -#include "fns.h" ! 5129: - ! 5130: -static Function fns[] = { ! 5131: - { "alternate", "alternate [lun]", "L?", sony_alt }, ! 5132: - { "config", "config", "", sony_conf }, ! 5133: - { "copy", "copy srclun start n destlun dest", "LIILI", sony_copy }, ! 5134: - { "diskid", "diskid [lun]", "L?", sony_diskid }, ! 5135: - { "eject", "eject lun", "L", sony_eject }, ! 5136: - { "inq", "inq [lun]", "L?", sony_inq }, ! 5137: - { "internal", "internal test [drive] # internal -1 for list", "II?", sony_internal }, ! 5138: - { "media", "media lun start count [file]", "LIIS?", sony_media }, ! 5139: - { "readid", "readid lun [start]", "LI?", sony_readid }, ! 5140: - { "rel", "rel lun [shelfside]", "LS?", sony_rel }, ! 5141: - { "sense", "sense [lun=0]", "L?", sony_sense }, ! 5142: - { "set", "set shelfside lun", "SL", sony_set }, ! 5143: - { "status", "status", "", sony_status }, ! 5144: - { 0 } ! 5145: -}; ! 5146: - ! 5147: -Device sonydev = { ! 5148: - "sony", "Sony WDA-3000", ! 5149: - sony_extsense, ! 5150: - fns ! 5151: -}; ! 5152: //GO.SYSIN DD scsi/sony/dev.c ! 5153: echo scsi/sony/inq.c 1>&2 ! 5154: sed 's/.//' >scsi/sony/inq.c <<'//GO.SYSIN DD scsi/sony/inq.c' ! 5155: -#include <stdio.h> ! 5156: -#include "../scsi.h" ! 5157: -#include "../scsish.h" ! 5158: -#include "fns.h" ! 5159: - ! 5160: -int ! 5161: -sony_inq(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5162: -{ ! 5163: - struct scsi_cmd cmd; ! 5164: - struct scsi_return ret; ! 5165: - int n, i; ! 5166: - ! 5167: -#pragma ref ncargs ! 5168: -#pragma ref cargs ! 5169: - ! 5170: - if(niargs == 0) ! 5171: - for(niargs = 0; niargs < 8; niargs++) ! 5172: - iargs[niargs] = niargs; ! 5173: - for(i = 0; i < niargs; i++){ ! 5174: - set6(cmd, 0x12, iargs[i]<<5, 0, 0, 6, 0); ! 5175: - if(n = s_io(0, &cmd, 0, &ret, 6, err)) ! 5176: - return(n); ! 5177: - printf("inq(%d,%d): ", s_id, iargs[i]); ! 5178: - if(ret.data[5]&0x80) ! 5179: - printf("power off (0x%x)\n", ret.data[5]&0xFF); ! 5180: - else if(ret.data[5]&0x40) ! 5181: - printf("empty (0x%x)\n", ret.data[5]&0xFF); ! 5182: - else ! 5183: - printf("%s,%s,%s,%s (0x%x)\n", ! 5184: - (ret.data[5]&0x08)?"write protect":"writable", ! 5185: - (ret.data[5]&0x04)?"no alternate":"", ! 5186: - (ret.data[5]&0x02)?"drive error":"", ! 5187: - (ret.data[5]&0x01)?"ready":"not ready", ! 5188: - ret.data[5]&0xFF); ! 5189: - } ! 5190: - return(0); ! 5191: -} ! 5192: //GO.SYSIN DD scsi/sony/inq.c ! 5193: echo scsi/sony/alt.c 1>&2 ! 5194: sed 's/.//' >scsi/sony/alt.c <<'//GO.SYSIN DD scsi/sony/alt.c' ! 5195: -#include <stdio.h> ! 5196: -#include "../scsi.h" ! 5197: -#include "../scsish.h" ! 5198: -#include "fns.h" ! 5199: - ! 5200: -static ! 5201: -table(int drive, int tab, uchar *data) ! 5202: -{ ! 5203: - int n, i; ! 5204: - ! 5205: - n = data[6]; ! 5206: - printf("(%d,%d): alternate table %d (%d entries)\n", s_id, drive, tab, n); ! 5207: - for(data += 0x18, i = 0; i < n; data += 4, i++) ! 5208: - printf("%ld%c", data[0]+256L*data[1]+256L*256*data[2], ! 5209: - (i%10 == 9)? '\n':' '); ! 5210: - if((i%10) && n) ! 5211: - putchar('\n'); ! 5212: -} ! 5213: - ! 5214: -int ! 5215: -sony_alt(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5216: -{ ! 5217: - struct scsi_cmd cmd; ! 5218: - struct scsi_return ret; ! 5219: - int n, i; ! 5220: - ! 5221: -#pragma ref ncargs ! 5222: -#pragma ref cargs ! 5223: - ! 5224: - if(niargs == 0) ! 5225: - iargs[0] = 0; ! 5226: - set6(cmd, 0xC3, iargs[0]<<5, 0, 0, 0, 0); ! 5227: - if(n = s_io(0, &cmd, 0, &ret, 4096, err)) ! 5228: - return(n); ! 5229: - for(i = 0; i < 4; i++) ! 5230: - table(iargs[0], i+1, &ret.data[1024*i]); ! 5231: - return(0); ! 5232: -} ! 5233: //GO.SYSIN DD scsi/sony/alt.c ! 5234: echo scsi/sony/config.c 1>&2 ! 5235: sed 's/.//' >scsi/sony/config.c <<'//GO.SYSIN DD scsi/sony/config.c' ! 5236: -#include <stdio.h> ! 5237: -#include "../scsi.h" ! 5238: -#include "../scsish.h" ! 5239: -#include "fns.h" ! 5240: - ! 5241: -static char mtab[5][2] = ! 5242: -{ ! 5243: - '0', '0', '1', '1', '1', '2', '2', '2', '?', '?' ! 5244: -}; ! 5245: -static char *brdname[] = { ! 5246: - "no doard", "T.D. Systems Viking", "U.S. Design 1158" ! 5247: -}; ! 5248: - ! 5249: -int ! 5250: -sony_conf(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5251: -{ ! 5252: - struct scsi_cmd cmd; ! 5253: - struct scsi_return ret; ! 5254: - int n, i; ! 5255: - char buf[512]; ! 5256: - ! 5257: -#pragma ref niargs ! 5258: -#pragma ref iargs ! 5259: -#pragma ref ncargs ! 5260: -#pragma ref cargs ! 5261: - ! 5262: - set6(cmd, 0x12, 0, 0, 0, 44, 0); ! 5263: - if(n = s_io(0, &cmd, 0, &ret, 44, err)) ! 5264: - return(n); ! 5265: - i = min(ret.data[37], 4); ! 5266: - fixedstr(&ret.data[8], 28, buf); ! 5267: - printf("config(%d,%d): %s device, '%s', %c controller%s, %c drive%s\n", ! 5268: - s_id, 0, (ret.data[0] == 0x4)? "WORM":"Unknown", ! 5269: - buf, mtab[i][0], (mtab[i][0] == '1')?"":"s", ! 5270: - mtab[i][1], (mtab[i][1] == '1')?"":"s"); ! 5271: - printf("\tUnibus-SCSI controller=%s\n", brdname[ret.type]); ! 5272: - printf("\tROMS:"); ! 5273: - if(ret.data[38] != 0xFF) ! 5274: - printf(" upper controller=0x%x,", ret.data[38]); ! 5275: - if(ret.data[40] != 0xFF) ! 5276: - printf(" lower controller=0x%x,", ret.data[40]); ! 5277: - printf( " IF-129=0x%x, SY-46=0x%x, SS-30=0x%x\n", ret.data[36], ! 5278: - ret.data[42], ret.data[43]); ! 5279: - return(0); ! 5280: -} ! 5281: //GO.SYSIN DD scsi/sony/config.c ! 5282: echo scsi/sony/status.c 1>&2 ! 5283: sed 's/.//' >scsi/sony/status.c <<'//GO.SYSIN DD scsi/sony/status.c' ! 5284: -#include <stdio.h> ! 5285: -#include "../scsi.h" ! 5286: -#include "../scsish.h" ! 5287: - ! 5288: -static ! 5289: -shelf(int i) ! 5290: -{ ! 5291: - printf(": "); ! 5292: - if(i&0x80){ ! 5293: - printf("%s,", (i&0x40)? "disk":"temporary"); ! 5294: - if(i&0x10) printf("wait loading,"); ! 5295: - if(i&0x08) printf("wait ejection,"); ! 5296: - if(i&0x20) printf("use shelf instead of drive for LUN %d", i&7); ! 5297: - } else ! 5298: - printf("no disk"); ! 5299: - printf("\n"); ! 5300: -} ! 5301: - ! 5302: -int ! 5303: -sony_istatus(struct scsi_return *ret, char *err) ! 5304: -{ ! 5305: - struct scsi_cmd cmd; ! 5306: - int n; ! 5307: - ! 5308: - set6(cmd, 0x1D, 0, 0, 0, 10, 0); ! 5309: - cmd.data[0] = 0xE2; /* internal status */ ! 5310: - cmd.data[1] = 0; ! 5311: - cmd.data[2] = 0; ! 5312: - cmd.data[3] = 0; ! 5313: - cmd.data[4] = 0; ! 5314: - cmd.data[5] = 0; ! 5315: - cmd.data[6] = 0; ! 5316: - cmd.data[7] = 0; ! 5317: - cmd.data[8] = 0; ! 5318: - cmd.data[9] = 0; ! 5319: - if(n = s_io(0, &cmd, 10, ret, 0, err)) ! 5320: - return(n); ! 5321: - setdiag(cmd, 0, 128); ! 5322: - if(n = s_io(0, &cmd, 0, ret, 128, err)) ! 5323: - return(n); ! 5324: - return(0); ! 5325: -} ! 5326: - ! 5327: -int ! 5328: -sony_status(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5329: -{ ! 5330: - struct scsi_return ret; ! 5331: - int n, i, start; ! 5332: - uchar *d; ! 5333: - ! 5334: -#pragma ref niargs ! 5335: -#pragma ref iargs ! 5336: -#pragma ref ncargs ! 5337: -#pragma ref cargs ! 5338: - ! 5339: - if(n = sony_istatus(&ret, err)) ! 5340: - return(n); ! 5341: - d = &ret.data[16]; ! 5342: - for(i = 0; i < 8; i++, d += 4){ ! 5343: - printf("drive %d: %sready,%sdisk in LUN,power %s,", i, ! 5344: - (d[0]&1)?"":"not ", (d[0]&0x40)?"":"no ", ! 5345: - (d[0]&0x80)?"off":"on"); ! 5346: - if(d[0]&0x40){ ! 5347: - if(d[1]&0x80){ ! 5348: - printf("disk in drive %d", d[1]&0x7f); ! 5349: - if(d[2]&0x80) ! 5350: - printf(", return shelf %d%c", (d[2]&0x7F)/2, "ab"[d[2]&1]); ! 5351: - } else ! 5352: - printf("disk in shelf %d%c (%d)", (d[1]&0x7f)/2, (d[1]&1)+'a', d[1]&0x7f); ! 5353: - } ! 5354: - printf("\n"); ! 5355: - } ! 5356: - for(i = 0; i < 50;){ ! 5357: - for(start = i; ++i < 50;) ! 5358: - if(d[i] != d[start]) ! 5359: - break; ! 5360: - if(i == start+1) ! 5361: - printf("%d", start); ! 5362: - else ! 5363: - printf("%d-%d", start, i-1); ! 5364: - shelf(d[start]); ! 5365: - } ! 5366: - d += 50; ! 5367: - printf("I/O shelf"); ! 5368: - shelf(*d); ! 5369: - d++; ! 5370: - printf("carrier: "); ! 5371: - i = *d&0x7F; ! 5372: - if(*d&0x80) ! 5373: - printf("disk shelf=%d%c (%d)\n", i/2, 'a'+(i&1), i); ! 5374: - else ! 5375: - printf("no disk\n"); ! 5376: - d++; ! 5377: - if(*d&0x80) ! 5378: - printf("upper drive: disk, LUN=%d\n", *d&7); ! 5379: - else ! 5380: - printf("upper drive: no disk\n"); ! 5381: - d++; ! 5382: - if(*d&0x80) ! 5383: - printf("lower drive: disk, LUN=%d\n", *d&7); ! 5384: - else ! 5385: - printf("lower drive: no disk\n"); ! 5386: - return(0); ! 5387: -} ! 5388: //GO.SYSIN DD scsi/sony/status.c ! 5389: echo scsi/sony/rel.c 1>&2 ! 5390: sed 's/.//' >scsi/sony/rel.c <<'//GO.SYSIN DD scsi/sony/rel.c' ! 5391: -#include <stdio.h> ! 5392: -#include "../scsi.h" ! 5393: -#include "../scsish.h" ! 5394: -#include "fns.h" ! 5395: - ! 5396: -int ! 5397: -sony_rel(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5398: -{ ! 5399: - struct scsi_cmd cmd; ! 5400: - struct scsi_return ret; ! 5401: - int n, i, j; ! 5402: - ! 5403: -#pragma ref niargs ! 5404: - ! 5405: - if(ncargs == 0){ ! 5406: - i = 0; ! 5407: - j = 0; /* its ignored anyway */ ! 5408: - } else { ! 5409: - i = 1; ! 5410: - if((j = shelfside(cargs[0], err)) < 0) ! 5411: - return(1); ! 5412: - } ! 5413: - set6(cmd, 0xD7, (iargs[0]<<5)|i, 0, j, 0, 0); ! 5414: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 5415: - return(n); ! 5416: - return(0); ! 5417: -} ! 5418: //GO.SYSIN DD scsi/sony/rel.c ! 5419: echo scsi/sony/set.c 1>&2 ! 5420: sed 's/.//' >scsi/sony/set.c <<'//GO.SYSIN DD scsi/sony/set.c' ! 5421: -#include <stdio.h> ! 5422: -#include "../scsi.h" ! 5423: -#include "../scsish.h" ! 5424: -#include "fns.h" ! 5425: - ! 5426: -int ! 5427: -sony_set(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5428: -{ ! 5429: - struct scsi_cmd cmd; ! 5430: - struct scsi_return ret; ! 5431: - int n, i; ! 5432: - ! 5433: -#pragma ref niargs ! 5434: -#pragma ref ncargs ! 5435: - ! 5436: - if((i = shelfside(cargs[0], err)) < 0) ! 5437: - return(1); ! 5438: - set6(cmd, 0xD6, iargs[0]<<5, 0, i, 0, 0); ! 5439: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 5440: - return(n); ! 5441: - return(0); ! 5442: -} ! 5443: //GO.SYSIN DD scsi/sony/set.c ! 5444: echo scsi/sony/eject.c 1>&2 ! 5445: sed 's/.//' >scsi/sony/eject.c <<'//GO.SYSIN DD scsi/sony/eject.c' ! 5446: -#include <stdio.h> ! 5447: -#include "../scsi.h" ! 5448: -#include "../scsish.h" ! 5449: -#include "fns.h" ! 5450: - ! 5451: -int ! 5452: -sony_eject(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5453: -{ ! 5454: - struct scsi_cmd cmd; ! 5455: - struct scsi_return ret; ! 5456: - int n; ! 5457: - ! 5458: -#pragma ref niargs ! 5459: -#pragma ref ncargs ! 5460: -#pragma ref cargs ! 5461: - ! 5462: - set6(cmd, 0xC0, iargs[0]<<5, 0, 0, 0, 0); ! 5463: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 5464: - return(n); ! 5465: - return(0); ! 5466: -} ! 5467: //GO.SYSIN DD scsi/sony/eject.c ! 5468: echo scsi/sony/shelfside.c 1>&2 ! 5469: sed 's/.//' >scsi/sony/shelfside.c <<'//GO.SYSIN DD scsi/sony/shelfside.c' ! 5470: -#include <stdio.h> ! 5471: -#include "../scsi.h" ! 5472: -#include "../scsish.h" ! 5473: -#include "fns.h" ! 5474: - ! 5475: -int ! 5476: -shelfside(char *arg, char *err) ! 5477: -{ ! 5478: - char *oarg = arg; ! 5479: - int shelf; ! 5480: - ! 5481: - if((*arg < '0') || (*arg > '9')){ ! 5482: -usage: ! 5483: - sprintf(err, "shelfside '%s' must be numa or numb", oarg); ! 5484: - return(-1); ! 5485: - } ! 5486: - shelf = 0; ! 5487: - while((*arg >= '0') && (*arg <= '9')) ! 5488: - shelf = 10*shelf + *arg++ - '0'; ! 5489: - shelf <<= 1; ! 5490: - if(*arg == 'a') ! 5491: - ; ! 5492: - else if(*arg == 'b') ! 5493: - shelf |= 1; ! 5494: - else ! 5495: - goto usage; ! 5496: - if(*++arg) ! 5497: - goto usage; ! 5498: - return(shelf); ! 5499: -} ! 5500: //GO.SYSIN DD scsi/sony/shelfside.c ! 5501: echo scsi/sony/diskid.c 1>&2 ! 5502: sed 's/.//' >scsi/sony/diskid.c <<'//GO.SYSIN DD scsi/sony/diskid.c' ! 5503: -#include <stdio.h> ! 5504: -#include "../scsi.h" ! 5505: -#include "../scsish.h" ! 5506: -#include "fns.h" ! 5507: - ! 5508: -int ! 5509: -sony_diskid(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5510: -{ ! 5511: - struct scsi_cmd cmd; ! 5512: - struct scsi_return ret; ! 5513: - int n; ! 5514: - ! 5515: -#pragma ref ncargs ! 5516: -#pragma ref cargs ! 5517: - ! 5518: - if(niargs == 0) ! 5519: - iargs[0] = 0; ! 5520: - set6(cmd, 0xC2, iargs[0]<<5, 0, 0, 0, 0); ! 5521: - if(n = s_io(0, &cmd, 0, &ret, 1024, err)) ! 5522: - return(n); ! 5523: - printf("(%d,%d) disk id block:\n", s_id, iargs[0]); ! 5524: - xd(ret.data, 1024, stdout); ! 5525: - return(0); ! 5526: -} ! 5527: //GO.SYSIN DD scsi/sony/diskid.c ! 5528: echo scsi/sony/internal.c 1>&2 ! 5529: sed 's/.//' >scsi/sony/internal.c <<'//GO.SYSIN DD scsi/sony/internal.c' ! 5530: -#include <stdio.h> ! 5531: -#include "../scsi.h" ! 5532: -#include "../scsish.h" ! 5533: -#include "fns.h" ! 5534: - ! 5535: -static ! 5536: -internal(int n, int b1, int nb, struct scsi_return *ret, char *err) ! 5537: -{ ! 5538: - struct scsi_cmd cmd; ! 5539: - ! 5540: - set6(cmd, 0x1D, b1, 0, 0, 10, 0); ! 5541: - cmd.data[0] = n; ! 5542: - cmd.data[1] = b1>>8; ! 5543: - cmd.data[2] = 0; ! 5544: - cmd.data[3] = 0; ! 5545: - cmd.data[4] = 0; ! 5546: - cmd.data[5] = 0; ! 5547: - cmd.data[6] = 0; ! 5548: - cmd.data[7] = 0; ! 5549: - cmd.data[8] = 0; ! 5550: - cmd.data[9] = 0; ! 5551: - if(n = s_io(0, &cmd, 10, ret, 0, err)) ! 5552: - return(n); ! 5553: - setdiag(cmd, 0, nb); ! 5554: - if(n = s_io(0, &cmd, 0, ret, nb, err)) ! 5555: - return(n); ! 5556: - return(0); ! 5557: -} ! 5558: - ! 5559: -static char *cmds[] = { ! 5560: - "internal command table", ! 5561: - "error information table", ! 5562: - "arm controller diagnostics", ! 5563: - "scsi control board diagnostics", ! 5564: - "drive controller diagnostics", ! 5565: - "jukebox status", ! 5566: - 0 ! 5567: -}; ! 5568: - ! 5569: -static char *msg1[16] = ! 5570: -{ ! 5571: - "drive not connected or powered off", ! 5572: - "drive connected but no disk", ! 5573: - "diagnostic aborted: write-protect", ! 5574: - "diagnostic aborted: write area full", ! 5575: - "urk 4", "urk 5", "urk 6", "urk 7", "urk 8", "urk 9", "urk 10", ! 5576: - "urk 11", "urk 12", "urk 13", "urk 14", "urk 15" ! 5577: -}; ! 5578: - ! 5579: -static char *testn[10] = ! 5580: -{ ! 5581: - "drive on/off", ! 5582: - "read disk id", ! 5583: - "move", ! 5584: - "seek", ! 5585: - "blank sector search", ! 5586: - "written sector search", ! 5587: - "search writable area", ! 5588: - "write", ! 5589: - "ECC margin check", ! 5590: - "read data compare" ! 5591: -}; ! 5592: - ! 5593: -int ! 5594: -sony_internal(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5595: -{ ! 5596: - struct scsi_cmd cmd; ! 5597: - struct scsi_return ret; ! 5598: - int n; ! 5599: - register unsigned char *d; ! 5600: - int i, drive, lower; ! 5601: - long t1, t2; ! 5602: - extern char *cmesg[]; ! 5603: - extern char *i0com[], *i1err[], *scsicmd[], *busid[], *scsiident[]; ! 5604: - ! 5605: -#pragma ref ncargs ! 5606: -#pragma ref cargs ! 5607: - ! 5608: - switch(iargs[0]) ! 5609: - { ! 5610: - case -1: ! 5611: - printf("available internal commands:\n"); ! 5612: - for(i = 0; cmds[i]; i++) ! 5613: - printf("\tinternal %d: %s\n", i, cmds[i]); ! 5614: - break; ! 5615: - case 0: ! 5616: - if(internal(0xE5, 0, 256, &ret, err)) ! 5617: - return(1); ! 5618: - printf("internal 0 (%s):\n", cmds[iargs[0]]); ! 5619: - printf("Diagnostic #E5: last 16 internal tasks (drive,shelf)\n"); ! 5620: - for(i = 0, d = ret.data; i < 16; i++, d += 16){ ! 5621: - printf("[%d] %s (%d,%d)\n", ! 5622: - d[0], i0com[d[1]], d[2], d[3]); ! 5623: - } ! 5624: - break; ! 5625: - case 1: ! 5626: - if(internal(0xE4, 0, 256, &ret, err)) ! 5627: - return(1); ! 5628: - printf("internal 1 (%s):\n", cmds[iargs[0]]); ! 5629: - printf("Diagnostic #E4: last 16 errors; initiator[identify] error[sense] (cmd)\n"); ! 5630: - for(i = 0, d = ret.data; i < 16; i++, d += 16){ ! 5631: - printf("%s[%s]: %s[#%x] (%s)\n", ! 5632: - busid[d[0]], scsiident[d[1]], i1err[d[14]], d[15], scsicmd[d[4]]); ! 5633: - } ! 5634: - break; ! 5635: - case 2: ! 5636: - printf("internal 2 (%s):\n", cmds[iargs[0]]); ! 5637: - fflush(stdout); ! 5638: - time(&t1); ! 5639: - if(internal(0x90, 0, 8, &ret, err)) ! 5640: - return(1); ! 5641: - time(&t2); ! 5642: - d = ret.data; ! 5643: - if(d[0] == 0) ! 5644: - printf("\tended normally"); ! 5645: - else ! 5646: - printf("\tfailed, error codes=#%x, #%x, #%x", ! 5647: - d[0], d[1], d[2]); ! 5648: - printf(" (time: %lds)\n", t2-t1); ! 5649: - break; ! 5650: - case 3: ! 5651: - printf("internal 3 (%s):\n", cmds[iargs[0]]); ! 5652: - fflush(stdout); ! 5653: - time(&t1); ! 5654: - if(internal(0xe0, 0, 8, &ret, err)) ! 5655: - return(1); ! 5656: - time(&t2); ! 5657: - d = ret.data; ! 5658: - if(d[0] == 0) ! 5659: - printf("\tended normally"); ! 5660: - else ! 5661: - printf("\tfailed, error codes=#%x, #%x, #%x", ! 5662: - d[0], d[1], d[2]); ! 5663: - printf(" (time: %lds)\n", t2-t1); ! 5664: - break; ! 5665: - case 4: ! 5666: - if(niargs == 1) ! 5667: - iargs[1] = 0; /* zero default */ ! 5668: - drive = iargs[1]; ! 5669: - if(sony_istatus(&ret, err)) ! 5670: - return(1); ! 5671: - if((ret.data[100]&0x80) && (drive == (ret.data[100]&7))) ! 5672: - lower = 0x100; ! 5673: - else if((ret.data[101]&0x80) && (drive == (ret.data[101]&7))) ! 5674: - lower = 0x200; ! 5675: - else { ! 5676: - fprintf(stderr, "drive %d not occupied\n", drive); ! 5677: - return(1); ! 5678: - } ! 5679: - printf("drive %d[%ser]: %s\n", drive, (lower == 0x200)?"low":"upp", cmds[iargs[0]]); ! 5680: - fflush(stdout); ! 5681: - time(&t1); ! 5682: - if(internal(0x18, lower, 256, &ret, err)) ! 5683: - return(1); ! 5684: - time(&t2); ! 5685: - d = ret.data; ! 5686: - if(d[1]&0x80){ ! 5687: - printf("diagnostic result:"); ! 5688: - if((d[1]&0x70) == 0) ! 5689: - printf(" no faults"); ! 5690: - else { ! 5691: - if(d[1]&0x10) ! 5692: - printf(" controller-fault"); ! 5693: - if(d[1]&0x20) ! 5694: - printf(" drive-fault"); ! 5695: - if(d[1]&0x10) ! 5696: - printf(" disk-fault"); ! 5697: - printf(" (last error code 0x%2.2ux)", d[4]); ! 5698: - } ! 5699: - } else ! 5700: - printf("diagnostic not performed: %s", msg1[d[1]&0xF]); ! 5701: - printf(" (time: %lds)\n", t2-t1); ! 5702: - for(i = 0; i < 10; i++) ! 5703: - printf("test %d[%s]: %s\n", i, testn[i], cmesg[d[i*8+drive+8]]); ! 5704: - printf("diagnostic count (drive:avail):"); ! 5705: - for(d += 104, i = 0; i < 8; i++, d += 2) ! 5706: - printf(" %d:%d", i, d[0]+d[1]*256); ! 5707: - printf("\n"); ! 5708: - break; ! 5709: - case 5: ! 5710: - set10(cmd, 0xD3, 0, 0, 0, 0, 0, 0, 0, 0, 0); ! 5711: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 5712: - return(n); ! 5713: - printf("%s: component(fatal err/err/cmds)\n", cmds[iargs[0]]); ! 5714: - d = ret.data; ! 5715: -#define ONE(str, x, sep) printf("%s(%d/%d/%d)%c", str, d[x+3], d[x+2], d[x+1]+256*d[x], sep) ! 5716: - ! 5717: - ONE("upper drive", 4, ' '); ! 5718: - ONE("lower drive", 8, ' '); ! 5719: - ONE("sys control", 12, ' '); ! 5720: - printf("backup mem(0/%d/%d)\n", d[19]+256*d[18], d[17]+256*d[16]); ! 5721: - break; ! 5722: - } ! 5723: - return(0); ! 5724: -} ! 5725: //GO.SYSIN DD scsi/sony/internal.c ! 5726: echo scsi/sony/i0.tab 1>&2 ! 5727: sed 's/.//' >scsi/sony/i0.tab <<'//GO.SYSIN DD scsi/sony/i0.tab' ! 5728: -i0com ! 5729: -00 nop ! 5730: -01 sense result ! 5731: -02 version check ! 5732: -04 recover disk warning ! 5733: -08 sense alternate information ! 5734: -0a error margin check ! 5735: -18 diagnostics ! 5736: -20 sense drive status ! 5737: -21 recalibrate ! 5738: -22 drive on ! 5739: -23 drive off ! 5740: -24 disk out ! 5741: -30 seek ! 5742: -31 move ! 5743: -32 read ! 5744: -a1 disk check ! 5745: -a2 carrier move ! 5746: -b1 disk set ! 5747: -b2 disk release ! 5748: -b3 disk rotate ! 5749: //GO.SYSIN DD scsi/sony/i0.tab ! 5750: echo scsi/sony/i1.tab 1>&2 ! 5751: sed 's/.//' >scsi/sony/i1.tab <<'//GO.SYSIN DD scsi/sony/i1.tab' ! 5752: -i1err ! 5753: -94 drive error (SONY) ! 5754: -a0 invalid command ! 5755: -a1 invalid LUN ! 5756: -a2 reserved bit nonzero ! 5757: -a3 illegal logical address ! 5758: -a4 illegal shelf number ! 5759: -a5 illegal parameter length ! 5760: -a6 illegal parameter ! 5761: -a7 unacceptable diagnostics parameter ! 5762: -a8 unit attention ! 5763: -a9 drive not ready ! 5764: -aa medium removal prevented ! 5765: -ab reserved ! 5766: -ac no disk in LUN ! 5767: //GO.SYSIN DD scsi/sony/i1.tab ! 5768: echo scsi/sony/scsi.tab 1>&2 ! 5769: sed 's/.//' >scsi/sony/scsi.tab <<'//GO.SYSIN DD scsi/sony/scsi.tab' ! 5770: -scsicmd ! 5771: -00 test unit ready ! 5772: -01 rezero unit ! 5773: -03 request sense ! 5774: -08 read ! 5775: -0a write ! 5776: -0b seek ! 5777: -0c move ! 5778: -12 inquiry ! 5779: -15 mode select ! 5780: -16 reserve ! 5781: -17 release ! 5782: -18 copy ! 5783: -1a mode sense ! 5784: -1b start/stop unit ! 5785: -1c receive diagnostics ! 5786: -1d send diagnostics ! 5787: -1e prevent/allow medium removal ! 5788: -25 read capacity ! 5789: -28 read ! 5790: -2a write ! 5791: -2c blank sector search ! 5792: -2d written sector search ! 5793: -c0 disk eject ! 5794: -c2 read disk id ! 5795: -c3 sense alternate information ! 5796: -c4 recover disk warning ! 5797: -d3 request recovered status ! 5798: -d6 disk set ! 5799: -d7 disk release ! 5800: -busid ! 5801: -01 0 ! 5802: -02 1 ! 5803: -80 7 ! 5804: -scsiident ! 5805: -80 no dis/reconnect-LUN 0 ! 5806: -81 no dis/reconnect-LUN 1 ! 5807: -82 no dis/reconnect-LUN 2 ! 5808: -83 no dis/reconnect-LUN 3 ! 5809: -84 no dis/reconnect-LUN 4 ! 5810: -85 no dis/reconnect-LUN 5 ! 5811: -86 no dis/reconnect-LUN 6 ! 5812: -87 no dis/reconnect-LUN 7 ! 5813: -c0 dis/reconnect-LUN 0 ! 5814: -c1 dis/reconnect-LUN 1 ! 5815: -c2 dis/reconnect-LUN 2 ! 5816: -c3 dis/reconnect-LUN 3 ! 5817: -c4 dis/reconnect-LUN 4 ! 5818: -c5 dis/reconnect-LUN 5 ! 5819: -c6 dis/reconnect-LUN 6 ! 5820: -c7 dis/reconnect-LUN 7 ! 5821: -cmesg ! 5822: -0 good ! 5823: -e0 test not done ! 5824: -ee diagnostic could not be done ! 5825: -fe drive not ready (no disk) ! 5826: -ff not connected or power off ! 5827: //GO.SYSIN DD scsi/sony/scsi.tab ! 5828: echo scsi/sony/media.c 1>&2 ! 5829: sed 's/.//' >scsi/sony/media.c <<'//GO.SYSIN DD scsi/sony/media.c' ! 5830: -#include <stdio.h> ! 5831: -#include <stddef.h> ! 5832: -#include "../scsi.h" ! 5833: -#include "../scsish.h" ! 5834: -#include "fns.h" ! 5835: - ! 5836: -static int cnts[256]; ! 5837: -static char *cmsg[256]; ! 5838: - ! 5839: -sony_media1(int drive, long lbn, int lower, struct scsi_return *ret, char *err) ! 5840: -{ ! 5841: - struct scsi_cmd cmd; ! 5842: - int n; ! 5843: - ! 5844: - set6(cmd, 0x1D, drive<<5, 0, 0, 10, 0); ! 5845: - cmd.data[0] = 0x0A; /* error margin check */ ! 5846: - cmd.data[1] = lower? 2:1; ! 5847: - cmd.data[2] = 0; ! 5848: - cmd.data[3] = 0; ! 5849: - cmd.data[4] = drive; ! 5850: - cmd.data[5] = lbn; ! 5851: - cmd.data[6] = lbn>>8; ! 5852: - cmd.data[7] = lbn>>16; ! 5853: - cmd.data[8] = 0; ! 5854: - cmd.data[9] = 0; ! 5855: - if(n = s_io(0, &cmd, 10, ret, 0, err)) ! 5856: - return(n); ! 5857: - setdiag(cmd, drive, 256); ! 5858: - if(n = s_io(0, &cmd, 0, ret, 256, err)) ! 5859: - return(n); ! 5860: - return(0); ! 5861: -} ! 5862: - ! 5863: -int ! 5864: -sony_media(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5865: -{ ! 5866: - struct scsi_return ret; ! 5867: - uchar *d; ! 5868: - int bn, c; ! 5869: - char buf[256]; ! 5870: - int lower; ! 5871: - int nline; ! 5872: - int cur, curb; ! 5873: - int drive = iargs[0]; ! 5874: - long lbn = iargs[1]; ! 5875: - int count = iargs[2]; ! 5876: - extern char *strdup(char *); ! 5877: - int verbose = 0; ! 5878: - FILE *fp = 0; ! 5879: - ! 5880: -#pragma ref niargs ! 5881: - ! 5882: - if(ncargs == 1){ ! 5883: - if(strcmp(cargs[0], "-v") == 0) ! 5884: - verbose = 1; ! 5885: - else if((fp = fopen(cargs[0], "w")) == NULL){ ! 5886: - pperror(err, cargs[0]); ! 5887: - return(1); ! 5888: - } ! 5889: - } ! 5890: - if(sony_istatus(&ret, err)) ! 5891: - return(1); ! 5892: - if((ret.data[100]&0x80) && (drive == (ret.data[100]&7))) ! 5893: - lower = 0; ! 5894: - else if((ret.data[101]&0x80) && (drive == (ret.data[101]&7))) ! 5895: - lower = 1; ! 5896: - else { ! 5897: - sprintf(err, "drive %d not occupied and ready\n", drive); ! 5898: - return(1); ! 5899: - } ! 5900: - printf("media margin check for %d blocks [%d-%d] on %s drive (%d,%d):", ! 5901: - count, lbn, lbn+count-1, lower? "lower":"upper", s_id, drive); ! 5902: - if(fp) ! 5903: - printf(" stored in '%s'", cargs[0]); ! 5904: - putchar('\n'); ! 5905: - if(cmsg[0] == 0){ ! 5906: - for(bn = 0; bn < 256; bn++){ ! 5907: - sprintf(buf, "rare error 0x%x", bn); ! 5908: - cmsg[bn] = strdup(buf); ! 5909: - } ! 5910: - cmsg[0] = "good"; ! 5911: - cmsg[0x40] = "seek error 1 (alternated)"; ! 5912: - cmsg[0x41] = "seek error 2 (alternated)"; ! 5913: - cmsg[0x42] = "seek error 3 (alternated)"; ! 5914: - cmsg[0x44] = "read error 1 (alternated)"; ! 5915: - cmsg[0x45] = "unwritten"; ! 5916: - cmsg[0x46] = "read error 3 (alternated)"; ! 5917: - cmsg[0x81] = "<50% burst"; ! 5918: - cmsg[0x82] = "50-96% burst (alternated)"; ! 5919: - cmsg[0x83] = ">96% burst (alternated)"; ! 5920: - cmsg[0x84] = "uncorrectable (alternated)"; ! 5921: - } ! 5922: -#define DO(ch,cp) if(fp) putc(ch,fp); else if(ch != cur){\ ! 5923: - int newb = bn+cp-ret.data;\ ! 5924: - if(verbose && (curb>=0)){\ ! 5925: - printf("%d %s@%d, ", newb-curb, cmsg[cur], curb);\ ! 5926: - if(++nline == 5){nline = 0; putchar('\n');}\ ! 5927: - }\ ! 5928: - cur = ch;\ ! 5929: - curb = newb;\ ! 5930: - } ! 5931: - cur = 256; ! 5932: - curb = -1; ! 5933: - nline = 0; ! 5934: - for(bn = 0; bn < 256; bn++) ! 5935: - cnts[bn] = 0; ! 5936: - for(bn = lbn, c = count; c >= 256; c -= 256, bn += 256){ ! 5937: - if(sony_media1(drive, bn, lower, &ret, err)) ! 5938: - return(1); ! 5939: - for(d = ret.data; d < &ret.data[256];){ ! 5940: - DO(*d, d); ! 5941: - cnts[*d++]++; ! 5942: - } ! 5943: - } ! 5944: - if(c){ ! 5945: - if(sony_media1(drive, bn, lower, &ret, err)) ! 5946: - return(1); ! 5947: - for(d = ret.data; c; c--){ ! 5948: - DO(*d, d); ! 5949: - cnts[*d++]++; ! 5950: - } ! 5951: - } ! 5952: - DO(256, d); ! 5953: - if(nline) ! 5954: - putchar('\n'); ! 5955: - printf("\t"); ! 5956: - for(c = 0; c < 256; c++) ! 5957: - if(cnts[c]) ! 5958: - printf("%d %s, ", cnts[c], cmsg[c]); ! 5959: - printf("\n"); ! 5960: - return(0); ! 5961: -} ! 5962: //GO.SYSIN DD scsi/sony/media.c ! 5963: echo scsi/sony/readid.c 1>&2 ! 5964: sed 's/.//' >scsi/sony/readid.c <<'//GO.SYSIN DD scsi/sony/readid.c' ! 5965: -#include <stdio.h> ! 5966: -#include "../scsi.h" ! 5967: -#include "../scsish.h" ! 5968: -#include "fns.h" ! 5969: - ! 5970: -static int ! 5971: -my_read(int lun, long blk, struct scsi_return *ret, char *err) ! 5972: -{ ! 5973: - struct scsi_cmd cmd; ! 5974: - int n; ! 5975: - ! 5976: - cmd.bus_id = s_id; ! 5977: - set10(cmd, 0x28, lun<<5, blk>>24, blk>>16, blk>>8, blk, 0, 0, 1, 0); ! 5978: - n = ss_io(0, &cmd, 0, ret, 1024, err); ! 5979: - return(n); ! 5980: -} ! 5981: - ! 5982: -int ! 5983: -sony_readid(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 5984: -{ ! 5985: - struct scsi_return ret; ! 5986: - char buf[128]; ! 5987: - int drive = iargs[0]; ! 5988: - long blk, lastb; ! 5989: - int pr = 0; ! 5990: - ! 5991: -#pragma ref ncargs ! 5992: -#pragma ref cargs ! 5993: - ! 5994: - buf[0] = 0; ! 5995: - if(niargs == 2){ ! 5996: - if((blk = iargs[1]) < 0){ ! 5997: - blk = -blk; ! 5998: - pr = 1; ! 5999: - } ! 6000: - } else { ! 6001: - if(my_read(drive, 0L, &ret, err) == 0) ! 6002: - goto done; ! 6003: - blk = 1; ! 6004: - } ! 6005: - for(lastb = -1;;){ ! 6006: - if(pr){ ! 6007: - printf("%d: ", blk); ! 6008: - } ! 6009: - if(my_read(drive, blk, &ret, err)) ! 6010: - break; ! 6011: - lastb = blk; ! 6012: - blk = ((long *)ret.data)[9]; ! 6013: - } ! 6014: - if(lastb < 0){ ! 6015: - printf("read(blk=%d) failed\n", blk); ! 6016: - return(1); ! 6017: - } ! 6018: - if(my_read(drive, lastb, &ret, err) != 0) ! 6019: - return(1); ! 6020: -done: ! 6021: - strncpy(buf, (char *)&ret.data[42], 128); ! 6022: - buf[127] = 0; ! 6023: - printf("(%d,%d): '%s'\n", s_id, drive, buf); ! 6024: - return(0); ! 6025: -} ! 6026: //GO.SYSIN DD scsi/sony/readid.c ! 6027: echo scsi/sony/copy.c 1>&2 ! 6028: sed 's/.//' >scsi/sony/copy.c <<'//GO.SYSIN DD scsi/sony/copy.c' ! 6029: -#include <stdio.h> ! 6030: -#include "../scsi.h" ! 6031: -#include "../scsish.h" ! 6032: -#include "fns.h" ! 6033: - ! 6034: -#define PROGRESS \ ! 6035: - if(sbase/TALK != goo){\ ! 6036: - goo = sbase/TALK;\ ! 6037: - time(&t2);\ ! 6038: - printf("\tdoing block %ld at %s", goo*TALK, ctime(&t2));\ ! 6039: - } ! 6040: - ! 6041: -static char good[256]; /* by default, all BAD */ ! 6042: -typedef enum { BAD = 0, GOOD } Searchtype; ! 6043: -static int copy1(int, int, int, int, int, int, int, char *); ! 6044: -static int search(int, int, int, int, Searchtype, char *); ! 6045: - ! 6046: -int ! 6047: -sony_copy(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6048: -{ ! 6049: - int n; ! 6050: - int sdr = iargs[0]; ! 6051: - int sbase = iargs[1]; ! 6052: - int nblocks = iargs[2]; ! 6053: - int ddr = iargs[3]; ! 6054: - int dbase = iargs[4]; ! 6055: - int starget = s_id; ! 6056: - int dtarget = s_id; ! 6057: - int wr, unwr; ! 6058: - long nb = nblocks; ! 6059: - long t1, t2; ! 6060: - long goo; ! 6061: - int lower; ! 6062: - struct scsi_return ret; ! 6063: -#define TALK 10000 ! 6064: - extern char *ctime(); ! 6065: - ! 6066: -#pragma ref niargs ! 6067: -#pragma ref ncargs ! 6068: -#pragma ref cargs ! 6069: - ! 6070: - printf("copying drive (%d,%d)[%d-%d] to drive (%d,%d)[%d-%d]\n", ! 6071: - starget, sdr, sbase, sbase+nblocks-1, ! 6072: - dtarget, ddr, dbase, dbase+nblocks-1); ! 6073: - if(sony_istatus(&ret, err)) ! 6074: - return(1); ! 6075: - if((ret.data[100]&0x80) && (sdr == (ret.data[100]&7))) ! 6076: - lower = 0; ! 6077: - else if((ret.data[101]&0x80) && (sdr == (ret.data[101]&7))) ! 6078: - lower = 1; ! 6079: - else { ! 6080: - sprintf(err, "drive %d not occupied\n", sdr); ! 6081: - return(1); ! 6082: - } ! 6083: - good[0] = good[0x81] = good[0x82] = good[0x83] = GOOD; ! 6084: - time(&t1); ! 6085: - goo = -1; ! 6086: - while(nblocks > 0){ ! 6087: - /* search for a block to copy */ ! 6088: - while(n = min(256, nblocks)){ ! 6089: - wr = search(sdr, lower, sbase, n, GOOD, err); ! 6090: - if(wr < 0) ! 6091: - break; ! 6092: - sbase += wr; ! 6093: - dbase += wr; ! 6094: - nblocks -= wr; ! 6095: - if(wr < n) ! 6096: - break; ! 6097: - PROGRESS ! 6098: - } ! 6099: - /* now copy until the first bad block */ ! 6100: - while(n = min(256, nblocks)){ ! 6101: - unwr = search(sdr, lower, sbase, n, BAD, err); ! 6102: - if(unwr < 0) ! 6103: - break; ! 6104: - /*printf("writing %d-%d\n", sbase, sbase+unwr-1);/**/ ! 6105: - if(copy1(starget, sdr, sbase, unwr, dtarget, ddr, dbase, err)) ! 6106: - break; ! 6107: - sbase += unwr; ! 6108: - dbase += unwr; ! 6109: - nblocks -= unwr; ! 6110: - PROGRESS ! 6111: - } ! 6112: - } ! 6113: - time(&t2); ! 6114: - t2 -= t1; ! 6115: - if(t2 == 0) t2 = 1; ! 6116: - printf("%ds: ", t2); ! 6117: - if(nblocks){ ! 6118: - printf("copy buggered up: sbase=%d nblks=%d dbase=%d\n", ! 6119: - sbase, nblocks, dbase); ! 6120: - return(1); ! 6121: - } ! 6122: - printf("%d blocks at %.1fKB/s\n", nb, nb/(float)t2); ! 6123: - return(0); ! 6124: -} ! 6125: - ! 6126: -static int ! 6127: -copy1(int st, int sd, int sb, int n, int dt, int dd, int db, char *err) ! 6128: -{ ! 6129: - struct scsi_cmd cmd; ! 6130: - struct scsi_return ret; ! 6131: - ! 6132: - set6(cmd, 0x18, sd<<5, 0, 0, 20, 0); ! 6133: - cmd.data[0] = 0x10; /* copy */ ! 6134: - cmd.data[1] = 0; ! 6135: - cmd.data[2] = 0; ! 6136: - cmd.data[3] = 0; ! 6137: - cmd.data[4] = (st<<5)|sd; ! 6138: - cmd.data[5] = (dt<<5)|dd; ! 6139: - cmd.data[6] = 0; ! 6140: - cmd.data[7] = 0; ! 6141: - cmd.data[8] = n>>24; ! 6142: - cmd.data[9] = n>>16; ! 6143: - cmd.data[10] = n>>8; ! 6144: - cmd.data[11] = n; ! 6145: - cmd.data[12] = sb>>24; ! 6146: - cmd.data[13] = sb>>16; ! 6147: - cmd.data[14] = sb>>8; ! 6148: - cmd.data[15] = sb; ! 6149: - cmd.data[16] = db>>24; ! 6150: - cmd.data[17] = db>>16; ! 6151: - cmd.data[18] = db>>8; ! 6152: - cmd.data[19] = db; ! 6153: - return(s_io(0, &cmd, 20, &ret, 0, err)); ! 6154: -} ! 6155: - ! 6156: -static int ! 6157: -search(int dr, int lower, int sbase, int n, Searchtype s, char *err) ! 6158: -{ ! 6159: - uchar *cp; ! 6160: - struct scsi_return ret; ! 6161: - ! 6162: - if(n <= 0) ! 6163: - return(0); ! 6164: - if(n > 256) ! 6165: - n = 256; ! 6166: - if(sony_media1(dr, sbase, lower, &ret, err)) ! 6167: - return(-1); ! 6168: - for(cp = ret.data; n-- > 0; cp++) ! 6169: - if(good[*cp] != s) ! 6170: - break; ! 6171: - return(cp-ret.data); ! 6172: -} ! 6173: //GO.SYSIN DD scsi/sony/copy.c ! 6174: echo scsi/sony/fns.h 1>&2 ! 6175: sed 's/.//' >scsi/sony/fns.h <<'//GO.SYSIN DD scsi/sony/fns.h' ! 6176: -extern int sony_inq(int, int *, int, char **, char *); ! 6177: -extern int sony_alt(int, int *, int, char **, char *); ! 6178: -extern int sony_conf(int, int *, int, char **, char *); ! 6179: -extern int sony_status(int, int *, int, char **, char *); ! 6180: -extern int sony_set(int, int *, int, char **, char *); ! 6181: -extern int sony_rel(int, int *, int, char **, char *); ! 6182: -extern int sony_eject(int, int *, int, char **, char *); ! 6183: -extern int sony_diskid(int, int *, int, char **, char *); ! 6184: -extern int sony_internal(int, int *, int, char **, char *); ! 6185: -extern int sony_media(int, int *, int, char **, char *); ! 6186: -extern int sony_readid(int, int *, int, char **, char *); ! 6187: -extern int sony_copy(int, int *, int, char **, char *); ! 6188: -extern int sony_sense(int, int *, int, char **, char *); ! 6189: -extern void sony_extsense(uchar *, char *, int); ! 6190: - ! 6191: -extern int shelfside(char *arg, char *err); ! 6192: //GO.SYSIN DD scsi/sony/fns.h ! 6193: echo scsi/sony/sense.c 1>&2 ! 6194: sed 's/.//' >scsi/sony/sense.c <<'//GO.SYSIN DD scsi/sony/sense.c' ! 6195: -#include <stdio.h> ! 6196: -#include "../scsi.h" ! 6197: -#include "../scsish.h" ! 6198: -#include "fns.h" ! 6199: - ! 6200: -int ! 6201: -sony_sense(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6202: -{ ! 6203: - struct scsi_cmd cmd; ! 6204: - struct scsi_return ret; ! 6205: - int n; ! 6206: - char buf[4096]; ! 6207: - ! 6208: -#pragma ref ncargs ! 6209: -#pragma ref cargs ! 6210: - ! 6211: - if(niargs == 0) ! 6212: - iargs[0] = 0; ! 6213: - set6(cmd, 0x03, iargs[0]<<5, 0, 0, 32, 0); ! 6214: - if(n = s_io(0, &cmd, 0, &ret, -32, err)) ! 6215: - return(n); ! 6216: - printf("sense(%d,%d): ", s_id, iargs[0]); ! 6217: - sony_extsense(ret.data, buf, sizeof buf); ! 6218: - printf("%s\n", buf); ! 6219: - return(0); ! 6220: -} ! 6221: - ! 6222: -static char *exstab[16] = ! 6223: -{ ! 6224: - "no sense", ! 6225: - "recovered error", ! 6226: - "not ready", ! 6227: - "medium error", ! 6228: - "hardware error", ! 6229: - "illegal request", ! 6230: - "unit attention", ! 6231: - "data protect", ! 6232: - "blank check", ! 6233: - "key #9", ! 6234: - "copy aborted", ! 6235: - "aborted command", ! 6236: - "key #c", ! 6237: - "volume overflow", ! 6238: - "miscompare", ! 6239: - "key #f", ! 6240: -}; ! 6241: - ! 6242: -void ! 6243: -sony_extsense(uchar *data, char *dest, int ndata) ! 6244: -{ ! 6245: - char buf[4096]; ! 6246: - extern char *nesd[]; ! 6247: - ! 6248: - dest[0] = 0; ! 6249: - switch(data[2]) ! 6250: - { ! 6251: - case 0: ! 6252: - sprintf(dest, "no error"); ! 6253: - break; ! 6254: - case 0x1: /* recovered error */ ! 6255: - sprintf(dest, "recovered error"); ! 6256: - break; ! 6257: - case 0xA: /* recovered error */ ! 6258: - sprintf(dest, "recovered error"); ! 6259: - break; ! 6260: - default: ! 6261: - if(data[7] != 4) ! 6262: - sprintf((char *)data, "warning: extra data is %d, not 4! ", data[7]); ! 6263: - sprintf(buf, "sense: %s", nesd[data[8]&0x7f]); ! 6264: - strcat(dest, buf); ! 6265: - if(data[8]&0x80){ ! 6266: - sprintf(buf, " at addr #%x", data[11]+256L*data[10]+256L*256*data[9]); ! 6267: - strcat(dest, buf); ! 6268: - } ! 6269: - sprintf(buf, ", ext sense: %s", exstab[data[2]]); ! 6270: - strcat(dest, buf); ! 6271: - if(data[0]&0x80){ ! 6272: - sprintf(buf, " info=#%x", data[6]+256L*data[5]+256L*256L*data[4]+256L*256L*256L*data[3]); ! 6273: - strcat(dest, buf); ! 6274: - } ! 6275: - break; ! 6276: - } ! 6277: -} ! 6278: //GO.SYSIN DD scsi/sony/sense.c ! 6279: echo scsi/sony/nesd.tab 1>&2 ! 6280: sed 's/.//' >scsi/sony/nesd.tab <<'//GO.SYSIN DD scsi/sony/nesd.tab' ! 6281: -nesd ! 6282: -00 no sense ! 6283: -01 invalid command ! 6284: -02 recovered error ! 6285: -03 illegal request ! 6286: -06 unit attention ! 6287: -07 parity error ! 6288: -08 message reject error ! 6289: -0a copy aborted ! 6290: -10 ecc trouible occurred ! 6291: -11 time out error ! 6292: -12 controller error ! 6293: -13 SONY I/F II hardware/firmware error ! 6294: -14 scsi hardware/firmware error ! 6295: -20 command not terminated ! 6296: -21 drive interface parity error ! 6297: -22 loading trouble ! 6298: -23 focus trouble ! 6299: -24 tracking trouble ! 6300: -25 spindle trouble ! 6301: -26 slide trouible ! 6302: -27 skew trouble ! 6303: -28 head lead out ! 6304: -29 write modulation trouble ! 6305: -2a under laser power ! 6306: -2b over laser power ! 6307: -2f drive error ! 6308: -30 drive power off ! 6309: -31 no disk in drive ! 6310: -32 drive not ready ! 6311: -38 disk already exists in drive ! 6312: -39 no disk in drive ! 6313: -3a disk already exists in shelf ! 6314: -40 write warning ! 6315: -41 write error ! 6316: -42 disk error ! 6317: -43 cannot read disk id ! 6318: -44 write protect error 1 ! 6319: -45 write protect error 2 ! 6320: -46 disk warning ! 6321: -47 alternation trouble ! 6322: -50 specified address not found ! 6323: -51 address block not found ! 6324: -52 all address could not be read ! 6325: -53 data could not be read ! 6326: -54 uncorrectable read error ! 6327: -55 tracking error ! 6328: -60 no data in specified address ! 6329: -68 z-axis servo error ! 6330: -69 roter servo error ! 6331: -6a hook servo error ! 6332: -6b i/o shelf error ! 6333: -6c drive 0 error ! 6334: -6d drive 1 error ! 6335: -6e shelf error ! 6336: -6f carrier error ! 6337: //GO.SYSIN DD scsi/sony/nesd.tab ! 6338: echo scsi/lib.c 1>&2 ! 6339: sed 's/.//' >scsi/lib.c <<'//GO.SYSIN DD scsi/lib.c' ! 6340: -#include <stdio.h> ! 6341: -#include "scsi.h" ! 6342: -#include "scsish.h" ! 6343: -#include "generic/fns.h" ! 6344: -#include "sony/fns.h" ! 6345: - ! 6346: -s_start(int dr, char *err) ! 6347: -{ ! 6348: - int iargs[1]; ! 6349: - char *cargs[1]; ! 6350: - ! 6351: - iargs[0] = dr; ! 6352: - return(gen_start(1, iargs, 0, cargs, err)); ! 6353: -} ! 6354: - ! 6355: -s_stop(int dr, char *err) ! 6356: -{ ! 6357: - int iargs[1]; ! 6358: - char *cargs[1]; ! 6359: - ! 6360: - iargs[0] = dr; ! 6361: - return(gen_stop(1, iargs, 0, cargs, err)); ! 6362: -} ! 6363: - ! 6364: -s_eject(int dr, char *err) ! 6365: -{ ! 6366: - int iargs[1]; ! 6367: - char *cargs[1]; ! 6368: - ! 6369: - iargs[0] = dr; ! 6370: - return(sony_eject(1, iargs, 0, cargs, err)); ! 6371: -} ! 6372: //GO.SYSIN DD scsi/lib.c ! 6373: echo scsi/wren/dev.c 1>&2 ! 6374: sed 's/.//' >scsi/wren/dev.c <<'//GO.SYSIN DD scsi/wren/dev.c' ! 6375: -#include <stdio.h> ! 6376: -#include "../scsi.h" ! 6377: -#include "../scsish.h" ! 6378: -#include "fns.h" ! 6379: - ! 6380: -static Function fns[] = { ! 6381: - { "diag", "diag", "", wr_diag }, ! 6382: - { "extinq", "extinq", "", wr_extinq }, ! 6383: - { "modesense", "modesense", "", wr_modesense }, ! 6384: - { "modeselect", "modeselect er-param er-retries read-recon write-recon cache-enable cache-thr cache-pre cache-size", "IIIIIIIII", wr_modeselect }, ! 6385: - { 0 } ! 6386: -}; ! 6387: -Device wrendev = { ! 6388: - "wren", "Wren V/VI/Runner-2", ! 6389: - gen_extsense, ! 6390: - fns ! 6391: -}; ! 6392: //GO.SYSIN DD scsi/wren/dev.c ! 6393: echo scsi/wren/inq.c 1>&2 ! 6394: sed 's/.//' >scsi/wren/inq.c <<'//GO.SYSIN DD scsi/wren/inq.c' ! 6395: -#include <stdio.h> ! 6396: -#include "../scsi.h" ! 6397: -#include "../scsish.h" ! 6398: -#include "fns.h" ! 6399: - ! 6400: -extern char *gen_rmb[2]; ! 6401: -extern char *gen_devtype[256]; ! 6402: - ! 6403: -int ! 6404: -wr_extinq(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6405: -{ ! 6406: - struct scsi_cmd cmd; ! 6407: - struct scsi_return ret; ! 6408: - int n; ! 6409: - char vendor[9], product[17]; ! 6410: - ! 6411: -#pragma ref niargs ! 6412: -#pragma ref iargs ! 6413: -#pragma ref ncargs ! 6414: -#pragma ref cargs ! 6415: - ! 6416: - set6(cmd, 0x12, 0, 0, 0, 96, 0); ! 6417: - if(n = s_io(0, &cmd, 0, &ret, 96, err)) ! 6418: - return(n); ! 6419: - fixedstr(&ret.data[8], 8, vendor); ! 6420: - fixedstr(&ret.data[16], 16, product); ! 6421: - printf("inq(%d,%d): %s %s, %s/%s rev=%0.4s serial=%0.8s\n", ! 6422: - s_id, 0, gen_rmb[ret.data[1]>>7], gen_devtype[ret.data[0]], ! 6423: - vendor, product, &ret.data[32], &ret.data[36]); ! 6424: - return(0); ! 6425: -} ! 6426: //GO.SYSIN DD scsi/wren/inq.c ! 6427: echo scsi/wren/wmode.c 1>&2 ! 6428: sed 's/.//' >scsi/wren/wmode.c <<'//GO.SYSIN DD scsi/wren/wmode.c' ! 6429: -#include <stdio.h> ! 6430: -#include "../scsi.h" ! 6431: -#include "../scsish.h" ! 6432: -#include "fns.h" ! 6433: - ! 6434: -int ! 6435: -wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6436: -{ ! 6437: - struct scsi_cmd cmd; ! 6438: - struct scsi_return ret; ! 6439: - int n; ! 6440: - ! 6441: -#pragma ref niargs ! 6442: -#pragma ref ncargs ! 6443: -#pragma ref cargs ! 6444: - ! 6445: - printf("changing modes to "); ! 6446: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 6447: - printf("er-param=%d(=#%x), ", iargs[0], iargs[0]); ! 6448: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 6449: - printf("er-retries=%d, ", iargs[1]); ! 6450: - if((iargs[2] < 256) && (iargs[2] >= 0)) ! 6451: - printf("read-recon=%d/256, ", iargs[2]); ! 6452: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 6453: - printf("write-recon=%d/256, ", iargs[3]); ! 6454: - if((iargs[4] < 256) && (iargs[4] >= 0)) ! 6455: - printf("read cache %sable, ", iargs[4]?"dis":"en"); ! 6456: - if((iargs[5] < 256) && (iargs[5] >= 0)) ! 6457: - printf("write cache %sable, ", iargs[5]?"en":"dis"); ! 6458: - if((iargs[6] < 256) && (iargs[6] >= 0)) ! 6459: - printf("cache max prefetch=%d, ", iargs[6]); ! 6460: - if((iargs[7] < 256) && (iargs[7] >= 0)) ! 6461: - printf("cache size=%d, ", iargs[7]); ! 6462: - if((iargs[8] < 256) && (iargs[8] >= 0)) ! 6463: - printf("cross cyl %sable, ", iargs[8]?"en":"dis"); ! 6464: - printf("\nsleep(10); kill me if you disagree\n"); ! 6465: - fflush(stdout); ! 6466: - sleep(10); ! 6467: - /* do error recovery */ ! 6468: - if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){ ! 6469: - set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0); ! 6470: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 6471: - return(n); ! 6472: - memcpy(cmd.data, ret.data, 20); ! 6473: - cmd.data[14] &= ~0x10; ! 6474: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 6475: - cmd.data[14] = iargs[0]; ! 6476: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 6477: - cmd.data[15] = iargs[1]; ! 6478: - set6(cmd, 0x15, 0x11, 0, 0, 20, 0); ! 6479: - if(n = s_io(0, &cmd, 20, &ret, 0, err)) ! 6480: - return(n); ! 6481: - } ! 6482: - /* reconnect */ ! 6483: - if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){ ! 6484: - set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0); ! 6485: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 6486: - return(n); ! 6487: - memcpy(cmd.data, ret.data, 24); ! 6488: - if((iargs[2] < 256) && (iargs[2] >= 0)) ! 6489: - cmd.data[14] = iargs[2]; ! 6490: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 6491: - cmd.data[15] = iargs[3]; ! 6492: - set6(cmd, 0x15, 0x11, 0, 0, 24, 0); ! 6493: - if(n = s_io(0, &cmd, 24, &ret, 0, err)) ! 6494: - return(n); ! 6495: - } ! 6496: - /* do cache params*/ ! 6497: - if(((iargs[4] < 256) && (iargs[4] >= 0)) ! 6498: - || ((iargs[5] < 256) && (iargs[5] >= 0)) ! 6499: - || ((iargs[6] < 65536) && (iargs[6] >= 0))){ ! 6500: - set6(cmd, 0x1A, 0, (0<<6)|0x08, 0, 28, 0); ! 6501: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 6502: - return(n); ! 6503: - memcpy(cmd.data, ret.data, 24); ! 6504: - if((iargs[4] < 256) && (iargs[4] >= 0)){ ! 6505: - cmd.data[14] &= ~0x01; ! 6506: - cmd.data[14] |= iargs[4]; ! 6507: - } ! 6508: - if((iargs[5] < 256) && (iargs[5] >= 0)){ ! 6509: - cmd.data[14] &= ~0x04; ! 6510: - cmd.data[14] |= iargs[5]? 0x04:0; ! 6511: - } ! 6512: - if((iargs[6] < 65536) && (iargs[6] >= 0)){ ! 6513: - cmd.data[20] = iargs[6]>>8; ! 6514: - cmd.data[21] = iargs[6]; ! 6515: - } ! 6516: - set6(cmd, 0x15, 0x11, 0, 0, 24, 0); ! 6517: - if(n = s_io(0, &cmd, 24, &ret, 0, err)) ! 6518: - return(n); ! 6519: - } ! 6520: - /* do cache control */ ! 6521: - if(((iargs[8] < 256) && (iargs[8] >= 0)) ! 6522: - || ((iargs[7] < 256) && (iargs[7] >= 0))){ ! 6523: - set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0); ! 6524: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 6525: - return(n); ! 6526: - memcpy(cmd.data, ret.data, 28); ! 6527: - cmd.data[14] &= ~0x80; ! 6528: - if(iargs[8]) ! 6529: - cmd.data[14] |= 0x80; ! 6530: - if((iargs[7] < 256) && (iargs[7] >= 0)){ ! 6531: - cmd.data[14] &= 0xF0; ! 6532: - cmd.data[14] |= iargs[7]&0xF; ! 6533: - } ! 6534: - set6(cmd, 0x15, 0x11, 0, 0, 28, 0); ! 6535: - if(n = s_io(0, &cmd, 28, &ret, 0, err)) ! 6536: - return(n); ! 6537: - } ! 6538: - return(0); ! 6539: -} ! 6540: //GO.SYSIN DD scsi/wren/wmode.c ! 6541: echo scsi/wren/diag.c 1>&2 ! 6542: sed 's/.//' >scsi/wren/diag.c <<'//GO.SYSIN DD scsi/wren/diag.c' ! 6543: -#include <stdio.h> ! 6544: -#include "../scsi.h" ! 6545: -#include "../scsish.h" ! 6546: -#include "fns.h" ! 6547: - ! 6548: -int ! 6549: -wr_diag(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6550: -{ ! 6551: - struct scsi_cmd cmd; ! 6552: - struct scsi_return ret; ! 6553: - int n; ! 6554: - long t; ! 6555: - ! 6556: -#pragma ref niargs ! 6557: -#pragma ref iargs ! 6558: -#pragma ref ncargs ! 6559: -#pragma ref cargs ! 6560: - ! 6561: - t = time((long *)0); ! 6562: - set6(cmd, 0x1D, 0x04, 0, 0, 0, 0); ! 6563: - if(n = s_io(0, &cmd, 0, &ret, 0, err)) ! 6564: - return(n); ! 6565: - set6(cmd, 0x1C, 0, 0, 0, 8, 0); ! 6566: - if(n = s_io(0, &cmd, 0, &ret, 8, err)) ! 6567: - return(n); ! 6568: - t = time((long *)0)-t; ! 6569: - printf("selftest diagnostic (%ds)\n", t); ! 6570: - if((ret.data[7] == 0) && (ret.data[2] == 0)) ! 6571: - printf("\tno errors\n"); ! 6572: - else ! 6573: - printf("\terror==#%x,#%x FRU=(#%x,#%x,#%x,#%x)\n", ! 6574: - ret.data[6], ret.data[7], ret.data[2], ! 6575: - ret.data[3], ret.data[4], ret.data[5]); ! 6576: - return(0); ! 6577: -} ! 6578: //GO.SYSIN DD scsi/wren/diag.c ! 6579: echo scsi/wren/fns.h 1>&2 ! 6580: sed 's/.//' >scsi/wren/fns.h <<'//GO.SYSIN DD scsi/wren/fns.h' ! 6581: -extern int wr_extinq(int, int *, int, char **, char *); ! 6582: -extern int wr_modesense(int, int *, int, char **, char *); ! 6583: -extern int wr_modeselect(int, int *, int, char **, char *); ! 6584: -extern int wr_diag(int, int *, int, char **, char *); ! 6585: //GO.SYSIN DD scsi/wren/fns.h ! 6586: echo scsi/wren/omode.c 1>&2 ! 6587: sed 's/.//' >scsi/wren/omode.c <<'//GO.SYSIN DD scsi/wren/omode.c' ! 6588: -#include <stdio.h> ! 6589: -#include "../scsi.h" ! 6590: -#include "../scsish.h" ! 6591: -#include "fns.h" ! 6592: - ! 6593: -#define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1])) ! 6594: - ! 6595: -static int ! 6596: -er(int pcf, char *err) ! 6597: -{ ! 6598: - struct scsi_cmd cmd; ! 6599: - struct scsi_return ret; ! 6600: - int n; ! 6601: - static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" }; ! 6602: - ! 6603: - set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0); ! 6604: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 6605: - return(n); ! 6606: - printf("error recovery:\n\t"); ! 6607: - for(n = 7; n >= 0; n--) ! 6608: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 6609: - printf("\n\t%d retries, max ecc span=%d\n", ret.data[15], ret.data[16]); ! 6610: - return(0); ! 6611: -} ! 6612: - ! 6613: -static int ! 6614: -dr(int pcf, char *err) ! 6615: -{ ! 6616: - struct scsi_cmd cmd; ! 6617: - struct scsi_return ret; ! 6618: - int n; ! 6619: - ! 6620: - set6(cmd, 0x1A, 0, (pcf<<6)|0x02, 0, 24, 0); ! 6621: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 6622: - return(n); ! 6623: - printf("disconnect/reconnect:\n"); ! 6624: - printf("\tread reconnect=%d/256,", ret.data[14]); ! 6625: - printf(" write reconnect=%d/256\n", ret.data[15]); ! 6626: - return(0); ! 6627: -} ! 6628: - ! 6629: -static int ! 6630: -fp(int pcf, char *err) ! 6631: -{ ! 6632: - struct scsi_cmd cmd; ! 6633: - struct scsi_return ret; ! 6634: - int n; ! 6635: - static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" }; ! 6636: - ! 6637: - set6(cmd, 0x1A, 0, (pcf<<6)|0x03, 0, 36, 0); ! 6638: - if(n = s_io(0, &cmd, 0, &ret, 36, err)) ! 6639: - return(n); ! 6640: - printf("format parameters:\n"); ! 6641: - printf("\tsec=%dB, trk=%d secs, interleave=%d trk skew=%d cyl skew=%d\n", ! 6642: - SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30)); ! 6643: - printf("\t%d alt sec/%d alt trk per zone(=%d trks), %d alt trks per vol\n", ! 6644: - SHORT(16), SHORT(18), SHORT(14), SHORT(20)); ! 6645: - printf("\tdrive type:"); ! 6646: - for(n = 7; n >= 3; n--) ! 6647: - printf(" %s%s", (ret.data[32]&(1<<n))? "":"~", bit[n]); ! 6648: - printf("\n"); ! 6649: - return(0); ! 6650: -} ! 6651: - ! 6652: -static int ! 6653: -geom(int pcf, char *err) ! 6654: -{ ! 6655: - struct scsi_cmd cmd; ! 6656: - struct scsi_return ret; ! 6657: - int n; ! 6658: - ! 6659: - set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0); ! 6660: - if(n = s_io(0, &cmd, 0, &ret, 32, err)) ! 6661: - return(n); ! 6662: - printf("drive geometry:\n\t%d cyls, %d heads\n", ! 6663: - (ret.data[14]<<16)|SHORT(15), ret.data[17]); ! 6664: - return(0); ! 6665: -} ! 6666: - ! 6667: -static int ! 6668: -cc(int pcf, char *err) ! 6669: -{ ! 6670: - struct scsi_cmd cmd; ! 6671: - struct scsi_return ret; ! 6672: - int n; ! 6673: - static char *bit[8] = { "", "", "", "", "CacheEnable", "RSVD", "WIE", "RSVD" }; ! 6674: - ! 6675: - set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0); ! 6676: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 6677: - return(n); ! 6678: - printf("cache control:\n\t"); ! 6679: - for(n = 7; n >= 4; n--) ! 6680: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 6681: - printf(", cache size=%d\n", ret.data[14]&0xF); ! 6682: - printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n", ! 6683: - ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]); ! 6684: - return(0); ! 6685: -} ! 6686: - ! 6687: -int ! 6688: -wr_modesense(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6689: -{ ! 6690: - int n; ! 6691: - ! 6692: -#pragma ref ncargs ! 6693: -#pragma ref cargs ! 6694: -#pragma ref niargs ! 6695: -#pragma ref iargs ! 6696: - ! 6697: -#define PCF 0 /* current values */ ! 6698: - ! 6699: - printf("mode sense(%d,0):\n", s_id); ! 6700: - if(n = er(PCF, err)) ! 6701: - return(n); ! 6702: - if(n = dr(PCF, err)) ! 6703: - return(n); ! 6704: - if(n = fp(PCF, err)) ! 6705: - return(n); ! 6706: - if(n = geom(PCF, err)) ! 6707: - return(n); ! 6708: - if(n = cc(PCF, err)) ! 6709: - return(n); ! 6710: - return(0); ! 6711: -} ! 6712: - ! 6713: -int ! 6714: -wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6715: -{ ! 6716: - struct scsi_cmd cmd; ! 6717: - struct scsi_return ret; ! 6718: - int n; ! 6719: - ! 6720: -#pragma ref niargs ! 6721: -#pragma ref ncargs ! 6722: -#pragma ref cargs ! 6723: - ! 6724: - printf("changing modes to "); ! 6725: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 6726: - printf("er-param=%d(=#%x), ", iargs[0], iargs[0]); ! 6727: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 6728: - printf("er-retries=%d, ", iargs[1]); ! 6729: - if((iargs[2] < 256) && (iargs[2] >= 0)) ! 6730: - printf("read-recon=%d/256, ", iargs[2]); ! 6731: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 6732: - printf("write-recon=%d/256, ", iargs[3]); ! 6733: - if((iargs[4] < 256) && (iargs[4] >= 0)) ! 6734: - printf("cache %sable, ", iargs[4]?"en":"dis"); ! 6735: - if((iargs[5] < 256) && (iargs[5] >= 0)) ! 6736: - printf("cache threshold=%d, ", iargs[5]); ! 6737: - if((iargs[6] < 256) && (iargs[6] >= 0)) ! 6738: - printf("cache max prefetch=%d, ", iargs[6]); ! 6739: - if((iargs[7] < 256) && (iargs[7] >= 0)) ! 6740: - printf("cache size=%d, ", iargs[7]); ! 6741: - printf("\nsleep(10); kill me if you disagree\n"); ! 6742: - fflush(stdout); ! 6743: - sleep(10); ! 6744: - /* do error recovery */ ! 6745: - if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){ ! 6746: - set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0); ! 6747: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 6748: - return(n); ! 6749: - memcpy(cmd.data, ret.data, 20); ! 6750: - cmd.data[14] &= ~0x10; ! 6751: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 6752: - cmd.data[14] = iargs[0]; ! 6753: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 6754: - cmd.data[15] = iargs[1]; ! 6755: - set6(cmd, 0x15, 0x11, 0, 0, 20, 0); ! 6756: - if(n = s_io(0, &cmd, 20, &ret, 0, err)) ! 6757: - return(n); ! 6758: - } ! 6759: - /* reconnect */ ! 6760: - if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){ ! 6761: - set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0); ! 6762: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 6763: - return(n); ! 6764: - memcpy(cmd.data, ret.data, 24); ! 6765: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 6766: - cmd.data[14] = iargs[3]; ! 6767: - if((iargs[4] < 256) && (iargs[4] >= 0)) ! 6768: - cmd.data[15] = iargs[4]; ! 6769: - set6(cmd, 0x15, 0x11, 0, 0, 24, 0); ! 6770: - if(n = s_io(0, &cmd, 24, &ret, 0, err)) ! 6771: - return(n); ! 6772: - } ! 6773: - /* do cache control */ ! 6774: - if(((iargs[4] < 256) && (iargs[4] >= 0)) ! 6775: - || ((iargs[5] < 256) && (iargs[5] >= 0)) ! 6776: - || ((iargs[6] < 256) && (iargs[6] >= 0)) ! 6777: - || ((iargs[7] < 256) && (iargs[7] >= 0))){ ! 6778: - set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0); ! 6779: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 6780: - return(n); ! 6781: - memcpy(cmd.data, ret.data, 28); ! 6782: - cmd.data[14] &= ~0x10; ! 6783: - if(iargs[4]) ! 6784: - cmd.data[14] |= 0x10; ! 6785: - if((iargs[7] < 256) && (iargs[7] >= 0)){ ! 6786: - cmd.data[14] &= 0xF0; ! 6787: - cmd.data[14] |= iargs[7]&0xF; ! 6788: - } ! 6789: - if((iargs[5] < 256) && (iargs[5] >= 0)) ! 6790: - cmd.data[15] = iargs[5]; ! 6791: - if((iargs[6] < 256) && (iargs[6] >= 0)) ! 6792: - cmd.data[16] = iargs[6]; ! 6793: - set6(cmd, 0x15, 0x11, 0, 0, 28, 0); ! 6794: - if(n = s_io(0, &cmd, 28, &ret, 0, err)) ! 6795: - return(n); ! 6796: - } ! 6797: - return(0); ! 6798: -} ! 6799: //GO.SYSIN DD scsi/wren/omode.c ! 6800: echo scsi/wren/oomode.c 1>&2 ! 6801: sed 's/.//' >scsi/wren/oomode.c <<'//GO.SYSIN DD scsi/wren/oomode.c' ! 6802: -#include <stdio.h> ! 6803: -#include "../scsi.h" ! 6804: -#include "../scsish.h" ! 6805: -#include "fns.h" ! 6806: - ! 6807: -#define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1])) ! 6808: - ! 6809: -static int ! 6810: -er(int pcf, char *err) ! 6811: -{ ! 6812: - struct scsi_cmd cmd; ! 6813: - struct scsi_return ret; ! 6814: - int n; ! 6815: - static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" }; ! 6816: - ! 6817: - set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0); ! 6818: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 6819: - return(n); ! 6820: - printf("error recovery:\n\t"); ! 6821: - for(n = 7; n >= 0; n--) ! 6822: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 6823: - printf("\n\t%d retries, max ecc span=%d\n", ret.data[15], ret.data[16]); ! 6824: - return(0); ! 6825: -} ! 6826: - ! 6827: -static int ! 6828: -dr(int pcf, char *err) ! 6829: -{ ! 6830: - struct scsi_cmd cmd; ! 6831: - struct scsi_return ret; ! 6832: - int n; ! 6833: - ! 6834: - set6(cmd, 0x1A, 0, (pcf<<6)|0x02, 0, 24, 0); ! 6835: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 6836: - return(n); ! 6837: - printf("disconnect/reconnect:\n"); ! 6838: - printf("\tread reconnect=%d/256,", ret.data[14]); ! 6839: - printf(" write reconnect=%d/256\n", ret.data[15]); ! 6840: - return(0); ! 6841: -} ! 6842: - ! 6843: -static int ! 6844: -fp(int pcf, char *err) ! 6845: -{ ! 6846: - struct scsi_cmd cmd; ! 6847: - struct scsi_return ret; ! 6848: - int n; ! 6849: - static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" }; ! 6850: - ! 6851: - set6(cmd, 0x1A, 0, (pcf<<6)|0x03, 0, 36, 0); ! 6852: - if(n = s_io(0, &cmd, 0, &ret, 36, err)) ! 6853: - return(n); ! 6854: - printf("format parameters:\n"); ! 6855: - printf("\tsec=%dB, trk=%d secs, interleave=%d trk skew=%d cyl skew=%d\n", ! 6856: - SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30)); ! 6857: - printf("\t%d alt sec/%d alt trk per zone(=%d trks), %d alt trks per vol\n", ! 6858: - SHORT(16), SHORT(18), SHORT(14), SHORT(20)); ! 6859: - printf("\tdrive type:"); ! 6860: - for(n = 7; n >= 3; n--) ! 6861: - printf(" %s%s", (ret.data[32]&(1<<n))? "":"~", bit[n]); ! 6862: - printf("\n"); ! 6863: - return(0); ! 6864: -} ! 6865: - ! 6866: -static int ! 6867: -geom(int pcf, char *err) ! 6868: -{ ! 6869: - struct scsi_cmd cmd; ! 6870: - struct scsi_return ret; ! 6871: - int n; ! 6872: - ! 6873: - set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0); ! 6874: - if(n = s_io(0, &cmd, 0, &ret, 32, err)) ! 6875: - return(n); ! 6876: - printf("drive geometry:\n\t%d cyls, %d heads\n", ! 6877: - (ret.data[14]<<16)|SHORT(15), ret.data[17]); ! 6878: - return(0); ! 6879: -} ! 6880: - ! 6881: -static int ! 6882: -cc(int pcf, char *err) ! 6883: -{ ! 6884: - struct scsi_cmd cmd; ! 6885: - struct scsi_return ret; ! 6886: - int n; ! 6887: - static char *bit[8] = { "", "", "", "", "CacheEnable", "RSVD", "WIE", "RSVD" }; ! 6888: - ! 6889: - set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0); ! 6890: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 6891: - return(n); ! 6892: - printf("cache control:\n\t"); ! 6893: - for(n = 7; n >= 4; n--) ! 6894: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 6895: - printf(", cache size=%d\n", ret.data[14]&0xF); ! 6896: - printf("\tprefetch: thr=%d max=%dx%d min=%dx%d\n", ! 6897: - ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]); ! 6898: - return(0); ! 6899: -} ! 6900: - ! 6901: -int ! 6902: -wr_modesense(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6903: -{ ! 6904: - int n; ! 6905: - ! 6906: -#pragma ref ncargs ! 6907: -#pragma ref cargs ! 6908: -#pragma ref niargs ! 6909: -#pragma ref iargs ! 6910: - ! 6911: -#define PCF 0 /* current values */ ! 6912: - ! 6913: - printf("mode sense(%d,0):\n", s_id); ! 6914: - if(n = er(PCF, err)) ! 6915: - return(n); ! 6916: - if(n = dr(PCF, err)) ! 6917: - return(n); ! 6918: - if(n = fp(PCF, err)) ! 6919: - return(n); ! 6920: - if(n = geom(PCF, err)) ! 6921: - return(n); ! 6922: - if(n = cc(PCF, err)) ! 6923: - return(n); ! 6924: - return(0); ! 6925: -} ! 6926: - ! 6927: -int ! 6928: -wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 6929: -{ ! 6930: - struct scsi_cmd cmd; ! 6931: - struct scsi_return ret; ! 6932: - int n; ! 6933: - ! 6934: -#pragma ref niargs ! 6935: -#pragma ref ncargs ! 6936: -#pragma ref cargs ! 6937: - ! 6938: - printf("changing modes to "); ! 6939: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 6940: - printf("er-param=%d(=#%x), ", iargs[0], iargs[0]); ! 6941: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 6942: - printf("er-retries=%d, ", iargs[1]); ! 6943: - if((iargs[2] < 256) && (iargs[2] >= 0)) ! 6944: - printf("read-recon=%d/256, ", iargs[2]); ! 6945: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 6946: - printf("write-recon=%d/256, ", iargs[3]); ! 6947: - if((iargs[4] < 256) && (iargs[4] >= 0)) ! 6948: - printf("cache %sable, ", iargs[4]?"en":"dis"); ! 6949: - printf("\nsleep(10); kill me if you disagree\n"); ! 6950: - fflush(stdout); ! 6951: - sleep(10); ! 6952: - /* do error recovery */ ! 6953: - if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){ ! 6954: - set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0); ! 6955: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 6956: - return(n); ! 6957: - memcpy(cmd.data, ret.data, 20); ! 6958: - cmd.data[14] &= ~0x10; ! 6959: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 6960: - cmd.data[14] = iargs[0]; ! 6961: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 6962: - cmd.data[15] = iargs[1]; ! 6963: - set6(cmd, 0x15, 0x11, 0, 0, 20, 0); ! 6964: - if(n = s_io(0, &cmd, 20, &ret, 0, err)) ! 6965: - return(n); ! 6966: - } ! 6967: - /* reconnect */ ! 6968: - if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){ ! 6969: - set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0); ! 6970: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 6971: - return(n); ! 6972: - memcpy(cmd.data, ret.data, 24); ! 6973: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 6974: - cmd.data[14] = iargs[3]; ! 6975: - if((iargs[4] < 256) && (iargs[4] >= 0)) ! 6976: - cmd.data[15] = iargs[4]; ! 6977: - set6(cmd, 0x15, 0x11, 0, 0, 24, 0); ! 6978: - if(n = s_io(0, &cmd, 24, &ret, 0, err)) ! 6979: - return(n); ! 6980: - } ! 6981: - /* do cache control */ ! 6982: - if((iargs[4] < 256) && (iargs[4] >= 0)){ ! 6983: - set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0); ! 6984: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 6985: - return(n); ! 6986: - memcpy(cmd.data, ret.data, 28); ! 6987: - cmd.data[14] &= ~0x10; ! 6988: - if(iargs[4]) ! 6989: - cmd.data[14] |= 0x10; ! 6990: - set6(cmd, 0x15, 0x11, 0, 0, 28, 0); ! 6991: - if(n = s_io(0, &cmd, 28, &ret, 0, err)) ! 6992: - return(n); ! 6993: - } ! 6994: - return(0); ! 6995: -} ! 6996: //GO.SYSIN DD scsi/wren/oomode.c ! 6997: echo scsi/wren/rmode.c 1>&2 ! 6998: sed 's/.//' >scsi/wren/rmode.c <<'//GO.SYSIN DD scsi/wren/rmode.c' ! 6999: -#include <stdio.h> ! 7000: -#include "../scsi.h" ! 7001: -#include "../scsish.h" ! 7002: -#include "fns.h" ! 7003: - ! 7004: -#define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1])) ! 7005: - ! 7006: -static int ! 7007: -er_w6(int pcf, char *err) ! 7008: -{ ! 7009: - struct scsi_cmd cmd; ! 7010: - struct scsi_return ret; ! 7011: - int n; ! 7012: - static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" }; ! 7013: - ! 7014: - set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0); ! 7015: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 7016: - return(n); ! 7017: - printf("error recovery:\n\t"); ! 7018: - for(n = 7; n >= 0; n--) ! 7019: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 7020: - printf("\n\t%d retries, max ecc span=%d, recov tlimit=%d\n", ! 7021: - ret.data[15], ret.data[16], ret.data[17]); ! 7022: - return(0); ! 7023: -} ! 7024: - ! 7025: -static int ! 7026: -dr_w6(int pcf, char *err) ! 7027: -{ ! 7028: - struct scsi_cmd cmd; ! 7029: - struct scsi_return ret; ! 7030: - int n; ! 7031: - ! 7032: - set6(cmd, 0x1A, 0, (pcf<<6)|0x02, 0, 24, 0); ! 7033: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 7034: - return(n); ! 7035: - printf("disconnect/reconnect:\n"); ! 7036: - printf("\tread reconnect=%d/256 full,", ret.data[14]); ! 7037: - printf(" write reconnect=%d/256 empty\n", ret.data[15]); ! 7038: - return(0); ! 7039: -} ! 7040: - ! 7041: -static int ! 7042: -fp_w6(int pcf, char *err) ! 7043: -{ ! 7044: - struct scsi_cmd cmd; ! 7045: - struct scsi_return ret; ! 7046: - int n; ! 7047: - static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" }; ! 7048: - ! 7049: - set6(cmd, 0x1A, 0, (pcf<<6)|0x03, 0, 36, 0); ! 7050: - if(n = s_io(0, &cmd, 0, &ret, 36, err)) ! 7051: - return(n); ! 7052: - printf("format parameters:\n"); ! 7053: - printf("\tsec=%d B, trk=%d secs, interleave=%d, trk_skew=%d, cyl_skew=%d\n", ! 7054: - SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30)); ! 7055: - printf("\t%d alt_sec/%d alt_trk per zone(=%d trks), %d alt_trk per vol\n", ! 7056: - SHORT(16), SHORT(18), SHORT(14), SHORT(20)); ! 7057: - printf("\tdrive type:"); ! 7058: - for(n = 7; n >= 3; n--) ! 7059: - printf(" %s%s", (ret.data[32]&(1<<n))? "":"~", bit[n]); ! 7060: - printf("\n"); ! 7061: - return(0); ! 7062: -} ! 7063: - ! 7064: -static int ! 7065: -geom_w6(int pcf, char *err) ! 7066: -{ ! 7067: - struct scsi_cmd cmd; ! 7068: - struct scsi_return ret; ! 7069: - int n; ! 7070: - ! 7071: - set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0); ! 7072: - if(n = s_io(0, &cmd, 0, &ret, 32, err)) ! 7073: - return(n); ! 7074: - printf("drive geometry:\n\t%d cyls, %d heads\n", ! 7075: - (ret.data[14]<<16)|SHORT(15), ret.data[17]); ! 7076: - return(0); ! 7077: -} ! 7078: - ! 7079: -static int ! 7080: -cc_w6(int pcf, char *err) ! 7081: -{ ! 7082: - struct scsi_cmd cmd; ! 7083: - struct scsi_return ret; ! 7084: - int n; ! 7085: - static char *bit[8] = { "", "", "", "", "CacheEnable", "RSVD", "WIE", "RSVD" }; ! 7086: - ! 7087: - set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0); ! 7088: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 7089: - return(n); ! 7090: - printf("cache control:\n\t"); ! 7091: - for(n = 7; n >= 4; n--) ! 7092: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 7093: - printf(", cache size=%d\n", ret.data[14]&0xF); ! 7094: - printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n", ! 7095: - ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]); ! 7096: - return(0); ! 7097: -} ! 7098: - ! 7099: -static int ! 7100: -er_wr2(int pcf, char *err) ! 7101: -{ ! 7102: - struct scsi_cmd cmd; ! 7103: - struct scsi_return ret; ! 7104: - int n; ! 7105: - static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" }; ! 7106: - ! 7107: - set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0); ! 7108: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 7109: - return(n); ! 7110: - printf("error recovery:\n\t"); ! 7111: - for(n = 7; n >= 0; n--) ! 7112: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 7113: - printf("\n\t%d retries, max ecc span=%d, %d wr retries, recov tlimit=%d\n", ! 7114: - ret.data[15], ret.data[16], ret.data[20], SHORT(22)); ! 7115: - return(0); ! 7116: -} ! 7117: - ! 7118: -static int ! 7119: -geom_wr2(int pcf, char *err) ! 7120: -{ ! 7121: - struct scsi_cmd cmd; ! 7122: - struct scsi_return ret; ! 7123: - int n; ! 7124: - static char *sspin[4] = { ! 7125: - "no spindle synch", ! 7126: - "synch-spindle slave", ! 7127: - "synch-spindle master", ! 7128: - "synch-spindle master control", ! 7129: - }; ! 7130: - ! 7131: - set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0); ! 7132: - if(n = s_io(0, &cmd, 0, &ret, 32, err)) ! 7133: - return(n); ! 7134: - printf("drive geometry:\n\t%d cyls, %d heads, %s, rotation rate %d\n", ! 7135: - (ret.data[14]<<16)|SHORT(15), ret.data[17], ! 7136: - sspin[ret.data[29]&3], SHORT(32)); ! 7137: - return(0); ! 7138: -} ! 7139: - ! 7140: -static int ! 7141: -cp_wr2(int pcf, char *err) ! 7142: -{ ! 7143: - struct scsi_cmd cmd; ! 7144: - struct scsi_return ret; ! 7145: - int n; ! 7146: - static char *bit[8] = { "ReadCacheDisable", "", "WriteCacheEnable", "", "", "", "", "" }; ! 7147: - ! 7148: - set6(cmd, 0x1A, 0, (pcf<<6)|0x08, 0, 24, 0); ! 7149: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 7150: - return(n); ! 7151: - printf("caching parameters:\n\t"); ! 7152: - for(n = 2; n >= 0; n -= 2) ! 7153: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 7154: - printf("\n\tprefetch: min=%d, max=%d, ceiling=%d\n", ! 7155: - SHORT(18), SHORT(20), SHORT(22)); ! 7156: - return(0); ! 7157: -} ! 7158: - ! 7159: -static int ! 7160: -cc_wr2(int pcf, char *err) ! 7161: -{ ! 7162: - struct scsi_cmd cmd; ! 7163: - struct scsi_return ret; ! 7164: - int n; ! 7165: - static char *bit[8] = { "", "", "", "", "CacheEnable", "SSM", "WIE", "CCEN" }; ! 7166: - ! 7167: - set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0); ! 7168: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 7169: - return(n); ! 7170: - printf("cache control:\n\t"); ! 7171: - for(n = 7; n >= 4; n--) ! 7172: - printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]); ! 7173: - printf(", cache size=%d\n", ret.data[14]&0xF); ! 7174: - printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n", ! 7175: - ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]); ! 7176: - return(0); ! 7177: -} ! 7178: - ! 7179: -typedef (*Fn)(int, char *); ! 7180: -static struct Drive ! 7181: -{ ! 7182: - char *type; /* match inq field */ ! 7183: - char *desc; /* print at the user */ ! 7184: - Fn fns[10]; ! 7185: -} drive[] = { /* first one is default when none match */ ! 7186: - { "94181-15", "Wren VI", er_w6, dr_w6, fp_w6, geom_w6, cc_w6, 0 }, ! 7187: - { "ST4767", "Wren Runner-2", er_wr2, dr_w6, fp_w6, geom_wr2, cp_wr2, cc_wr2, 0 }, ! 7188: - { 0 } ! 7189: -}; ! 7190: - ! 7191: -int ! 7192: -wr_modesense(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 7193: -{ ! 7194: - int n, i, retv; ! 7195: - char product[17]; ! 7196: - int found; ! 7197: - struct scsi_cmd cmd; ! 7198: - struct scsi_return ret; ! 7199: - ! 7200: -#pragma ref ncargs ! 7201: -#pragma ref cargs ! 7202: -#pragma ref niargs ! 7203: -#pragma ref iargs ! 7204: - ! 7205: -#define PCF 0 /* current values */ ! 7206: - ! 7207: - /* find drive type */ ! 7208: - set6(cmd, 0x12, 0, 0, 0, 32, 0); ! 7209: - if(n = s_io(0, &cmd, 0, &ret, 32, err)) ! 7210: - return(n); ! 7211: - fixedstr(&ret.data[16], 16, product); ! 7212: - for(n = 0, found = 0; drive[n].type; n++) ! 7213: - if(strcmp(product, drive[n].type) == 0){ ! 7214: - found = 1; ! 7215: - break; ! 7216: - } ! 7217: - if(!found) ! 7218: - n = 0; ! 7219: - ! 7220: - if(found) ! 7221: - printf("mode sense(%d,0)[%s(%s)]:\n", s_id, drive[n].desc, product); ! 7222: - else ! 7223: - printf("mode sense(%d,0)[using %s, found '%s']:\n", s_id, drive[n].desc, product); ! 7224: - for(i = 0; drive[n].fns[i]; i++) ! 7225: - if(retv = (*drive[n].fns[i])(PCF, err)) ! 7226: - return(retv); ! 7227: - return(0); ! 7228: -} ! 7229: //GO.SYSIN DD scsi/wren/rmode.c ! 7230: echo scsi/wren/w6mode.c 1>&2 ! 7231: sed 's/.//' >scsi/wren/w6mode.c <<'//GO.SYSIN DD scsi/wren/w6mode.c' ! 7232: -#include <stdio.h> ! 7233: -#include "../scsi.h" ! 7234: -#include "../scsish.h" ! 7235: -#include "fns.h" ! 7236: - ! 7237: -int ! 7238: -wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err) ! 7239: -{ ! 7240: - struct scsi_cmd cmd; ! 7241: - struct scsi_return ret; ! 7242: - int n; ! 7243: - ! 7244: -#pragma ref niargs ! 7245: -#pragma ref ncargs ! 7246: -#pragma ref cargs ! 7247: - ! 7248: - printf("changing modes to "); ! 7249: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 7250: - printf("er-param=%d(=#%x), ", iargs[0], iargs[0]); ! 7251: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 7252: - printf("er-retries=%d, ", iargs[1]); ! 7253: - if((iargs[2] < 256) && (iargs[2] >= 0)) ! 7254: - printf("read-recon=%d/256, ", iargs[2]); ! 7255: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 7256: - printf("write-recon=%d/256, ", iargs[3]); ! 7257: - if((iargs[4] < 256) && (iargs[4] >= 0)) ! 7258: - printf("cache %sable, ", iargs[4]?"en":"dis"); ! 7259: - if((iargs[5] < 256) && (iargs[5] >= 0)) ! 7260: - printf("cache threshold=%d, ", iargs[5]); ! 7261: - if((iargs[6] < 256) && (iargs[6] >= 0)) ! 7262: - printf("cache max prefetch=%d, ", iargs[6]); ! 7263: - if((iargs[7] < 256) && (iargs[7] >= 0)) ! 7264: - printf("cache size=%d, ", iargs[7]); ! 7265: - printf("\nsleep(10); kill me if you disagree\n"); ! 7266: - fflush(stdout); ! 7267: - sleep(10); ! 7268: - /* do error recovery */ ! 7269: - if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){ ! 7270: - set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0); ! 7271: - if(n = s_io(0, &cmd, 0, &ret, 20, err)) ! 7272: - return(n); ! 7273: - memcpy(cmd.data, ret.data, 20); ! 7274: - cmd.data[14] &= ~0x10; ! 7275: - if((iargs[0] < 256) && (iargs[0] >= 0)) ! 7276: - cmd.data[14] = iargs[0]; ! 7277: - if((iargs[1] < 256) && (iargs[1] >= 0)) ! 7278: - cmd.data[15] = iargs[1]; ! 7279: - set6(cmd, 0x15, 0x11, 0, 0, 20, 0); ! 7280: - if(n = s_io(0, &cmd, 20, &ret, 0, err)) ! 7281: - return(n); ! 7282: - } ! 7283: - /* reconnect */ ! 7284: - if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){ ! 7285: - set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0); ! 7286: - if(n = s_io(0, &cmd, 0, &ret, 24, err)) ! 7287: - return(n); ! 7288: - memcpy(cmd.data, ret.data, 24); ! 7289: - if((iargs[3] < 256) && (iargs[3] >= 0)) ! 7290: - cmd.data[14] = iargs[3]; ! 7291: - if((iargs[4] < 256) && (iargs[4] >= 0)) ! 7292: - cmd.data[15] = iargs[4]; ! 7293: - set6(cmd, 0x15, 0x11, 0, 0, 24, 0); ! 7294: - if(n = s_io(0, &cmd, 24, &ret, 0, err)) ! 7295: - return(n); ! 7296: - } ! 7297: - /* do cache control */ ! 7298: - if(((iargs[4] < 256) && (iargs[4] >= 0)) ! 7299: - || ((iargs[5] < 256) && (iargs[5] >= 0)) ! 7300: - || ((iargs[6] < 256) && (iargs[6] >= 0)) ! 7301: - || ((iargs[7] < 256) && (iargs[7] >= 0))){ ! 7302: - set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0); ! 7303: - if(n = s_io(0, &cmd, 0, &ret, 28, err)) ! 7304: - return(n); ! 7305: - memcpy(cmd.data, ret.data, 28); ! 7306: - cmd.data[14] &= ~0x10; ! 7307: - if(iargs[4]) ! 7308: - cmd.data[14] |= 0x10; ! 7309: - if((iargs[7] < 256) && (iargs[7] >= 0)){ ! 7310: - cmd.data[14] &= 0xF0; ! 7311: - cmd.data[14] |= iargs[7]&0xF; ! 7312: - } ! 7313: - if((iargs[5] < 256) && (iargs[5] >= 0)) ! 7314: - cmd.data[15] = iargs[5]; ! 7315: - if((iargs[6] < 256) && (iargs[6] >= 0)) ! 7316: - cmd.data[16] = iargs[6]; ! 7317: - set6(cmd, 0x15, 0x11, 0, 0, 28, 0); ! 7318: - if(n = s_io(0, &cmd, 28, &ret, 0, err)) ! 7319: - return(n); ! 7320: - } ! 7321: - return(0); ! 7322: -} ! 7323: //GO.SYSIN DD scsi/wren/w6mode.c ! 7324: echo scsi/nohup.out 1>&2 ! 7325: sed 's/.//' >scsi/nohup.out <<'//GO.SYSIN DD scsi/nohup.out' ! 7326: //GO.SYSIN DD scsi/nohup.out ! 7327: echo shipped 1>&2 ! 7328: sed 's/.//' >shipped <<'//GO.SYSIN DD shipped' ! 7329: //GO.SYSIN DD shipped ! 7330: echo sym.c 1>&2 ! 7331: sed 's/.//' >sym.c <<'//GO.SYSIN DD sym.c' ! 7332: -#include <libc.h> ! 7333: -#include "worm.h" ! 7334: -#include "sym.h" ! 7335: - ! 7336: -#define NHASH 20011 /* prime please */ ! 7337: -#define HASHMUL 79L /* this is a good value */ ! 7338: -static Symtab *hash[NHASH]; ! 7339: -int sym_mem_fail; ! 7340: - ! 7341: -syminit() ! 7342: -{ ! 7343: - register Symtab **s, *ss; ! 7344: - ! 7345: - for(s = hash; s < &hash[NHASH]; s++){ ! 7346: - for(ss = *s; ss; ss = ss->next) ! 7347: - free((char *)ss); ! 7348: - *s = 0; ! 7349: - } ! 7350: -} ! 7351: - ! 7352: -void * ! 7353: -symlook(sym, space, install) ! 7354: - char *sym; ! 7355: - void *install; ! 7356: -{ ! 7357: - register long h; ! 7358: - register char *p; ! 7359: - register Symtab *s; ! 7360: - ! 7361: - for(p = sym, h = space; *p; h += *p++) ! 7362: - h *= HASHMUL; ! 7363: - if(h < 0) ! 7364: - h = ~h; ! 7365: - h %= NHASH; ! 7366: - for(s = hash[h]; s; s = s->next) ! 7367: - if((s->space == space) && (strcmp(s->name, sym) == 0)){ ! 7368: - if(install) ! 7369: - s->value = install; ! 7370: - return(s->value); ! 7371: - } ! 7372: - if(install){ ! 7373: - s = (Symtab *)malloc((unsigned)sizeof(Symtab)); ! 7374: - if(s == 0){ ! 7375: - sym_mem_fail++; ! 7376: - return(install); ! 7377: - } ! 7378: - s->space = space; ! 7379: - s->name = sym; ! 7380: - s->value = install; ! 7381: - s->next = hash[h]; ! 7382: - hash[h] = s; ! 7383: - } ! 7384: - return(install); ! 7385: -} ! 7386: - ! 7387: -symdel(sym, space) ! 7388: - char *sym; ! 7389: -{ ! 7390: - register long h; ! 7391: - register char *p; ! 7392: - register Symtab *s, *ls; ! 7393: - ! 7394: - for(p = sym, h = space; *p; h += *p++) ! 7395: - h *= HASHMUL; ! 7396: - if(h < 0) ! 7397: - h = ~h; ! 7398: - h %= NHASH; ! 7399: - for(s = hash[h], ls = 0; s; ls = s, s = s->next) ! 7400: - if((s->space == space) && (strcmp(s->name, sym) == 0)){ ! 7401: - if(ls) ! 7402: - ls->next = s->next; ! 7403: - else ! 7404: - hash[h] = s->next; ! 7405: - free((char *)s); ! 7406: - } ! 7407: -} ! 7408: - ! 7409: -symtraverse(space, fn) ! 7410: - void (*fn)(); ! 7411: -{ ! 7412: - register Symtab **s, *ss, *next; ! 7413: - ! 7414: - for(s = hash; s < &hash[NHASH]; s++) ! 7415: - for(ss = *s; ss; ss = next){ ! 7416: - next = ss->next; ! 7417: - if(ss->space == space) ! 7418: - (*fn)(ss->value); ! 7419: - } ! 7420: -} ! 7421: - ! 7422: -symstat() ! 7423: -{ ! 7424: - register Symtab **s, *ss; ! 7425: - int n[NHASH]; ! 7426: - register i, j; ! 7427: - int tot; ! 7428: - double d; ! 7429: - ! 7430: - for(i = 0; i < NHASH; i++) ! 7431: - n[i] = 0; ! 7432: - for(s = hash; s < &hash[NHASH]; s++){ ! 7433: - for(j = 0, ss = *s; ss; ss = ss->next) ! 7434: - j++; ! 7435: - n[j]++; ! 7436: - } ! 7437: - Fprint(1, "N=%ld mul=%ld\n", NHASH, HASHMUL); ! 7438: - for(i = 0, d = 0, tot = 0; i < NHASH; i++){ ! 7439: - if(n[i]) Fprint(1, "%d of length %d\n", n[i], i); ! 7440: - d += n[i]*i; ! 7441: - if(i) tot += n[i]; ! 7442: - } ! 7443: - Fprint(1, "ave len = %g\n", d/tot); ! 7444: -} ! 7445: - ! 7446: -symdump(sym, space) ! 7447: - char *sym; ! 7448: -{ ! 7449: - register long h; ! 7450: - register char *p; ! 7451: - register Symtab *s; ! 7452: - ! 7453: - for(p = sym, h = space; *p; h += *p++) ! 7454: - h *= HASHMUL; ! 7455: - if(h < 0) ! 7456: - h = ~h; ! 7457: - h %= NHASH; ! 7458: - print("symdump(%s):\n", sym); ! 7459: - for(s = hash[h]; s; s = s->next) ! 7460: - print("\t%s: space=%d value=%ld\n", s->name, s->space, s->value); ! 7461: -} ! 7462: //GO.SYSIN DD sym.c ! 7463: echo sym.h 1>&2 ! 7464: sed 's/.//' >sym.h <<'//GO.SYSIN DD sym.h' ! 7465: -typedef struct Symtab ! 7466: -{ ! 7467: - short space; ! 7468: - char *name; ! 7469: - void *value; ! 7470: - struct Symtab *next; ! 7471: -} Symtab; ! 7472: -extern void *symlook(); ! 7473: - ! 7474: -#define S_INODE 1 ! 7475: -#define S_UID 2 ! 7476: -#define S_GID 3 ! 7477: -#define S_FAIL 4 /* fetch */ ! 7478: -#define S_TOGO 5 /* wormy */ ! 7479: - ! 7480: -extern int sym_mem_fail; ! 7481: //GO.SYSIN DD sym.h ! 7482: echo t0 1>&2 ! 7483: sed 's/.//' >t0 <<'//GO.SYSIN DD t0' ! 7484: - ! 7485: -static Inode *inodes; ! 7486: -static long ip; ! 7487: -static long ninodes = 0; ! 7488: -static char *nameb; ! 7489: -static long np; ! 7490: -static long nnameb = 0; ! 7491: -static long nblocks; ! 7492: -#define IINC 1024 ! 7493: -#define NINC (64*IINC) ! 7494: - ! 7495: -ininit() ! 7496: -{ ! 7497: - if(nnameb == 0){ ! 7498: - nameb = malloc((unsigned)(nnameb = NINC)); ! 7499: - if(nameb == 0){ ! 7500: - fprint(2, "wmv: malloc fail, %d bytes\n", nnameb); ! 7501: - exit(1); ! 7502: - } ! 7503: - } ! 7504: - np = 0; ! 7505: - if(ninodes == 0){ ! 7506: - inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC)); ! 7507: - if(inodes == 0){ ! 7508: - fprint(2, "wmv: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 7509: - exit(1); ! 7510: - } ! 7511: - } ! 7512: - ip = 0; ! 7513: -} ! 7514: - ! 7515: -inadd(s, i) ! 7516: - Superblock *s; ! 7517: - register Inode *i; ! 7518: -{ ! 7519: - register long len; ! 7520: - ! 7521: - len = strlen(i->name.n)+1; ! 7522: - if(np+len > nnameb){ ! 7523: - while(np+len > nnameb) ! 7524: - nnameb += NINC; ! 7525: - nameb = realloc(nameb, (unsigned)nnameb); ! 7526: - if(nameb == 0){ ! 7527: - fprint(2, "wmv: realloc fail, %d bytes\n", nnameb); ! 7528: - exit(1); ! 7529: - } ! 7530: - } ! 7531: - strcpy(nameb+np, i->name.n); ! 7532: - i->name.o = np; ! 7533: - np += len; ! 7534: - if(ip == ninodes){ ! 7535: - ninodes += IINC; ! 7536: - inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode)); ! 7537: - if(inodes == 0){ ! 7538: - fprint(2, "wmv: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 7539: - exit(1); ! 7540: - } ! 7541: - } ! 7542: - inodes[ip++] = *i; ! 7543: -} ! 7544: - ! 7545: -inwrite(s) ! 7546: - Superblock *s; ! 7547: -{ ! 7548: - char *e; ! 7549: - ! 7550: - if(e = lkwri(s, inodes, ip, nameb, np, 0L)){ ! 7551: - fprint(2, "%s\n", e); ! 7552: - return(1); ! 7553: - } ! 7554: - return(0); ! 7555: -} ! 7556: //GO.SYSIN DD t0 ! 7557: echo t1 1>&2 ! 7558: sed 's/.//' >t1 <<'//GO.SYSIN DD t1' ! 7559: - ! 7560: -static Inode *inodes; ! 7561: -static long ip; ! 7562: -static long ninodes = 0; ! 7563: -static char *nameb; ! 7564: -static long np; ! 7565: -static long nnameb = 0; ! 7566: -static long nblocks; ! 7567: -#define IINC 1024 ! 7568: -#define NINC (64*IINC) ! 7569: - ! 7570: -ininit() ! 7571: -{ ! 7572: - if(nnameb == 0) ! 7573: - nameb = malloc((unsigned)(nnameb = NINC)); ! 7574: - np = 0; ! 7575: - if(ninodes == 0) ! 7576: - inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC)); ! 7577: - ip = 0; ! 7578: -} ! 7579: - ! 7580: -inadd(s, i) ! 7581: - Superblock *s; ! 7582: - register Inode *i; ! 7583: -{ ! 7584: - register long len; ! 7585: - ! 7586: - len = strlen(i->name.n)+1; ! 7587: - if(np+len > nnameb){ ! 7588: - while(np+len > nnameb) ! 7589: - nnameb += NINC; ! 7590: - nameb = realloc(nameb, (unsigned)nnameb); ! 7591: - } ! 7592: - strcpy(nameb+np, i->name.n); ! 7593: - i->name.o = np; ! 7594: - np += len; ! 7595: - if(ip == ninodes){ ! 7596: - ninodes += IINC; ! 7597: - inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode)); ! 7598: - } ! 7599: - inodes[ip++] = *i; ! 7600: - return(0); ! 7601: -} ! 7602: - ! 7603: -inwrite(s) ! 7604: - Superblock *s; ! 7605: -{ ! 7606: - char *e; ! 7607: - ! 7608: - if(e = lkwri(s, inodes, ip, nameb, np, 0L)){ ! 7609: - fprint(2, "%s\n", e); ! 7610: - bad = 1; ! 7611: - return; ! 7612: - } ! 7613: -} ! 7614: //GO.SYSIN DD t1 ! 7615: echo timenow.c 1>&2 ! 7616: sed 's/.//' >timenow.c <<'//GO.SYSIN DD timenow.c' ! 7617: -#include <libc.h> ! 7618: -#include "worm.h" ! 7619: - ! 7620: -char * ! 7621: -timenow() ! 7622: -{ ! 7623: - long tim; ! 7624: - char *tims; ! 7625: - ! 7626: - time(&tim); ! 7627: - tims = ctime(&tim); ! 7628: - tims[19] = 0; ! 7629: - return(tims); ! 7630: -} ! 7631: //GO.SYSIN DD timenow.c ! 7632: echo vlink.c 1>&2 ! 7633: sed 's/.//' >vlink.c <<'//GO.SYSIN DD vlink.c' ! 7634: -#include <libc.h> ! 7635: -#include "worm.h" ! 7636: -#include "sym.h" ! 7637: - ! 7638: -char * ! 7639: -lkopi(s, blk, doinodes) ! 7640: - register Superblock *s; ! 7641: - long blk; ! 7642: -{ ! 7643: - register Inode *i; ! 7644: - short fd = s->fd; ! 7645: - char *b; ! 7646: - long nb; ! 7647: - char *nameb; ! 7648: - Inode *inodes; ! 7649: - static char buf[64]; ! 7650: - ! 7651: - if((b = malloc(s->blocksize)) == 0){ ! 7652: - sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 7653: - return(buf); ! 7654: - } ! 7655: - numinodes = 0; ! 7656: - numnamechars = 0; ! 7657: - for(;;){ ! 7658: - if(s->magic != SMAGIC){ ! 7659: - fprint(2, "bad Superblock at %ld\n", blk); ! 7660: - exit(1); ! 7661: - } ! 7662: - if(s->ninodes){ ! 7663: - numinodes += s->ninodes; ! 7664: - numnamechars += s->ninochars; ! 7665: - } ! 7666: - if(doinodes && s->ninodes){ ! 7667: - nb = (s->ninodes+IPERB-1)/IPERB; ! 7668: - inodes = (Inode *)malloc((unsigned)(s->blocksize*nb)); ! 7669: - if(inodes == 0){ ! 7670: - sprint(buf, "inode malloc(%d) fail, sbrk=%d\n", ! 7671: - (s->blocksize*nb), sbrk(0)); ! 7672: - return(buf); ! 7673: - } ! 7674: - Seek(s, s->binodes); ! 7675: - if(Read(s, (char *)inodes, nb)) ! 7676: - goto skip; ! 7677: - nb = (s->ninochars+s->blocksize-1)/s->blocksize; ! 7678: - nameb = malloc((unsigned)(s->blocksize*nb)); ! 7679: - if(nameb == 0){ ! 7680: - sprint(buf, "name buffer malloc(%d) fail, sbrk=%d\n", ! 7681: - (s->blocksize*nb), sbrk(0)); ! 7682: - return(buf); ! 7683: - } ! 7684: - if(Read(s, nameb, nb)) ! 7685: - goto skip; ! 7686: - for(nb = 0, i = inodes; nb < s->ninodes; nb++, i++){ ! 7687: - i->name.n = i->name.o+nameb; ! 7688: - if(i->block < 0) ! 7689: - (void)symdel(i->name.n, S_INODE); ! 7690: - else ! 7691: - (void)symlook(i->name.n, S_INODE, (void *)i); ! 7692: - } ! 7693: - if(sym_mem_fail){ ! 7694: - sprint(buf, "%d inode malloc fails: %d, %d sbrk=%d\n", ! 7695: - sym_mem_fail, numinodes, s->ninodes, sbrk(0)); ! 7696: - return(buf); ! 7697: - } ! 7698: - } ! 7699: - skip: ! 7700: - blk = s->nextsb; ! 7701: - Seek(s, blk); ! 7702: - if(Read(s, b, 1L)) ! 7703: - break; ! 7704: - *s = *((Superblock *)b); ! 7705: - s->fd = fd; ! 7706: - if(s->myblock == 0) ! 7707: - s->myblock = blk; ! 7708: - } ! 7709: - free(b); ! 7710: - return((char *)0); ! 7711: -} ! 7712: - ! 7713: -char * ! 7714: -lkwri(s, i, ni, c, nc, ndata) ! 7715: - Superblock *s; ! 7716: - Inode *i; ! 7717: - long ni, nc, ndata; ! 7718: - char *c; ! 7719: -{ ! 7720: - char *b; ! 7721: - long blk; ! 7722: - static char buf[256]; ! 7723: - long ib, ic; ! 7724: - ! 7725: - s->ninodes = ni; ! 7726: - s->ninochars = nc; ! 7727: - ib = (ni+IPERB-1)/IPERB; ! 7728: - ic = (nc+s->blocksize-1)/s->blocksize; ! 7729: - if(ndata+ib+ic+1 > s->nfree) /* one for superblock */ ! 7730: - return("not enough space for new files"); ! 7731: - s->binodes = s->nextffree+ndata; ! 7732: - s->nextffree += ndata+ib+ic; ! 7733: - s->nfree -= ndata+ib+ic; ! 7734: - ! 7735: - if((b = malloc(s->blocksize)) == 0){ ! 7736: - sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 7737: - return(buf); ! 7738: - } ! 7739: - blk = s->nextsb; ! 7740: - s->nextsb = s->nextffree++; ! 7741: - s->nfree--; ! 7742: - s->myblock = blk; ! 7743: - time(&s->ctime); ! 7744: - memset(b, 0, s->blocksize); ! 7745: - *((Superblock *)b) = *s; ! 7746: - Seek(s, blk); ! 7747: - if(Write(s, b, 1L)){ ! 7748: - sprint(buf, "couldn't write superblock at %d", blk); ! 7749: - return(buf); ! 7750: - } ! 7751: - free(b); ! 7752: - Seek(s, s->binodes); ! 7753: - if(Write(s, (char *)i, ib)) ! 7754: - return("write1 error"); ! 7755: - if(Write(s, c, ic)) ! 7756: - return("write2 error"); ! 7757: - return((char *)0); ! 7758: -} ! 7759: - ! 7760: - ! 7761: -char * ! 7762: -lkwsb(s) ! 7763: - Superblock *s; ! 7764: -{ ! 7765: - char *b; ! 7766: - long blk; ! 7767: - static char buf[64]; ! 7768: - ! 7769: - if((b = malloc(s->blocksize)) == 0){ ! 7770: - sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 7771: - return(buf); ! 7772: - } ! 7773: - blk = s->nextsb; ! 7774: - s->nextsb = s->nextffree++; ! 7775: - s->nfree--; ! 7776: - memset(b, 0, s->blocksize); ! 7777: - s->myblock = blk; ! 7778: - *((Superblock *)b) = *s; ! 7779: - Seek(s, blk); ! 7780: - if(Write(s, b, 1L)) ! 7781: - return("couldn't write superblock"); ! 7782: - free(b); ! 7783: - return((char *)0); ! 7784: -} ! 7785: - ! 7786: -Inode * ! 7787: -vinodefn(s) ! 7788: - char *s; ! 7789: -{ ! 7790: - return((Inode *)symlook(s, S_INODE, (void *)0)); ! 7791: -} ! 7792: - ! 7793: -void ! 7794: -vtraverse(fn) ! 7795: - void (*fn)(); ! 7796: -{ ! 7797: - symtraverse(S_INODE, fn); ! 7798: -} ! 7799: //GO.SYSIN DD vlink.c ! 7800: echo wbtree.c 1>&2 ! 7801: sed 's/.//' >wbtree.c <<'//GO.SYSIN DD wbtree.c' ! 7802: -#include <libc.h> ! 7803: -#include "worm.h" ! 7804: -#include "sym.h" ! 7805: -#include <sys/types.h> ! 7806: -#include <sys/stat.h> ! 7807: -#include <fio.h> ! 7808: - ! 7809: -Inode **inos; ! 7810: -long nino; ! 7811: -int fdT, fdF; ! 7812: -char *inonames; ! 7813: -char *timenow(); ! 7814: -char *tmp = "/tmp"; ! 7815: - ! 7816: -cmp(a, b) ! 7817: - Inode **a, **b; ! 7818: -{ ! 7819: - return(strcmp((*a)->name.n, (*b)->name.n)); ! 7820: -} ! 7821: - ! 7822: -main(argc, argv) ! 7823: - char **argv; ! 7824: -{ ! 7825: - Superblock s, news; ! 7826: - char *e; ! 7827: - char *dev = "/dev/worm0"; ! 7828: - int c, fd; ! 7829: - char dbname[256]; ! 7830: - extern char *optarg; ! 7831: - extern int optind; ! 7832: - void blkfn(); ! 7833: - ! 7834: - while((c = getopt(argc, argv, "t:f:")) != -1) ! 7835: - switch(c) ! 7836: - { ! 7837: - case 'f': dev = optarg; break; ! 7838: - case 't': tmp = optarg; break; ! 7839: - case '?': usage(); ! 7840: - } ! 7841: - dev = mapdev(dev); ! 7842: - if(optind != argc-1) ! 7843: - usage(); ! 7844: - sprint(dbname, "%s/cbt%d", tmp, getpid()); ! 7845: - fd = dbinit(dbname); ! 7846: - if((s.fd = open(dev, 2)) < 0){ ! 7847: - perror(dev); ! 7848: - exit(1); ! 7849: - } ! 7850: - if(e = openinode(&s, DO_INODE|SPIN_DOWN)){ ! 7851: - fprint(2, "%s: %s\n", dev, e); ! 7852: - exit(1); ! 7853: - } ! 7854: - if(strcmp(argv[optind], s.vol_id)){ ! 7855: - fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id); ! 7856: - exit(1); ! 7857: - } ! 7858: - if((inos = (Inode **)malloc(sizeof(inos[0])*(int)numinodes)) == 0){ ! 7859: - fprint(2, "out of memory (%d inodes, %d bytes)\n", numinodes, sizeof(inos[0])*(int)numinodes); ! 7860: - exit(1); ! 7861: - } ! 7862: - nino = 0; ! 7863: - inodetraverse(blkfn); ! 7864: - fprint(2, "%s: sorting inodes\n", timenow()); ! 7865: - qsort((char *)inos, (int)nino, sizeof(inos[0]), cmp); ! 7866: - news = s; ! 7867: - news.ninodes = nino; ! 7868: - creatdb(fd, dbname, &news); /* fills in nF, nT, inochars */ ! 7869: - c = NBLKS(&news, news.nF)+NBLKS(&news, news.nT)+NBLKS(&news, news.ninochars); ! 7870: - if(c > news.nfree){ ! 7871: - fprint(2, "%s: sorry, not enough blocks; %d+%d+%d>%d\n", ! 7872: - NBLKS(&news, news.nF), NBLKS(&news, news.nT), ! 7873: - NBLKS(&news, news.ninochars), news.nfree); ! 7874: - exit(1); ! 7875: - } ! 7876: - Seek(&s, news.binodes = s.nextffree); ! 7877: - fdwrite(&s, fdF, (int)news.nF); ! 7878: - fdwrite(&s, fdT, (int)news.nT); ! 7879: - memwrite(&s, inonames, (int)news.ninochars); ! 7880: - /* set up link ptrs so that zeroing block zero undoes btreeing */ ! 7881: - s.nfree -= c; ! 7882: - s.nextffree += c; ! 7883: - s.ninodes = 0; ! 7884: - if(e = lkwsb(&s)) ! 7885: - fprint(2, "%s\n", e); ! 7886: - news.nextffree = s.nextffree; ! 7887: - news.nfree = s.nfree; ! 7888: - news.myblock = 0; ! 7889: - news.version = VBTREE; ! 7890: - news.nextsb = s.myblock; ! 7891: - time(&news.ctime); ! 7892: - Seek(&s, news.myblock); ! 7893: - free((char *)inos); ! 7894: - e = malloc(news.blocksize); ! 7895: - if(e == 0){ ! 7896: - fprint(2, "wbtree: unbelievable malloc fail of %d\n", news.blocksize); ! 7897: - exit(1); ! 7898: - } ! 7899: - memset(e, 0, news.blocksize); ! 7900: - *((Superblock *)e) = news; ! 7901: - Write(&s, e, 1L); ! 7902: - exit(0); ! 7903: -} ! 7904: - ! 7905: -usage() ! 7906: -{ ! 7907: - fprint(2, "Usage: worm btree [-fdevice] [-ttmpdir] vol_id\n"); ! 7908: - exit(2); ! 7909: -} ! 7910: - ! 7911: -dbinit(name) ! 7912: - char *name; ! 7913: -{ ! 7914: - char buf[256]; ! 7915: - struct stat sbuf; ! 7916: - int pid, pip[2]; ! 7917: - ! 7918: - fprint(2, "%s: init db '%s'\n", timenow(), name); ! 7919: - sprint(buf, "cbt creat %s", name); ! 7920: - if(system(buf)) ! 7921: - exit(1); ! 7922: - pipe(pip); ! 7923: - pid = fork(); ! 7924: - if(pid < 0){ ! 7925: - perror("fork"); ! 7926: - exit(1); ! 7927: - } ! 7928: - if(pid){ ! 7929: - close(pip[0]); ! 7930: - return(pip[1]); ! 7931: - } else { ! 7932: - close(pip[1]); ! 7933: - dup2(pip[0], 0); ! 7934: - close(pip[0]); ! 7935: - execl("/usr/lib/btree/btbuild", "btbuild", name, 0); ! 7936: - perror("execl"); ! 7937: - exit(1); ! 7938: - return(0); ! 7939: - } ! 7940: -} ! 7941: - ! 7942: -creatdb(fd, name, s) ! 7943: - char *name; ! 7944: - Superblock *s; /* fills in nF, nT, inochars */ ! 7945: -{ ! 7946: - char buf[256]; ! 7947: - struct stat sbuf; ! 7948: - int status, i; ! 7949: - short n; ! 7950: - char *np; ! 7951: - ! 7952: - fprint(2, "%s: creating db '%s'\n", timenow(), name); ! 7953: - inonames = malloc((int)numnamechars+1024); ! 7954: - if(inonames == 0){ ! 7955: - sprint(buf, "malloc(%d) namechars failed", numnamechars+1024); ! 7956: - perror(buf); ! 7957: - exit(1); ! 7958: - } ! 7959: - Finit(fd, (char *)0); ! 7960: - np = inonames; ! 7961: - for(i = 0; i < nino; i++){ ! 7962: - n = strlen(inos[i]->name.n); ! 7963: - Fwrite(fd, (char *)&n, 2L); ! 7964: - Fwrite(fd, inos[i]->name.n, (long)n); ! 7965: - memcpy(np, inos[i]->name.n, n+1); ! 7966: - inos[i]->name.o = np - inonames; ! 7967: - np += n+1; ! 7968: - n = sizeof(Inode); ! 7969: - Fwrite(fd, (char *)&n, 2L); ! 7970: - Fwrite(fd, (char *)inos[i], (long)n); ! 7971: - } ! 7972: - s->ninochars = np-inonames; ! 7973: - Fflush(fd); ! 7974: - close(fd); ! 7975: - if(wait(&status) < 0){ ! 7976: - perror("wbtree: wait"); ! 7977: - exit(1); ! 7978: - } ! 7979: - if(status){ ! 7980: - fprint(2, "wbtree: bad status %d from btbuild\n", status); ! 7981: - exit(1); ! 7982: - } ! 7983: - sprint(buf, "%s.F", name); ! 7984: - if(((fdF = open(buf, 0)) < 0) || (fstat(fdF, &sbuf) < 0)){ ! 7985: - perror(buf); ! 7986: - exit(1); ! 7987: - } ! 7988: - unlink(buf); ! 7989: - s->nF = sbuf.st_size; ! 7990: - sprint(buf, "%s.T", name); ! 7991: - if(((fdT = open(buf, 0)) < 0) || (fstat(fdT, &sbuf) < 0)){ ! 7992: - perror(buf); ! 7993: - exit(1); ! 7994: - } ! 7995: - unlink(buf); ! 7996: - s->nT = sbuf.st_size; ! 7997: - fprint(2, "%s: db done\n", timenow()); ! 7998: -} ! 7999: - ! 8000: -void ! 8001: -blkfn(i) ! 8002: - Inode *i; ! 8003: -{ ! 8004: - inos[nino++] = i; ! 8005: -} ! 8006: - ! 8007: -fdwrite(s, fd, cnt) ! 8008: - Superblock *s; ! 8009: -{ ! 8010: - char b[BIGBLOCK]; ! 8011: - int n; ! 8012: - ! 8013: - lseek(fd, 0L, 0); ! 8014: - while(cnt >= sizeof b){ ! 8015: - n = read(fd, b, sizeof b); ! 8016: - if(n != sizeof b){ ! 8017: - perror("short read"); ! 8018: - exit(3); ! 8019: - } ! 8020: - Write(s, b, NBLKS(s, sizeof b)); ! 8021: - cnt -= sizeof b; ! 8022: - } ! 8023: - if(cnt){ ! 8024: - if(read(fd, b, cnt) != cnt){ ! 8025: - perror("short read"); ! 8026: - exit(4); ! 8027: - } ! 8028: - memset(b+cnt, 0, sizeof b - cnt); ! 8029: - Write(s, b, NBLKS(s, cnt)); ! 8030: - } ! 8031: -} ! 8032: - ! 8033: -memwrite(s, base, cnt) ! 8034: - Superblock *s; ! 8035: - char *base; ! 8036: -{ ! 8037: - int chunk = (BIGBLOCK/1024)*s->blocksize; ! 8038: - ! 8039: - while(cnt >= chunk){ ! 8040: - Write(s, base, NBLKS(s, chunk)); ! 8041: - cnt -= chunk; ! 8042: - base += chunk; ! 8043: - } ! 8044: - if(cnt) ! 8045: - Write(s, base, NBLKS(s, cnt)); ! 8046: -} ! 8047: - ! 8048: -char * ! 8049: -timenow() ! 8050: -{ ! 8051: - long tim; ! 8052: - char *tims; ! 8053: - ! 8054: - time(&tim); ! 8055: - tims = ctime(&tim); ! 8056: - tims[19] = 0; ! 8057: - return(tims); ! 8058: -} ! 8059: //GO.SYSIN DD wbtree.c ! 8060: echo wcat.c 1>&2 ! 8061: sed 's/.//' >wcat.c <<'//GO.SYSIN DD wcat.c' ! 8062: -#include <libc.h> ! 8063: -#include "sym.h" ! 8064: -#include "worm.h" ! 8065: - ! 8066: -main(argc, argv) ! 8067: - char **argv; ! 8068: -{ ! 8069: - Superblock s; ! 8070: - char *e; ! 8071: - Inode *i; ! 8072: - int c; ! 8073: - char *dev = "/dev/worm0"; ! 8074: - extern char *optarg; ! 8075: - extern int optind; ! 8076: - ! 8077: - while((c = getopt(argc, argv, "f:")) != -1) ! 8078: - switch(c) ! 8079: - { ! 8080: - case 'f': dev = optarg; break; ! 8081: - case '?': usage(); ! 8082: - } ! 8083: - if(optind+2 != argc) ! 8084: - usage(); ! 8085: - dev = mapdev(dev); ! 8086: - if((s.fd = open(dev, 0)) < 0){ ! 8087: - perror(dev); ! 8088: - exit(1); ! 8089: - } ! 8090: - if(e = openinode(&s, DO_INODE|SPIN_DOWN)){ ! 8091: - fprint(2, "%s: %s\n", dev, e); ! 8092: - exit(1); ! 8093: - } ! 8094: - if(strcmp(s.vol_id, argv[optind])){ ! 8095: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id); ! 8096: - exit(1); ! 8097: - } ! 8098: - if(i = inodeof(argv[++optind])) ! 8099: - c = pr(&s, i); ! 8100: - else { ! 8101: - fprint(2, "wcat: can't find %s\n", argv[optind]); ! 8102: - c = 1; ! 8103: - } ! 8104: - exit(c); ! 8105: -} ! 8106: - ! 8107: -usage() ! 8108: -{ ! 8109: - fprint(2, "Usage: worm cat [-fdevice] vol_id file\n"); ! 8110: - exit(1); ! 8111: -} ! 8112: - ! 8113: -pr(s, i) ! 8114: - Superblock *s; ! 8115: - register Inode *i; ! 8116: -{ ! 8117: - char b[BIGBLOCK]; ! 8118: - register long len, n; ! 8119: - long nb; ! 8120: - int fd; ! 8121: - ! 8122: - fd = 1; ! 8123: - nb = sizeof b / s->blocksize; ! 8124: - Seek(s, i->block); ! 8125: - for(n = i->nbytes, len = nb*s->blocksize; n > 0;){ ! 8126: - if(len > n){ ! 8127: - len = n; ! 8128: - nb = (len+s->blocksize-1)/s->blocksize; ! 8129: - } ! 8130: - Read(s, b, nb); ! 8131: - if(write(fd, b, (int)len) != len){ ! 8132: - perror("write"); ! 8133: - return(1); ! 8134: - } ! 8135: - n -= len; ! 8136: - } ! 8137: - close(fd); ! 8138: - return(0); ! 8139: -} ! 8140: //GO.SYSIN DD wcat.c ! 8141: echo wcopy.c 1>&2 ! 8142: sed 's/.//' >wcopy.c <<'//GO.SYSIN DD wcopy.c' ! 8143: -#include <libc.h> ! 8144: -#include <fio.h> ! 8145: -#include <sys/types.h> ! 8146: -#include <sys/stat.h> ! 8147: -#include <signal.h> ! 8148: -#include "worm.h" ! 8149: - ! 8150: -long minfree = 40000; ! 8151: -int verbose = 0; ! 8152: - ! 8153: -main(argc, argv) ! 8154: - char **argv; ! 8155: -{ ! 8156: - Superblock in, out; ! 8157: - char *e; ! 8158: - char buf[4096]; ! 8159: - int n; ! 8160: - long lineno; ! 8161: - int c; ! 8162: - char *dev = "/dev/worm0"; ! 8163: - long tfiles, tbytes; ! 8164: - int eof; ! 8165: - char first[4096]; ! 8166: - extern char *optarg; ! 8167: - extern int optind; ! 8168: - ! 8169: - argout = argv[0]; ! 8170: - while((c = getopt(argc, argv, "vm:f:")) != -1) ! 8171: - switch(c) ! 8172: - { ! 8173: - case 'f': dev = optarg; break; ! 8174: - case 'm': minfree = atol(optarg); break; ! 8175: - case 'v': verbose = 1; break; ! 8176: - case '?': usage(); ! 8177: - } ! 8178: - ! 8179: - if(optind+3 != argc) ! 8180: - usage(); ! 8181: - e = mapdev(argv[optind+1]); ! 8182: - if((out.fd = open(e, 2)) < 0){ ! 8183: - perror(e); ! 8184: - exit(1); ! 8185: - } ! 8186: - if(e = openinode(&out, SPIN_DOWN)){ ! 8187: - fprint(2, "%s: %s\n", *argv, e); ! 8188: - exit(1); ! 8189: - } ! 8190: - if(strcmp(out.vol_id, argv[optind+2])){ ! 8191: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind+2], out.vol_id); ! 8192: - exit(1); ! 8193: - } ! 8194: - if(out.version != VLINK){ ! 8195: - fprint(2, "%s: can't write on a b-tree disk\n", out.vol_id); ! 8196: - exit(1); ! 8197: - } ! 8198: - dev = mapdev(dev); ! 8199: - if((in.fd = open(dev, 2)) < 0){ ! 8200: - perror(*argv); ! 8201: - exit(1); ! 8202: - } ! 8203: - if(e = openinode(&in, DO_INODE|SPIN_DOWN)){ ! 8204: - fprint(2, "%s: %s\n", *argv, e); ! 8205: - exit(1); ! 8206: - } ! 8207: - if(strcmp(in.vol_id, argv[optind])){ ! 8208: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], in.vol_id); ! 8209: - exit(1); ! 8210: - } ! 8211: - for(n = 1; n <= NSIG; n++) ! 8212: - signal(n, SIG_IGN); ! 8213: - eof = 0; ! 8214: - tfiles = tbytes = 0; ! 8215: - lineno = 0; ! 8216: - while(!eof){ ! 8217: - /* flush seperater lines */ ! 8218: - while(e = Frdline(0)){ ! 8219: - lineno++; ! 8220: - if(*e) ! 8221: - break; ! 8222: - } ! 8223: - if(e == 0) ! 8224: - break; ! 8225: - ininit(); ! 8226: - proc(&out, e); ! 8227: - strncpy(first, e, sizeof first); ! 8228: - if(out.nfree < minfree){ ! 8229: - fprint(2, "wcopy: disk %s full before copying group '%s' line %d\n", ! 8230: - out.vol_id, first, lineno); ! 8231: - exit(1); ! 8232: - } ! 8233: - while(e = Frdline(0)){ ! 8234: - lineno++; ! 8235: - if(*e == 0) ! 8236: - break; ! 8237: - proc(&out, e); ! 8238: - } ! 8239: - if(e == 0) ! 8240: - eof = 1; ! 8241: - if(bad) ! 8242: - exit(1); ! 8243: - nfiles = nbytes = 0; ! 8244: - blkdone = 0; ! 8245: - inwrite(&out, &in); ! 8246: - if(bad) ! 8247: - exit(1); ! 8248: - if(verbose) ! 8249: - fprint(1, "%s group('%s' %d files, %.6fMB) done\n", ! 8250: - timenow(), first, nfiles, nbytes/1e6); ! 8251: - tfiles += nfiles; ! 8252: - tbytes += nbytes; ! 8253: - } ! 8254: - if(verbose) ! 8255: - fprint(1, "%s total: %d files, %.6fMB\n", timenow(), tfiles, tbytes/1e6); ! 8256: - exit(0); ! 8257: -} ! 8258: - ! 8259: -usage() ! 8260: -{ ! 8261: - fprint(2, "Usage: worm copy [-v] [-m minfree] [-f src_dev] src_id dest_dev dest_id < files\n"); ! 8262: - exit(1); ! 8263: -} ! 8264: - ! 8265: -proc(s, file) ! 8266: - Superblock *s; ! 8267: - char *file; ! 8268: -{ ! 8269: - struct stat sbuf; ! 8270: - unsigned short mode; ! 8271: - Inode i; ! 8272: - Inode *srci; ! 8273: - ! 8274: - if((srci = inodeof(file)) == 0){ ! 8275: - fprint(2, "can't find file '%s'\n", file); ! 8276: - return; ! 8277: - } ! 8278: - memset((char *)&i, 0, sizeof(i)); ! 8279: - i = *srci; ! 8280: - i.block = 0; ! 8281: - nbytes += i.nbytes; ! 8282: - if(inadd(s, &i)) ! 8283: - bad = 1; ! 8284: -} ! 8285: - ! 8286: -writeout(dest, i, blk, src) ! 8287: - Superblock *dest, *src; ! 8288: - Inode *i; ! 8289: - long *blk; ! 8290: -{ ! 8291: - char b[BIGBLOCK]; ! 8292: - Inode *srci; ! 8293: - long n, len, blen; ! 8294: - char *name; ! 8295: - ! 8296: - n = (i->nbytes+dest->blocksize-1)/dest->blocksize; ! 8297: - *blk += n; ! 8298: - blkdone += n; ! 8299: - blen = sizeof b/dest->blocksize; ! 8300: - len = blen*dest->blocksize; ! 8301: - nbytes += i->nbytes; ! 8302: - nfiles++; ! 8303: - name = i->name.n; ! 8304: - srci = inodeof(name); ! 8305: - Seek(src, srci->block); ! 8306: - for(n = i->nbytes; n > len; n -= len){ ! 8307: - if(Read(src, b, blen)){ ! 8308: - out: ! 8309: - fprint(2, "read problem: seek=%d n=%d blen=%d len=%d; ", ! 8310: - srci->block, n, blen, len); ! 8311: - perror(name); ! 8312: - bad = 1; ! 8313: - return; ! 8314: - } ! 8315: - if(Write(dest, b, blen)){ ! 8316: -fprint(2, "nb=%d, n=%d len=%d blen=%d\n", i->nbytes, n, len, blen); ! 8317: - perror("data write"); ! 8318: - exit(1); ! 8319: - } ! 8320: - } ! 8321: - if(n){ ! 8322: - n += dest->blocksize-1; ! 8323: - n /= dest->blocksize; ! 8324: - if(Read(src, b, n)) ! 8325: - goto out; ! 8326: - if(Write(dest, b, n)){ ! 8327: - perror("data write"); ! 8328: - exit(1); ! 8329: - } ! 8330: - } ! 8331: -} ! 8332: //GO.SYSIN DD wcopy.c ! 8333: echo wdir.c 1>&2 ! 8334: sed 's/.//' >wdir.c <<'//GO.SYSIN DD wdir.c' ! 8335: -#include <libc.h> ! 8336: -#include "worm.h" ! 8337: -#include "sym.h" ! 8338: -#include <sys/types.h> ! 8339: -#include <sys/stat.h> ! 8340: - ! 8341: -char *dumpdir(); ! 8342: -int verbose = 0; ! 8343: - ! 8344: -main(argc, argv) ! 8345: - char **argv; ! 8346: -{ ! 8347: - Superblock s, news; ! 8348: - char *e; ! 8349: - char *dev = "/dev/worm0"; ! 8350: - int update = 0; ! 8351: - int c; ! 8352: - char buf[1024]; ! 8353: - extern char *optarg; ! 8354: - extern int optind; ! 8355: - void blkfn(); ! 8356: - ! 8357: - while((c = getopt(argc, argv, "f:vu")) != -1) ! 8358: - switch(c) ! 8359: - { ! 8360: - case 'f': dev = optarg; break; ! 8361: - case 'u': update = 1; break; ! 8362: - case 'v': verbose = 1; break; ! 8363: - case '?': usage(); ! 8364: - } ! 8365: - dev = mapdev(dev); ! 8366: - if(optind != argc-1) ! 8367: - usage(); ! 8368: - if((s.fd = open(dev, 2)) < 0){ ! 8369: - perror(dev); ! 8370: - exit(1); ! 8371: - } ! 8372: - if(e = openinode(&s, SPIN_DOWN)){ ! 8373: - fprint(2, "%s: %s\n", dev, e); ! 8374: - exit(2); ! 8375: - } ! 8376: - if(s.version != VBTREE){ ! 8377: - fprint(2, "%s is not a btree!\n", s.vol_id); ! 8378: - exit(2); ! 8379: - } ! 8380: - if(strcmp(argv[optind], s.vol_id)){ ! 8381: - fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id); ! 8382: - exit(1); ! 8383: - } ! 8384: - if(e = dumpdir(&s, update)){ ! 8385: - fprint(2, "%s: %s\n", dev, e); ! 8386: - exit(2); ! 8387: - } ! 8388: - sprint(buf, "/usr/worm/tmp/%s", s.vol_id); ! 8389: - unlink(buf); ! 8390: - exit(0); ! 8391: -} ! 8392: - ! 8393: -usage() ! 8394: -{ ! 8395: - fprint(2, "Usage: dir [-fdevice] -v] [-u] vol_id\n"); ! 8396: - exit(2); ! 8397: -} ! 8398: - ! 8399: -char * ! 8400: -dumpdir(s, update) ! 8401: - register Superblock *s; ! 8402: -{ ! 8403: - char *b; ! 8404: - static char buf[64]; ! 8405: - char name[256], buf1[256]; ! 8406: - ! 8407: - if((b = malloc(s->blocksize)) == 0){ ! 8408: - sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 8409: - return(buf); ! 8410: - } ! 8411: - numinodes = s->ninodes; ! 8412: - sprint(name, "/usr/worm/dirs/%s", s->vol_id); ! 8413: - Seek(s, s->binodes); ! 8414: - sprint(buf1, "%s.F", name); ! 8415: - copyout(s, buf1, s->nF, update, verbose); ! 8416: - sprint(buf1, "%s.T", name); ! 8417: - copyout(s, buf1, s->nT, update, verbose); ! 8418: - sprint(buf1, "%s.I", name); ! 8419: - copyout(s, buf1, s->ninochars, update, verbose); ! 8420: - free(b); ! 8421: - return((char *)0); ! 8422: -} ! 8423: //GO.SYSIN DD wdir.c ! 8424: echo wild 1>&2 ! 8425: sed 's/.//' >wild <<'//GO.SYSIN DD wild' ! 8426: //GO.SYSIN DD wild ! 8427: echo wls.c 1>&2 ! 8428: sed 's/.//' >wls.c <<'//GO.SYSIN DD wls.c' ! 8429: -#include <libc.h> ! 8430: -#include "worm.h" ! 8431: -#include "sym.h" ! 8432: -#include <sys/types.h> ! 8433: -#include <sys/stat.h> ! 8434: -#include <pwd.h> ! 8435: -#include <grp.h> ! 8436: - ! 8437: -int lflag = 0; ! 8438: -int bflag = 0; ! 8439: - ! 8440: -main(argc, argv) ! 8441: - char **argv; ! 8442: -{ ! 8443: - Superblock s; ! 8444: - register Inode *i; ! 8445: - char *e; ! 8446: - char *dev = "/dev/worm0"; ! 8447: - int c; ! 8448: - extern char *optarg; ! 8449: - extern int optind; ! 8450: - void pr(); ! 8451: - ! 8452: - while((c = getopt(argc, argv, "lbf:")) != -1) ! 8453: - switch(c) ! 8454: - { ! 8455: - case 'f': dev = optarg; break; ! 8456: - case 'l': lflag = 1; break; ! 8457: - case 'b': bflag = 1; break; ! 8458: - case '?': usage(); ! 8459: - } ! 8460: - dev = mapdev(dev); ! 8461: - if((s.fd = open(dev, 0)) < 0){ ! 8462: - perror(dev); ! 8463: - exit(1); ! 8464: - } ! 8465: - if(e = openinode(&s, DO_INODE|SPIN_DOWN)){ ! 8466: - fprint(2, "%s: %s\n", dev, e); ! 8467: - exit(1); ! 8468: - } ! 8469: - c = 0; ! 8470: - if(optind < argc) ! 8471: - while(optind < argc){ ! 8472: - if(i = inodeof(argv[optind])) ! 8473: - pr(i); ! 8474: - else { ! 8475: - Fprint(2, "%s not found\n", argv[optind]); ! 8476: - c = 1; ! 8477: - } ! 8478: - optind++; ! 8479: - } ! 8480: - else ! 8481: - inodetraverse(pr); ! 8482: - exit(c); ! 8483: -} ! 8484: - ! 8485: -char * ! 8486: -suid(n) ! 8487: -{ ! 8488: - static char buf[24]; ! 8489: - struct passwd *p; ! 8490: - char *s; ! 8491: - ! 8492: - sprint(buf, "#%d", n); ! 8493: - if(s = (char *)symlook(buf, S_UID, (void *)0)) ! 8494: - strcpy(buf, s); ! 8495: - else { ! 8496: - s = strdup(buf); ! 8497: - if(p = getpwuid(n)) ! 8498: - strcpy(buf, p->pw_name); ! 8499: - (void)symlook(s, S_UID, (void *)strdup(buf)); ! 8500: - } ! 8501: - return(buf); ! 8502: -} ! 8503: - ! 8504: -char * ! 8505: -sgid(n) ! 8506: -{ ! 8507: - static char buf[24]; ! 8508: - struct group *g; ! 8509: - char *s; ! 8510: - ! 8511: - sprint(buf, "#%d", n); ! 8512: - if(s = (char *)symlook(buf, S_GID, (void *)0)) ! 8513: - strcpy(buf, s); ! 8514: - else { ! 8515: - s = strdup(buf); ! 8516: - if(g = getgrgid(n)) ! 8517: - strcpy(buf, g->gr_name); ! 8518: - (void)symlook(s, S_GID, (void *)strdup(buf)); ! 8519: - } ! 8520: - return(buf); ! 8521: -} ! 8522: - ! 8523: -mode(n, sx) ! 8524: -{ ! 8525: - Fputc(1, (n&4)? 'r':'-'); ! 8526: - Fputc(1, (n&2)? 'w':'-'); ! 8527: - Fputc(1, (n&1)? sx:'-'); ! 8528: -} ! 8529: - ! 8530: -void ! 8531: -pr(i) ! 8532: - register Inode *i; ! 8533: -{ ! 8534: - char *s; ! 8535: - ! 8536: - if(lflag){ ! 8537: - Fputc(1, ((i->mode&S_IFMT) == S_IFDIR)? 'd':'-'); ! 8538: - mode(i->mode>>6, ((i->mode&S_IFMT) == S_ISUID)? 's':'x'); ! 8539: - mode(i->mode>>3, ((i->mode&S_IFMT) == S_ISGID)? 's':'x'); ! 8540: - mode(i->mode, 'x'); ! 8541: - Fputc(1, ((i->mode&S_IFMT) == S_IFLNK)? 'L':' '); ! 8542: - s = ctime(&i->ctime); ! 8543: - s += 4; ! 8544: - s[12] = 0; ! 8545: - Fprint(1, "%2d%8s%7s %6ld %s %s\n", 1, suid(i->uid), sgid(i->gid), ! 8546: - i->nbytes, s, i->name.n); ! 8547: - return; ! 8548: - } ! 8549: - if(bflag) ! 8550: - Fprint(1, "%s\t%ld\n", i->name.n, i->block); ! 8551: - else ! 8552: - Fprint(1, "%s\n", i->name.n); ! 8553: -} ! 8554: - ! 8555: -usage() ! 8556: -{ ! 8557: - fprint(2, "Usage: worm ls [-fdevice] [-l] [-b] [files ...]\n"); ! 8558: - exit(2); ! 8559: -} ! 8560: //GO.SYSIN DD wls.c ! 8561: echo wmkfs.c 1>&2 ! 8562: sed 's/.//' >wmkfs.c <<'//GO.SYSIN DD wmkfs.c' ! 8563: -#include <libc.h> ! 8564: -#include "worm.h" ! 8565: -#include <sys/types.h> ! 8566: -#include <sys/udaioc.h> ! 8567: - ! 8568: -usage() ! 8569: -{ ! 8570: - fprint(2, "Usage: worm mkfs [-fdevice] [-ccomments] [-bblksize] [-nnblks] [-vnewvol_id] vol_id\n"); ! 8571: - fprint(2, "e.g. worm mkfs -f1 -c\"512x512x24 movies\" tdmovies1a\n"); ! 8572: - exit(1); ! 8573: -} ! 8574: - ! 8575: -main(argc, argv) ! 8576: - char **argv; ! 8577: -{ ! 8578: - Superblock s, os; ! 8579: - char *b; ! 8580: - long sb; ! 8581: - int c; ! 8582: - char *volid; ! 8583: - char *dev = "/dev/worm0"; ! 8584: - char *nblks = 0; ! 8585: - char *bsize = 0; ! 8586: - char *nvolid = 0; ! 8587: - char *comments = 0; ! 8588: - char *e; ! 8589: - int virgin; ! 8590: - extern optind; ! 8591: - extern char *optarg; ! 8592: - ! 8593: - while((c = getopt(argc, argv, "f:n:b:c:v:")) != -1) ! 8594: - switch(c) ! 8595: - { ! 8596: - case 'b': bsize = optarg; break; ! 8597: - case 'c': comments = optarg; break; ! 8598: - case 'f': dev = optarg; break; ! 8599: - case 'n': nblks = optarg; break; ! 8600: - case 'v': nvolid = optarg; break; ! 8601: - case '?': usage(); ! 8602: - } ! 8603: - if(optind != argc-1) ! 8604: - usage(); ! 8605: - volid = argv[optind]; ! 8606: - if(strlen(volid) > sizeof(s.vol_id)-1) ! 8607: - volid[sizeof(s.vol_id)-1] = 0; ! 8608: - c = volid[strlen(volid)-1]; ! 8609: - if((c != 'a') && (c != 'b')){ ! 8610: - if(nvolid == 0){ ! 8611: - fprint(2, "worm mkfs: vol_id '%s' must end in 'a' or 'b'\n", volid); ! 8612: - exit(1); ! 8613: - } ! 8614: - fprint(2, "worm mkfs: warning: vol_id '%s' should end in 'a' or 'b'\n", volid); ! 8615: - } ! 8616: - if(nvolid){ ! 8617: - if(strlen(nvolid) > sizeof(s.vol_id)-1) ! 8618: - nvolid[sizeof(s.vol_id)-1] = 0; ! 8619: - c = nvolid[strlen(nvolid)-1]; ! 8620: - if((c != 'a') && (c != 'b')){ ! 8621: - fprint(2, "worm mkfs: vol_id '%s' must end in 'a' or 'b'\n", nvolid); ! 8622: - exit(1); ! 8623: - } ! 8624: - } ! 8625: - dev = mapdev(dev); ! 8626: - if((s.fd = open(dev, 2)) < 0){ ! 8627: - perror(dev); ! 8628: - exit(1); ! 8629: - } ! 8630: - /* ! 8631: - now, do we read the current superblock or make one up? ! 8632: - this is hard to answer in general, push the answer off to virginal() ! 8633: - */ ! 8634: - virgin = virginal(&s); ! 8635: - if(virgin){ ! 8636: - setdefaults(&s, nblks); ! 8637: - if((s.blocksize < 512) || (s.blocksize%512)){ ! 8638: - fprint(2, "worm mkfs: bad blocksize '%s'\n", bsize); ! 8639: - exit(1); ! 8640: - } ! 8641: - strcpy(s.vol_id, volid); ! 8642: - } else { ! 8643: - if(strcmp(volid, s.vol_id)){ ! 8644: - fprint(2, "worm mkfs: volid mismatch; expected %s, got %s\n", ! 8645: - volid, s.vol_id); ! 8646: - exit(1); ! 8647: - } ! 8648: - } ! 8649: - /* set any new parameters */ ! 8650: - if(nvolid) ! 8651: - strcpy(s.vol_id, nvolid); ! 8652: - if(bsize) ! 8653: - s.blocksize = atoi(bsize); ! 8654: - if(s.blocksize < 512){ ! 8655: - fprint(2, "wormmkfs: bad nblocks = '%s'\n", nblks); ! 8656: - exit(1); ! 8657: - } ! 8658: - if(s.blocksize % sizeof(Inode)){ ! 8659: - fprint(2, "worm mkfs: sizeof(Inode)=%d does not divide blocksize %d\n", ! 8660: - sizeof(Inode), s.blocksize); ! 8661: - exit(1); ! 8662: - } ! 8663: - if(comments){ ! 8664: - if(strlen(comments) > sizeof(s.comment)-1) ! 8665: - comments[sizeof(s.comment)-1] = 0; ! 8666: - strcpy(s.comment, comments); ! 8667: - } ! 8668: - /* only check if we are changing it */ ! 8669: - if(nblks && !virgin){ ! 8670: - s.nblocks = atoi(nblks); ! 8671: - s.nfree = s.nblocks - s.nextffree; ! 8672: - if(s.nfree <= 1){ ! 8673: - fprint(2, "worm mkfs: new nblocks(%d) is too small\n", s.nblocks); ! 8674: - exit(1); ! 8675: - } ! 8676: - } ! 8677: - /* now allocate the new superblock */ ! 8678: - sb = s.nextsb; ! 8679: - s.myblock = sb; ! 8680: - s.nextsb = sb+1; ! 8681: - s.nextffree = sb+2; ! 8682: - s.nfree -= 1; ! 8683: - s.ninodes = 0; ! 8684: - s.ninochars = 0; ! 8685: - s.binodes = 0; ! 8686: - time(&s.ctime); ! 8687: - /* write it */ ! 8688: - if((b = malloc(s.blocksize)) == 0){ ! 8689: - fprint(2, "worm mkfs: cannot malloc buffer %d bytes\n", s.blocksize); ! 8690: - exit(1); ! 8691: - } ! 8692: - memset(b, 0, s.blocksize); ! 8693: - memcpy(b, (char *)&s, sizeof(s)); ! 8694: - Seek(&s, sb); ! 8695: - if(Write(&s, b, 1L)) ! 8696: - exit(1); ! 8697: - ioctl(s.fd, UIOSPDW); ! 8698: - exit(0); ! 8699: -} ! 8700: - ! 8701: -setdefaults(s, nblks) ! 8702: - Superblock *s; ! 8703: - char *nblks; ! 8704: -{ ! 8705: - struct ud_unit sz; ! 8706: - char buf[1024]; ! 8707: - ! 8708: - s->magic = SMAGIC; ! 8709: - s->blocksize = 1024; ! 8710: - s->version = VLINK; ! 8711: - if(nblks){ ! 8712: - s->nblocks = atoi(nblks); ! 8713: - if(s->nblocks <= 2){ ! 8714: - fprint(2, "worm mkfs: nblocks(%d) too small\n", s->nblocks); ! 8715: - exit(1); ! 8716: - } ! 8717: - } else { ! 8718: - read(s->fd, buf, sizeof buf); /* ignore error */ ! 8719: - if(ioctl(s->fd, UIOCHAR, &sz) >= 0){ ! 8720: - switch(sz.radsize) ! 8721: - { /* note below figures/2 used in scsi/volid.c */ ! 8722: - case 3275999: /* sony 12in clv single density */ ! 8723: - s->nblocks = 1600000; ! 8724: - break; ! 8725: - case 6551999: /* sony 12in clv double density */ ! 8726: - s->nblocks = 3250000; ! 8727: - break; ! 8728: - default: ! 8729: - fprint(2, "worm mkfs: unknown size %d\n", sz.radsize); ! 8730: - exit(1); ! 8731: - } ! 8732: - } else ! 8733: - s->nblocks = 1600000; ! 8734: - fprint(2, "worm mkfs: using disk size %d\n", s->nblocks); ! 8735: - } ! 8736: - s->zero = 0; ! 8737: - s->nfree = s->nblocks-1; ! 8738: - s->nextffree = 0; ! 8739: - s->nextsb = 1; ! 8740: - s->vol_id[0] = 0; ! 8741: - s->comment[0] = 0; ! 8742: - s->myblock = 0; ! 8743: - s->ctime = 0; ! 8744: -} ! 8745: - ! 8746: -virginal(s) ! 8747: - Superblock *s; ! 8748: -{ ! 8749: - char buf[1024]; ! 8750: - static char zeros[1024]; ! 8751: - long sb; ! 8752: - char *e; ! 8753: - extern char *getenv(); ! 8754: - ! 8755: - if(e = getenv("WORMZERO")) ! 8756: - sb = atoi(e); ! 8757: - else ! 8758: - sb = 1; ! 8759: - bigseek(s->fd, sb, 1024, 0); ! 8760: - errno = 0; ! 8761: - if(read(s->fd, buf, 1024) == 1024) ! 8762: - goto valid; ! 8763: - if((errno != ENXIO) && (errno != 0) && memcmp(buf, zeros, 1024)) ! 8764: - goto invalid; ! 8765: - errno = 0; ! 8766: - if(read(s->fd, buf, 1024) == 1024){ /* try next block */ ! 8767: -valid: ! 8768: - if(e = openinode(s, SPIN_DOWN)){ ! 8769: - fprint(2, "worm mkfs: %s\n", e); ! 8770: - exit(1); ! 8771: - } ! 8772: - return(0); ! 8773: - } else { ! 8774: - if((errno == ENXIO) || (errno == 0) || (memcmp(buf, zeros, 1024) == 0)) ! 8775: - return(1); ! 8776: -invalid: ! 8777: - perror("worm mkfs: I/O errors probing for superblock"); ! 8778: - exit(1); ! 8779: - } ! 8780: -} ! 8781: //GO.SYSIN DD wmkfs.c ! 8782: echo wmount.c 1>&2 ! 8783: sed 's/.//' >wmount.c <<'//GO.SYSIN DD wmount.c' ! 8784: -#include <libc.h> ! 8785: -#include "worm.h" ! 8786: - ! 8787: -main(argc, argv) ! 8788: - char **argv; ! 8789: -{ ! 8790: - Superblock s; ! 8791: - char *e, *vol_id = 0, *vol; ! 8792: - char *dev = "/dev/worm0"; ! 8793: - int c; ! 8794: - long nf = 0; ! 8795: - char wflag[512]; ! 8796: - char buf[512]; ! 8797: - int i; ! 8798: - extern char *optarg; ! 8799: - extern int optind; ! 8800: - extern long atol(); ! 8801: - ! 8802: - wflag[0] = 0; ! 8803: - while((c = getopt(argc, argv, "w:")) != -1) ! 8804: - switch(c) ! 8805: - { ! 8806: - case 'w': sprint(wflag, "-w%s", optarg); break; ! 8807: - case '?': usage(); ! 8808: - } ! 8809: - if(optind < argc){ ! 8810: - vol_id = argv[optind++]; ! 8811: - if(optind != argc) ! 8812: - usage(); ! 8813: - } ! 8814: - if(vol_id == 0){ ! 8815: - for(i = 0; ; i++){ ! 8816: - sprint(buf, "%d", i); ! 8817: - dev = mapdev(buf); ! 8818: - if((s.fd = open(dev, 0)) < 0){ ! 8819: - if(errno == ENOENT) ! 8820: - break; ! 8821: - if(errno == ENXIO) ! 8822: - continue; ! 8823: - perror(dev); ! 8824: - exit(2); ! 8825: - } ! 8826: - if(e = openinode(&s, SPIN_DOWN)){ ! 8827: - fprint(2, "%s: %s\n", dev, e); ! 8828: - exit(2); ! 8829: - } ! 8830: - print("%s: %s\n", dev, s.vol_id); ! 8831: - close(s.fd); ! 8832: - } ! 8833: - exit(0); ! 8834: - } ! 8835: - if(isjukebox()){ ! 8836: - jload(vol_id, wflag); ! 8837: - exit(0); ! 8838: - } ! 8839: - { ! 8840: - for(i = 0; ; i++){ ! 8841: - sprint(buf, "%d", i); ! 8842: - dev = mapdev(buf); ! 8843: - if((s.fd = open(dev, 0)) < 0){ ! 8844: - if(errno == ENOENT) ! 8845: - break; ! 8846: - if(errno == ENXIO) ! 8847: - continue; ! 8848: - perror(dev); ! 8849: - exit(2); ! 8850: - } ! 8851: - if(e = openinode(&s, SPIN_DOWN)){ ! 8852: - fprint(2, "%s: %s\n", dev, e); ! 8853: - exit(2); ! 8854: - } ! 8855: - if(strcmp(vol_id, s.vol_id) == 0){ ! 8856: - print("%s\n", buf); ! 8857: - exit(0); ! 8858: - } ! 8859: - close(s.fd); ! 8860: - } ! 8861: - } ! 8862: - fprint(2, "worm mount: couldn't find %s\n", vol_id); ! 8863: - exit(1); ! 8864: -} ! 8865: - ! 8866: -usage() ! 8867: -{ ! 8868: - print("Usage: worm mount [-wsecs] [vol_id]\n"); ! 8869: - exit(2); ! 8870: -} ! 8871: - ! 8872: -/* ! 8873: - return zero if there isn't a jukebox ! 8874: -*/ ! 8875: -isjukebox() ! 8876: -{ ! 8877: - return(access("/dev/scsi", 6) == 0); ! 8878: -} ! 8879: - ! 8880: -/* ! 8881: - secs is the number of seconds to wait ! 8882: -*/ ! 8883: -jload(vol, secs) ! 8884: - char *vol, *secs; ! 8885: -{ ! 8886: - if(*secs) ! 8887: - execlp("/usr/lib/worm/jukebox", "jukebox", secs, "-m", vol, (char *)0); ! 8888: - else ! 8889: - execlp("/usr/lib/worm/jukebox", "jukebox", "-m", vol, (char *)0); ! 8890: - perror("execlp(/usr/lib/worm/jukebox)"); ! 8891: - exit(1); ! 8892: -} ! 8893: //GO.SYSIN DD wmount.c ! 8894: echo wmv.c 1>&2 ! 8895: sed 's/.//' >wmv.c <<'//GO.SYSIN DD wmv.c' ! 8896: -#include <libc.h> ! 8897: -#include "worm.h" ! 8898: -#include "sym.h" ! 8899: -#include <sys/types.h> ! 8900: -#include <sys/stat.h> ! 8901: -#include <pwd.h> ! 8902: -#include <grp.h> ! 8903: -#include <signal.h> ! 8904: - ! 8905: -int lflag = 0; ! 8906: -int bflag = 0; ! 8907: - ! 8908: -main(argc, argv) ! 8909: - char **argv; ! 8910: -{ ! 8911: - Superblock s; ! 8912: - register Inode *i; ! 8913: - Inode newi; ! 8914: - char *e; ! 8915: - char *dev = "/dev/worm0"; ! 8916: - int c; ! 8917: - extern char *optarg; ! 8918: - extern int optind; ! 8919: - void pr(); ! 8920: - ! 8921: - while((c = getopt(argc, argv, "lbf:")) != -1) ! 8922: - switch(c) ! 8923: - { ! 8924: - case 'f': dev = optarg; break; ! 8925: - case 'l': lflag = 1; break; ! 8926: - case 'b': bflag = 1; break; ! 8927: - case '?': usage(); ! 8928: - } ! 8929: - dev = mapdev(dev); ! 8930: - if((s.fd = open(dev, 2)) < 0){ ! 8931: - perror(dev); ! 8932: - exit(1); ! 8933: - } ! 8934: - if(e = openinode(&s, DO_INODE|SPIN_DOWN)){ ! 8935: - fprint(2, "%s: %s\n", dev, e); ! 8936: - exit(1); ! 8937: - } ! 8938: - if(optind != argc-3) ! 8939: - usage(); ! 8940: - if(strcmp(s.vol_id, argv[optind])){ ! 8941: - fprint(2, "worm mv: vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id); ! 8942: - exit(1); ! 8943: - } ! 8944: - optind++; ! 8945: - if((i = inodeof(argv[optind])) == 0){ ! 8946: - Fprint(2, "%s not found\n", argv[optind]); ! 8947: - exit(1); ! 8948: - } ! 8949: - optind++; ! 8950: - if(strlen(argv[optind]) < 1){ ! 8951: - Fprint(2, "worm mv: destination name is null\n"); ! 8952: - exit(1); ! 8953: - } ! 8954: - for(c = 1; c <= NSIG; c++) ! 8955: - signal(c, SIG_IGN); ! 8956: - ininit(); ! 8957: - newi = *i; ! 8958: - i->block = -1; ! 8959: - inadd(&s, i); ! 8960: - newi.name.n = argv[optind]; ! 8961: - inadd(&s, &newi); ! 8962: - if(inwrite(&s)) ! 8963: - exit(1); ! 8964: - exit(0); ! 8965: -} ! 8966: - ! 8967: -usage() ! 8968: -{ ! 8969: - fprint(2, "Usage: worm mv [-fdevice] vol_id from to\n"); ! 8970: - exit(2); ! 8971: -} ! 8972: - ! 8973: -static Inode *inodes; ! 8974: -static long ip; ! 8975: -static long ninodes = 0; ! 8976: -static char *nameb; ! 8977: -static long np; ! 8978: -static long nnameb = 0; ! 8979: -static long nblocks; ! 8980: -#define IINC 1024 ! 8981: -#define NINC (64*IINC) ! 8982: - ! 8983: -ininit() ! 8984: -{ ! 8985: - if(nnameb == 0){ ! 8986: - nameb = malloc((unsigned)(nnameb = NINC)); ! 8987: - if(nameb == 0){ ! 8988: - fprint(2, "wmv: malloc fail, %d bytes\n", nnameb); ! 8989: - exit(1); ! 8990: - } ! 8991: - } ! 8992: - np = 0; ! 8993: - if(ninodes == 0){ ! 8994: - inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC)); ! 8995: - if(inodes == 0){ ! 8996: - fprint(2, "wmv: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 8997: - exit(1); ! 8998: - } ! 8999: - } ! 9000: - ip = 0; ! 9001: -} ! 9002: - ! 9003: -inadd(s, i) ! 9004: - Superblock *s; ! 9005: - register Inode *i; ! 9006: -{ ! 9007: - register long len; ! 9008: - ! 9009: - len = strlen(i->name.n)+1; ! 9010: - if(np+len > nnameb){ ! 9011: - while(np+len > nnameb) ! 9012: - nnameb += NINC; ! 9013: - nameb = realloc(nameb, (unsigned)nnameb); ! 9014: - if(nameb == 0){ ! 9015: - fprint(2, "wmv: realloc fail, %d bytes\n", nnameb); ! 9016: - exit(1); ! 9017: - } ! 9018: - } ! 9019: - strcpy(nameb+np, i->name.n); ! 9020: - i->name.o = np; ! 9021: - np += len; ! 9022: - if(ip == ninodes){ ! 9023: - ninodes += IINC; ! 9024: - inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode)); ! 9025: - if(inodes == 0){ ! 9026: - fprint(2, "wmv: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 9027: - exit(1); ! 9028: - } ! 9029: - } ! 9030: - inodes[ip++] = *i; ! 9031: -} ! 9032: - ! 9033: -inwrite(s) ! 9034: - Superblock *s; ! 9035: -{ ! 9036: - char *e; ! 9037: - ! 9038: - if(e = lkwri(s, inodes, ip, nameb, np, 0L)){ ! 9039: - fprint(2, "%s\n", e); ! 9040: - return(1); ! 9041: - } ! 9042: - return(0); ! 9043: -} ! 9044: //GO.SYSIN DD wmv.c ! 9045: echo woffline.c 1>&2 ! 9046: sed 's/.//' >woffline.c <<'//GO.SYSIN DD woffline.c' ! 9047: -#include <libc.h> ! 9048: -#include "worm.h" ! 9049: -#include <sys/types.h> ! 9050: -#include <sys/udaioc.h> ! 9051: - ! 9052: -main(argc, argv) ! 9053: - char **argv; ! 9054: -{ ! 9055: - Superblock s; ! 9056: - char *vol_id = 0; ! 9057: - char buf[1024]; ! 9058: - char *dev = "/dev/worm0"; ! 9059: - int c; ! 9060: - extern char *optarg; ! 9061: - extern int optind; ! 9062: - ! 9063: - while((c = getopt(argc, argv, "f:")) != -1) ! 9064: - switch(c) ! 9065: - { ! 9066: - case 'f': dev = optarg; break; ! 9067: - case '?': usage(); ! 9068: - } ! 9069: - if(optind != argc) ! 9070: - usage(); ! 9071: - dev = mapdev(dev); ! 9072: - if((s.fd = open(dev, 2)) < 0){ ! 9073: - if(!vol_id) ! 9074: - perror(dev); ! 9075: - exit(2); ! 9076: - } ! 9077: - /* have to read to make ioctl work */ ! 9078: - lseek(s.fd, 1024L, 0); ! 9079: - read(s.fd, buf, sizeof buf); ! 9080: - if(ioctl(s.fd, UIOSPDW) < 0){ ! 9081: - perror("ioctl"); ! 9082: - exit(2); ! 9083: - } ! 9084: - exit(0); ! 9085: -} ! 9086: - ! 9087: -usage() ! 9088: -{ ! 9089: - print("Usage: worm offline [-fdevice]\n"); ! 9090: - exit(2); ! 9091: -} ! 9092: //GO.SYSIN DD woffline.c ! 9093: echo worm.h 1>&2 ! 9094: sed 's/.//' >worm.h <<'//GO.SYSIN DD worm.h' ! 9095: -#include <errno.h> ! 9096: - ! 9097: -#define SMAGIC 0x21746967 ! 9098: -#define DMAGIC 0x3A746967 ! 9099: - ! 9100: -typedef struct Superblock ! 9101: -{ ! 9102: - long magic; /* magic number for Superblock */ ! 9103: - unsigned short blocksize; /* physical size of blocks */ ! 9104: - short version; /* type of superblock */ ! 9105: - long nblocks; /* number of blocks on device */ ! 9106: - long zero; /* first logical data block */ ! 9107: - long nfree; /* number of free blocks */ ! 9108: - long ninodes; /* number of inodes */ ! 9109: - long ninochars; /* number of bytes of inode names */ ! 9110: - long binodes; /* start of inodes */ ! 9111: - long nextffree; /* next free file block */ ! 9112: - long nextsb; /* next superblock */ ! 9113: - short fd; /* fildes for device (in core) */ ! 9114: - char vol_id[128]; /* name the disk can be mounted as */ ! 9115: - char comment[128]; /* comments */ ! 9116: - long myblock; /* where this superblock is */ ! 9117: - long nF; /* bytes for .F (VBTREE) */ ! 9118: - long nT; /* bytes for .T (VBTREE) */ ! 9119: - long ctime; /* create time for this superblock */ ! 9120: -} Superblock; ! 9121: - ! 9122: -typedef struct Inode ! 9123: -{ ! 9124: - long magic; /* magic number for Dirent */ ! 9125: - long block; /* starting block of file */ ! 9126: - long nbytes; /* bytes in file */ ! 9127: - long ctime; /* creation time */ ! 9128: - union { ! 9129: - char *n; /* core - name */ ! 9130: - long o; /* disk - offset into chars block */ ! 9131: - } name; /* filename */ ! 9132: - long pad1; /* to 32 bytes */ ! 9133: - short mode; /* a la stat */ ! 9134: - short uid; /* owner */ ! 9135: - short gid; /* owner */ ! 9136: - short pad2; /* to 32 bytes */ ! 9137: -} Inode; ! 9138: -#define IPERB (s->blocksize/sizeof(Inode)) ! 9139: - ! 9140: -extern char *openinode(), *lkwri(), *lkwsb(); ! 9141: -extern char *mapdev(); ! 9142: -extern Inode *(*inodefn)(); ! 9143: -extern void (*traversefn)(); ! 9144: -extern long numinodes; ! 9145: -extern long numnamechars; ! 9146: -extern char *timenow(); ! 9147: - ! 9148: -#define inodeof(s) (*inodefn)(s) ! 9149: -#define inodetraverse(fn) (*traversefn)(fn) ! 9150: - ! 9151: -#define VLINK 1 /* linked list version */ ! 9152: -#define VBTREE 2 /* cbt */ ! 9153: - ! 9154: -#define NBLKS(s, x) (long)(((s)->blocksize-1+(x))/(s)->blocksize) ! 9155: - ! 9156: -/* ! 9157: - flags for openinode ! 9158: -*/ ! 9159: -#define DO_INODE 1 ! 9160: -#define SPIN_DOWN 2 ! 9161: - ! 9162: -#define BIGBLOCK (60*1024L) /* max read/write */ ! 9163: - ! 9164: -/* ! 9165: - in.c declarations ! 9166: -*/ ! 9167: - ! 9168: -extern int bad; ! 9169: -extern long nbytes; ! 9170: -extern long blkdone; ! 9171: -extern long nfiles; ! 9172: -extern char *argout; ! 9173: //GO.SYSIN DD worm.h ! 9174: echo wpoke.c 1>&2 ! 9175: sed 's/.//' >wpoke.c <<'//GO.SYSIN DD wpoke.c' ! 9176: -#include <libc.h> ! 9177: -#include "worm.h" ! 9178: - ! 9179: -main(argc, argv) ! 9180: - char **argv; ! 9181: -{ ! 9182: - Superblock s; ! 9183: - char *e, *vol_id = 0; ! 9184: - char *dev = "/dev/worm0"; ! 9185: - int c; ! 9186: - long nf = 0; ! 9187: - int vflag = 0; ! 9188: - Superblock ss; ! 9189: - extern char *optarg; ! 9190: - extern int optind; ! 9191: - extern long atol(); ! 9192: - ! 9193: - while((c = getopt(argc, argv, "vF:f:")) != -1) ! 9194: - switch(c) ! 9195: - { ! 9196: - case 'f': dev = optarg; break; ! 9197: - case 'F': nf = atol(optarg); break; ! 9198: - case 'v': vflag = 1; break; ! 9199: - case '?': usage(); ! 9200: - } ! 9201: - if(optind < argc){ ! 9202: - vol_id = argv[optind++]; ! 9203: - if(optind != argc) ! 9204: - usage(); ! 9205: - } ! 9206: - dev = mapdev(dev); ! 9207: - if((s.fd = open(dev, 0)) < 0){ ! 9208: - perror(dev); ! 9209: - exit(2); ! 9210: - } ! 9211: - if(read(s.fd, &ss, sizeof ss) != sizeof ss){ ! 9212: - if(errno == ENXIO) ! 9213: - print("unwritten block zero\n"); ! 9214: - else ! 9215: - perror("block zero"); ! 9216: - } else { ! 9217: - if(ss.magic == SMAGIC){ ! 9218: - print("appears to be a good superblock at zero\n"); ! 9219: - exit(0); ! 9220: - } else if(ss.magic == 0){ ! 9221: - print("appears to be a zero'ed block at zero.\n"); ! 9222: - } else ! 9223: - print("ignoring bogus block at zero\n"); ! 9224: - } ! 9225: - vlink(s.fd, 1); ! 9226: - exit(0); ! 9227: -} ! 9228: - ! 9229: -usage() ! 9230: -{ ! 9231: - print("Usage: worm poke [-v] [-fdevice] [-Fnfree] [vol_id]\n"); ! 9232: - exit(2); ! 9233: -} ! 9234: - ! 9235: -vlink(fd, blk) ! 9236: -{ ! 9237: - Superblock s; ! 9238: - int i, n; ! 9239: - ! 9240: - while(blk < 1650000){ ! 9241: -loop: ! 9242: -print("reading sb at %d\n", blk); ! 9243: - bigseek(fd, blk, 1024, 0); ! 9244: - if(read(fd, &s, sizeof s) == sizeof s){ ! 9245: - if(s.magic == SMAGIC){ ! 9246: - blk = s.nextsb; ! 9247: - continue; ! 9248: - } ! 9249: - print("apparent garbage at supposed superblock@%ld\n", blk); ! 9250: - } else { ! 9251: - print("bad read at blk %ld, errno=%d\n", blk, errno); ! 9252: - lseek(fd, 1024, 1); ! 9253: - blk++; ! 9254: - } ! 9255: - for(i = 0; i < 50; i++){ ! 9256: - n = read(fd, &s, sizeof s); ! 9257: - if(n < 0){ ! 9258: - lseek(fd, 1024, 1); ! 9259: - continue; ! 9260: - } ! 9261: - if((n == sizeof s) && (s.magic == SMAGIC)){ ! 9262: - blk += i; ! 9263: - print("after error, skipped %d blocks to apparent superblock at %ld\n", i, blk); ! 9264: - goto loop; ! 9265: - } ! 9266: - } ! 9267: - print("after error, no superblock after %d tries\n", i); ! 9268: - blk += i; ! 9269: - } ! 9270: -} ! 9271: //GO.SYSIN DD wpoke.c ! 9272: echo wread.c 1>&2 ! 9273: sed 's/.//' >wread.c <<'//GO.SYSIN DD wread.c' ! 9274: -#include <libc.h> ! 9275: -#include <fio.h> ! 9276: -#include "sym.h" ! 9277: -#include "worm.h" ! 9278: -#include <sys/types.h> ! 9279: -#include <sys/stat.h> ! 9280: - ! 9281: -char *prefix = ""; ! 9282: -int dflag = 0; ! 9283: -int quiet = 0; ! 9284: -int mflag = 0; ! 9285: - ! 9286: -main(argc, argv) ! 9287: - char **argv; ! 9288: -{ ! 9289: - Superblock s; ! 9290: - char *e; ! 9291: - int c; ! 9292: - char *dev = "/dev/worm0"; ! 9293: - extern char *optarg; ! 9294: - extern int optind; ! 9295: - ! 9296: - while((c = getopt(argc, argv, "dmf:p:s")) != -1) ! 9297: - switch(c) ! 9298: - { ! 9299: - case 'd': dflag = 1; break; ! 9300: - case 'f': dev = optarg; break; ! 9301: - case 'm': mflag = 1; break; ! 9302: - case 'p': prefix = optarg; break; ! 9303: - case 's': quiet = 1; break; ! 9304: - case '?': usage(); ! 9305: - } ! 9306: - if(optind >= argc) ! 9307: - usage(); ! 9308: - dev = mapdev(dev); ! 9309: - if((s.fd = open(dev, 0)) < 0){ ! 9310: - perror(dev); ! 9311: - exit(1); ! 9312: - } ! 9313: - if(e = openinode(&s, DO_INODE|SPIN_DOWN)){ ! 9314: - fprint(2, "%s: %s\n", dev, e); ! 9315: - exit(1); ! 9316: - } ! 9317: - if(strcmp(s.vol_id, argv[optind])){ ! 9318: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id); ! 9319: - exit(1); ! 9320: - } ! 9321: - optind++; ! 9322: - c = 0; ! 9323: - if(optind >= argc){ ! 9324: - while(e = Frdline(0)) ! 9325: - if(pr(&s, e)) ! 9326: - c = 1; ! 9327: - } else { ! 9328: - while(optind < argc) ! 9329: - if(pr(&s, argv[optind++])) ! 9330: - c = 1; ! 9331: - } ! 9332: - exit(c); ! 9333: -} ! 9334: - ! 9335: -usage() ! 9336: -{ ! 9337: - fprint(2, "Usage: worm read [-fdevice] [-pprefix] [-dm] vol_id [files ...]\n"); ! 9338: - exit(1); ! 9339: -} ! 9340: - ! 9341: -pr(s, name) ! 9342: - Superblock *s; ! 9343: - char *name; ! 9344: -{ ! 9345: - register Inode *i; ! 9346: - char b[63*1024L]; ! 9347: - register long len, n; ! 9348: - long nb; ! 9349: - int fd; ! 9350: - char buf[4096]; ! 9351: - ! 9352: - if((i = inodeof(name)) == 0){ ! 9353: - fprint(2, "%s not found\n", name); ! 9354: - return(1); ! 9355: - } ! 9356: - sprint(buf, "%s%s", prefix, name); ! 9357: - name = buf; ! 9358: - if((fd = create(name, i->mode, i->uid, i->gid, i->ctime)) < 0){ ! 9359: - if(dflag){ ! 9360: - createdirs(name); ! 9361: - fd = create(name, i->mode, i->uid, i->gid, i->ctime); ! 9362: - } ! 9363: - if(fd < 0){ ! 9364: - perror(name); ! 9365: - return(1); ! 9366: - } ! 9367: - } ! 9368: - if(fd == 0) /* a directory */ ! 9369: - return(0); ! 9370: - nb = sizeof b / s->blocksize; ! 9371: - Seek(s, i->block); ! 9372: - for(n = i->nbytes, len = nb*s->blocksize; n > 0;){ ! 9373: - if(len > n){ ! 9374: - len = n; ! 9375: - nb = (len+s->blocksize-1)/s->blocksize; ! 9376: - } ! 9377: - if(Read(s, b, nb)){ ! 9378: - fprint(2, "while writing %s: ", name); ! 9379: - perror("read"); ! 9380: - exit(1); ! 9381: - } ! 9382: - if(write(fd, b, (int)len) != len){ ! 9383: - fprint(2, "while writing %s: ", name); ! 9384: - perror("write"); ! 9385: - exit(1); ! 9386: - } ! 9387: - n -= len; ! 9388: - } ! 9389: - close(fd); ! 9390: - if(mflag){ ! 9391: - time_t tp[2]; ! 9392: - ! 9393: - tp[0] = tp[1] = i->ctime; ! 9394: - utime(name, tp); ! 9395: - } ! 9396: - return(0); ! 9397: -} ! 9398: - ! 9399: -createdirs(s) ! 9400: - char *s; ! 9401: -{ ! 9402: - char *ls, *ss; ! 9403: - ! 9404: - for(ls = s; *ls == '/'; ls++) ! 9405: - ; ! 9406: - for(; *ls && (ss = strchr(ls, '/')); ls = ss+1){ ! 9407: - *ss = 0; ! 9408: - if(access(s, 0) < 0){ ! 9409: - if(mkdir(s, 0777) < 0){ ! 9410: - perror(s); ! 9411: - return; ! 9412: - } else if(!quiet) ! 9413: - fprint(2, "created %s\n", s); ! 9414: - } ! 9415: - *ss = '/'; ! 9416: - } ! 9417: -} ! 9418: - ! 9419: -create(name, mode, uid, gid, t) ! 9420: - char *name; ! 9421: - time_t t; ! 9422: -{ ! 9423: - time_t tp[2]; ! 9424: - ! 9425: - tp[0] = tp[1] = t; ! 9426: - if((mode&S_IFMT) == S_IFDIR){ ! 9427: - if(access(name, 0) >= 0){ ! 9428: - if(chmod(name, mode) < 0){ ! 9429: - perror(name); ! 9430: - return(-1); ! 9431: - } ! 9432: - } else { ! 9433: - if(mkdir(name, mode) < 0){ ! 9434: - perror(name); ! 9435: - return(-1); ! 9436: - } ! 9437: - } ! 9438: - chown(name, uid, gid); ! 9439: - utime(name, tp); ! 9440: - return(0); ! 9441: - } else { ! 9442: - int fd; ! 9443: - ! 9444: - if((fd = creat(name, mode)) >= 0){ ! 9445: - chown(name, uid, gid); ! 9446: - utime(name, tp); ! 9447: - } ! 9448: - return(fd); ! 9449: - } ! 9450: -} ! 9451: //GO.SYSIN DD wread.c ! 9452: echo wreset.c 1>&2 ! 9453: sed 's/.//' >wreset.c <<'//GO.SYSIN DD wreset.c' ! 9454: -#include <libc.h> ! 9455: -#include "worm.h" ! 9456: -#include <sys/types.h> ! 9457: -#include <sys/udaioc.h> ! 9458: - ! 9459: -main(argc, argv) ! 9460: - char **argv; ! 9461: -{ ! 9462: - Superblock s; ! 9463: - char *e, *vol_id = 0; ! 9464: - char buf[1024]; ! 9465: - char *dev = "/dev/worm0"; ! 9466: - int c; ! 9467: - extern char *optarg; ! 9468: - extern int optind; ! 9469: - ! 9470: - while((c = getopt(argc, argv, "f:")) != -1) ! 9471: - switch(c) ! 9472: - { ! 9473: - case 'f': dev = optarg; break; ! 9474: - case '?': usage(); ! 9475: - } ! 9476: - if(optind != argc) ! 9477: - usage(); ! 9478: - dev = mapdev(dev); ! 9479: - if((s.fd = open(dev, 2)) < 0){ ! 9480: - if(!vol_id) ! 9481: - perror(dev); ! 9482: - exit(2); ! 9483: - } ! 9484: - /* ! 9485: - normally, you have to read to bring the drive online. ! 9486: - however, when you are likely to call reset, the drive ! 9487: - is online and blocked so skip the read ! 9488: - */ ! 9489: - /*lseek(s.fd, 1024L, 0); ! 9490: - read(s.fd, buf, sizeof buf);/**/ ! 9491: - if(ioctl(s.fd, UIORST) < 0) ! 9492: - perror("reset ioctl"); ! 9493: - exit(0); ! 9494: -} ! 9495: - ! 9496: -usage() ! 9497: -{ ! 9498: - print("Usage: worm reset [-fdevice]\n"); ! 9499: - exit(2); ! 9500: -} ! 9501: //GO.SYSIN DD wreset.c ! 9502: echo wrm.c 1>&2 ! 9503: sed 's/.//' >wrm.c <<'//GO.SYSIN DD wrm.c' ! 9504: -#include <libc.h> ! 9505: -#include <fio.h> ! 9506: -#include <sys/types.h> ! 9507: -#include <sys/stat.h> ! 9508: -#include <signal.h> ! 9509: -#include "worm.h" ! 9510: - ! 9511: -static int bad = 0; ! 9512: -static long nbytes; ! 9513: -static long nfiles; ! 9514: -char *argout; ! 9515: - ! 9516: -main(argc, argv) ! 9517: - char **argv; ! 9518: -{ ! 9519: - Superblock s; ! 9520: - char *e; ! 9521: - char buf[4096]; ! 9522: - int n; ! 9523: - int c; ! 9524: - char *dev = "/dev/worm0"; ! 9525: - extern char *optarg; ! 9526: - extern int optind; ! 9527: - ! 9528: - argout = argv[0]; ! 9529: - while((c = getopt(argc, argv, "f:")) != -1) ! 9530: - switch(c) ! 9531: - { ! 9532: - case 'f': dev = optarg; break; ! 9533: - case '?': usage(); ! 9534: - } ! 9535: - ! 9536: - if(optind >= argc) ! 9537: - usage(); ! 9538: - dev = mapdev(dev); ! 9539: - if((s.fd = open(dev, 2)) < 0){ ! 9540: - perror(*argv); ! 9541: - exit(1); ! 9542: - } ! 9543: - if(e = openinode(&s, DO_INODE|SPIN_DOWN)){ ! 9544: - fprint(2, "%s: %s\n", *argv, e); ! 9545: - exit(1); ! 9546: - } ! 9547: - if(strcmp(s.vol_id, argv[optind])){ ! 9548: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id); ! 9549: - exit(1); ! 9550: - } ! 9551: - if(s.nfree == 0){ ! 9552: - fprint(2, "%s: can't write any more!\n", dev); ! 9553: - exit(1); ! 9554: - } ! 9555: - if(s.version != VLINK){ ! 9556: - fprint(2, "%s: can't write on a b-tree disk\n", s.vol_id); ! 9557: - exit(1); ! 9558: - } ! 9559: - for(n = 1; n <= NSIG; n++) ! 9560: - signal(n, SIG_IGN); ! 9561: - ininit(); ! 9562: - if(++optind < argc) ! 9563: - while(optind < argc) ! 9564: - proc(&s, argv[optind++]); ! 9565: - else ! 9566: - while(e = Frdline(0)) ! 9567: - proc(&s, e); ! 9568: - if(bad) ! 9569: - exit(1); ! 9570: - inwrite(&s); ! 9571: - if(bad) ! 9572: - exit(1); ! 9573: - exit(0); ! 9574: -} ! 9575: - ! 9576: -usage() ! 9577: -{ ! 9578: - fprint(2, "Usage: worm rm [-fdevice] vol_id [files]\n"); ! 9579: - exit(1); ! 9580: -} ! 9581: - ! 9582: -proc(s, file) ! 9583: - Superblock *s; ! 9584: - char *file; ! 9585: -{ ! 9586: - Inode i; ! 9587: - ! 9588: - if(inodeof(file) == 0){ ! 9589: - fprint(2, "%s: not on worm\n", file); ! 9590: - return; ! 9591: - } ! 9592: - i.magic = DMAGIC; ! 9593: - i.block = -1; ! 9594: - i.name.n = file; ! 9595: - if(inadd(s, &i)) ! 9596: - bad = 1; ! 9597: -} ! 9598: - ! 9599: -static Inode *inodes; ! 9600: -static long ip; ! 9601: -static long ninodes = 0; ! 9602: -static char *nameb; ! 9603: -static long np; ! 9604: -static long nnameb = 0; ! 9605: -static long nblocks; ! 9606: -#define IINC 1024 ! 9607: -#define NINC (64*IINC) ! 9608: - ! 9609: -ininit() ! 9610: -{ ! 9611: - if(nnameb == 0){ ! 9612: - nameb = malloc((unsigned)(nnameb = NINC)); ! 9613: - if(nameb == 0){ ! 9614: - fprint(2, "wrm: malloc fail, %d bytes\n", nnameb); ! 9615: - exit(1); ! 9616: - } ! 9617: - } ! 9618: - np = 0; ! 9619: - if(ninodes == 0){ ! 9620: - inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC)); ! 9621: - if(inodes == 0){ ! 9622: - fprint(2, "wrm: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 9623: - exit(1); ! 9624: - } ! 9625: - } ! 9626: - ip = 0; ! 9627: -} ! 9628: - ! 9629: -inadd(s, i) ! 9630: - Superblock *s; ! 9631: - register Inode *i; ! 9632: -{ ! 9633: - register long len; ! 9634: - ! 9635: - len = strlen(i->name.n)+1; ! 9636: - if(np+len > nnameb){ ! 9637: - while(np+len > nnameb) ! 9638: - nnameb += NINC; ! 9639: - nameb = realloc(nameb, (unsigned)nnameb); ! 9640: - if(nameb == 0){ ! 9641: - fprint(2, "wrm: realloc fail, %d bytes\n", nnameb); ! 9642: - exit(1); ! 9643: - } ! 9644: - } ! 9645: - strcpy(nameb+np, i->name.n); ! 9646: - i->name.o = np; ! 9647: - np += len; ! 9648: - if(ip == ninodes){ ! 9649: - ninodes += IINC; ! 9650: - inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode)); ! 9651: - if(inodes == 0){ ! 9652: - fprint(2, "wrm: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode)); ! 9653: - exit(1); ! 9654: - } ! 9655: - } ! 9656: - inodes[ip++] = *i; ! 9657: - return(0); ! 9658: -} ! 9659: - ! 9660: -inwrite(s) ! 9661: - Superblock *s; ! 9662: -{ ! 9663: - char *e; ! 9664: - ! 9665: - if(e = lkwri(s, inodes, ip, nameb, np, 0L)){ ! 9666: - fprint(2, "%s\n", e); ! 9667: - bad = 1; ! 9668: - return; ! 9669: - } ! 9670: -} ! 9671: //GO.SYSIN DD wrm.c ! 9672: echo wstat.c 1>&2 ! 9673: sed 's/.//' >wstat.c <<'//GO.SYSIN DD wstat.c' ! 9674: -#include <libc.h> ! 9675: -#include "worm.h" ! 9676: - ! 9677: -main(argc, argv) ! 9678: - char **argv; ! 9679: -{ ! 9680: - Superblock s; ! 9681: - char *e, *vol_id = 0; ! 9682: - char *dev = "/dev/worm0"; ! 9683: - int c; ! 9684: - long nf = 0; ! 9685: - int vflag = 0; ! 9686: - extern char *optarg; ! 9687: - extern int optind; ! 9688: - extern long atol(); ! 9689: - ! 9690: - while((c = getopt(argc, argv, "vF:f:")) != -1) ! 9691: - switch(c) ! 9692: - { ! 9693: - case 'f': dev = optarg; break; ! 9694: - case 'F': nf = atol(optarg); break; ! 9695: - case 'v': vflag = 1; break; ! 9696: - case '?': usage(); ! 9697: - } ! 9698: - if(optind < argc){ ! 9699: - vol_id = argv[optind++]; ! 9700: - if(optind != argc) ! 9701: - usage(); ! 9702: - } ! 9703: - dev = mapdev(dev); ! 9704: - if((s.fd = open(dev, 0)) < 0){ ! 9705: - if(!vol_id && !nf) ! 9706: - perror(dev); ! 9707: - exit(2); ! 9708: - } ! 9709: - if(e = openinode(&s, SPIN_DOWN)){ ! 9710: - if(!vol_id && !nf) ! 9711: - fprint(2, "%s: %s\n", dev, e); ! 9712: - exit(2); ! 9713: - } ! 9714: - if(nf){ ! 9715: - if(vol_id) ! 9716: - if(strcmp(vol_id, s.vol_id) != 0) ! 9717: - exit(1); ! 9718: - exit(s.nfree >= nf? 0:3); ! 9719: - } ! 9720: - if(vol_id) ! 9721: - exit(strcmp(vol_id, s.vol_id) != 0); ! 9722: - if(vflag){ ! 9723: - Fprint(1, "%s: %s, %s\t%ldx%uhd blocks, %ld (=%.1fMB) free, zero=%ld this_sb@%ld next_sb@%ld\n", ! 9724: - s.vol_id, s.comment, ctime(&s.ctime), s.nblocks, s.blocksize, ! 9725: - s.nfree, s.nfree*(double)s.blocksize*1e-6, s.zero, s.myblock, s.nextsb); ! 9726: - } else ! 9727: - Fprint(1, "%s: %.0f%% used (%.1fMB free)\n", s.vol_id, ! 9728: - s.nextffree*100.0/s.nblocks, s.nfree*(double)s.blocksize*1e-6); ! 9729: - exit(0); ! 9730: -} ! 9731: - ! 9732: -usage() ! 9733: -{ ! 9734: - print("Usage: worm stat [-v] [-fdevice] [-Fnfree] [vol_id]\n"); ! 9735: - exit(2); ! 9736: -} ! 9737: //GO.SYSIN DD wstat.c ! 9738: echo wtmpdir.c 1>&2 ! 9739: sed 's/.//' >wtmpdir.c <<'//GO.SYSIN DD wtmpdir.c' ! 9740: -#include <libc.h> ! 9741: -#include "worm.h" ! 9742: -#include "sym.h" ! 9743: -#include <sys/types.h> ! 9744: -#include <sys/stat.h> ! 9745: -#include <pwd.h> ! 9746: -#include <grp.h> ! 9747: - ! 9748: -Inode *inodebase, *inext; ! 9749: -char *namebase, *cnext; ! 9750: - ! 9751: -main(argc, argv) ! 9752: - char **argv; ! 9753: -{ ! 9754: - Superblock s; ! 9755: - char *e; ! 9756: - char *dev = "/dev/worm0"; ! 9757: - register c, j; ! 9758: - register Inode *from, *to; ! 9759: - extern char *optarg; ! 9760: - extern int optind; ! 9761: - char *vlk(); ! 9762: - int cmp(); ! 9763: - int fd; ! 9764: - int verbose = 0; ! 9765: - char buf[512]; ! 9766: - long ni, nc; ! 9767: - ! 9768: - while((c = getopt(argc, argv, "vf:")) != -1) ! 9769: - switch(c) ! 9770: - { ! 9771: - case 'v': verbose = 1; break; ! 9772: - case 'f': dev = optarg; break; ! 9773: - case '?': usage(); ! 9774: - } ! 9775: - dev = mapdev(dev); ! 9776: - if((s.fd = open(dev, 0)) < 0){ ! 9777: - perror(dev); ! 9778: - exit(1); ! 9779: - } ! 9780: - if(e = openinode(&s, SPIN_DOWN)){ ! 9781: - fprint(2, "%s: %s\n", dev, e); ! 9782: - exit(1); ! 9783: - } ! 9784: - if(s.version != VLINK){ ! 9785: - fprint(2, "%s: not a vlink disk, no action taken.\n", s.vol_id); ! 9786: - exit(1); ! 9787: - } ! 9788: - if(optind != argc-1) ! 9789: - usage(); ! 9790: - if(strcmp(argv[optind], s.vol_id)){ ! 9791: - fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id); ! 9792: - exit(1); ! 9793: - } ! 9794: - if(verbose) ! 9795: - print("%d inodes\n", numinodes); ! 9796: - if((inodebase = (Inode *)malloc(s.blocksize+(int)numinodes*sizeof(Inode))) == 0){ ! 9797: - fprint(2, "malloc of %ld inodes failed\n", numinodes); ! 9798: - exit(2); ! 9799: - } ! 9800: - if((namebase = malloc(s.blocksize+(int)numnamechars+(int)numinodes)) == 0){ ! 9801: - fprint(2, "malloc of %ld chars failed\n", numnamechars); ! 9802: - exit(2); ! 9803: - } ! 9804: - inext = inodebase; ! 9805: - cnext = namebase; ! 9806: - s.ninodes = 0; ! 9807: - s.nextsb = 2; ! 9808: - if(e = vlk(&s)){ ! 9809: - fprint(2, "%s: %s\n", dev, e); ! 9810: - exit(1); ! 9811: - } ! 9812: - j = inext-inodebase; ! 9813: - if(verbose) ! 9814: - print("%d in base\n", j); ! 9815: - qsort((char *)inodebase, j, sizeof(*inodebase), cmp); ! 9816: - for(to = inodebase, from = inodebase+1; from < inext; from++) ! 9817: - if(strcmp(from->name.o+namebase, from[-1].name.o+namebase)) ! 9818: - *to++ = from[-1]; ! 9819: - else { ! 9820: - while((++from < inext) && (strcmp(from->name.o+namebase, from[-1].name.o+namebase) == 0)) ! 9821: - ; ! 9822: - } ! 9823: - if(from == inext) ! 9824: - *to++ = from[-1]; ! 9825: - inext = to; ! 9826: - j = inext-inodebase; ! 9827: - sprint(buf, "/usr/worm/tmp/%s", s.vol_id); ! 9828: - if((fd = creat(buf, 0666)) < 0){ ! 9829: - perror(buf); ! 9830: - exit(1); ! 9831: - } ! 9832: - ni = j; ! 9833: - nc = cnext-namebase; ! 9834: - write(fd, (char *)&s.ctime, 4); ! 9835: - write(fd, (char *)&ni, 4); ! 9836: - write(fd, (char *)inodebase, (int)ni*sizeof(Inode)); ! 9837: - write(fd, (char *)&nc, 4); ! 9838: - write(fd, namebase, (int)nc); ! 9839: - exit(0); ! 9840: -} ! 9841: - ! 9842: -usage() ! 9843: -{ ! 9844: - fprint(2, "Usage: worm tmpdir [-fdevice] vol_id\n"); ! 9845: - exit(2); ! 9846: -} ! 9847: - ! 9848: -cmp(a, b) ! 9849: - Inode *a, *b; ! 9850: -{ ! 9851: - return(strcmp(namebase+a->name.o, namebase+b->name.o)); ! 9852: -} ! 9853: - ! 9854: -char * ! 9855: -vlk(s) ! 9856: - register Superblock *s; ! 9857: -{ ! 9858: - register Inode *i; ! 9859: - short fd = s->fd; ! 9860: - register long j; ! 9861: - long blk = -1; /* shouldn't be accessed first time through */ ! 9862: - char *b; ! 9863: - long nb; ! 9864: - Inode *iend; ! 9865: - static char buf[64]; ! 9866: - ! 9867: - if((b = malloc(s->blocksize)) == 0){ ! 9868: - sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize); ! 9869: - return(buf); ! 9870: - } ! 9871: - for(;;){ ! 9872: - if(s->magic != SMAGIC){ ! 9873: - fprint(2, "bad Superblock at %ld\n", blk); ! 9874: - exit(1); ! 9875: - } ! 9876: - if(s->ninodes){ ! 9877: - nb = (s->ninodes+IPERB-1)/IPERB; ! 9878: - Seek(s, s->binodes); ! 9879: - if(Read(s, (char *)inext, nb)) ! 9880: - goto skip; ! 9881: - j = cnext-namebase; ! 9882: - for(i = inext, iend = i+s->ninodes; i < iend; i++) ! 9883: - i->name.o += j; ! 9884: - inext += s->ninodes; ! 9885: - nb = (s->ninochars+s->blocksize-1)/s->blocksize; ! 9886: - if(Read(s, cnext, nb)) ! 9887: - goto skip; ! 9888: - cnext += (s->ninochars+1)&~1; ! 9889: - } ! 9890: - skip: ! 9891: - blk = s->nextsb; ! 9892: - Seek(s, blk); ! 9893: - if(Read(s, b, 1L)) ! 9894: - break; ! 9895: - *s = *((Superblock *)b); ! 9896: - s->fd = fd; ! 9897: - if(s->myblock == 0) ! 9898: - s->myblock = blk; ! 9899: - } ! 9900: - free(b); ! 9901: - return((char *)0); ! 9902: -} ! 9903: //GO.SYSIN DD wtmpdir.c ! 9904: echo wwrite.c 1>&2 ! 9905: sed 's/.//' >wwrite.c <<'//GO.SYSIN DD wwrite.c' ! 9906: -#include <libc.h> ! 9907: -#include <fio.h> ! 9908: -#include <sys/types.h> ! 9909: -#include <sys/stat.h> ! 9910: -#include <signal.h> ! 9911: -#include "worm.h" ! 9912: - ! 9913: -main(argc, argv) ! 9914: - char **argv; ! 9915: -{ ! 9916: - Superblock s; ! 9917: - char *e; ! 9918: - char buf[4096]; ! 9919: - int n; ! 9920: - int c; ! 9921: - char *dev = "/dev/worm0"; ! 9922: - extern char *optarg; ! 9923: - extern int optind; ! 9924: - ! 9925: - argout = argv[0]; ! 9926: - while((c = getopt(argc, argv, "f:")) != -1) ! 9927: - switch(c) ! 9928: - { ! 9929: - case 'f': dev = optarg; break; ! 9930: - case '?': usage(); ! 9931: - } ! 9932: - ! 9933: - if(optind >= argc) ! 9934: - usage(); ! 9935: - dev = mapdev(dev); ! 9936: - if((s.fd = open(dev, 2)) < 0){ ! 9937: - perror(*argv); ! 9938: - exit(1); ! 9939: - } ! 9940: - if(e = openinode(&s, SPIN_DOWN)){ ! 9941: - fprint(2, "%s: %s\n", *argv, e); ! 9942: - exit(1); ! 9943: - } ! 9944: - if(strcmp(s.vol_id, argv[optind])){ ! 9945: - fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id); ! 9946: - exit(1); ! 9947: - } ! 9948: - if(s.nfree == 0){ ! 9949: - fprint(2, "%s: can't write any more!\n", dev); ! 9950: - exit(1); ! 9951: - } ! 9952: - if(s.version != VLINK){ ! 9953: - fprint(2, "%s: can't write on a b-tree disk\n", s.vol_id); ! 9954: - exit(1); ! 9955: - } ! 9956: - for(n = 1; n <= NSIG; n++) ! 9957: - signal(n, SIG_IGN); ! 9958: - ininit(); ! 9959: - if(++optind < argc) ! 9960: - while(optind < argc) ! 9961: - proc(&s, argv[optind++]); ! 9962: - else ! 9963: - while(e = Frdline(0)) ! 9964: - proc(&s, e); ! 9965: - if(bad) ! 9966: - exit(1); ! 9967: - nfiles = nbytes = 0; ! 9968: - inwrite(&s, (void *)0); ! 9969: - if(bad) ! 9970: - exit(1); ! 9971: - fprint(1, "%d files, %.6fMb\n", nfiles, nbytes/1e6); ! 9972: - exit(0); ! 9973: -} ! 9974: - ! 9975: -usage() ! 9976: -{ ! 9977: - fprint(2, "Usage: worm write [-fdevice] vol_id [files]\n"); ! 9978: - exit(1); ! 9979: -} ! 9980: - ! 9981: -proc(s, file) ! 9982: - Superblock *s; ! 9983: - char *file; ! 9984: -{ ! 9985: - struct stat sbuf; ! 9986: - unsigned short mode; ! 9987: - Inode i; ! 9988: - ! 9989: - memset((char *)&i, 0, sizeof(i)); ! 9990: - if(stat(file, &sbuf) < 0){ ! 9991: - perror(file); ! 9992: - return; ! 9993: - } ! 9994: - mode = sbuf.st_mode&S_IFMT; ! 9995: - if((mode == S_IFREG) || (mode == S_IFDIR)){ ! 9996: - i.magic = DMAGIC; ! 9997: - i.block = 0; ! 9998: - i.nbytes = sbuf.st_size; ! 9999: - nbytes += i.nbytes; ! 10000: - i.ctime = sbuf.st_ctime; ! 10001: - i.name.n = file; ! 10002: - i.mode = sbuf.st_mode; ! 10003: - i.uid = sbuf.st_uid; ! 10004: - i.gid = sbuf.st_gid; ! 10005: - if(inadd(s, &i)) ! 10006: - bad = 1; ! 10007: - } else ! 10008: - fprint(2, "%s is not a file\n", file); ! 10009: -} ! 10010: - ! 10011: -writeout(s, i, blk) ! 10012: - Superblock *s; ! 10013: - Inode *i; ! 10014: - long *blk; ! 10015: -{ ! 10016: - char b[63*1024L]; ! 10017: - int fd; ! 10018: - long n, len, blen; ! 10019: - char *name; ! 10020: - ! 10021: - n = (i->nbytes+s->blocksize-1)/s->blocksize; ! 10022: - *blk += n; ! 10023: - blkdone += n; ! 10024: - blen = sizeof b/s->blocksize; ! 10025: - len = blen*s->blocksize; ! 10026: - nbytes += i->nbytes; ! 10027: - nfiles++; ! 10028: - name = i->name.n; ! 10029: - if((fd = open(name, 0)) < 0) ! 10030: - goto out; ! 10031: - for(n = i->nbytes; n > len; n -= len){ ! 10032: - if(read(fd, (char *)b, (int)len) != len){ ! 10033: - out: ! 10034: - perror(name); ! 10035: - bad = 1; ! 10036: - return; ! 10037: - } ! 10038: - if(Write(s, b, blen)){ ! 10039: -fprint(2, "nb=%d, n=%d len=%d blen=%d\n", i->nbytes, n, len, blen); ! 10040: - perror("data write"); ! 10041: - exit(1); ! 10042: - } ! 10043: - } ! 10044: - if(n){ ! 10045: - memset(b, 0, sizeof b); ! 10046: - if(read(fd, (char *)b, (int)n) != n) ! 10047: - goto out; ! 10048: - n += s->blocksize-1; ! 10049: - n /= s->blocksize; ! 10050: - if(Write(s, b, n)){ ! 10051: - perror("data write"); ! 10052: - exit(1); ! 10053: - } ! 10054: - } ! 10055: - close(fd); ! 10056: -} ! 10057: //GO.SYSIN DD wwrite.c
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.