|
|
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.