V10/cmd/worm/worm.bundle
# To unbundle, sh this file
echo LL.c 1>&2
mkdir scsi scsi/osanity scsi/scsi scsi/inc scsi/generic scsi/sony scsi/wren
sed 's/.//' >LL.c <<'//GO.SYSIN DD LL.c'
-#include <sys/param.h>
-
-/*
- * long-long support
- */
-
-#define M 0x80000000
-
-unsigned
-Lshift(ll, l)
-llong_t ll;
-long l;
-{
- return (ll.hi<<(32-l)) | (ll.lo>>l);
-}
-
-llong_t
-ltoL(l)
-long l;
-{
- llong_t t;
-
- t.hi = 0;
- t.lo = l;
- return t;
-}
-
-llong_t
-Lladd(ll, l)
-llong_t ll;
-long l;
-{
- llong_t t;
- long cin;
-
- t = ll;
- t.lo += l;
- cin = ll.lo^t.lo;
- if (l>=0) {
- if ((ll.lo&cin)&M)
- t.hi++;
- } else {
- if ((~ll.lo&cin)&M)
- t.hi--;
- }
- return t;
-}
-
-llong_t
-Luadd(ll, u)
-llong_t ll;
-unsigned long u;
-{
- llong_t t;
- long cin;
-
- t = ll;
- t.lo += u;
- cin = ll.lo^t.lo;
- if ((ll.lo&cin)&M)
- t.hi++;
- return t;
-}
-
-llong_t
-LLadd(lla, llb)
-llong_t lla, llb;
-{
- llong_t t;
-
- t.hi = lla.hi+llb.hi;
- t.lo = lla.lo+llb.lo;
- if ((lla.lo&llb.lo | lla.lo&~t.lo | llb.lo&~t.lo)&M)
- t.hi++;
- return t;
-}
-
-llong_t
-Llmul(a, b)
- llong_t a;
- unsigned long b;
-{
- llong_t r;
-
- r = ltoL(0);
- while(b){
- if(b&1)
- r = LLadd(r, a);
- b >>= 1;
- a = LLadd(a, a);
- }
- return(r);
-}
//GO.SYSIN DD LL.c
echo btree.c 1>&2
sed 's/.//' >btree.c <<'//GO.SYSIN DD btree.c'
-#include <libc.h>
-#include <cbt.h>
-#undef nfree
-#include "worm.h"
-#include "sym.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-static char *inonames;
-static bfile *bf;
-static dirlk(), wormdir();
-
-char *
-cbtinit(s, blk, doinodes)
- register Superblock *s;
- long blk;
-{
- static char buf[64];
- char name[256], buf1[256];
-
- if(s->magic != SMAGIC){
- fprint(2, "bad Superblock at %ld\n", blk);
- exit(1);
- }
- numinodes = s->ninodes;
- if(doinodes){
- inonames = malloc(s->blocksize*(int)NBLKS(s, s->ninochars));
- if(inonames == 0){
- sprint(buf, "cbtinit: can't malloc %d\n", s->blocksize*(int)NBLKS(s, s->ninochars));
- return(buf);
- }
- if(dirlk(s) == 0)
- wormdir(s);
- } else
- inonames = 0;
- return((char *)0);
-}
-
-static
-dirlk(s)
- register Superblock *s;
-{
- char name[256], buf1[256];
- struct stat sbuf;
- int fd;
-
- sprint(name, "/usr/worm/dirs/%s", s->vol_id);
- sprint(buf1, "%s.I", name);
- if(stat(buf1, &sbuf) < 0)
- return(0);
- if(sbuf.st_mtime < s->ctime)
- return(0); /* worm is more recent than disk */
- if((bf = bopen(name, 0)) == 0)
- return(0);
- sprint(buf1, "%s.I", name);
- if((fd = open(buf1, 0)) < 0){
- fprint(2, "%s: btree but no inodes\n", name);
- return(0);
- }
- if(read(fd, inonames, (int)s->ninochars) != s->ninochars){
- fprint(2, "%s: expected %d chars\n", buf1, s->ninochars);
- close(fd);
- return(0);
- }
- close(fd);
- return(1);
-}
-
-static
-wormdir(s)
- register Superblock *s;
-{
- char name[256], buf1[256];
-
- sprint(name, "/tmp/worm%d", getpid());
- Seek(s, s->binodes);
- sprint(buf1, "%s.F", name);
- copyout(s, buf1, s->nF, 0, 0);
- sprint(buf1, "%s.T", name);
- copyout(s, buf1, s->nT, 0, 0);
- if(Read(s, inonames, NBLKS(s, s->ninochars)))
- return(0);
- if((bf = bopen(name, 0)) == 0){
- fprint(2, "can't bopen %s", name);
- return(0);
- }
- sprint(buf1, "%s.F", name); unlink(buf1);
- sprint(buf1, "%s.T", name); unlink(buf1);
- return(1);
-}
-
-copyout(s, name, len, overwrite, verbose)
- register Superblock *s;
- char *name;
- long len;
-{
- int fd, l;
- char *buf;
-
- if(access(name, 0) == 0){
- if(!overwrite){
- fprint(2, "%s already exists!\n", name);
- exit(1);
- }
- if(verbose)
- fprint(2, "overwriting %s\n", name);
- }
- if((fd = creat(name, 0666)) < 0){
- perror(name);
- exit(1);
- }
- if((buf = malloc(l = (BIGBLOCK/1024)*s->blocksize)) == 0){
- fprint(2, "can't malloc %d\n", l);
- exit(1);
- }
- if(verbose)
- print("%s: %d bytes\n", name, len);
- while(len >= l){
- if(Read(s, buf, NBLKS(s, l)))
- exit(1);
- if(write(fd, buf, l) != l){
- perror(name);
- exit(2);
- }
- len -= l;
- }
- if(Read(s, buf, NBLKS(s, len)))
- exit(2);
- if(write(fd, buf, (int)len) != len){
- perror(name);
- exit(2);
- }
- free(buf);
-}
-
-Inode *
-binodefn(s)
- char *s;
-{
- static Inode i;
- mbuf key;
-
- if(inonames == 0)
- return((Inode *)0);
- key.mdata = s;
- key.mlen = strlen(s);
- if(bseek(bf, key) != 1)
- return((Inode *)0);
- key.mdata = (char *)&i;
- if(bread(bf, (mbuf *)0, &key)){
- perror("inode read");
- return((Inode *)0);
- }
- i.name.n = i.name.o+inonames;
- return(&i);
-}
-
-void
-btraverse(fn)
- void (*fn)();
-{
- static Inode i;
- mbuf key;
-
- if(inonames == 0)
- return;
- bfirst(bf);
- key.mdata = (char *)&i;
- while(bread(bf, (mbuf *)0, &key) == 0){
- i.name.n = i.name.o+inonames;
- (*fn)(&i);
- }
-}
//GO.SYSIN DD btree.c
echo c.c 1>&2
sed 's/.//' >c.c <<'//GO.SYSIN DD c.c'
-#include <sys/param.h>
-main(argc, argv)
- char **argv;
-{
- Long off;
- long a, b;
-
- a = atoi(argv[1]);
- b = atoi(argv[2]);
- off = Llmul(ltoL(a), b);
- print("%d(#%x) x %d(#%x) = #%ux%0.8ux(%.0f)\n", a, a, b, b, off.hi, off.lo,
- ((float)off.lo) + 65536.0*65536.0*off.hi);
- if(llseek(open("/dev/null", 0), off, 0) < 0)
- perror("seek");
-}
//GO.SYSIN DD c.c
echo crap 1>&2
sed 's/.//' >crap <<'//GO.SYSIN DD crap'
-#include <libc.h>
-#include "sym.h"
-#include "worm.h"
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e;
- Inode *i;
- int c;
- char *dev = "/dev/worm0";
- extern char *optarg;
- extern int optind;
-
- while((c = getopt(argc, argv, "f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case '?': usage();
- }
- if(optind+2 != argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 0)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- if(strcmp(s.vol_id, argv[optind])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
- exit(1);
- }
- if(i = inodeof(argv[++optind]))
- c = pr(&s, i);
- else {
- fprint(2, "wcat: can't find %s\n", argv[optind]);
- c = 1;
- }
- exit(c);
-}
-
-usage()
-{
- fprint(2, "Usage: worm cat [-fdevice] vol_id file\n");
- exit(1);
-}
-
-pr(s, i)
- Superblock *s;
- register Inode *i;
-{
- char b[BIGBLOCK];
- register long len, n;
- long nb;
- int fd;
-
- fd = 1;
- nb = sizeof b / s->blocksize;
- Seek(s, i->block);
- for(n = i->nbytes, len = nb*s->blocksize; n > 0;){
- if(len > n){
- len = n;
- nb = (len+s->blocksize-1)/s->blocksize;
- }
- Read(s, b, nb);
- if(write(fd, b, (int)len) != len){
- perror("write");
- return(1);
- }
- n -= len;
- }
- close(fd);
- return(0);
-}
//GO.SYSIN DD crap
echo flink.c 1>&2
sed 's/.//' >flink.c <<'//GO.SYSIN DD flink.c'
-#include <libc.h>
-#include "worm.h"
-
-static Inode *inodebase;
-static char *namebase;
-static long nnames, ninodes;
-static char *expanded;
-static readinodes;
-static ifd;
-
-static Inode *diskinode();
-
-static Inode *
-finode(s)
- char *s;
-{
- register lo, hi, m;
- register Inode *i;
-
- if(readinodes == 0)
- return(diskinode(s));
-#define EXPAND(in) (i = inodebase+(in), expanded[in]?0:(i->name.n=i->name.o+namebase, expanded[in]=1))
-#define CMP(str, in) (EXPAND(in), strcmp(str, i->name.n))
-
- if(CMP(s, lo = 0) < 0)
- return(0);
- if(CMP(s, (hi = ninodes)-1) > 0)
- return(0);
- while(lo < hi-1){
- m = (lo+hi)/2;
- if(CMP(s, m) < 0)
- hi = m;
- else
- lo = m;
- }
- if(CMP(s, lo) == 0)
- return(inodebase+lo);
- else
- return(0);
-}
-
-static void
-ftraverse(fn)
- void (*fn)();
-{
- register Inode *i;
- register n;
-
- if(readinodes == 0){
- readinodes = 1;
- lseek(ifd, 8L, 0);
- read(ifd, (char *)inodebase, (int)ninodes*sizeof(Inode));
- }
- for(n = 0; n < ninodes; n++){
- EXPAND(n);
- (*fn)(i);
- }
-}
-
-fastlink(s, msg, ifn, tfn)
- Superblock *s;
- char **msg;
- Inode *(**ifn)();
- void (**tfn)();
-{
- int n;
- long t;
- static char buf[256];
-
- *msg = 0;
- *ifn = finode;
- *tfn = ftraverse;
- sprint(buf, "/usr/worm/tmp/%s", s->vol_id);
- if((ifd = open(buf, 0)) < 0)
- return(0);
- read(ifd, (char *)&t, 4);
- if(t != s->ctime)
- return(0);
- read(ifd, (char *)&ninodes, 4);
- inodebase = (Inode *)malloc(n = ninodes*sizeof(Inode));
- expanded = malloc((int)ninodes);
- memset(expanded, 0, (int)ninodes);
- lseek(ifd, (long)n, 1);
- readinodes = 0;
- read(ifd, (char *)&nnames, 4);
- namebase = malloc((int)nnames);
- read(ifd, namebase, (int)nnames);
- numinodes = ninodes;
- numnamechars = nnames;
- return(1);
-}
-
-static
-readi(ino, ip)
- Inode *ip;
-{
- static myino = -1;
- static Inode myi;
-
- if(ino != myino){
- myino = ino;
- lseek(ifd, 8L+myino*sizeof(Inode), 0);
- read(ifd, (char *)&myi, sizeof myi);
- myi.name.n = myi.name.o+namebase;
- }
- *ip = myi;
-}
-
-static Inode *
-diskinode(s)
- char *s;
-{
- register lo, hi, m;
- static Inode ii;
- register Inode *i = ⅈ
-
-#define READ(in) readi(in, i)
-#undef CMP
-#define CMP(str, in) (READ(in), strcmp(str, i->name.n))
-
- if(ninodes <= 0)
- return(0);
- if(CMP(s, lo = 0) < 0)
- return(0);
- if(CMP(s, (hi = ninodes)-1) > 0)
- return(0);
- while(lo < hi-1){
- m = (lo+hi)/2;
- if(CMP(s, m) < 0)
- hi = m;
- else
- lo = m;
- }
- if(CMP(s, lo) == 0)
- return(i);
- else
- return(0);
-}
//GO.SYSIN DD flink.c
echo getopt.c 1>&2
sed 's/.//' >getopt.c <<'//GO.SYSIN DD getopt.c'
-#define ERR(str, chr) if(opterr){fprint(2, "%s%s%c\n", argv[0], str, chr);}
-int opterr = 1;
-int optind = 1;
-int optopt;
-char *optarg;
-char *strchr();
-
-int
-getopt (argc, argv, opts)
-char **argv, *opts;
-{
- static int sp = 1;
- register c;
- register char *cp;
-
- if (sp == 1)
- if (optind >= argc ||
- argv[optind][0] != '-' || argv[optind][1] == '\0')
- return -1;
- else if (strcmp(argv[optind], "--") == 0) {
- optind++;
- return -1;
- }
- optopt = c = argv[optind][sp];
- if (c == ':' || (cp=strchr(opts, c)) == 0) {
- ERR (": illegal option -- ", c);
- if (argv[optind][++sp] == '\0') {
- optind++;
- sp = 1;
- }
- return '?';
- }
- if (*++cp == ':') {
- if (argv[optind][sp+1] != '\0')
- optarg = &argv[optind++][sp+1];
- else if (++optind >= argc) {
- ERR (": option requires an argument -- ", c);
- sp = 1;
- return '?';
- } else
- optarg = argv[optind++];
- sp = 1;
- } else {
- if (argv[optind][++sp] == '\0') {
- sp = 1;
- optind++;
- }
- optarg = 0;
- }
- return c;
-}
//GO.SYSIN DD getopt.c
echo in.c 1>&2
sed 's/.//' >in.c <<'//GO.SYSIN DD in.c'
-#include <libc.h>
-#include <fio.h>
-#include "worm.h"
-
-int bad = 0;
-long nbytes;
-long blkdone;
-long nfiles;
-char *argout;
-
-static Inode *inodes;
-static long ip;
-static long ninodes = 0;
-static char *nameb;
-static long np;
-static long nnameb = 0;
-static long nblocks;
-#define IINC 1024
-#define NINC (64*IINC)
-
-ininit()
-{
- if(nnameb == 0){
- nameb = malloc((unsigned)(nnameb = NINC));
- if(nameb == 0){
- fprint(2, "wwrite: malloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- np = 0;
- if(ninodes == 0){
- inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC));
- if(inodes == 0){
- fprint(2, "wwrite: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- ip = 0;
- nblocks = 0;
-}
-
-inadd(s, i)
- Superblock *s;
- register Inode *i;
-{
- register long len;
-
- len = strlen(i->name.n)+1;
- if(np+len > nnameb){
- while(np+len > nnameb)
- nnameb += NINC;
- nameb = realloc(nameb, (unsigned)nnameb);
- if(nameb == 0){
- fprint(2, "wwrite: realloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- strcpy(nameb+np, i->name.n);
- i->name.o = np;
- np += len;
- i->block = s->nextffree + nblocks;
- if(ip == ninodes){
- ninodes += IINC;
- inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode));
- if(inodes == 0){
- fprint(2, "wwrite: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- inodes[ip++] = *i;
- nblocks += (i->nbytes+s->blocksize-1)/s->blocksize;
- return(0);
-}
-
-inwrite(s, arg)
- Superblock *s;
- void *arg;
-{
- int i, j;
- long next = s->nextffree;
- char *e;
-
- if(e = lkwri(s, inodes, ip, nameb, np, nblocks)){
- fprint(2, "%s\n", e);
- bad = 1;
- return;
- }
- Seek(s, next);
- argout[2] = ' ';
- for(i = 0; i < ip; i++){
- inodes[i].block = next;
- inodes[i].name.n = inodes[i].name.o + nameb;
- writeout(s, &inodes[i], &next, arg);
- j = (blkdone*100)/nblocks;
- argout[0] = j/10+'0';
- argout[1] = j%10+'0';
- }
-}
//GO.SYSIN DD in.c
echo inode.c 1>&2
sed 's/.//' >inode.c <<'//GO.SYSIN DD inode.c'
-#include <libc.h>
-#include "worm.h"
-#include <sys/types.h>
-#include <sys/udaioc.h>
-
-Inode *(*inodefn)();
-void (*traversefn)();
-extern Inode *vinodefn(), *binodefn();
-extern void vtraverse(), btraverse();
-extern char *lkopi(), *cbtinit();
-long numinodes;
-long numnamechars;
-
-char *
-openinode(s, flags)
- register Superblock *s;
-{
- short fd = s->fd;
- char *b, *z;
- long blk;
- unsigned short ibuf[3];
- static char buf[64];
- extern char *getenv();
- extern long atol();
-int goo; extern errno; int ntry;
-
- if(z = getenv("WORMZERO"))
- blk = atol(z);
- else
- blk = 0;
- ntry = 0;
-loop:
- bigseek(s->fd, blk, 1024, 0);
- if(((goo = read(s->fd, (char *)ibuf, sizeof ibuf)) != sizeof ibuf) ||
- ((((long)ibuf[1])<<16|ibuf[0]) != SMAGIC)){
- if((goo < 0) && (errno == ENXIO))
- blk++; /* blank check (unwritten), try next blk */
- else if((goo == sizeof ibuf) && (ibuf[0] == 0) && (ibuf[1] == 0))
- blk++; /* zeroes(??), try next blk */
- else {
- fprint(2, "DEBUGGING[%d]: read=%d magic=0x%lx errno=%d\n",
- ntry, goo, (((long)ibuf[1])<<16|ibuf[0]), errno);
- if(ntry++ < 3)
- goto loop;
- }
- bigseek(s->fd, blk, 1024, 0);
- if(read(s->fd, (char *)ibuf, sizeof ibuf) < sizeof ibuf)
- return("no block size");
- }
- if(flags&SPIN_DOWN)
- ioctl(s->fd, UIOSPDW);
- s->blocksize = ibuf[2]; /* magic is 0-1 */
- if((b = malloc(s->blocksize)) == 0){
- sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize);
- return(buf);
- }
- bigseek(s->fd, blk, 1024, 0);
- if(read(s->fd, b, s->blocksize) != s->blocksize)
- return("superblock read error");
- *s = *((Superblock *)b);
- free(b);
- s->fd = fd;
- if(s->myblock == 0)
- s->myblock = blk;
- switch(s->version)
- {
- case VLINK:
- if(flags&DO_INODE){
- Superblock tmpsb;
-
- tmpsb = *s;
- if(b = lkopi(s, blk, 0))
- return(b);
- if(fastlink(s, &b, &inodefn, &traversefn))
- return(b);
- *s = tmpsb;
- }
- inodefn = vinodefn;
- traversefn = vtraverse;
- return(lkopi(s, blk, flags&DO_INODE));
- case VBTREE:
- inodefn = binodefn;
- traversefn = btraverse;
- return(cbtinit(s, blk, flags&DO_INODE));
- default:
- sprint(buf, "unknown version %d@%ld", s->version, blk);
- return(buf);
- }
-}
//GO.SYSIN DD inode.c
echo io.c 1>&2
sed 's/.//' >io.c <<'//GO.SYSIN DD io.c'
-#include <libc.h>
-#include "worm.h"
-
-Read(s, buf, n)
- register Superblock *s;
- char *buf;
- long n;
-{
- register k;
- int len;
-
- n *= s->blocksize;
- if(n != (int)n){
- fprint(2, "bad arg to Read n=%ld\n", n);
- abort();
- }
- len = BIGBLOCK;
- while(n){
- if(n < len) len = n;
- if((k = read(s->fd, buf, len)) != len){
- if(k && (errno != ENXIO)){
- perror("Read");
- exit(1);
- }
- return(1);
- }
- n -= len;
- buf += len;
- }
- return(0);
-}
-
-Write(s, buf, n)
- register Superblock *s;
- char *buf;
- long n;
-{
- register k;
- int len;
- char msg[256];
-
- n *= s->blocksize;
- if(n != (int)n){
- fprint(2, "bad arg to Write n=%d\n", n);
- abort();
- }
- len = BIGBLOCK;
- while(n){
- if(n < len) len = n;
- if((k = write(s->fd, buf, len)) != len){
- sprint(msg, "Write %d blks (%dB)", n/s->blocksize, n);
- perror(msg);
- return(1);
- }
- n -= len;
- buf += len;
- }
- return(0);
-}
-
-Seek(s, blk)
- register Superblock *s;
- long blk;
-{
- bigseek(s->fd, blk, s->blocksize, 0);
-}
-
-bigseek(fd, a, b, ptr)
-{
-#define SEEK64 /**/
-#ifdef SEEK64
-#include <sys/param.h>
- llong_t off;
- extern llong_t Llmul(), ltoL();
-
- off = Llmul(ltoL(a), b);
- llseek(fd, off, ptr);
-#else
- lseek(fd, a*(long)b, ptr);
-#endif
-}
//GO.SYSIN DD io.c
echo mapdev.c 1>&2
sed 's/.//' >mapdev.c <<'//GO.SYSIN DD mapdev.c'
-char *
-mapdev(s)
- char *s;
-{
- static char buf[128];
-
- if((s[1] == 0) && (*s >= '0') && (*s <= '9')){
- sprint(buf, "/dev/worm%c", *s);
- s = buf;
- }
- return(s);
-}
//GO.SYSIN DD mapdev.c
echo mkfile 1>&2
sed 's/.//' >mkfile <<'//GO.SYSIN DD mkfile'
-CFLAGS=-g -I.
-CC=cc
-LIB=worm.a
-BIN=/usr/lib/worm
-L=io inode vlink flink sym getopt mapdev btree LL in timenow
-OBJ=${L:%=$LIB(%.o)}
-NPROC=2
-# remember to change /usr/bin/worm if you add programs
-ALL=wmkfs wstat wwrite wread wls woffline wcat wbtree wrm\
- wdir wreset wmv wtmpdir wmount wcopy jukebox scsish
-BALL=${ALL:%=$BIN/%}
-
-all:V: $ALL
-
-scsish jukebox:Pexit 1: /unix
- cd scsi; mk both
-
-$LIB:Q: $OBJ
- names=`membername $newprereq`
- ar rv $LIB $names && rm $names
- ranlib $LIB
-
-'^(w[^.]*)$':R: \\1.o $LIB #O/\\1
- $CC $CFLAGS -o $target $stem1.o $LIB -lcbt
-
-'^(poot)$':R: \\1.o $LIB #O/\\1
- $CC $CFLAGS -o $target $stem1.o $LIB -lcbt
-
-'^(O/w[^.]*)$':R: \\1.O $COBJ
- cyntax $prereq && > $target
-
-$BIN/'(w[^.]*)$':R: \\1
- cp $stem1 $target && strip $target; chmod 775 $target
-$BIN/'(scsish|jukebox)':R: \\1
- cp $stem1 $target && strip $target; chmod 775 $target
-
-sym.o wtree.o thing.o: sym.h
-wtree.o thing.o: thing.h
-
-$LIB(%.o):N: %.o
-%.o: worm.h
-O/%.O: %.c
- cyntax -c $stem.c && mv $stem.O O
-O/%.O: worm.h
-
-pp:
- smallpr mkfile worm.h *.c
-
-clean:V:
- rm -f *.o *.a $ALL core O/*
-
-install:V: $BALL
-
-ship:V: shipped
-shipped: $BALL /usr/bin/worm
- ship $newprereq && touch $target
-
-goo:V: wmv wls wwrite wmkfs
- set +e
- > temp
- wmkfs -ftemp testa
- wwrite -ftemp testa w*.[ch]
- wls -ftemp -l wreset.c; wls -ftemp -b wreset.c
- wmv -ftemp testa wreset.c xxx
- wls -ftemp -l wreset.c xxx; wls -ftemp -b xxx
-
-wild: $BALL
- dest=wild ship $newprereq && touch $target
-
-poot:V: wcopy wls wstat wmkfs
- > temp1
- wmkfs -ftemp1 -n300 test7a; wstat -v -ftemp1
- wls -ftemp | wcopy -ftemp -v -m0 testa temp1 test7a
- wstat -v -ftemp; wls -ftemp -b | sort | mc
- wstat -v -ftemp1; wls -ftemp1 -b | sort | mc
- #wstat -v -ftemp; wstat -v -ftemp1
- wls -ftemp | wcopy -ftemp -v -m0 testa temp1 test7a
- wstat -v -ftemp1; wls -ftemp1 -b | sort | mc
- set +e;(wls -ftemp; echo; wls -ftemp; echo; wls -ftemp)| tee temp2 | wcopy -ftemp -v -m100 testa temp1 test7a
- wstat -v -ftemp1; wls -ftemp1 -b | sort | mc
-
-goop:V: wmkfs wstat wwrite
- > temp
- wmkfs -ftemp -n1000 testa; wstat -vftemp
- wmkfs -n666 -ftemp testa; wstat -vftemp
//GO.SYSIN DD mkfile
echo owcopy.c 1>&2
sed 's/.//' >owcopy.c <<'//GO.SYSIN DD owcopy.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <grp.h>
-
-char *timenow();
-long minfree = 40000;
-int verbose = 0;
-static char *copy();
-
-main(argc, argv)
- char **argv;
-{
- char *e;
- char *dev = "/dev/worm0";
- char *dest = 0;
- Superblock in, out;
- long start = 1;
- long count = 1000000L;
- int c;
- extern char *optarg;
- extern int optind;
- void pr();
-
- while((c = getopt(argc, argv, "vc:m:s:f:")) != -1)
- switch(c)
- {
- case 'c': count = atol(optarg); break;
- case 'f': dev = optarg; break;
- case 'm': minfree = atol(optarg); break;
- case 's': start = atol(optarg); break;
- case 'v': verbose = 1; break;
- case '?': usage();
- }
- dev = mapdev(dev);
- if((in.fd = open(dev, 0)) < 0){
- perror(dev);
- exit(1);
- }
- if(optind+3 != argc)
- usage();
-
- if(e = openinode(&in, SPIN_DOWN)){
- fprint(2, "worm copy: %s: %s\n", dev, e);
- exit(1);
- }
- if(strcmp(argv[optind], in.vol_id)){
- fprint(2, "src vol_id mismatch: expected %s, got %s\n",
- argv[optind], in.vol_id);
- exit(1);
- }
- dest = mapdev(argv[optind+1]);
- if((out.fd = open(dest, 2)) < 0){
- perror(dest);
- exit(1);
- }
- if(e = openinode(&out, SPIN_DOWN)){
- fprint(2, "worm copy: %s: %s\n", dest, e);
- exit(1);
- }
- if(strcmp(argv[optind+2], out.vol_id)){
- fprint(2, "destination vol_id mismatch: expected %s, got %s\n",
- argv[optind+2], out.vol_id);
- exit(1);
- }
- if(e = copy(&in, start, count, &out)){
- fprint(2, "worm copy: %s: %s\n", dest, e);
- exit(1);
- }
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: worm copy [-v] [-fdevice] [-s startblk] [-c count] [-m minfree] srcvolid destdev destvolid\n");
- exit(2);
-}
-
-static char *
-copy(in, blk, count, out)
- register Superblock *in, *out;
- long blk, count;
-{
- register Inode *i;
- short fd = in->fd;
- char *b, *err;
- long nb, ndata;
- char *nameb;
- Inode *inodes = 0;
- Inode *iend;
- long delta;
- static char buf[64];
- extern char *lkwri();
-
- in->blocksize = 1024;
- if((b = malloc(in->blocksize)) == 0){
- sprint(buf, "couldn't malloc buffer (%d bytes)", in->blocksize);
- return(buf);
- }
- Seek(in, blk);
- if(Read(in, b, 1)){
- fprint(2, "worm copy: unexpected read error\n");
- exit(1);
- }
- *in = *((Superblock *)b);
- in->fd = fd;
- while(count-- > 0){
- if(in->magic != SMAGIC){
- fprint(2, "bad Superblock at %ld\n", blk);
- exit(1);
- }
- if(in->ninodes){
- if(verbose)
- fprint(2, "%s reading chunk %s:%ld (%.1f%%)\n",
- timenow(), in->vol_id, in->myblock,
- in->myblock*100./(float)in->nblocks);
- if(out->nfree < minfree){
- fprint(2, "worm copy: disk %s has < %d free at input %d\n",
- out->vol_id, minfree, in->myblock);
- exit(1);
- }
- nb = (in->ninodes+(in->blocksize/sizeof(Inode))-1)/(in->blocksize/sizeof(Inode));
- inodes = (Inode *)malloc((unsigned)(in->blocksize*nb));
- if(inodes == 0){
- sprint(buf, "inode malloc(%d) fail, sbrk=%d\n",
- (in->blocksize*nb), sbrk(0));
- return(buf);
- }
- Seek(in, in->binodes);
- if(Read(in, (char *)inodes, nb))
- goto skip;
- delta = out->nextffree - inodes->block;
-print("%d inodes; delta=%d\n", in->ninodes, delta);
- for(i = inodes, iend = inodes+in->ninodes; i < iend; i++)
- if(i->block > 0)
- i->block += delta;
- nb = (in->ninochars+in->blocksize-1)/in->blocksize;
- nameb = malloc((unsigned)(in->blocksize*nb));
- if(nameb == 0){
- sprint(buf, "name buffer malloc(%d) fail, sbrk=%d\n",
- (in->blocksize*nb), sbrk(0));
- return(buf);
- }
- if(Read(in, nameb, nb))
- goto skip;
- ndata = in->binodes - in->myblock - 1;
- if(err = lkwri(out, inodes, in->ninodes, nameb, in->ninochars, ndata)){
- fprint(2, "wcopy: lkwri: %s at input %d\n", err, in->myblock);
- exit(1);
- }
- dcopy(in, out, ndata);
- }
- skip:
- blk = in->nextsb;
- Seek(in, blk);
- if(Read(in, b, 1L))
- break;
- *in = *((Superblock *)b);
- in->fd = fd;
- if(in->myblock == 0)
- in->myblock = blk;
- }
- free(b);
- if(verbose)
- fprint(2, "%s copy done, %s is %.1f%% full\n", timenow(), out->vol_id,
- out->myblock*100.0/(float)out->nblocks);
- return((char *)0);
-}
-
-dcopy(in, out, n)
- Superblock *in, *out;
- long n;
-{
- char buf[BIGBLOCK];
- long bs;
-
- bs = BIGBLOCK/in->blocksize;
- Seek(in, in->myblock+1);
- Seek(out, out->myblock+1);
- while(n > 0){
- if(bs > n) bs = n;
- if(Read(in, buf, bs)){
- fprint(2, "wcopy: warning: data read error at %d\n", in->myblock);
- }
- if(Write(out, buf, bs)){
- fprint(2, "wcopy: dcopy write error\n");
- exit(1);
- }
- n -= bs;
- }
-}
-
-char *
-timenow()
-{
- long tim;
- char *tims;
-
- time(&tim);
- tims = ctime(&tim);
- tims[19] = 0;
- return(tims);
-}
//GO.SYSIN DD owcopy.c
echo partial.news 1>&2
sed 's/.//' >partial.news <<'//GO.SYSIN DD partial.news'
-the worm programs now only run properly on systems
-with llseek in the kernel. the three systems that matter
//GO.SYSIN DD partial.news
echo poot.c 1>&2
sed 's/.//' >poot.c <<'//GO.SYSIN DD poot.c'
-#include <libc.h>
-#include "sym.h"
-#include "worm.h"
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char buf[1024];
- char *e;
- Inode *i;
- int c;
- char *com = 0;
- char *dev = "/dev/worm0";
- extern char *optarg;
- extern int optind;
-
- while((c = getopt(argc, argv, "f:c:")) != -1)
- switch(c)
- {
- case 'c': com = optarg; break;
- case 'f': dev = optarg; break;
- case '?': usage();
- }
- if(optind+2 != argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 2)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- if(strcmp(s.vol_id, argv[optind])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
- exit(1);
- }
- if(s.version != VBTREE){
- fprint(2, "poot: %s must be a btree disk\n", s.vol_id);
- exit(1);
- }
- memset(buf, sizeof buf, 0);
- memset(s.vol_id, sizeof s.vol_id, 0);
- strcpy(s.vol_id, argv[++optind]);
- if(com){
- memset(s.comment, sizeof s.comment, 0);
- strcpy(s.comment, com);
- }
- memcpy(buf, &s, 1024);
- lseek(s.fd, 0, 0);
- if(write(s.fd, buf, 1024) != 1024){
- perror("write of new superblock");
- exit(1);
- }
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: poot [-fdevice] [-ccnewcomment] vol_id new_vol_id\n");
- exit(1);
-}
//GO.SYSIN DD poot.c
echo scsi/mkfile 1>&2
sed 's/.//' >scsi/mkfile <<'//GO.SYSIN DD scsi/mkfile'
-SYS=research
-< $SYS.mk
-JL=juke.a
-X=allocate cold getstatus ioshelves iodr_sh lib load nlun warm
-JLIB=${X:%=$JL(%.o)}
-JSRC=${X:%=%.c}
-
-SL=scsi.a
-X=s_$IO ge_sense s_volid s_pperror s_fixedstr s_longat s_xd
-SLIB=${X:%=$SL(%.o)}
-
-SHL=scsish.a
-GENERIC=ge_dev ge_inq ge_stop ge_start ge_capacity ge_display\
- ge_reset ge_tur ge_scsi ge_readt ge_copy # ge_sense in $SL
-SONY=so_dev so_inq so_alt so_config so_status so_eject so_rel so_set\
- so_shelfside so_diskid so_internal so_media so_readid so_copy\
- so_i0.tab so_i1.tab so_scsi.tab so_sense so_nesd.tab
-WREN=wr_dev wr_inq wr_rmode wr_wmode wr_diag
-X=$GENERIC $SONY $WREN
-SHLIB=${X:%=$SHL(%.o)}
-
-all:V: jukebox scsish
-
-both:V: ../jukebox ../scsish
-
-../%: %
- cp $prereq $target
-
-jukebox: jukebox.o $JL $SHL $SL
- $CC $CFLAGS -o $target $prereq $LDFLAGS
-
-scsish: scsish.o $SHL $SL
- $CC $CFLAGS -o $target $prereq $LDFLAGS
-
-jpp:V:
- pr mkfile juke.h scsi.h jukebox.c $JSRC | lp -ddp -n2
-
-poot:V: scsish
- echo 'dev scsi
- copy 4 0 10 5 0 1' | scsish
-
-scsi.cpio:V: inc/scsi.h
- find * -print | sed -e '/\.[oa]$/d' -e '/\.cpio$/d' | cpio -oc > $target
-inc/scsi.h:Pcmp -s: /usr/include/scsi.h
- cp $prereq $target
-
-
-# below is just magic; believe it.
-
-$JL(%.o):N: %.o
-$JL:Q: $JLIB
- names=`membername $newprereq`
- ar rv $JL $names && rm $names
- $RANLIB $JL
-
-$SL(%.o):N: %.o
-$SL:Q: $SLIB
- names=`membername $newprereq`
- ar rv $SL $names && rm $names
- $RANLIB $SL
-
-$SHL(%.o):N: %.o
-$SHL:Q: $SHLIB
- names=`membername $newprereq`
- ar rv $SHL $names && rm $names
- $RANLIB $SHL
-
-s_%.o: scsi/%.c
- cd scsi; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target
-so_%.o: sony/%.c
- cd sony; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target
-so_%.o: sony/fns.h
-ge_%.o: generic/%.c
- cd generic; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target
-ge_%.o: generic/fns.h
-wr_%.o: wren/%.c
- cd wren; $CC $CFLAGS -c $stem.c && mv $stem.o ../$target
-wr_%.o: wren/fns.h
-so_%.o wr_%.o ge_%.o: scsish.h scsi.h
-
-so_%.tab.o:Q: sony/%.tab
- cd sony
- echo generating $target
- p=$stem.tab
- awk -F' ' '
- 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;
- h["8"]=8;h["9"]=9;h["a"]=10;h["b"]=11;h["c"]=12;h["d"]=13;h["e"]=14;h["f"]=15;
- }
- function done( i){
- for(i = 0; i < 256; i++) if(x[i]){
- print "\t\"" x[i] "\","
- x[i] = ""
- } else printf "\t\"<#%x>\",\n", i
- print "};"
- }
- function hex(n, i){
- return(h[substr(n, 1, 1)]*16+h[substr(n, 2, 1)]);
- }
- NF == 1 { if(NR > 1) done(); print "char *" $1 "[] = {" }
- NF > 1 { x[hex($1)] = $2; }
- END { done(); }' < $p > $p.c && $CC $CFLAGS -c $p.c && mv $p.o ../$target
- rm $p.c
//GO.SYSIN DD scsi/mkfile
echo scsi/cold.c 1>&2
sed 's/.//' >scsi/cold.c <<'//GO.SYSIN DD scsi/cold.c'
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include "scsi.h"
-#include "juke.h"
-
-static sort(char *buf);
-
-cold_inv(char type, char *buf)
-{
- Side side;
- int drive, sh, nsh;
- int n;
- char vol_id[512];
- int didit[NSHELF];
-
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
-printf("getstatus done\n");
- /* first clear out nonexistent labels */
- n = 0;
- for(sh = 0; sh < NSHELF; sh++){
- if((j_status.shelf[sh]&0xC0) == 0xC0){
- n++;
- j_shelf[sh] = "there";
- } else
- j_shelf[sh] = 0;
- didit[sh] = 0;
- }
- printf("%d disks in shelves.\n", n);
- /* second, clear the drives */
- for(sh = 0; sh < NSHELF; sh++)
- if(j_shelf[sh] == 0)
- break;
- for(drive = 0; drive < 8; drive++){
- if(!j_status.lun[drive].diskin)
- continue; /* no disk in drive */
-printf("clearing drive %d:\n", drive);
- if(j_status.lun[drive].diskindrive && !j_status.lun[drive].shelfvalid){
- if(j_drive_to_shelf(drive, sh, SIDEA, buf))
- return(-1);
- for(sh++; sh < NSHELF; sh++)
- if(j_shelf[sh] == 0)
- break;
- n++;
- } else
- if(j_drive_to_shelf(drive, -1, SIDEA, buf))
- return(-1);
- printf("\n");
- }
- printf("reloading %d disks.\n", n);
- side = SIDEA;
- drive = min(nlun+1, NLUN-1);
- j_wrshelf = 1;
- for(sh = 0; sh < NSHELF; sh++){
- if(didit[sh])
- continue;
- j_shelf[sh] = 0;
- /* the C0 means disk properly present (not temp) */
- if((j_status.shelf[sh]&0xC0) == 0xC0){
- if(getvol(sh, drive, vol_id, &side))
- errexit(vol_id);
- switch(type)
- {
- case 'c':
- for(nsh = 0; j_shelf[nsh]; nsh++)
- ;
- break;
- case 's':
- case 'r':
- while(j_shelf[nsh = nrand(NSHELF)])
- ;
- break;
- case 'u':
- default:
- nsh = sh;
- break;
- }
- printf("%s@%d -> %d\n", vol_id, sh, nsh);
- if(j_drive_to_shelf(drive, nsh, side, buf) < 0)
- return(-1);
- j_shelf[nsh] = strdup(vol_id);
- didit[nsh] = 1;
- sleep(2);
- }
- }
- printf("process any new disks.\n");
- if(warm_inv(buf))
- return(-1);
- if(type == 's')
- return(sort(buf));
- return(0);
-}
-
-getvol(int sh, int drive, char *vol_id, int *side)
-{
- int i;
- char buf[512];
-
- if(j_shelf_to_drive(sh, SIDEA, drive, vol_id) < 0)
- return(-1);
- if((i = j_rvolid(drive, buf)) < 0)
- goto softerr;
- if(i == 0)
- *side = SIDEA;
- else {
- *side = SIDEB;
- if(j_drive_to_shelf(drive, sh, SIDEA, vol_id) < 0)
- return(-1);
- if(j_shelf_to_drive(sh, SIDEB, drive, vol_id) < 0)
- return(-1);
- if((i = j_rvolid(drive, buf)) < 0)
- goto softerr;
- }
- if(i > 0)
- strcpy(vol_id, UNALLOCATED);
- else {
- strcpy(vol_id, buf);
- i = strlen(vol_id)-1;
- if(i < 0){
- sprintf(buf, "apparently good superblock but null vol_id");
- goto softerr;
- } else if(vol_id[i] == 'a')
- vol_id[i] = 0;
- else if(vol_id[i] == 'b'){
- vol_id[i] = 0;
- *side = !*side;
- } else {
- sprintf(buf, "vol_id '%s' must end in a or b", vol_id);
- strcpy(vol_id, buf);
- return(-1);
- }
- }
- return(0);
-softerr:
- *side = SIDEA;
- fprintf(stderr, "error in reading shelf %d: %s; proceeding\n", sh, buf);
- sprintf(vol_id, "DISK_ERROR%d", sh);
- gen_reset(0, (int *)0, 0, (char **)0, buf);
- return(0);
-}
-
-static int index[NSHELF];
-static
-cmp(int *a, int *b)
-{
- char *sa = j_shelf[*a], *sb = j_shelf[*b];
-
- if((sa == 0) && (sb == 0)) return(0);
- if(sa == 0) return(-1);
- if(sb == 0) return(1);
- return(strcmp(sa, sb));
-}
-
-static char *disk[8];
-
-static
-sd(int a, int b, char *err)
-{
- disk[b] = j_shelf[a];
- return(j_shelf_to_drive(a, SIDEB, b, err));
-}
-static
-ds(int a, int b, char *err)
-{
- j_shelf[b] = disk[a];
- return(j_drive_to_shelf(a, b, SIDEB, err));
-}
-
-static
-sort(char *errbuf)
-{
- int i, j, org;
-
- for(i = 0; i < NSHELF; i++)
- index[i] = i;
- qsort(index, NSHELF, sizeof index[0], cmp);
- for(i = 0; i < NSHELF; i++){
- if(index[i] < 0) continue;
- if(sd(org = i, NLUN-1, errbuf) < 0)
- return(-1);
- j = index[i];
- index[i] = -1;
- while(j != org){
- if(sd(j, NLUN-2, errbuf) < 0)
- return(-1);
- if(ds(NLUN-2, i, errbuf) < 0)
- return(-1);
- i = j;
- if(index[i] < 0)
- break;
- j = index[i];
- index[i] = -1;
- }
- if(ds(NLUN-1, i, errbuf) < 0)
- return(-1);
- }
- return(0);
-}
//GO.SYSIN DD scsi/cold.c
echo scsi/osanity/tstfill.c 1>&2
sed 's/.//' >scsi/osanity/tstfill.c <<'//GO.SYSIN DD scsi/osanity/tstfill.c'
-short pat[][8] =
-{
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0xb6db, 0xeb6d, 0xb6db, 0xeb6d, 0xb6db, 0xeb6d, 0xb6db, 0xeb6d,
- 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
- 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA, 0xAAAA,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
-};
-
-fillbuf(buf, n)
- char *buf;
-{
- int i = 0;
- register j;
-
- while(n > 0){
- if(i >= sizeof(pat)/sizeof(pat[0]))
- i = 0;
- for(j = 0; j < 64; j++, buf += 16)
- memcpy(buf, pat[i], 16);
- n--;
- i++;
- }
-}
//GO.SYSIN DD scsi/osanity/tstfill.c
echo scsi/osanity/tstrd.c 1>&2
sed 's/.//' >scsi/osanity/tstrd.c <<'//GO.SYSIN DD scsi/osanity/tstrd.c'
-main(argc, argv)
- char **argv;
-{
- long first, last, t;
- char buf[32768], buf1[32768], *bufp;
- int fd, n;
- char *worm = "/dev/worm0";
-
- if((argc < 3) || (argc > 4)){
- print("Usage: tstrd [device] firstblock firstnonblock\n");
- exit(1);
- }
- if(argc > 3)
- worm = *++argv;
- if((fd = open(worm, 0)) < 0){
- perror(worm);
- exit(1);
- }
- first = atol(argv[1]);
- last = atol(argv[2]);
- if((first < 0) || (last <= first)){
- print("bad first=%ld last=%ld\n", first, last);
- exit(1);
- }
- print("reading blocks %ld - %ld inclusive on %s\n", first, last-1, worm);
- fillbuf(buf, 32);
- bufp = &buf[1024*(first%5)];
- lseek(fd, first*1024, 0);
- while(first < last){
- n = last-first;
- if(n > 25) n = 25;
- if(read(fd, buf1, n*1024) != n*1024){
- print("block %ld: ", first);
- perror("read");
- exit(1);
- }
- if(memcmp(bufp, buf1, n*1024)){
- print("block %ld: bytes differ\n", first);
- exit(1);
- }
- if((first%5000) == 0){
- t = time((long *)0);
- print("done block %ld: %s", first, ctime(&t));
- }
- first += n;
- }
- exit(0);
-}
//GO.SYSIN DD scsi/osanity/tstrd.c
echo scsi/osanity/tstsk.c 1>&2
sed 's/.//' >scsi/osanity/tstsk.c <<'//GO.SYSIN DD scsi/osanity/tstsk.c'
-main(argc, argv)
- char **argv;
-{
- long first, last, t;
- char buf[32768], buf1[32768], *bufp;
- int fd, n, i;
- char *worm = "/dev/worm0";
- long bands[50][2];
- int nbands;
- long loop;
- double tseek, tbl;
- float floop;
-
- if(argc < 3){
- print("Usage: tstsk [device] firstblock firstnonblock ...\n");
- exit(1);
- }
- if((argc&1) == 0)
- worm = *++argv;
- if((fd = open(worm, 0)) < 0){
- perror(worm);
- exit(1);
- }
- nbands = 0;
- while(*++argv){
- first = atol(*argv);
- last = atol(*++argv);
- if((first < 0) || (last <= first)){
- print("bad first=%ld last=%ld\n", first, last);
- exit(1);
- }
- bands[nbands][0] = first;
- bands[nbands][1] = last;
- nbands++;
- }
- tseek = tbl = 0;
- last = 0;
- fillbuf(buf, 32);
- for(loop = 0;; loop++){
- i = nrand(nbands);
- first = bands[i][0] + lrand()%(bands[i][1]-bands[i][0]);
- n = 20;
- if(first+n > bands[i][1])
- first = bands[i][1]-n;
- if(first < bands[i][0])
- first = bands[i][0], n = bands[i][1]-first;
- tbl += n;
- lseek(fd, first*1024, 0);
- last -= first;
- if(last < 0) last = -last;
- tseek += last;
- bufp = &buf[1024*(first%5)];
- if(read(fd, buf1, n*1024) != n*1024){
- print("block %ld: ", first);
- perror("read");
- exit(1);
- }
- if(memcmp(bufp, buf1, n*1024)){
- print("block %ld: bytes differ\n", first);
- exit(1);
- }
- if(loop && ((loop%100) == 0)){
- t = time((long *)0);
- floop = loop+1;
- print("loop %ld: ave blocks=%.1f, ave seek=%.1fk at %s",
- loop, tbl/floop, tseek/floop, ctime(&t));
- }
- last = first+n;
- }
-}
//GO.SYSIN DD scsi/osanity/tstsk.c
echo scsi/osanity/tstwr.c 1>&2
sed 's/.//' >scsi/osanity/tstwr.c <<'//GO.SYSIN DD scsi/osanity/tstwr.c'
-main(argc, argv)
- char **argv;
-{
- long first, last, t;
- char buf[32768], buf1[32768], *bufp;
- int fd, n;
- char *worm = "/dev/worm0";
-
- if((argc < 3) || (argc > 4)){
- print("Usage: tstwr [device] firstblock firstnonblock\n");
- exit(1);
- }
- if(argc > 3)
- worm = *++argv;
- if((fd = open(worm, 1)) < 0){
- perror(worm);
- exit(1);
- }
- first = atol(argv[1]);
- last = atol(argv[2]);
- if((first < 0) || (last <= first)){
- print("bad first=%ld last=%ld\n", first, last);
- exit(1);
- }
- print("writing blocks %ld - %ld inclusive on %s\n", first, last-1, worm);
- fillbuf(buf, 32);
- bufp = &buf[1024*(first%5)];
- lseek(fd, first*1024, 0);
- while(first < last){
- n = last-first;
- if(n > 25) n = 25;
- if(write(fd, bufp, n*1024) != n*1024){
- print("block %ld: ", first);
- perror("write");
- exit(1);
- }
- if((first%5000) == 0){
- t = time((long *)0);
- print("done block %ld: %s", first, ctime(&t));
- }
- first += n;
- }
- exit(0);
-}
//GO.SYSIN DD scsi/osanity/tstwr.c
echo scsi/osanity/mkfile 1>&2
sed 's/.//' >scsi/osanity/mkfile <<'//GO.SYSIN DD scsi/osanity/mkfile'
-CFLAGS=-g
-NPROC=2
-ALL=tstwr tstrd tstsk
-
-all:V: $ALL
-
-tst%: tst%.o tstfill.o
- $CC $CFLAGS -o $target $prereq
-
-clean:V:
- rm -f *.o $ALL core
//GO.SYSIN DD scsi/osanity/mkfile
echo scsi/osanity/seek 1>&2
sed 's/.//' >scsi/osanity/seek <<'//GO.SYSIN DD scsi/osanity/seek'
-tstsk 5 100000 400000 500000 800000 900000 1200000 1300000 1500000 1600000
//GO.SYSIN DD scsi/osanity/seek
echo scsi/juke.3 1>&2
sed 's/.//' >scsi/juke.3 <<'//GO.SYSIN DD scsi/juke.3'
-.TH INTERNAL 3
-.CT 2 file_io
-.SH NAME
-jukebox routines
-.tr %"
-.SH SYNOPSIS
-.B "#include %hdr.h%"
-.PP
-.tr %%
-.B "int j_shelf_to_drive(int sh, Side side, int dr, char *err)"
-.PP
-.B "int j_drive_to_shelf(int dr, int sh, Side side, char *err)"
-.PP
-.B "int j_empty_drive(int tlim, char *buf)"
-.PP
-.B "void j_rdshelves(char *buf)"
-.PP
-.B "int j_getstatus(char *buf)"
-.PP
-.B "int j_scsiio(struct scsi_cmd *cmd, int ncmd,"
-.br
-.B "\ \ \ \ \ \ struct scsi_return *ret, int nret, char *err)"
-.PP
-.B "int j_shelfof(char *vol_id)"
-.PP
-.B "int j_volid(int dr, char *err)"
-.PP
-.B "extern char *j_shelf[NSHELF];"
-.PP
-.B "extern void pperror(char *buf, char *mesg);
-.SH DESCRIPTION
-.I J_shelf_to_drive
-places the disk in shelf
-.I sh
-in logical drive
-.IR dr .
-It returns 0 on success;
-otherwise an error message is placed in
-.I err .
-.PP
-.I J_drive_to_shelf
-places the disk
-in logical drive
-.IR dr
-in shelf
-.IR sh .
-If
-.I sh
-is negative,
-the disk is returned to its home shelf.
-It returns 0 on success;
-otherwise an error message is placed in
-.IR err .
-.PP
-.I J_rdshelves
-initializes each element of
-.I j_shelf
-to the volid of the disk on that shelf.
-A zero pointer means there is no disk;
-a name of
-.B UNALLOCATED
-means the disk has not been allocated a name yet.
-It returns 0 on success;
-otherwise an error message is placed in
-.IR err .
-.PP
-.I J_getstatus
-initializes
-.B j_status
-which include the following fields:
-.EX
- struct Lunstatus lun[NLUN]; /* disk status */
- uchar shelf[NSHELF]; /* shelf status */
- uchar iounit; /* I/O unit status */
- uchar carrier; /* carrier status */
- uchar udrive; /* upper drive status */
- uchar ldrive; /* lower drive status */
-.EE
-A return value of 0 implies success;
-otherwise \-1 is returned and an error message is placed in
-.IR err .
-.PP
-.I J_scsiio
-performs a SCSI transaction.
-It sends the command in
-.I cmd
-and
-.I ncmd
-data bytes and stores the return status in
-.IR ret .
-A return value of 0 implies success;
-otherwise \-1 is returned and an error message is placed in
-.IR err .
-.PP
-.I J_shelfof
-returns the shelf number of the disk labelled
-.IR vol_id .
-If there is no such disk,
-\-1 is returned.
-.PP
-.I J_volid
-returns the volid of the disk on drive
-.I dr
-in
-.IR err .
-A return value of 0 implies success;
-otherwise \-1 is returned and an error message is placed in
-.IR err .
-.PP
-.I Pperror
-returns an error message that is contained in
-.IR buf.
-.PP
-.SH "SEE ALSO"
-.SH DIAGNOSTICS
//GO.SYSIN DD scsi/juke.3
echo scsi/warm.c 1>&2
sed 's/.//' >scsi/warm.c <<'//GO.SYSIN DD scsi/warm.c'
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include "scsi.h"
-#include "juke.h"
-
-warm_inv(char *buf)
-{
- Side side;
- int drive, sh;
- char vol_id[512];
-
- if(j_rdshelves(buf)) /* read in shelf names */
- return(-1);
- side = SIDEA;
- drive = min(nlun+1, NLUN-1);
- for(;;){
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
- for(sh = 0; sh < NSHELF; sh++)
- if(j_status.shelf[sh]&0x10) break;
- if(sh >= NSHELF)
- break;
- if(getvol(127, drive, vol_id, &side)){
- strcpy(buf, vol_id);
- return(-1);
- }
- for(sh = 0; j_shelf[sh]; sh++)
- ;
- printf("%s -> %d\n", vol_id, sh);
- if(j_drive_to_shelf(drive, sh, side, buf) < 0)
- return(-1);
- j_wrshelf = 1;
- j_shelf[sh] = strdup(vol_id);
- sleep(1);
- }
- return(0);
-}
//GO.SYSIN DD scsi/warm.c
echo scsi/juke.h 1>&2
sed 's/.//' >scsi/juke.h <<'//GO.SYSIN DD scsi/juke.h'
-#define NLUN 8
-#define NSHELF 50
-extern int nlun;
-extern void setnlun(void);
-extern char *j_shelf[NSHELF];
-extern int j_wrshelf; /* need to write out shelves */
-extern j_rdshelves(char *err);
-extern j_wrshelves(char *err);
-extern j_inventory(char cold, int tlim, char *err);
-
-typedef enum { SIDEA = 0, SIDEB = 1 } Side;
-
-struct Lunstatus
-{
- unsigned int poweron:1; /* is power on ? */
- unsigned int diskin:1; /* is disk in drive? */
- unsigned int ready:1; /* is disk spun up or spun down? */
- unsigned int writeprotect:1; /* is disk write protected? */
- unsigned int diskindrive:1; /* is driveshelf a drive number? */
- unsigned int shelfvalid:1; /* is retshelf valid? */
- uchar driveshelf; /* drive number */
- uchar retshelf; /* return shelf */
-};
-
-struct Jstatus
-{
- struct Lunstatus lun[NLUN]; /* disk status */
- uchar shelf[NSHELF]; /* shelf status */
- uchar iounit; /* I/O unit status */
- uchar carrier; /* carrier status */
- uchar udrive; /* upper drive status */
- uchar ldrive; /* lower drive status */
-};
-extern struct Jstatus j_status;
-extern int j_getstatus(char *err);
-extern int j_shelfof(char *vol_id);
-extern int j_driveof(char *vol_id);
-
-extern char *strdup(char *);
-extern int j_shelf_to_drive(int, Side, int, char *);
-extern int j_drive_to_shelf(int, int, Side, char *);
-extern int j_empty_drive(long, char *);
-extern int j_rvolid(int, char *);
-extern int j_wvolid(int, char *, char *);
-extern void pperror(char *buf, char *mesg);
-extern int reserve_drive(int, char *);
-extern int release_drive(int, char *);
-extern int cold_inv(char, char *);
-extern int warm_inv(char *);
-extern int j_load(char *vol_id, char *buf, long tlim);
-extern int j_unload(char *vol_id, char *buf);
-
-#define JUKEDIR "/usr/worm/jukedir"
-#define UNALLOCATED "<unallocated>"
//GO.SYSIN DD scsi/juke.h
echo scsi/scsi.h 1>&2
sed 's/.//' >scsi/scsi.h <<'//GO.SYSIN DD scsi/scsi.h'
-typedef unsigned char uchar;
-
-struct scsi_cmd
-{
- unsigned long id;
- uchar bus_id; /* SCSI id of destination device */
- uchar flags;
- uchar cmd[10]; /* SCSI command */
- uchar data[4096]; /* optional data */
-};
-
-struct scsi_return
-{
- unsigned long id;
- uchar scsi_stat; /* scsi status byte */
- uchar scsi_msg; /* scsi message byte */
- uchar flags;
- uchar type; /* 1=td 2=us */
- unsigned short reg1; /* td=sa, us=per */
- unsigned short reg2; /* td=mscp, us=per */
- unsigned char sense[22];
- char pad[2];
- uchar data[4096]; /* any data */
- uchar nread; /* chars read(-8) if ret count was -ve */
-};
-
-#define set6(x,a,b,c,d,e,f) (x).flags=0,(x).cmd[0]=(a),(x).cmd[1]=(b),(x).cmd[2]=(c),\
- (x).cmd[3]=(d),(x).cmd[4]=(e),(x).cmd[5]=(f)
-#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),\
- (x).cmd[3]=(d),(x).cmd[4]=(e),(x).cmd[5]=(f),(x).cmd[6]=(g),(x).cmd[7]=(h),\
- (x).cmd[8]=(i),(x).cmd[9]=(j)
-#define setdiag(x,lun,n) (x).flags=0,(x).cmd[0]=0x1C,(x).cmd[1]=(lun)<<5,(x).cmd[2] = 0,\
- (x).cmd[3]=(n)>>8,(x).cmd[4]=(n),(x).cmd[5]=0
-
-extern s_io(int, struct scsi_cmd *, int, struct scsi_return *, int, char *);/* return 0 on no error, does sense on error */
-extern ss_io(int, struct scsi_cmd *, int, struct scsi_return *, int, char *);/* return 0 on no error */
-extern int s_ignua; /* should s_io ignore unit attentions? */
-extern void (*ss_extsense)(uchar *, char *, int);
-extern int s_start(int, char *);
-extern int s_stop(int, char *);
-extern int s_eject(int, char *);
-extern int s_id;
-extern unsigned long longat(uchar *);
//GO.SYSIN DD scsi/scsi.h
echo scsi/jukebox.c 1>&2
sed 's/.//' >scsi/jukebox.c <<'//GO.SYSIN DD scsi/jukebox.c'
-#include <stdio.h>
-#include <limits.h>
-#include "scsi.h"
-#include "juke.h"
-
-main(int argc, char *argv[])
-{
- int c;
- int aflag = 0, eflag = 0, mflag = 0, pflag = 0;
- int rflag = 0, sflag = 0, uflag = 0, Uflag = 0;
- long secs = 3600L*24*183; /* half a year is enough */
- char *vol_id;
- char errbuf[1024];
- extern int optind;
- extern char *optarg;
-
- setbuf(stdout, (char *)0); /* turn off buffering */
- while((c = getopt(argc, argv, "aemprsuUw:")) != -1)
- switch (c)
- {
- case 'a': aflag = 1; break;
- case 'e': eflag = 1; break;
- case 'm': mflag = 1; break;
- case 'p': pflag = 1; break;
- case 'r': rflag = 1; break;
- case 's': sflag = 1; break;
- case 'u': uflag = 1; break;
- case 'U': Uflag = 1; break;
- case 'w': secs = atol(optarg); break;
- default: usage(); break;
- }
- s_id = 2;
- setnlun();
- if(!aflag&&!eflag&&!mflag&&!pflag&&!rflag&&!uflag&&!Uflag)
- sflag = 1;
- vol_id = (optind < argc)? argv[optind] : 0;
- if(uflag || Uflag)
- unload(Uflag);
- if(eflag){
- if(vol_id == 0){
- strcpy(errbuf, "-e needs a vol_id");
- goto scram;
- }
- if(eject(vol_id, errbuf))
- goto scram;
- }
- if(rflag){
- unload(1);
- sleep(1);
- if(cold_inv(vol_id? *vol_id : 'u', errbuf) < 0)
- goto scram;
- }
- if(aflag){
- if(vol_id == 0){
- strcpy(errbuf, "-a needs a vol_id");
- goto scram;
- }
- if(allocate(vol_id, errbuf))
- goto scram;
- }
- if(mflag){
- if((c = j_load(vol_id, errbuf, secs)) < 0)
- goto scram;
- if(s_start(c, errbuf) < 0)
- fprintf(stderr, "jukebox: %s\n", errbuf);
- if(s_stop(c, errbuf) < 0)
- fprintf(stderr, "jukebox: %s\n", errbuf);
- printf("%d\n", c);
- }
- if(sflag)
- prstatus();
- if(pflag){
- if(j_rdshelves(errbuf) < 0)
- goto scram;
- for(c = 0; c < NSHELF; c++)
- if(j_shelf[c])
- printf("%d: %s\n", c, j_shelf[c]);
- }
- if(j_wrshelf)
- if(j_wrshelves(errbuf))
- errexit(errbuf);
- exit(0);
-scram:
- if(j_wrshelf)
- j_wrshelves(errbuf);
- errexit(errbuf);
-}
-
-usage()
-{
- fprintf(stderr, "Usage: jukebox [-aemprsuU] [-w secs] [vol_id\n");
- exit(1);
-}
-
-errexit(char *errbuf)
-{
- fprintf(stderr, "jukebox: %s\n", errbuf);
- exit(1);
-}
-
-prstatus()
-{
- struct Lunstatus *l;
- int c;
- char errbuf[1024];
- static char *spin[2] = { "offline", "online" };
-
- if(j_getstatus(errbuf)){
- fprintf(stderr, "jukebox: %s\n", errbuf);
- exit(1);
- }
- if(j_rdshelves(errbuf)){
- fprintf(stderr, "jukebox: %s\n", errbuf);
- exit(1);
- }
- for(c = 0; c < 8; c++){
- l = &j_status.lun[c];
- if(!l->diskin)
- continue;
- printf("lun %d(", c);
- if(j_status.udrive == (0x80|c))
- printf("upper,%s", spin[l->ready]);
- else if(j_status.ldrive == (0x80|c))
- printf("lower,%s", spin[l->ready]);
- else
- printf("in shelf");
- printf("): ");
- if(l->shelfvalid){
- if(j_shelf[l->retshelf>>1])
- printf("%s%c", j_shelf[l->retshelf>>1], "ab"[l->retshelf&1]);
- else
- printf("unallocated shelf number %d??", l->retshelf);
- } else
- printf("<unknown shelf??>");
- printf("\n");
- }
-}
-
-unload(int force)
-{
- struct Lunstatus *l;
- int c;
- char errbuf[1024];
-
- if(j_getstatus(errbuf)){
- fprintf(stderr, "jukebox: %s\n", errbuf);
- exit(1);
- }
- if(j_rdshelves(errbuf)){
- fprintf(stderr, "jukebox: %s\n", errbuf);
- exit(1);
- }
- for(c = 0; c < 8; c++){
- l = &j_status.lun[c];
- if(!l->diskin)
- continue;
- if(force || !l->ready)
- if(j_drive_to_shelf(c, -1, SIDEA, errbuf))
- fprintf(stderr, "jukebox: %s\n", errbuf);
- }
-}
-
-eject(char *vol_id, char *errbuf)
-{
- int sh;
- int dr;
-
- if(j_rdshelves(errbuf)){
- fprintf(stderr, "jukebox: %s\n", errbuf);
- exit(1);
- }
- sh = j_shelfof(vol_id);
- if(sh < 0){
- sprintf(errbuf, "xcan't find vol_id %s", vol_id);
- return(-1);
- }
- j_wrshelf = 1;
- if((dr = j_driveof(vol_id)) >= 0){
- j_shelf[sh] = 0;
- return(s_eject(dr, errbuf));
- }
- dr = NLUN-1;
- if(j_shelf_to_drive(sh, SIDEA, dr, errbuf) < 0)
- return(-1);
- if(s_eject(dr, errbuf))
- return(-1);
- j_shelf[sh] = 0;
- return(0);
-}
//GO.SYSIN DD scsi/jukebox.c
echo scsi/getstatus.c 1>&2
sed 's/.//' >scsi/getstatus.c <<'//GO.SYSIN DD scsi/getstatus.c'
-#include <stddef.h>
-#include <stdio.h>
-#include "scsi.h"
-#include "juke.h"
-
-struct Jstatus j_status;
-
-static
-dolun(struct Lunstatus *lun, uchar *u)
-{
- lun->poweron = ((*u)&0x80) == 0;
- lun->diskin = ((*u)&0x40) != 0;
- lun->ready = ((*u)&0x01) != 0;
- u++;
- lun->diskindrive = ((*u)&0x80) != 0;
- lun->driveshelf = (*u)&0x7F;
- u++;
- lun->shelfvalid = ((*u)&0x80) != 0;
- lun->retshelf = (*u)&0x7F;
-}
-
-j_getstatus(char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int i;
-
- set6(cmd, 0x1D, 0, 0, 0, 10, 0);
- memset(cmd.data, 0, 10);
- cmd.data[0] = 0xE2;
- if(s_io(1, &cmd, 10, &ret, 0, err))
- return(-1);
- set6(cmd, 0x1C, 0, 0, 0, 128, 0);
- if(s_io(0, &cmd, 0, &ret, 128, err))
- return(-1);
- for(i = 0; i < 8; i++)
- dolun(&j_status.lun[i], &ret.data[16+4*i]);
- for(i = 0; i < NSHELF; i++)
- j_status.shelf[i] = ret.data[48+i];
- j_status.iounit = ret.data[98];
- j_status.carrier = ret.data[99];
- j_status.udrive = ret.data[100];
- j_status.ldrive = ret.data[101];
- return(0);
-}
//GO.SYSIN DD scsi/getstatus.c
echo scsi/nlun.c 1>&2
sed 's/.//' >scsi/nlun.c <<'//GO.SYSIN DD scsi/nlun.c'
-#include <stdio.h>
-#include "scsi.h"
-#include "juke.h"
-
-int nlun = 1;
-
-void
-setnlun(void)
-{
- char buf[512];
-
- for(nlun = 0; nlun < NLUN; nlun++){
- sprintf(buf, "/dev/worm%d", nlun);
- if(access(buf, 0) < 0)
- return;
- }
-}
//GO.SYSIN DD scsi/nlun.c
echo scsi/allocate.c 1>&2
sed 's/.//' >scsi/allocate.c <<'//GO.SYSIN DD scsi/allocate.c'
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include "scsi.h"
-#include "juke.h"
-
-allocate(char *vol_id, char *buf)
-{
- int drive, sh;
- char nbuf[512];
-
- if(j_rdshelves(buf)) /* read in shelf names */
- return(-1);
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
- sh = j_shelfof(vol_id);
- if(sh >= 0){
- sprintf(buf, "there is an existing '%s' on shelf %d", vol_id, sh);
- return(-1);
- }
- sh = j_shelfof(UNALLOCATED);
- if(sh < 0){
- sprintf(buf, "no unallocated disks");
- return(-1);
- }
- printf("using unallocated disk from shelf %d\n", sh);
- drive = min(nlun+1, NLUN-1);
- if(j_shelf_to_drive(sh, SIDEB, drive, buf) < 0)
- return(-1);
- sprintf(nbuf, "%sb", vol_id);
- if(j_wvolid(drive, nbuf, buf))
- return(-1);
- j_wrshelf = 1;
- j_shelf[sh] = strdup(vol_id);
- if(j_drive_to_shelf(drive, sh, SIDEB, buf) < 0)
- return(-1);
- if(j_shelf_to_drive(sh, SIDEA, drive, buf) < 0)
- return(-1);
- sprintf(nbuf, "%sa", vol_id);
- if(j_wvolid(drive, nbuf, buf))
- return(-1);
- if(j_drive_to_shelf(drive, sh, SIDEA, buf) < 0)
- return(-1);
- return(0);
-}
//GO.SYSIN DD scsi/allocate.c
echo scsi/scsi/dslib.c 1>&2
sed 's/.//' >scsi/scsi/dslib.c <<'//GO.SYSIN DD scsi/scsi/dslib.c'
-/*
-|| dslib.c - library routines for /dev/scsi
-||
-|| Copyright 1988, 1989, by
-|| Gene Dronek (Vulcan Laboratory) and
-|| Rich Morin (Canta Forda Computer Laboratory).
-|| All rights reserved.
-*/
-#ident "dslib.c: $Revision: 1.4 $"
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "dslib.h"
-#ifdef aux
-#include <sys/vio.h>
-#include <sys/scsireq.h>
-#endif aux
-
-int dsdebug=0;
-long dsreqflags; /* flag bits always set by filldsreq */
-
-#define min(i,j) ( (i) < (j) ? (i) : (j) )
-
-
-/*
-|| Startup/shutdown -----------------------------------------------
-*/
-
-static struct context *dsc[FDSIZ];
-
-
-/*
-|| dsopen - open device, set up structures
-*/
-
-struct dsreq *
-dsopen(opath, oflags)
- char *opath;
- int oflags;
-{
-
- struct dsreq *dsp;
- struct context *cp;
- int fd;
- DSDBG(fprintf(stderr,"dsopen(%s,%x) ", opath, oflags));
-
- fd = open(opath, oflags);
- if (fd < 0)
- return NULL; /* can't open */
- if (dsc[fd] != NULL) /* already in use */
- ds_zot("dsopen: fd already in use");
-
- cp = (struct context *) calloc(1, sizeof(struct context));
- if (cp == NULL) /* can't allocate */
- ds_zot("dsopen: can't allocate space");
- dsc[fd] = cp;
- cp->dsc_fd = fd;
- dsp = &(cp->dsc_dsreq);
-
- dsp->ds_flags = 0;
- dsp->ds_time = 10 * 1000; /* 10 second default timeout */
- dsp->ds_private = (ulong) cp; /* pointer back to context */
- dsp->ds_cmdbuf = cp->dsc_cmd;
- dsp->ds_cmdlen = sizeof cp->dsc_cmd;
- dsp->ds_databuf = 0;
- dsp->ds_datalen = 0;
- dsp->ds_sensebuf = cp->dsc_sense;
- dsp->ds_senselen = sizeof cp->dsc_sense;
- DSDBG(fprintf(stderr,"=>cp %x, dsp %x\n", cp, dsp));
- return dsp;
-}
-
-
-/*
-|| dsclose - close device, release context struct.
-*/
-
-dsclose(dsp)
- struct dsreq *dsp;
-{
- int fd;
- struct context *cp;
-
- if (dsp == NULL)
- ds_zot("dsclose: dsp is NULL");
-
- cp = (struct context *)dsp->ds_private;
- fd = getfd(dsp);
- if ( cp == NULL )
- ds_zot("dsclose: private is NULL");
-
- cfree(cp);
- dsc[fd] = (struct context *)NULL;
- return;
-}
-
-
-/*
-|| Generic SCSI CCS Command functions ------------------------------------
-||
-|| dsp dsreq pointer
-|| data data buffer pointer
-|| datalen data buffer length
-|| lba logical block address
-|| vu vendor unique bits
-*/
-
-/*
-|| testunitready00 - issue group 0 "Test Unit Ready" command (0x00)
-*/
-
-testunitready00(dsp)
- struct dsreq *dsp;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_TEST, 0, 0, 0, 0, 0);
- filldsreq(dsp, 0, 0, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| requestsense03 - issue group 0 "Request Sense" command (0x03)
-*/
-
-requestsense03(dsp, data, datalen, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_REQU, 0, 0, 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| write0a - issue group 0 "Write" command (0x0a)
-*/
-
-write0a(dsp, data, datalen, lba, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_WRIT, B3(lba), B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| inquiry12 - issue group 0 "Inquiry" command (0x12)
-*/
-
-inquiry12(dsp, data, datalen, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_INQU, 0, 0, 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| modeselect15 - issue group 0 "Mode Select" command (0x15)
-||
-|| save 0 - don't save saveable pages
-|| 1 - save saveable pages
-*/
-
-modeselect15(dsp, data, datalen, save, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char save, vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_MSEL, save&1, 0, 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_WRITE|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| modesense1a - issue group 0 "Mode Sense" command (0x1a)
-||
-|| pagectrl 0 - current values
-|| 1 - changeable values
-|| 2 - default values
-|| 3 - saved values
-||
-|| pagecode 0 - vendor unique
-|| 1 - error recovery
-|| 2 - disconnect/reconnect
-|| 3 - direct access dev. fmt.
-|| 4 - rigid disk geometry
-|| 5 - flexible disk
-|| 6-9 - see specific dev. types
-|| 0a - implemented options
-|| 0b - medium types supported
-|| 3f - return all pages
-*/
-
-modesense1a(dsp, data, datalen, pagectrl, pagecode, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char pagectrl, pagecode, vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN, 0x10,
- ((pagectrl&3)<<6) | (pagecode&0x3F),
- 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| senddiagnostic1d - issue group 0 "Send Diagnostic" command (0x1d)
-||
-|| self 0 - run test, hold results
-|| 1 - run test, return status
-||
-|| dofl 0 - device online
-|| 1 - device offline
-||
-|| uofl 0 - unit online
-|| 1 - unit offline
-*/
-
-senddiagnostic1d(dsp, data, datalen, self, dofl, uofl, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char self, dofl, uofl, vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN,
- (self&1)<<2 | (dofl&1)<<1 | (uofl&1),
- 0, B2(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| readcapacity25 - issue group 1 "Read Capacity" command (0x25)
-||
-|| pmi 0 - return last logical block, entire unit
-|| 1 - return last logical block, current track
-*/
-
-readcapacity25(dsp, data, datalen, lba, pmi, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char pmi, vu;
-{
- fillg1cmd(dsp, CMDBUF(dsp), G1_RCAP, 0, B4(lba), 0, 0, pmi&1, B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE
- /* |DSRQ_CTRL2 */ );
- /* dsp->ds_time = 100; /* often takes a while */
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| readextended28 - issue group 1 "Read Extended" command (0x28)
-*/
-
-readextended28(dsp, data, datalen, lba, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char vu;
-{
- fillg1cmd(dsp, CMDBUF(dsp), G1_READ, 0, B4(lba), 0, B2(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE
- /* |DSRQ_CTRL2 */ );
- /* dsp->ds_time = 100; /* often takes a while */
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| writeextended2a - issue group 1 "Write Extended" command (0x2a)
-*/
-
-writeextended2a(dsp, data, datalen, lba, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char vu;
-{
- fillg1cmd(dsp, CMDBUF(dsp), G1_WRIT, 0, B4(lba), 0, B2(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE
- /* |DSRQ_CTRL2 */ );
- /* dsp->ds_time = 100; /* often takes a while */
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| Support functions ----------------------------------------------------
-*/
-
-/*
-|| fillg0cmd - Fill a Group 0 command buffer
-*/
-
-fillg0cmd(dsp, cmd, b0,b1,b2,b3,b4,b5)
- struct dsreq *dsp;
- uchar_t *cmd, b0,b1,b2,b3,b4,b5;
-{
- uchar_t *c = cmd;
- DSDBG(fprintf(stderr,"fillg0cmd(%x,%x, %02x %02x %02x %02x %02x %02x)\n",
- dsp, cmd, b0,b1,b2,b3,b4,b5));
- *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5;
-
- CMDBUF(dsp) = (caddr_t) cmd;
- CMDLEN(dsp) = 6;
-}
-
-
-/*
-|| fillg1cmd - Fill a Group 1 command buffer
-*/
-
-fillg1cmd(dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)
- struct dsreq *dsp;
- uchar_t *cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9;
-{
- uchar_t *c = cmd;
- DSDBG(fprintf(stderr,
- "fillg1cmd(%x,%x, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)\n",
- dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9));
-
- *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5;
- *c++ = b6, *c++ = b7, *c++ = b8, *c++ = b9;
-
- CMDBUF(dsp) = (caddr_t) cmd;
- CMDLEN(dsp) = 10;
-}
-
-
-/*
-|| filldsreq - Fill a dsreq structure
-*/
-
-filldsreq(dsp,data,datalen,flags)
- struct dsreq *dsp;
- uchar_t *data;
-{
- DSDBG(fprintf(stderr,"filldsreq(%x,%x,%d,%x) cmdlen %d\n",
- dsp,data,datalen,flags,CMDLEN(dsp)));
- dsp->ds_flags = flags | dsreqflags |
- (((dsdebug&1) ? DSRQ_TRACE : 0) |
- ((dsdebug&2) ? DSRQ_PRINT : 0));
- dsp->ds_time = 10 * 1000; /* default to 10 seconds */
- dsp->ds_link = 0;
- dsp->ds_synch = 0;
- dsp->ds_ret = 0;
-
- DATABUF(dsp) = (caddr_t) data;
- DATALEN(dsp) = datalen;
-}
-
-
-/*
-|| bprint - print array of bytes, in hex.
-*/
-
-#define hex(x) "0123456789ABCDEF" [ (x) & 0xF ]
-
-bprint(s,n,nperline,space)
- char *s;
-{
- int i, x;
- char *sp = (space) ? " ": "";
-
- for(i=0;i<n;i++) {
- x = s[i];
- fprintf(stderr,((i%4==3)?"%c%c%s%s":"%c%c%s"),
- hex(x>>4), hex(x), sp, sp);
- if ( i%nperline == (nperline - 1) )
- fprintf(stderr,"\n");
- }
- if ( space )
- fprintf(stderr,"\n");
-}
-
-
-/*
-|| doscsireq - issue scsi command, return status or -1 error.
-*/
-
-doscsireq( fd, dsp)
- int fd; /* ioctl file descriptor */
- struct dsreq *dsp; /* devscsi request packet */
-{
- int cc;
- int retries = 4;
- uchar_t sbyte;
-
- DSDBG(fprintf(stderr,"doscsireq(%d,%x) %x ---- %s\n",fd,dsp,
- (CMDBUF(dsp))[0],
- ds_vtostr( (CMDBUF(dsp))[0], cmdnametab)));
-
- /*
- * loop, issuing command
- * until done, or further retry pointless
- */
-
- while ( --retries > 0 ) {
-
- caddr_t sp;
-
- sp = SENSEBUF(dsp);
- DSDBG(fprintf(stderr,"cmdbuf = ");
- bprint(CMDBUF(dsp),CMDLEN(dsp),16,1));
- if ( (dsp->ds_flags & DSRQ_WRITE) )
- DSDBG(bprint( DATABUF(dsp), min(50,DATALEN(dsp)),16,1 ));
-
-DSDBG(fprintf(stderr,"databuf datalen %x %d\n",DATABUF(dsp), DATALEN(dsp)));
- cc = ioctl( fd, DS_ENTER, dsp);
- if ( cc < 0) {
- ds_panic(dsp, "cannot ioctl fd %d\n",fd);
- }
-
- DSDBG(fprintf(stderr,"cmdlen after ioctl=%d\n",CMDLEN(dsp)));
- DSDBG(fprintf(stderr,"ioctl=%d ret=%x %s",
- cc, RET(dsp),
- RET(dsp) ? ds_vtostr(RET(dsp),dsrtnametab) : ""));
- DSDBG(if (SENSESENT(dsp)) fprintf(stderr," sensesent=%d",
- SENSESENT(dsp)));
-
- DSDBG(fprintf(stderr,
- " cmdsent=%d datasent=%d sbyte=%x %s\n",
- CMDSENT(dsp), DATASENT(dsp), STATUS(dsp),
- ds_vtostr(STATUS(dsp), cmdstatustab)));
- DSDBG(if ( FLAGS(dsp) & DSRQ_READ )
- bprint( DATABUF(dsp), min(16*16,DATASENT(dsp)), 16,1));
-
-#ifdef aux
- /*
- * check for AUX bus-error
- * we retry with poll-dma
- */
- if ( RET(dsp) == DSRT_AGAIN ) {
- int n = SDC_RDPOLL|SDC_WRPOLL;
- DSDBG(fprintf(stderr,"setting rd/wr-poll"));
- cc = ioctl( fd, DS_SET, n); /* set bits */
- if ( cc != 0 )
- return -1;
- }
-#endif aux
-
- if ( RET(dsp) == DSRT_NOSEL )
- continue; /* retry noselect 3X */
-
- /* decode sense data returned */
- if ( SENSESENT(dsp) ) {
- DSDBG(
- fprintf(stderr, "sense key %x - %s\n",
- SENSEKEY(sp),
- ds_vtostr( SENSEKEY(sp), sensekeytab));
- bprint( SENSEBUF(dsp),
- min(100, SENSESENT(dsp)),
- 16,1);
- );
- }
- DSDBG(fprintf(stderr, "sbyte %x\n", STATUS(dsp)));
-
- /* decode scsi command status byte */
- sbyte = STATUS(dsp);
- switch (sbyte) {
- case 0x08: /* BUSY */
- case 0x18: /* RESERV CONFLICT */
- sleep(2);
- continue;
- case 0x00: /* GOOD */
- case 0x02: /* CHECK CONDITION */
- case 0x10: /* INTERM/GOOD */
- default:
- return sbyte;
- }
- }
- return -1; /* fail retry limit */
-}
-
-
-/*
-|| opttovar - lookup option in table, return var addr (NULL if fail)
-*/
-
-int *
-opttovar( ostr, table)
- char *ostr;
- struct opttab{
- char *opt;
- int *var;
- } *table;
-{
- register struct opttab *tp;
-
- for (tp=table; (tp->var); tp++)
- if ( strncmp( ostr, tp->opt, 3) == 0 )
- break;
-
- if ( !tp->var )
- fprintf(stderr,"unknown option %s", ostr);
-
- return (tp->var);
-}
-
-
-/*
-|| ds_vtostr - lookup value in table to return string pointer
-*/
-
-char *
-ds_vtostr( v, table)
- long v;
- struct vtab *table;
-{
- register struct vtab *tp;
-
- for (tp=table; (tp->string); tp++)
- if ( v == tp->val )
- break;
-
- return (tp->string) ? tp->string : "";
-}
-
-
-/*
-|| ds_panic - yelp, leave...
-*/
-
-ds_panic( fmt, v)
- char *fmt;
- int v;
-{
- extern errno;
-
- fprintf(stderr,fmt,v);
- fprintf(stderr,"\nerrno = %d\n",errno);
- exit(1);
-}
-
-
-/*
-|| ds_zot - go away, with a message.
-*/
-
-ds_zot(message)
- char *message;
-{
- fprintf(stderr, "%s\n", message);
- exit(1);
-}
//GO.SYSIN DD scsi/scsi/dslib.c
echo scsi/scsi/volid.c 1>&2
sed 's/.//' >scsi/scsi/volid.c <<'//GO.SYSIN DD scsi/scsi/volid.c'
-#include <stddef.h>
-#include <stdio.h>
-#include "../scsi.h"
-#include "../juke.h"
-
-static
-myread(int drive, long block, struct scsi_return *ret, char *err)
-{
- struct scsi_cmd cmd;
-
- cmd.bus_id = s_id;
- set10(cmd, 0x28, drive<<5, block>>24, block>>16, block>>8, block, 0, 0, 1, 0);
- return(s_io(0, &cmd, 0, ret, 1024, err));
-}
-
-j_rvolid(int drive, char *err)
-{
- struct scsi_return ret;
- long b, lastb;
- char buf[1024];
- int debug = 0;
-
- err[0] = 0;
- if(s_start(drive, err) < 0)
- return(-1);
- if(myread(drive, 0L, &ret, err) == 0){
- memset(buf, 0, 1024);
- if(memcmp(buf, ret.data, 1024)){
- if(debug)
- fprintf(stderr, "superblok at 0\n");
- goto done; /* found a superblock at 0 */
- }
- }
- for(b = 1, lastb = -1;;){
-hack:
- if(debug)
- fprintf(stderr, "read block %d\n", b);
- if(myread(drive, b, &ret, err))
- break;
- lastb = b;
- b = ((long *)ret.data)[9];
- }
- if(lastb < 0){
- if(b == 1){ /* for disks with a bad block 1 */
- b = 2;
- goto hack;
- }
- if(debug)
- fprintf(stderr, "tried for superblock at blocks 1,2\n");
- sprintf(err, "no superblock");
- s_stop(drive, buf);
- return(1);
- }
- if(myread(drive, lastb, &ret, err) < 0){
- s_stop(drive, buf);
- fprintf(stderr, "read fail on block %d (b=%d)\n", lastb, b);/**/
- return(-1);
- }
- if(debug)
- fprintf(stderr, "superblock at %d\n", lastb);
-done:
- strncpy(err, (char *)&ret.data[42], 128);
- err[127] = 0;
- s_stop(drive, buf);
- return(0);
-}
-
-static
-mywrite(int drive, long block, struct scsi_cmd *cmd, struct scsi_return *ret, char *err)
-{
- set10((*cmd), 0x2A, drive<<5, block>>24, block>>16, block>>8, block, 0, 0, 1, 0);
- return(s_io(0, cmd, 1024, ret, 0, err));
-}
-
-j_wvolid(int drive, char *vol_id, char *err)
-{
- char tmpfile[L_tmpnam];
- char buf[512];
- struct scsi_return ret;
- struct scsi_cmd cmd;
- FILE *fp;
- int n;
-
- printf("mkfs %s\n", vol_id);
- /* first get the capacity/size for mkfs to make a valid superblock */
- tmpnam(tmpfile);
- if((fp = fopen(tmpfile, "w+r")) == NULL){
- pperror(err, tmpfile);
- return(-1);
- }
- if(s_start(drive, err) < 0)
- return(-1);
- set10(cmd, 0x25, drive<<5, 0, 0, 0, 0, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 8, err))
- return(n);
- switch(longat(&ret.data[0]))
- {
- case 1637999: /* sony 12in clv single density */
- sprintf(buf, "worm mkfs -n %d -f %s %s", 1600000, tmpfile, vol_id);
- break;
- case 3275999: /* sony 12in clv double density */
- sprintf(buf, "worm mkfs -n %d -f %s %s", 3250000, tmpfile, vol_id);
- break;
- default:
- fprintf(stderr, "warning: bad capacity %d\n", longat(&ret.data[0]));
- sprintf(buf, "worm mkfs -f %s %s", tmpfile, vol_id);
- break;
- }
- if(system(buf)){
- sprintf(err, "%s: error", buf);
- return(-1);
- }
- unlink(tmpfile);
- fseek(fp, 1024L, 0);
- if(fread(cmd.data, 1, 1024, fp) == 0){
- pperror(err, "mkfs read");
- return(-1);
- }
- fclose(fp);
- if(mywrite(drive, 1L, &cmd, &ret, err))
- return(-1);
- unlink(tmpfile);
- s_stop(drive, err);
- return(0);
-}
//GO.SYSIN DD scsi/scsi/volid.c
echo scsi/scsi/pperror.c 1>&2
sed 's/.//' >scsi/scsi/pperror.c <<'//GO.SYSIN DD scsi/scsi/pperror.c'
-#include "../scsi.h"
-
-void
-pperror(char *buf, char *mesg)
-{
- extern int sys_nerr;
- extern char *sys_errlist[];
- extern int errno;
-
- if((errno < 0) || (errno >= sys_nerr))
- sprintf(buf, "%s: unknown errno %d", mesg, errno);
- else
- sprintf(buf, "%s: %s", mesg, sys_errlist[errno]);
-}
//GO.SYSIN DD scsi/scsi/pperror.c
echo scsi/scsi/fixedstr.c 1>&2
sed 's/.//' >scsi/scsi/fixedstr.c <<'//GO.SYSIN DD scsi/scsi/fixedstr.c'
-#include "../scsi.h"
-
-void
-fixedstr(uchar *src, int len, char *dest)
-{
- uchar *s;
-
- while((*src == ' ') && (len > 0))
- src++, len--;
- for(s = src+len-1; s >= src; s--)
- if(*s != ' ')
- break;
- memcpy(dest, (char *)src, len = s-src+1);
- dest[len] = 0;
-}
//GO.SYSIN DD scsi/scsi/fixedstr.c
echo scsi/scsi/longat.c 1>&2
sed 's/.//' >scsi/scsi/longat.c <<'//GO.SYSIN DD scsi/scsi/longat.c'
-#include "../scsi.h"
-
-unsigned long
-longat(uchar *src)
-{
- unsigned long n;
-
- n = *src++;
- n = (n<<8) | *src++;
- n = (n<<8) | *src++;
- n = (n<<8) | *src;
- return(n);
-}
//GO.SYSIN DD scsi/scsi/longat.c
echo scsi/scsi/xd.c 1>&2
sed 's/.//' >scsi/scsi/xd.c <<'//GO.SYSIN DD scsi/scsi/xd.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-
-#define WIDTH 32
-
-void
-xd(uchar *p, int n, FILE *fp)
-{
- register i, nd, l;
- unsigned char buf[WIDTH];
- int didstar;
- unsigned char *s;
-
- for(nd = 0; n > 0; n -= l, nd += l){
- l = min(WIDTH, n);
- if(nd && (l == WIDTH) && (memcmp(buf, p, l) == 0)){
- p += WIDTH;
- if(didstar++ == 0)
- fprintf(fp, "*\n");
- continue;
- }
- memcpy(buf, p, l);
- didstar = 0;
- fprintf(fp, "%5.5d", nd);
- s = p;
- for(i = 0; i < l; i++){
- if((i%4) == 0) putc(' ', fp);
- fprintf(fp, "%2.2x", *p++);
- }
- putc('\n', fp);
- fprintf(fp, " ");
- for(i = 0; i < l; i++){
- if((i%4) == 0) putc(' ', fp);
- if((*s >= ' ') && (*s < 0177))
- fprintf(fp, " %c", *s++);
- else switch(*s++)
- {
- case '\n': fprintf(fp, "\\n"); break;
- case '\t': fprintf(fp, "\\t"); break;
- default: fprintf(fp, ".."); break;
- }
- }
- putc('\n', fp);
- }
- fprintf(fp, "%5.5d\n", nd);
-}
//GO.SYSIN DD scsi/scsi/xd.c
echo scsi/scsi/md_io.c 1>&2
sed 's/.//' >scsi/scsi/md_io.c <<'//GO.SYSIN DD scsi/scsi/md_io.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include <sys/types.h>
-#include <sys/dsreq.h>
-
-#define DEV(buf, target, lun) sprintf(buf, "/dev/scsi/sc0d%dl%d", target, lun)
-
-static fd = -1;
-int s_id;
-void (*ss_extsense)(uchar *, char *, int);
-
-ss_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err)
-{
- int retv;
- dsreq_t ds;
- char dev[512];
-
- err[0] = 0;
- retv = -1;
- if(ncmd && nret){
- sprintf(err, "both input (%d bytes) and output (%d bytes) expected", ncmd, nret);
- return(retv);
- }
- if(cmd->bus_id & 0x8000){
- sprintf(err, "reset not supported");
- return(retv);
- }
- if(fd < 0){
- DEV(dev, cmd->bus_id, ((cmd->cmd[1]>>5)&7));
- if((fd = open(dev, 2)) < 0){
- pperror(err, dev);
- return(-1);
- }
- }
- ds.ds_flags = DSRQ_SENSE;
- ds.ds_time = 30000;
- ds.ds_cmdbuf = (char *)cmd->cmd;
- ds.ds_cmdlen = 10;
- if(ncmd){
- ds.ds_databuf = (char *)cmd->data;
- ds.ds_datalen = ncmd;
- ds.ds_flags |= DSRQ_WRITE;
- } else {
- ds.ds_databuf = (char *)ret->data;
- ds.ds_datalen = nret;
- ds.ds_flags |= DSRQ_READ;
- }
- ds.ds_sensebuf = (char *)ret->sense;
- ds.ds_senselen = sizeof ret->sense;
- ds.ds_iovbuf = 0;
- ds.ds_link = 0;
- if(ioctl(fd, DS_ENTER, &ds) < 0){
- pperror(err, "DS_ENTER ioctl");
-err_ret:
- close(fd);
- fd = -1;
- return(retv);
- }
- if(ds.ds_ret
- && (ds.ds_ret != DSRT_SHORT)
- && (ds.ds_ret != DSRT_OK)
- ) /* an error */
- fprintf(stderr, "ds_ret = #%x\n", ds.ds_ret);
- ret->type = 3;
- ret->scsi_stat = ds.ds_status;
- ret->scsi_msg = ds.ds_msg;
- ret->reg1 = ret->reg2 = 0;
- if(nret >= 0){
- if(ds.ds_datasent != nret){
- if(ds.ds_datasent == 0)
- retv = 1;
- else
- sprintf(err, "data transfer error; wanted %d, got %d", nret, ds.ds_datasent);
- goto err_ret;
- }
- } else {
- ret->nread = ds.ds_datasent;
- }
- if(!preserve){
- close(fd);
- fd = -1;
- }
- return(0);
-}
-
-static char *smsg[16] =
-{
- "good", "check condition", "met/good", "reserved",
- "busy", "reserved", "reserved", "reserved",
- "intermediate good", "reserved", "intermediate good/met", "reserved",
- "reservation conflict", "reserved", "reserved", "reserved",
-};
-
-s_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err)
-{
- int n;
- int status;
- char buf[512];
- char ioerr[512];
-
- cmd->bus_id = s_id;
- if(n = ss_io(preserve, cmd, ncmd, ret, nret, err)){
- if(n < 0)
- return(n);
- strcpy(ioerr, err);
- err[0] = 0;
- } else
- ioerr[0] = 0;
- if(status = ret->scsi_stat){
- (*ss_extsense)(ret->data, buf, sizeof buf);
- sprintf(err, "%s; %s", ioerr[0]? ioerr : smsg[(status>>1)&0xF], buf);
- return(1);
- }
- return(0);
-}
//GO.SYSIN DD scsi/scsi/md_io.c
echo scsi/scsi/h_io.c 1>&2
sed 's/.//' >scsi/scsi/h_io.c <<'//GO.SYSIN DD scsi/scsi/h_io.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include <scsi.h>
-
-#define DEV "/dev/scsi"
-
-static fd = -1;
-int s_id;
-int s_ignua = 1;
-void (*ss_extsense)(uchar *, char *, int);
-
-ss_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err)
-{
- int n;
- int retv;
-
- err[0] = 0;
- retv = -1;
- if(fd < 0){
- if((fd = open(DEV, 2)) < 0){
- pperror(err, DEV);
- return(-1);
- }
- }
- cmd->flags |= (ncmd == 0)? SCSI_RD:SCSI_WR;
- if((n = write(fd, cmd, 16+ncmd)) != 16+ncmd){
- pperror(err, "scsiio write");
-err_ret:
- close(fd);
- fd = -1;
- return(retv);
- }
- if(nret >= 0){
- if((n = read(fd, ret, 36+nret)) != 36+nret){
- if(n == 36)
- retv = 1;
- else
- pperror(err, "scsiio read");
- goto err_ret;
- }
- } else {
- if((n = read(fd, ret, 36-nret)) < 0){
- pperror(err, "scsiio read");
- goto err_ret;
- }
- ret->nread = n-36;
- }
- if(!preserve){
- close(fd);
- fd = -1;
- }
- return(0);
-}
-
-static char *smsg[16] =
-{
- "good", "check condition", "met/good", "reserved",
- "busy", "reserved", "reserved", "reserved",
- "intermediate good", "reserved", "intermediate good/met", "reserved",
- "reservation conflict", "reserved", "reserved", "reserved",
-};
-
-s_io(int preserve, struct scsi_cmd *cmd, int ncmd, struct scsi_return *ret, int nret, char *err)
-{
- int n;
- int status;
- char buf[512];
- char ioerr[512];
- struct scsi_cmd mycmd;
- int ignoredua = 0;
-
- cmd->bus_id = s_id;
-again:
- if(n = ss_io(preserve, cmd, ncmd, ret, nret, err)){
- if(n < 0)
- return(n);
- strcpy(ioerr, err);
- err[0] = 0;
- } else
- ioerr[0] = 0;
- if(status = ret->scsi_stat){
- mycmd.bus_id = s_id;
- set6(mycmd, 0x03, cmd->cmd[1]&0xE0, 0, 0, 100, 0);
- if(n = ss_io(0, &mycmd, 0, ret, -100, err))
- return(n);
- if(s_ignua){ /* ignore unit attention ?? */
- if((ret->data[2]&0xF) == 6){ /* it is */
- if(ignoredua++ == 0){ /* but only ignore once */
- mycmd.bus_id = s_id;
- set6(mycmd, 0x12, cmd->cmd[1]&0xE0, 0, 0, 5, 0);
- if(n = ss_io(0, &mycmd, 0, ret, 5, err))
- return(n);
- goto again;
- }
- }
- }
- if(ss_extsense == 0)
- ss_extsense = gen_extsense;
- (*ss_extsense)(ret->data, buf, sizeof buf);
- sprintf(err, "%s; %s", ioerr[0]? ioerr : smsg[(status>>1)&0xF], buf);
- return(1);
- }
- return(0);
-}
//GO.SYSIN DD scsi/scsi/h_io.c
echo scsi/scsi/gendev 1>&2
sed 's/.//' >scsi/scsi/gendev <<'//GO.SYSIN DD scsi/scsi/gendev'
-awk 'END { for(t = 1; t < 8; t++) for(l=0; l < 8; l++){
- printf "/etc/mknod sc0d%dl%d c 43 %d\n", t, l, l*8+t
- }
- print "chmod 600 *; chown andrew *"
- }' < /dev/null
//GO.SYSIN DD scsi/scsi/gendev
echo scsi/iodr_sh.c 1>&2
sed 's/.//' >scsi/iodr_sh.c <<'//GO.SYSIN DD scsi/iodr_sh.c'
-#include "scsi.h"
-#include "juke.h"
-
-j_shelf_to_drive(int sh, Side side, int dr, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
-
- set6(cmd, 0xD6, dr<<5, 0, (sh<<1)|side, 0, 0);
- return(s_io(0, &cmd, 0, &ret, 0, err));
-}
-
-j_drive_to_shelf(int dr, int sh, Side side, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
-
- if(sh < 0)
- set6(cmd, 0xD7, dr<<5, 0, 0, 0, 0);
- else
- set6(cmd, 0xD7, (dr<<5)|1, 0, (sh<<1)|side, 0, 0);
- return(s_io(0, &cmd, 0, &ret, 0, err));
-}
-
-int
-j_empty_drive(long tlimit, char *buf)
-{
- int i, tstop;
-
- tstop = time((long *)0) + tlimit;
- while(time((long *)0) <= tstop){
- setnlun(); /* in case it changes */
- /* look for empty drives */
- for(i = 0; i < nlun; i++)
- if(!j_status.lun[i].diskin)
- return(i);
- /* look for spun down drives */
- for(i = 0; i < nlun; i++){
- if(!j_status.lun[i].ready){
- if(j_drive_to_shelf(i, -1, SIDEA, buf))
- return(-1);
- else
- return(i);
- }
- }
- sleep(10);
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
- }
- return(-1);
-}
//GO.SYSIN DD scsi/iodr_sh.c
echo scsi/ioshelves.c 1>&2
sed 's/.//' >scsi/ioshelves.c <<'//GO.SYSIN DD scsi/ioshelves.c'
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include "scsi.h"
-#include "juke.h"
-
-char *j_shelf[NSHELF];
-int j_wrshelf = 0;
-
-j_rdshelves(char *err)
-{
- FILE *fp;
- static haveread = 0;
- int shno;
- char vname[256];
-
- if(haveread)
- return(0);
- for(shno = 0; shno < NSHELF; shno++)
- j_shelf[shno] = 0;
- if((fp = fopen(JUKEDIR, "r")) == NULL){
- pperror(err, JUKEDIR);
- return(-1);
- }
- while(fscanf(fp, "%d %s\n", &shno, vname) == 2){
- if((shno < 0) || (shno >= NSHELF)){
- fprintf(stderr, "Warning: bad shelf number in %s: %d (vol_id=%s)\n",
- JUKEDIR, shno, vname);
- continue;
-
- }
- j_shelf[shno] = strdup(vname);
- }
- fclose(fp);
- haveread = 1;
- return(0);
-}
-
-j_wrshelves(char *err)
-{
- FILE *fp;
- int shno;
-
- if((fp = fopen(JUKEDIR, "w")) == NULL){
- pperror(err, JUKEDIR);
- return(-1);
- }
- for(shno = 0; shno < NSHELF; shno++)
- if(j_shelf[shno])
- fprintf(fp, "%d %s\n", shno, j_shelf[shno]);
- fclose(fp);
- return(0);
-}
-
-int
-j_shelfof(char *vol_id)
-{
- int i;
- char buf[512];
-
- for(;;){
- for(i = 0; i < NSHELF; i++)
- if(j_shelf[i] && (strcmp(j_shelf[i], vol_id) == 0))
- return(i);
- if((i = warm_inv(buf)) <= 0)
- break;
- }
- if(i < 0)
- fprintf(stderr, "jukebox: %s\n", buf);
- return(-1);
-}
-
-int
-j_driveof(char *vol_id)
-{
- int i, sh;
-
- if((sh = j_shelfof(vol_id)) < 0)
- return(-1);
- for(i = 0; i < NLUN; i++)
- if(j_status.lun[i].shelfvalid && (j_status.lun[i].retshelf == sh))
- return(i);
- return(-1);
-}
//GO.SYSIN DD scsi/ioshelves.c
echo scsi/scsish.c 1>&2
sed 's/.//' >scsi/scsish.c <<'//GO.SYSIN DD scsi/scsish.c'
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
-#include "scsi.h"
-#include "scsish.h"
-
-extern Device genericdev;
-static Device *dev = 0;
-static Function *function(char *, Device **);
-static void parse(FILE *);
-
-main()
-{
- setbuf(stdout, (char *)0);
- scsi_target(2);
- set_sony();
- printf("dev=%s, target=%d:\n", dev? dev->name:genericdev.name, s_id);
- parse(stdin);
- exit(0);
-}
-
-static void
-parse(FILE *fp)
-{
- int i, n;
- char *param;
- char buf[4096];
- char *ptrs[100], *cargs[20];
- int iargs[20];
- int nc, ni;
- Function *fn;
- Device *thatdev;
- char err[512];
-
- for(;;){
- printf("> ");
- fflush(stdout);
- if(fgets(buf, sizeof buf, fp) == NULL)
- break;
- if(param = strchr(buf, '\n'))
- *param = 0;
- n = getmfields(buf, ptrs, sizeof ptrs/sizeof ptrs[0]);
- if(n < 1)
- continue;
- if((fn = function(ptrs[0], &thatdev)) == 0){
- fprintf(stderr, "can't find cmd '%s'\n", ptrs[0]);
- continue;
- }
- ni = nc = 0;
- param = fn->param;
- for(i = 1; i < n; i++){
- switch(*param++)
- {
- case 'I':
- iargs[ni++] = atoi(ptrs[i]);
- break;
- case 'L':
- iargs[ni++] = atoi(ptrs[i]);
- if((iargs[ni-1] < 0) || (iargs[ni-1] > 7)){
- fprintf(stderr, "%s: lun %d out of range\n", ptrs[0], iargs[ni-1]);
- continue;
- }
- break;
- case 'S':
- cargs[nc++] = ptrs[i];
- break;
- default:
- break;
- }
- if(*param == '?')
- param++;
- }
- while(param[0] && param[1] && (param[1] == '?'))
- param += 2;
- if((i == n) != (*param == 0)){
- printf("param mismatch: %s: i=%d/n=%d param='%s'\n",
- ptrs[0], i, n, param);
- printf("device %s: %s\n", thatdev->name, fn->help);
- continue;
- }
- if((*fn->fn)(ni, iargs, nc, cargs, err))
- fprintf(stderr, "error in '%s': %s\n", fn->name, err);
- }
-}
-
-static Function *
-flook(Function *f, char *name)
-{
- for(; f->help; f++)
- if(strncmp(f->name, name, strlen(f->name)) == 0)
- return(f);
- return(0);
-}
-
-static Function *
-function(char *name, Device **devptr)
-{
- Function *f = 0;
-
- if(dev && dev->fns && (f = flook(dev->fns, name)))
- *devptr = dev;
- else if(f = flook(genericdev.fns, name))
- *devptr = &genericdev;
- return(f);
-}
-
-void
-setdevice(Device *d)
-{
- dev = d;
- ss_extsense = dev->extsense;
-}
-
-static
-help(Device *d, char *cmd, Device *prec)
-{
- Function *f;
- Function *base;
-
- base = (prec && prec->fns)? prec->fns:0;
- if(cmd == 0){
- printf("device %s(%s):\n", d->name, d->verbose);
- if(f = d->fns)
- while(f->name){
- if((base == 0) || (flook(base, f->name) == 0))
- printf("\t%s\n", f->help);
- f++;
- }
- return(0);
- } else {
- if(f = d->fns)
- while(f->name)
- if(strcmp(f->name, cmd) == 0){
- printf("(%s) %s\n", d->name, f->help);
- return(1);
- } else
- f++;
- return(0);
- }
-}
-
-int
-gen_help(int niargs, int *iargs, int ncargs, char **cargs)
-{
-#pragma ref niargs
-#pragma ref iargs
-
- if(dev)
- if(help(dev, ncargs == 0? 0:cargs[0], (Device *)0))
- return(0);
- help(&genericdev, ncargs == 0? 0:cargs[0], dev);
- return(0);
-}
-
-extern Device sonydev;
-extern Device wrendev;
-static Device *devs[] = {
- &genericdev,
- &sonydev,
- &wrendev,
- 0
-};
-
-int
-gen_dev(int niargs, int *iargs, int ncargs, char **cargs)
-{
- Device **d;
-
-#pragma ref niargs
-#pragma ref iargs
-
- if(ncargs == 0)
- printf("dev=%s\n", dev? dev->name : genericdev.name);
- else if(strcmp(cargs[0], "?") == 0){
- printf("available devices:\n");
- for(d = devs; *d; d++)
- printf("\t%s(%s)\n", (*d)->name, (*d)->verbose);
- } else {
- for(d = devs; *d; d++)
- if(strcmp(cargs[0], (*d)->name) == 0)
- break;
- if(*d)
- setdevice(*d);
- else
- fprintf(stderr, "device '%s' unknown\n", cargs[0]);
- }
- return(0);
-}
-
-void
-scsi_target(int n)
-{
- if((n < 0) || (n >= 8))
- fprintf(stderr, "%d is an invalid target\n", n);
- else
- s_id = n;
-}
-
-set_sony()
-{
- int iargs[1];
- char *cargs[1];
-
- cargs[0] = "sony";
- gen_dev(0, iargs, 1, cargs);
-}
//GO.SYSIN DD scsi/scsish.c
echo scsi/dslib.c 1>&2
sed 's/.//' >scsi/dslib.c <<'//GO.SYSIN DD scsi/dslib.c'
-/*
-|| dslib.c - library routines for /dev/scsi
-||
-|| Copyright 1988, 1989, by
-|| Gene Dronek (Vulcan Laboratory) and
-|| Rich Morin (Canta Forda Computer Laboratory).
-|| All rights reserved.
-*/
-#ident "dslib.c: $Revision: 1.4 $"
-
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "dslib.h"
-#ifdef aux
-#include <sys/vio.h>
-#include <sys/scsireq.h>
-#endif aux
-
-int dsdebug=0;
-long dsreqflags; /* flag bits always set by filldsreq */
-
-#define min(i,j) ( (i) < (j) ? (i) : (j) )
-
-
-/*
-|| Startup/shutdown -----------------------------------------------
-*/
-
-static struct context *dsc[FDSIZ];
-
-
-/*
-|| dsopen - open device, set up structures
-*/
-
-struct dsreq *
-dsopen(opath, oflags)
- char *opath;
- int oflags;
-{
-
- struct dsreq *dsp;
- struct context *cp;
- int fd;
- DSDBG(fprintf(stderr,"dsopen(%s,%x) ", opath, oflags));
-
- fd = open(opath, oflags);
- if (fd < 0)
- return NULL; /* can't open */
- if (dsc[fd] != NULL) /* already in use */
- ds_zot("dsopen: fd already in use");
-
- cp = (struct context *) calloc(1, sizeof(struct context));
- if (cp == NULL) /* can't allocate */
- ds_zot("dsopen: can't allocate space");
- dsc[fd] = cp;
- cp->dsc_fd = fd;
- dsp = &(cp->dsc_dsreq);
-
- dsp->ds_flags = 0;
- dsp->ds_time = 10 * 1000; /* 10 second default timeout */
- dsp->ds_private = (ulong) cp; /* pointer back to context */
- dsp->ds_cmdbuf = cp->dsc_cmd;
- dsp->ds_cmdlen = sizeof cp->dsc_cmd;
- dsp->ds_databuf = 0;
- dsp->ds_datalen = 0;
- dsp->ds_sensebuf = cp->dsc_sense;
- dsp->ds_senselen = sizeof cp->dsc_sense;
- DSDBG(fprintf(stderr,"=>cp %x, dsp %x\n", cp, dsp));
- return dsp;
-}
-
-
-/*
-|| dsclose - close device, release context struct.
-*/
-
-dsclose(dsp)
- struct dsreq *dsp;
-{
- int fd;
- struct context *cp;
-
- if (dsp == NULL)
- ds_zot("dsclose: dsp is NULL");
-
- cp = (struct context *)dsp->ds_private;
- fd = getfd(dsp);
- if ( cp == NULL )
- ds_zot("dsclose: private is NULL");
-
- cfree(cp);
- dsc[fd] = (struct context *)NULL;
- return;
-}
-
-
-/*
-|| Generic SCSI CCS Command functions ------------------------------------
-||
-|| dsp dsreq pointer
-|| data data buffer pointer
-|| datalen data buffer length
-|| lba logical block address
-|| vu vendor unique bits
-*/
-
-/*
-|| testunitready00 - issue group 0 "Test Unit Ready" command (0x00)
-*/
-
-testunitready00(dsp)
- struct dsreq *dsp;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_TEST, 0, 0, 0, 0, 0);
- filldsreq(dsp, 0, 0, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| requestsense03 - issue group 0 "Request Sense" command (0x03)
-*/
-
-requestsense03(dsp, data, datalen, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_REQU, 0, 0, 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| write0a - issue group 0 "Write" command (0x0a)
-*/
-
-write0a(dsp, data, datalen, lba, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_WRIT, B3(lba), B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| inquiry12 - issue group 0 "Inquiry" command (0x12)
-*/
-
-inquiry12(dsp, data, datalen, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_INQU, 0, 0, 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| modeselect15 - issue group 0 "Mode Select" command (0x15)
-||
-|| save 0 - don't save saveable pages
-|| 1 - save saveable pages
-*/
-
-modeselect15(dsp, data, datalen, save, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char save, vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_MSEL, save&1, 0, 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_WRITE|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| modesense1a - issue group 0 "Mode Sense" command (0x1a)
-||
-|| pagectrl 0 - current values
-|| 1 - changeable values
-|| 2 - default values
-|| 3 - saved values
-||
-|| pagecode 0 - vendor unique
-|| 1 - error recovery
-|| 2 - disconnect/reconnect
-|| 3 - direct access dev. fmt.
-|| 4 - rigid disk geometry
-|| 5 - flexible disk
-|| 6-9 - see specific dev. types
-|| 0a - implemented options
-|| 0b - medium types supported
-|| 3f - return all pages
-*/
-
-modesense1a(dsp, data, datalen, pagectrl, pagecode, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char pagectrl, pagecode, vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN, 0x10,
- ((pagectrl&3)<<6) | (pagecode&0x3F),
- 0, B1(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| senddiagnostic1d - issue group 0 "Send Diagnostic" command (0x1d)
-||
-|| self 0 - run test, hold results
-|| 1 - run test, return status
-||
-|| dofl 0 - device online
-|| 1 - device offline
-||
-|| uofl 0 - unit online
-|| 1 - unit offline
-*/
-
-senddiagnostic1d(dsp, data, datalen, self, dofl, uofl, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen;
- char self, dofl, uofl, vu;
-{
- fillg0cmd(dsp, CMDBUF(dsp), G0_MSEN,
- (self&1)<<2 | (dofl&1)<<1 | (uofl&1),
- 0, B2(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE);
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| readcapacity25 - issue group 1 "Read Capacity" command (0x25)
-||
-|| pmi 0 - return last logical block, entire unit
-|| 1 - return last logical block, current track
-*/
-
-readcapacity25(dsp, data, datalen, lba, pmi, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char pmi, vu;
-{
- fillg1cmd(dsp, CMDBUF(dsp), G1_RCAP, 0, B4(lba), 0, 0, pmi&1, B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE
- /* |DSRQ_CTRL2 */ );
- /* dsp->ds_time = 100; /* often takes a while */
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| readextended28 - issue group 1 "Read Extended" command (0x28)
-*/
-
-readextended28(dsp, data, datalen, lba, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char vu;
-{
- fillg1cmd(dsp, CMDBUF(dsp), G1_READ, 0, B4(lba), 0, B2(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE
- /* |DSRQ_CTRL2 */ );
- /* dsp->ds_time = 100; /* often takes a while */
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| writeextended2a - issue group 1 "Write Extended" command (0x2a)
-*/
-
-writeextended2a(dsp, data, datalen, lba, vu)
- struct dsreq *dsp;
- caddr_t data;
- long datalen, lba;
- char vu;
-{
- fillg1cmd(dsp, CMDBUF(dsp), G1_WRIT, 0, B4(lba), 0, B2(datalen), B1(vu<<6));
- filldsreq(dsp, data, datalen, DSRQ_READ|DSRQ_SENSE
- /* |DSRQ_CTRL2 */ );
- /* dsp->ds_time = 100; /* often takes a while */
- return(doscsireq(getfd(dsp), dsp));
-}
-
-
-/*
-|| Support functions ----------------------------------------------------
-*/
-
-/*
-|| fillg0cmd - Fill a Group 0 command buffer
-*/
-
-fillg0cmd(dsp, cmd, b0,b1,b2,b3,b4,b5)
- struct dsreq *dsp;
- uchar_t *cmd, b0,b1,b2,b3,b4,b5;
-{
- uchar_t *c = cmd;
- DSDBG(fprintf(stderr,"fillg0cmd(%x,%x, %02x %02x %02x %02x %02x %02x)\n",
- dsp, cmd, b0,b1,b2,b3,b4,b5));
- *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5;
-
- CMDBUF(dsp) = (caddr_t) cmd;
- CMDLEN(dsp) = 6;
-}
-
-
-/*
-|| fillg1cmd - Fill a Group 1 command buffer
-*/
-
-fillg1cmd(dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9)
- struct dsreq *dsp;
- uchar_t *cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9;
-{
- uchar_t *c = cmd;
- DSDBG(fprintf(stderr,
- "fillg1cmd(%x,%x, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x)\n",
- dsp, cmd, b0,b1,b2,b3,b4,b5,b6,b7,b8,b9));
-
- *c++ = b0, *c++ = b1, *c++ = b2, *c++ = b3, *c++ = b4, *c++ = b5;
- *c++ = b6, *c++ = b7, *c++ = b8, *c++ = b9;
-
- CMDBUF(dsp) = (caddr_t) cmd;
- CMDLEN(dsp) = 10;
-}
-
-
-/*
-|| filldsreq - Fill a dsreq structure
-*/
-
-filldsreq(dsp,data,datalen,flags)
- struct dsreq *dsp;
- uchar_t *data;
-{
- DSDBG(fprintf(stderr,"filldsreq(%x,%x,%d,%x) cmdlen %d\n",
- dsp,data,datalen,flags,CMDLEN(dsp)));
- dsp->ds_flags = flags | dsreqflags |
- (((dsdebug&1) ? DSRQ_TRACE : 0) |
- ((dsdebug&2) ? DSRQ_PRINT : 0));
- dsp->ds_time = 10 * 1000; /* default to 10 seconds */
- dsp->ds_link = 0;
- dsp->ds_synch = 0;
- dsp->ds_ret = 0;
-
- DATABUF(dsp) = (caddr_t) data;
- DATALEN(dsp) = datalen;
-}
-
-
-/*
-|| bprint - print array of bytes, in hex.
-*/
-
-#define hex(x) "0123456789ABCDEF" [ (x) & 0xF ]
-
-bprint(s,n,nperline,space)
- char *s;
-{
- int i, x;
- char *sp = (space) ? " ": "";
-
- for(i=0;i<n;i++) {
- x = s[i];
- fprintf(stderr,((i%4==3)?"%c%c%s%s":"%c%c%s"),
- hex(x>>4), hex(x), sp, sp);
- if ( i%nperline == (nperline - 1) )
- fprintf(stderr,"\n");
- }
- if ( space )
- fprintf(stderr,"\n");
-}
-
-
-/*
-|| doscsireq - issue scsi command, return status or -1 error.
-*/
-
-doscsireq( fd, dsp)
- int fd; /* ioctl file descriptor */
- struct dsreq *dsp; /* devscsi request packet */
-{
- int cc;
- int retries = 4;
- uchar_t sbyte;
-
- DSDBG(fprintf(stderr,"doscsireq(%d,%x) %x ---- %s\n",fd,dsp,
- (CMDBUF(dsp))[0],
- ds_vtostr( (CMDBUF(dsp))[0], cmdnametab)));
-
- /*
- * loop, issuing command
- * until done, or further retry pointless
- */
-
- while ( --retries > 0 ) {
-
- caddr_t sp;
-
- sp = SENSEBUF(dsp);
- DSDBG(fprintf(stderr,"cmdbuf = ");
- bprint(CMDBUF(dsp),CMDLEN(dsp),16,1));
- if ( (dsp->ds_flags & DSRQ_WRITE) )
- DSDBG(bprint( DATABUF(dsp), min(50,DATALEN(dsp)),16,1 ));
-
-DSDBG(fprintf(stderr,"databuf datalen %x %d\n",DATABUF(dsp), DATALEN(dsp)));
- cc = ioctl( fd, DS_ENTER, dsp);
- if ( cc < 0) {
- ds_panic(dsp, "cannot ioctl fd %d\n",fd);
- }
-
- DSDBG(fprintf(stderr,"cmdlen after ioctl=%d\n",CMDLEN(dsp)));
- DSDBG(fprintf(stderr,"ioctl=%d ret=%x %s",
- cc, RET(dsp),
- RET(dsp) ? ds_vtostr(RET(dsp),dsrtnametab) : ""));
- DSDBG(if (SENSESENT(dsp)) fprintf(stderr," sensesent=%d",
- SENSESENT(dsp)));
-
- DSDBG(fprintf(stderr,
- " cmdsent=%d datasent=%d sbyte=%x %s\n",
- CMDSENT(dsp), DATASENT(dsp), STATUS(dsp),
- ds_vtostr(STATUS(dsp), cmdstatustab)));
- DSDBG(if ( FLAGS(dsp) & DSRQ_READ )
- bprint( DATABUF(dsp), min(16*16,DATASENT(dsp)), 16,1));
-
-#ifdef aux
- /*
- * check for AUX bus-error
- * we retry with poll-dma
- */
- if ( RET(dsp) == DSRT_AGAIN ) {
- int n = SDC_RDPOLL|SDC_WRPOLL;
- DSDBG(fprintf(stderr,"setting rd/wr-poll"));
- cc = ioctl( fd, DS_SET, n); /* set bits */
- if ( cc != 0 )
- return -1;
- }
-#endif aux
-
- if ( RET(dsp) == DSRT_NOSEL )
- continue; /* retry noselect 3X */
-
- /* decode sense data returned */
- if ( SENSESENT(dsp) ) {
- DSDBG(
- fprintf(stderr, "sense key %x - %s\n",
- SENSEKEY(sp),
- ds_vtostr( SENSEKEY(sp), sensekeytab));
- bprint( SENSEBUF(dsp),
- min(100, SENSESENT(dsp)),
- 16,1);
- );
- }
- DSDBG(fprintf(stderr, "sbyte %x\n", STATUS(dsp)));
-
- /* decode scsi command status byte */
- sbyte = STATUS(dsp);
- switch (sbyte) {
- case 0x08: /* BUSY */
- case 0x18: /* RESERV CONFLICT */
- sleep(2);
- continue;
- case 0x00: /* GOOD */
- case 0x02: /* CHECK CONDITION */
- case 0x10: /* INTERM/GOOD */
- default:
- return sbyte;
- }
- }
- return -1; /* fail retry limit */
-}
-
-
-/*
-|| opttovar - lookup option in table, return var addr (NULL if fail)
-*/
-
-int *
-opttovar( ostr, table)
- char *ostr;
- struct opttab{
- char *opt;
- int *var;
- } *table;
-{
- register struct opttab *tp;
-
- for (tp=table; (tp->var); tp++)
- if ( strncmp( ostr, tp->opt, 3) == 0 )
- break;
-
- if ( !tp->var )
- fprintf(stderr,"unknown option %s", ostr);
-
- return (tp->var);
-}
-
-
-/*
-|| ds_vtostr - lookup value in table to return string pointer
-*/
-
-char *
-ds_vtostr( v, table)
- long v;
- struct vtab *table;
-{
- register struct vtab *tp;
-
- for (tp=table; (tp->string); tp++)
- if ( v == tp->val )
- break;
-
- return (tp->string) ? tp->string : "";
-}
-
-
-/*
-|| ds_panic - yelp, leave...
-*/
-
-ds_panic( fmt, v)
- char *fmt;
- int v;
-{
- extern errno;
-
- fprintf(stderr,fmt,v);
- fprintf(stderr,"\nerrno = %d\n",errno);
- exit(1);
-}
-
-
-/*
-|| ds_zot - go away, with a message.
-*/
-
-ds_zot(message)
- char *message;
-{
- fprintf(stderr, "%s\n", message);
- exit(1);
-}
//GO.SYSIN DD scsi/dslib.c
echo scsi/load.c 1>&2
sed 's/.//' >scsi/load.c <<'//GO.SYSIN DD scsi/load.c'
-#include <stdio.h>
-#include <stddef.h>
-#include <string.h>
-#include "scsi.h"
-#include "juke.h"
-
-j_load(char *vol_id, char *buf, long tlimit)
-{
- Side side;
- int n, sh, dr;
- char disk_to_load[256];
- struct Lunstatus *l;
-
- if(j_rdshelves(buf)) /* read in shelf names */
- return(-1);
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
- /* now check which side we want */
- n = strlen(vol_id);
- strcpy(disk_to_load, vol_id);
- if(disk_to_load[n-1] == 'a')
- side = SIDEA;
- else if(disk_to_load[n-1] == 'b')
- side = SIDEB;
- else {
- sprintf(buf, "vol_id '%s' must end in a or b", vol_id);
- return(-1);
- }
- disk_to_load[n-1] = 0;
- /* which shelf is that? */
- sh = j_shelfof(disk_to_load);
- if(sh < 0){
- sprintf(buf, "can't find vol_id %s", disk_to_load);
- return(-1);
- }
- while(tlimit >= 0){
- for(n = 0; n < NLUN; n++){
- l = &j_status.lun[n];
- if(l->diskin && l->shelfvalid && (sh == (l->retshelf>>1))){
- if(((l->retshelf&1) == side) && (n < nlun))
- return(n);
- if(l->ready)
- goto await;
- if(j_drive_to_shelf(n, -1, 0, buf))
- return(-1);
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
- break;
- }
- }
- /* disk is available */
- dr = j_empty_drive(tlimit, buf);
- if(dr < 0){
- sprintf(buf, "can't find a free drive");
- return(-1);
- }
- if(j_shelf_to_drive(sh, side, dr, buf) < 0)
- return(-1);
- return(dr);
-await:
- sleep(10);
- tlimit -= 10;
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
- }
- sprintf(buf, "disk '%s' busy", disk_to_load);
- return(-1);
-}
//GO.SYSIN DD scsi/load.c
echo scsi/main.c 1>&2
sed 's/.//' >scsi/main.c <<'//GO.SYSIN DD scsi/main.c'
-#include <stdio.h>
-#include "jukebox.h"
-#include "hdr.h"
-
-main(int argc, char *argv[])
-{
- int c;
- int err = 0, cold = 0, warm = 0;
- char *toload = 0, *uload = 0;
- char *drive = 0;
- char buf[256];
- extern int optind;
- extern char *optarg;
-
- setbuf(stdout, (char *)0); /* turn off buffering */
- /* gather options */
- while ((c = getopt(argc,argv,"cn:l:wu:")) != -1)
- switch (c)
- {
- case 'l': toload = optarg; break;
- case 'c': cold = 1; break;
- case 'w': warm = 1; break;
- case 'u': uload = optarg ; break;
- case 'n': drive = optarg ; break;
- default: err = 1; break;
- }
- if(err)
- exit(1);
- /* now actually do some work */
- if (toload){
- if (j_load(toload, buf, 30))
- printf("load %s failed: %s\n", toload, buf);
- else
- printf("loaded %s on %s\n", toload, buf);
- }
- if(drive){
- if(j_volid(atoi(drive), buf))
- printf("j_volid(%s) failed: %s\n", drive, buf);
- else
- printf("%s is mounted on drive %d\n", buf, atoi(drive));
- }
- if(cold){
- printf("invent cold: %d\n", cold);
- cold_inventory(30, buf);
-
- }
- if (warm) {
- printf("invent warm: %d\n", warm);
- warm_inventory(buf);
-
- }
-
-
- if (uload){
- if (j_unload(uload, buf))
- printf("unload %s failed: %s\n", uload, buf);
- else
- printf("unloaded %s from %s\n", uload, buf);
-
-
- }
- exit(0);
-}
//GO.SYSIN DD scsi/main.c
echo scsi/inc/scsi.h 1>&2
sed 's/.//' >scsi/inc/scsi.h <<'//GO.SYSIN DD scsi/inc/scsi.h'
-#define SCSI_WR 0x80
-#define SCSI_RD 0x40
-#define SCSI_BRESET 0x20
-#define SCSI_RESET 0x10
-#define SCSI_SENSE 0x08
-#define SCSI_LTMOUT 0x04
-
-
-#define SCSI_CERR 0x01
//GO.SYSIN DD scsi/inc/scsi.h
echo scsi/research.mk 1>&2
sed 's/.//' >scsi/research.mk <<'//GO.SYSIN DD scsi/research.mk'
-# config stuff: research unix
-CC=lcc
-CFLAGS=-g
-RANLIB=ranlib
-LDFLAGS=
-IO=h_io
-NPROC=2
//GO.SYSIN DD scsi/research.mk
echo scsi/sgi.mk 1>&2
sed 's/.//' >scsi/sgi.mk <<'//GO.SYSIN DD scsi/sgi.mk'
-# config stuff: sgi; system v with moran/droneck /dev/scsi
-CC=pcc # must be ansi
-RANLIB=:
-LDFLAGS= -lds
-IO=md_io
-CFLAGS=-g -I../inc
-NPROC=4
//GO.SYSIN DD scsi/sgi.mk
echo scsi/unload.c 1>&2
sed 's/.//' >scsi/unload.c <<'//GO.SYSIN DD scsi/unload.c'
-#include <stdio.h>
-#include <stddef.h>
-#include <string.h>
-#include "scsi.h"
-#include "juke.h"
-
-j_unload(char *vol_id, char *buf)
-{
- Side side;
- int i, sh, dr;
- char disk_to_unload[256];
-
- if(j_rdshelves(buf)) /* read in shelf names */
- return(-1);
- if(j_getstatus(buf)) /* get the jukebox status */
- return(-1);
- /* now check which side we want */
-
- strcpy(disk_to_unload, vol_id);
- side = SIDEA;
- sh = j_shelfof(disk_to_unload);
- if(sh < 0){
- sprintf(buf, "can not find vol_id %s", disk_to_unload);
- return(-1);
- }
- dr = -1;
- for(i = 0; i < NLUN; i++){
- printf("dr:.. %d ", i);
- printf(" rtsh: %d\n", j_status.lun[i].retshelf);
-
- /* is sh = retshelf? */
-
- if( (j_status.lun[i].retshelf>>1 == sh) ||
- (j_status.lun[i].retshelf == sh*2+1) ){ dr = i;
- break;
- } }
- printf("dr: %d, sh: %d, side: %d, i: %d\n", dr, sh, side, i);
- if (dr == -1){
- sprintf(buf, "no drive has vol_id %s", disk_to_unload);
- return(-1);
- }
- /* put vol_id in it's shelf*/
- if (j_drive_to_shelf(dr, sh, side, buf) >= 0){
- sprintf(buf,"/dev/worm%d\n", dr);
- return(0);
- }
- return(-1);
-}
//GO.SYSIN DD scsi/unload.c
echo scsi/README 1>&2
sed 's/.//' >scsi/README <<'//GO.SYSIN DD scsi/README'
- This is a simple extensible shell (scsish) for poking at scsi
-devices, particularly the simpler kinds commonly called toasters.
-it is supposed to be self-documenting in use; try the help command.
-my use of the moran-dronek /dev/scsi library is still imperfect;
-there is still some some debugging showing.
-
- To compile, you first need mk. you then have to pick a system type
-to set some flags; currently we support research and sgi.
-yours may differ, particularly as no one else has our ansi C compiler for the sgi.
-the only problem i would expect is the normal header file crap you get
-mixing ansi and non-ansi files. i recommend setting NPROC=1 while debugging hdr files.
-if you change (header) files, try putting them in the directory inc
-(then others may benefit). To support a new system (say sgi-gcc), just create
-a new file sgi-gcc.mk and so on. you may be missing some devices in
-your /dev/scsi; the script scsi/gendev may help (but check the major/minor
-numbers and permissions).
-
- As for modifying/extending scsish, it has been designed to be not too hard.
-Adding a new device means adding a new set of rules (like the other rules)
-to mkfile and creating a new directory (say exabyte) and at least two files in it
-(dev.c and fns.h). The wren directory is a small example you can clone.
-Adding new functions to any device means updating a file list in mkfile,
-updating dev.c and fns.h in the device directory. The argument syntax
-scheme is arguably pokey, but liveable. at some future point we should probably
-switch over to osterhout's tcl.
-
- as always, i invite you send extensions/fixes etc back to
-andrew@research.att.com
//GO.SYSIN DD scsi/README
echo scsi/TODO 1>&2
sed 's/.//' >scsi/TODO <<'//GO.SYSIN DD scsi/TODO'
- | COPY drive NUMBER NUMBER drive NUMBER {/*:COPY sdrive sstart nblocks ddrive dstart:: */
- s_copy($2, $3, $4, $5, $6);
- }
- | READ drive NUMBER {
- struct scsi_ret output;
- s_read($2, $3, 1, &output);
- scsiodump(output.data, 1024);
- }
- | WRITE drive NUMBER { s_write($2, $3, 1); }
- | WRITE drive NUMBER NUMBER { s_write($2, $3, $4); } /*:WRITE drive start n:: */
//GO.SYSIN DD scsi/TODO
echo scsi/scsish.h 1>&2
sed 's/.//' >scsi/scsish.h <<'//GO.SYSIN DD scsi/scsish.h'
-typedef int (*Functionfn)(int, int *, int, char **, char *);
-
-typedef struct
-{
- char *name;
- char *help;
- char *param;
- Functionfn fn;
-} Function;
-
-typedef struct
-{
- char *name;
- char *verbose;
- void (*extsense)(uchar *, char *, int);
- Function *fns;
-} Device;
-extern void setdevice(Device *);
-
-extern void scsi_target(int);
-extern void fixedstr(uchar *src, int len, char *dest);
-extern void gen_extsense(uchar *, char *, int);
-extern int shelfside(char *arg, char *err);
-extern void xd(uchar *base, int, FILE *fp);
//GO.SYSIN DD scsi/scsish.h
echo scsi/generic/dev.c 1>&2
sed 's/.//' >scsi/generic/dev.c <<'//GO.SYSIN DD scsi/generic/dev.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static int gen_id(int, int *, int, char **, char *);
-
-static Function fns[] = {
- { "capacity", "capacity [lun=0]", "L?", gen_capacity },
- { "copy", "copy srclun start n destlun dest", "LIILII?", gen_copy },
- { "display", "display", "", gen_display },
- { "dev", "dev [type] # dev ? for list", "S?", gen_dev },
- { "help", "help [cmd]", "S?", gen_help },
- { "id", "id [target=0]", "L?", gen_id },
- { "inq", "inq [lun=0]", "L?", gen_inq },
- { "readt", "readt count [lun=0]", "IL?", gen_readt },
- { "reset", "reset", "", gen_reset },
- { "scsi", "scsi bytes... # 6 or 10", "I?I?I?I?I?I?I?I?I?I?", gen_scsi },
- { "sense", "sense [lun=0]", "L?", gen_sense },
- { "start", "start [lun=0]", "L?", gen_start },
- { "stop", "stop [lun=0]", "L?", gen_stop },
- { "testunit", "testunit [lun=0", "L?", gen_tur },
- { 0 }
-};
-
-Device genericdev = {
- "scsi", "generic scsi",
- gen_extsense,
- fns
-};
-
-static int
-gen_id(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
-#pragma ref ncargs
-#pragma ref cargs
-#pragma ref err
-
- if(niargs == 0)
- printf("current SCSI id = %d\n", s_id);
- else
- scsi_target(iargs[0]);
- return(0);
-}
//GO.SYSIN DD scsi/generic/dev.c
echo scsi/generic/inq.c 1>&2
sed 's/.//' >scsi/generic/inq.c <<'//GO.SYSIN DD scsi/generic/inq.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-char *gen_rmb[2] = { "nonremovable", "removable" };
-char *gen_devtype[256] = {
- "direct access",
- "sequential access",
- "printer",
- "processor",
- "worm",
- "cd-rom"
-};
-
-int
-gen_inq(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- for(niargs = 0; niargs < 8; niargs++)
- iargs[niargs] = niargs;
- for(i = 0; i < niargs; i++){
- set6(cmd, 0x12, iargs[i]<<5, 0, 0, 36, 0);
- if(n = s_io(0, &cmd, 0, &ret, -36, err))
- return(n);
- printf("inq(%d,%d): %s %s;", s_id, iargs[i],
- gen_rmb[ret.data[1]>>7], gen_devtype[ret.data[0]]);
- if(ret.data[4] >= 16){
- char buf[256];
-
- fixedstr(&ret.data[8], 8, buf);
- printf(" %s", buf);
- if(ret.data[4] >= 32){
- fixedstr(&ret.data[16], 16, buf);
- printf("/%s", buf);
- if(ret.data[4] >= 36){
- fixedstr(&ret.data[32], 4, buf);
- printf(" rev=%s", buf);
- }
- }
- }
- printf(" [%d bytes]\n", ret.data[4]);
- }
- return(0);
-}
//GO.SYSIN DD scsi/generic/inq.c
echo scsi/generic/sense.c 1>&2
sed 's/.//' >scsi/generic/sense.c <<'//GO.SYSIN DD scsi/generic/sense.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-gen_sense(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set6(cmd, 0x03, iargs[0]<<5, 0, 0, 4, 0);
- if(n = s_io(0, &cmd, 0, &ret, 4, err))
- return(n);
- printf("sense(%d,%d): ", s_id, iargs[0]);
- if((ret.data[0]&0x7F) == 0)
- printf("no error\n");
- else {
- printf("error class=0x%x, code=0x%x, sense=0x%x",
- (ret.data[0]>>4)&7, ret.data[0]&0xF, ret.data[2]&0xF);
- if(ret.data[0]&0x80)
- printf(", addr=0x%x", ret.data[3]+256L*ret.data[2]+256L*256*ret.data[1]);
- printf("\n");
- }
- return(0);
-}
-
-static char *exstab[16] =
-{
- "no sense",
- "recovered error",
- "not ready",
- "medium error",
- "hardware error",
- "illegal request",
- "unit attention",
- "data protect",
- "blank check",
- "vendor specific (#9)",
- "copy aborted",
- "aborted command",
- "equal",
- "volume overflow",
- "miscompare",
- "reserved (#f)",
-};
-
-void
-gen_extsense(uchar *data, char *dest, int ndata)
-{
- int class;
-
- class = (data[0]>>4)&7;
- if(class == 7){
- if(data[0]&0x80)
- 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]);
- else
- sprintf(dest, "extended sense: %s", exstab[data[2]&0xF]);
- } else {
- sprintf(dest, "sense: class=#%x, code=#%x", class, data[0]&0xF);
- }
-}
//GO.SYSIN DD scsi/generic/sense.c
echo scsi/generic/start.c 1>&2
sed 's/.//' >scsi/generic/start.c <<'//GO.SYSIN DD scsi/generic/start.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-gen_start(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set6(cmd, 0x1B, iargs[0]<<5, 0, 0, 1, 0);
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- return(0);
-}
//GO.SYSIN DD scsi/generic/start.c
echo scsi/generic/stop.c 1>&2
sed 's/.//' >scsi/generic/stop.c <<'//GO.SYSIN DD scsi/generic/stop.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-gen_stop(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set6(cmd, 0x1B, iargs[0]<<5, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- return(0);
-}
//GO.SYSIN DD scsi/generic/stop.c
echo scsi/generic/capacity.c 1>&2
sed 's/.//' >scsi/generic/capacity.c <<'//GO.SYSIN DD scsi/generic/capacity.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-gen_capacity(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- unsigned long ns, ss;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set10(cmd, 0x25, iargs[0]<<5, 0, 0, 0, 0, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 8, err))
- return(n);
- ns = longat(&ret.data[0]);
- ss = longat(&ret.data[4]);
- printf("capacity(%d,%d): %ld blocks of %ld bytes (#%xx#%x)\n", s_id, iargs[0],
- ns, ss, ns, ss);
- return(0);
-}
//GO.SYSIN DD scsi/generic/capacity.c
echo scsi/generic/display.c 1>&2
sed 's/.//' >scsi/generic/display.c <<'//GO.SYSIN DD scsi/generic/display.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-extern char *gen_rmb[2];
-extern char *gen_devtype[256];
-
-int
-gen_display(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i, old_id;
- int retv = 0;
- char rev[100], vendor[100], product[100];
-
-#pragma ref niargs
-#pragma ref iargs
-#pragma ref ncargs
-#pragma ref cargs
-
- old_id = s_id;
- for(s_id = 0; s_id < 8; s_id++){
- printf("target %d:\n");
- set6(cmd, 0x00, 0, 0, 0, 0, 0);
- if(s_io(0, &cmd, 0, &ret, 0, err))
- continue;
- printf("responded to test unit ready\n");
- continue;
- for(i = 0; i < 8; i++){
- set6(cmd, 0x12, i<<5, 0, 0, 36, 0);
- if(n = s_io(0, &cmd, 0, &ret, -36, err)){
- retv = n;
- break;
- }
- if(ret.nread >= 16)
- fixedstr(&ret.data[8], 8, vendor);
- else
- sprintf(vendor, "??");
- if(ret.nread >= 32)
- fixedstr(&ret.data[16], 16, product);
- else
- sprintf(product, "??");
- if(ret.nread >= 16)
- fixedstr(&ret.data[32], 4, rev);
- else
- sprintf(vendor, "??");
- printf("\tlun(%d): %s %s, %s/%s rev=%s\n", i,
- gen_rmb[ret.data[1]>>7], gen_devtype[ret.data[0]],
- vendor, product, rev);
- }
- }
- s_id = old_id;
- return(retv);
-}
//GO.SYSIN DD scsi/generic/display.c
echo scsi/generic/reset.c 1>&2
sed 's/.//' >scsi/generic/reset.c <<'//GO.SYSIN DD scsi/generic/reset.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-#include <scsi.h>
-
-int
-gen_reset(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
-
-#pragma ref niargs
-#pragma ref iargs
-#pragma ref ncargs
-#pragma ref cargs
-
- set6(cmd, 0, 0, 0, 0, 0, 0);
- cmd.bus_id = s_id;
- cmd.flags |= SCSI_RESET | SCSI_BRESET;
- /* should probably test for some kind of error... */
- ss_io(0, &cmd, 0, &ret, 0, err);
- return(0);
-}
//GO.SYSIN DD scsi/generic/reset.c
echo scsi/generic/tur.c 1>&2
sed 's/.//' >scsi/generic/tur.c <<'//GO.SYSIN DD scsi/generic/tur.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-gen_tur(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set6(cmd, 0x00, iargs[0]<<5, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- printf("(%d,%d): good status\n", s_id, iargs[0]);
- return(0);
-}
//GO.SYSIN DD scsi/generic/tur.c
echo scsi/generic/scsi.c 1>&2
sed 's/.//' >scsi/generic/scsi.c <<'//GO.SYSIN DD scsi/generic/scsi.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-gen_scsi(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- switch(niargs)
- {
- case 6:
- set6(cmd, iargs[0], iargs[1], iargs[2], iargs[3], iargs[4], iargs[5]);
- break;
- case 10:
- set10(cmd, iargs[0], iargs[1], iargs[2], iargs[3], iargs[4], iargs[5], iargs[6], iargs[7], iargs[8], iargs[9]);
- break;
- default:
- sprintf(err, "number of bytes (%d) must be 6 or 10\n", niargs);
- return(1);
- }
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- return(0);
-}
//GO.SYSIN DD scsi/generic/scsi.c
echo scsi/generic/fns.h 1>&2
sed 's/.//' >scsi/generic/fns.h <<'//GO.SYSIN DD scsi/generic/fns.h'
-extern int gen_inq(int, int *, int, char **, char *);
-extern int gen_dev(int, int *, int, char **, char *);
-extern int gen_help(int, int *, int, char **, char *);
-extern int gen_sense(int, int *, int, char **, char *);
-extern int gen_start(int, int *, int, char **, char *);
-extern int gen_stop(int, int *, int, char **, char *);
-extern int gen_capacity(int, int *, int, char **, char *);
-extern int gen_display(int, int *, int, char **, char *);
-extern int gen_reset(int, int *, int, char **, char *);
-extern int gen_tur(int, int *, int, char **, char *);
-extern int gen_scsi(int, int *, int, char **, char *);
-extern int gen_readt(int, int *, int, char **, char *);
-extern int gen_copy(int, int *, int, char **, char *);
//GO.SYSIN DD scsi/generic/fns.h
echo scsi/generic/readt.c 1>&2
sed 's/.//' >scsi/generic/readt.c <<'//GO.SYSIN DD scsi/generic/readt.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-gen_readt(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i;
- unsigned long ns, ss;
- long bs, addr;
- long t1, t2;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 1)
- iargs[1] = 0;
- set10(cmd, 0x25, iargs[1]<<5, 0, 0, 0, 0, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 8, err))
- return(n);
- ns = longat(&ret.data[0]);
- ss = longat(&ret.data[4]);
- bs = ss? sizeof(ret.data)/ss : 1;
- time(&t1);
- srand(t1);
- addr = nrand(ns-iargs[0])-1;
- printf("read(%d,%d): %d blocks @%d (chunk=%dx%d),", s_id, iargs[1], iargs[0], addr, bs, ss);
- fflush(stdout);
- time(&t1);
- for(i = iargs[0]; i > 0; i -= bs){
- set10(cmd, 0x28, iargs[1]<<5, addr>>24, addr>>16, addr>>8, addr,
- 0, 0, bs*0, 0);
- if(n = s_io(0, &cmd, 0, &ret, bs*ss, err))
- return(n);
- addr += bs;
- }
- time(&t2);
- printf(" t=%ds (%.0fKB/s)\n", t2-t1, (iargs[0]*(float)ss/1024.)/((t1 == t2)? 1:t2-t1));
- return(0);
-}
//GO.SYSIN DD scsi/generic/readt.c
echo scsi/generic/copy.c 1>&2
sed 's/.//' >scsi/generic/copy.c <<'//GO.SYSIN DD scsi/generic/copy.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-#define PROGRESS \
- if(sbase/TALK != goo){\
- goo = sbase/TALK;\
- time(&t2);\
- printf("\tdoing block %ld at %s", goo*TALK, ctime(&t2));\
- }
-
-static int copy1(int, int, int, int, int, int, int, char *);
-
-int
-gen_copy(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- int n;
- int sdr = 0;
- int sbase = iargs[1];
- int nblocks = iargs[2];
- int ddr = 0;
- int dbase = iargs[4];
- int starget = iargs[0];
- int dtarget = iargs[3];
- int block = 256;
- long nb = nblocks;
- long t1, t2;
- long goo;
-
-#define TALK 10000
- extern char *ctime();
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 6)
- block = iargs[5];
- printf("copying drive (%d,%d)[%d-%d] to drive (%d,%d)[%d-%d] blk=%dK\n",
- starget, sdr, sbase, sbase+nblocks-1,
- dtarget, ddr, dbase, dbase+nblocks-1, block);
- time(&t1);
- goo = -1;
- while(nblocks > 0){
- n = min(block, nblocks);
- printf("writing %d-%d\n", sbase, sbase+n-1);/**/
- if(copy1(starget, sdr, sbase, n, dtarget, ddr, dbase, err))
- break;
- sbase += n;
- dbase += n;
- nblocks -= n;
- PROGRESS
- }
- time(&t2);
- t2 -= t1;
- if(t2 == 0) t2 = 1;
- printf("%ds: ", t2);
- if(nblocks){
- printf("copy buggered up: sbase=%d nblks=%d dbase=%d\n",
- sbase, nblocks, dbase);
- return(1);
- }
- printf("%d blocks at %.1fKB/s\n", nb, nb/(float)t2);
- return(0);
-}
-
-static int
-copy1(int st, int sd, int sb, int n, int dt, int dd, int db, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
-
- set6(cmd, 0x18, sd<<5, 0, 0, 20, 0);
- cmd.data[0] = 0x10; /* copy */
- cmd.data[1] = 0;
- cmd.data[2] = 0;
- cmd.data[3] = 0;
- cmd.data[4] = (st<<5)|sd;
- cmd.data[5] = (dt<<5)|dd;
- cmd.data[6] = 0;
- cmd.data[7] = 0;
- cmd.data[8] = n>>24;
- cmd.data[9] = n>>16;
- cmd.data[10] = n>>8;
- cmd.data[11] = n;
- cmd.data[12] = sb>>24;
- cmd.data[13] = sb>>16;
- cmd.data[14] = sb>>8;
- cmd.data[15] = sb;
- cmd.data[16] = db>>24;
- cmd.data[17] = db>>16;
- cmd.data[18] = db>>8;
- cmd.data[19] = db;
- return(s_io(0, &cmd, 20, &ret, 0, err));
-}
//GO.SYSIN DD scsi/generic/copy.c
echo scsi/sony/dev.c 1>&2
sed 's/.//' >scsi/sony/dev.c <<'//GO.SYSIN DD scsi/sony/dev.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static Function fns[] = {
- { "alternate", "alternate [lun]", "L?", sony_alt },
- { "config", "config", "", sony_conf },
- { "copy", "copy srclun start n destlun dest", "LIILI", sony_copy },
- { "diskid", "diskid [lun]", "L?", sony_diskid },
- { "eject", "eject lun", "L", sony_eject },
- { "inq", "inq [lun]", "L?", sony_inq },
- { "internal", "internal test [drive] # internal -1 for list", "II?", sony_internal },
- { "media", "media lun start count [file]", "LIIS?", sony_media },
- { "readid", "readid lun [start]", "LI?", sony_readid },
- { "rel", "rel lun [shelfside]", "LS?", sony_rel },
- { "sense", "sense [lun=0]", "L?", sony_sense },
- { "set", "set shelfside lun", "SL", sony_set },
- { "status", "status", "", sony_status },
- { 0 }
-};
-
-Device sonydev = {
- "sony", "Sony WDA-3000",
- sony_extsense,
- fns
-};
//GO.SYSIN DD scsi/sony/dev.c
echo scsi/sony/inq.c 1>&2
sed 's/.//' >scsi/sony/inq.c <<'//GO.SYSIN DD scsi/sony/inq.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-sony_inq(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- for(niargs = 0; niargs < 8; niargs++)
- iargs[niargs] = niargs;
- for(i = 0; i < niargs; i++){
- set6(cmd, 0x12, iargs[i]<<5, 0, 0, 6, 0);
- if(n = s_io(0, &cmd, 0, &ret, 6, err))
- return(n);
- printf("inq(%d,%d): ", s_id, iargs[i]);
- if(ret.data[5]&0x80)
- printf("power off (0x%x)\n", ret.data[5]&0xFF);
- else if(ret.data[5]&0x40)
- printf("empty (0x%x)\n", ret.data[5]&0xFF);
- else
- printf("%s,%s,%s,%s (0x%x)\n",
- (ret.data[5]&0x08)?"write protect":"writable",
- (ret.data[5]&0x04)?"no alternate":"",
- (ret.data[5]&0x02)?"drive error":"",
- (ret.data[5]&0x01)?"ready":"not ready",
- ret.data[5]&0xFF);
- }
- return(0);
-}
//GO.SYSIN DD scsi/sony/inq.c
echo scsi/sony/alt.c 1>&2
sed 's/.//' >scsi/sony/alt.c <<'//GO.SYSIN DD scsi/sony/alt.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static
-table(int drive, int tab, uchar *data)
-{
- int n, i;
-
- n = data[6];
- printf("(%d,%d): alternate table %d (%d entries)\n", s_id, drive, tab, n);
- for(data += 0x18, i = 0; i < n; data += 4, i++)
- printf("%ld%c", data[0]+256L*data[1]+256L*256*data[2],
- (i%10 == 9)? '\n':' ');
- if((i%10) && n)
- putchar('\n');
-}
-
-int
-sony_alt(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set6(cmd, 0xC3, iargs[0]<<5, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 4096, err))
- return(n);
- for(i = 0; i < 4; i++)
- table(iargs[0], i+1, &ret.data[1024*i]);
- return(0);
-}
//GO.SYSIN DD scsi/sony/alt.c
echo scsi/sony/config.c 1>&2
sed 's/.//' >scsi/sony/config.c <<'//GO.SYSIN DD scsi/sony/config.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static char mtab[5][2] =
-{
- '0', '0', '1', '1', '1', '2', '2', '2', '?', '?'
-};
-static char *brdname[] = {
- "no doard", "T.D. Systems Viking", "U.S. Design 1158"
-};
-
-int
-sony_conf(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i;
- char buf[512];
-
-#pragma ref niargs
-#pragma ref iargs
-#pragma ref ncargs
-#pragma ref cargs
-
- set6(cmd, 0x12, 0, 0, 0, 44, 0);
- if(n = s_io(0, &cmd, 0, &ret, 44, err))
- return(n);
- i = min(ret.data[37], 4);
- fixedstr(&ret.data[8], 28, buf);
- printf("config(%d,%d): %s device, '%s', %c controller%s, %c drive%s\n",
- s_id, 0, (ret.data[0] == 0x4)? "WORM":"Unknown",
- buf, mtab[i][0], (mtab[i][0] == '1')?"":"s",
- mtab[i][1], (mtab[i][1] == '1')?"":"s");
- printf("\tUnibus-SCSI controller=%s\n", brdname[ret.type]);
- printf("\tROMS:");
- if(ret.data[38] != 0xFF)
- printf(" upper controller=0x%x,", ret.data[38]);
- if(ret.data[40] != 0xFF)
- printf(" lower controller=0x%x,", ret.data[40]);
- printf( " IF-129=0x%x, SY-46=0x%x, SS-30=0x%x\n", ret.data[36],
- ret.data[42], ret.data[43]);
- return(0);
-}
//GO.SYSIN DD scsi/sony/config.c
echo scsi/sony/status.c 1>&2
sed 's/.//' >scsi/sony/status.c <<'//GO.SYSIN DD scsi/sony/status.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-
-static
-shelf(int i)
-{
- printf(": ");
- if(i&0x80){
- printf("%s,", (i&0x40)? "disk":"temporary");
- if(i&0x10) printf("wait loading,");
- if(i&0x08) printf("wait ejection,");
- if(i&0x20) printf("use shelf instead of drive for LUN %d", i&7);
- } else
- printf("no disk");
- printf("\n");
-}
-
-int
-sony_istatus(struct scsi_return *ret, char *err)
-{
- struct scsi_cmd cmd;
- int n;
-
- set6(cmd, 0x1D, 0, 0, 0, 10, 0);
- cmd.data[0] = 0xE2; /* internal status */
- cmd.data[1] = 0;
- cmd.data[2] = 0;
- cmd.data[3] = 0;
- cmd.data[4] = 0;
- cmd.data[5] = 0;
- cmd.data[6] = 0;
- cmd.data[7] = 0;
- cmd.data[8] = 0;
- cmd.data[9] = 0;
- if(n = s_io(0, &cmd, 10, ret, 0, err))
- return(n);
- setdiag(cmd, 0, 128);
- if(n = s_io(0, &cmd, 0, ret, 128, err))
- return(n);
- return(0);
-}
-
-int
-sony_status(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_return ret;
- int n, i, start;
- uchar *d;
-
-#pragma ref niargs
-#pragma ref iargs
-#pragma ref ncargs
-#pragma ref cargs
-
- if(n = sony_istatus(&ret, err))
- return(n);
- d = &ret.data[16];
- for(i = 0; i < 8; i++, d += 4){
- printf("drive %d: %sready,%sdisk in LUN,power %s,", i,
- (d[0]&1)?"":"not ", (d[0]&0x40)?"":"no ",
- (d[0]&0x80)?"off":"on");
- if(d[0]&0x40){
- if(d[1]&0x80){
- printf("disk in drive %d", d[1]&0x7f);
- if(d[2]&0x80)
- printf(", return shelf %d%c", (d[2]&0x7F)/2, "ab"[d[2]&1]);
- } else
- printf("disk in shelf %d%c (%d)", (d[1]&0x7f)/2, (d[1]&1)+'a', d[1]&0x7f);
- }
- printf("\n");
- }
- for(i = 0; i < 50;){
- for(start = i; ++i < 50;)
- if(d[i] != d[start])
- break;
- if(i == start+1)
- printf("%d", start);
- else
- printf("%d-%d", start, i-1);
- shelf(d[start]);
- }
- d += 50;
- printf("I/O shelf");
- shelf(*d);
- d++;
- printf("carrier: ");
- i = *d&0x7F;
- if(*d&0x80)
- printf("disk shelf=%d%c (%d)\n", i/2, 'a'+(i&1), i);
- else
- printf("no disk\n");
- d++;
- if(*d&0x80)
- printf("upper drive: disk, LUN=%d\n", *d&7);
- else
- printf("upper drive: no disk\n");
- d++;
- if(*d&0x80)
- printf("lower drive: disk, LUN=%d\n", *d&7);
- else
- printf("lower drive: no disk\n");
- return(0);
-}
//GO.SYSIN DD scsi/sony/status.c
echo scsi/sony/rel.c 1>&2
sed 's/.//' >scsi/sony/rel.c <<'//GO.SYSIN DD scsi/sony/rel.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-sony_rel(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i, j;
-
-#pragma ref niargs
-
- if(ncargs == 0){
- i = 0;
- j = 0; /* its ignored anyway */
- } else {
- i = 1;
- if((j = shelfside(cargs[0], err)) < 0)
- return(1);
- }
- set6(cmd, 0xD7, (iargs[0]<<5)|i, 0, j, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- return(0);
-}
//GO.SYSIN DD scsi/sony/rel.c
echo scsi/sony/set.c 1>&2
sed 's/.//' >scsi/sony/set.c <<'//GO.SYSIN DD scsi/sony/set.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-sony_set(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n, i;
-
-#pragma ref niargs
-#pragma ref ncargs
-
- if((i = shelfside(cargs[0], err)) < 0)
- return(1);
- set6(cmd, 0xD6, iargs[0]<<5, 0, i, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- return(0);
-}
//GO.SYSIN DD scsi/sony/set.c
echo scsi/sony/eject.c 1>&2
sed 's/.//' >scsi/sony/eject.c <<'//GO.SYSIN DD scsi/sony/eject.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-sony_eject(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref niargs
-#pragma ref ncargs
-#pragma ref cargs
-
- set6(cmd, 0xC0, iargs[0]<<5, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- return(0);
-}
//GO.SYSIN DD scsi/sony/eject.c
echo scsi/sony/shelfside.c 1>&2
sed 's/.//' >scsi/sony/shelfside.c <<'//GO.SYSIN DD scsi/sony/shelfside.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-shelfside(char *arg, char *err)
-{
- char *oarg = arg;
- int shelf;
-
- if((*arg < '0') || (*arg > '9')){
-usage:
- sprintf(err, "shelfside '%s' must be numa or numb", oarg);
- return(-1);
- }
- shelf = 0;
- while((*arg >= '0') && (*arg <= '9'))
- shelf = 10*shelf + *arg++ - '0';
- shelf <<= 1;
- if(*arg == 'a')
- ;
- else if(*arg == 'b')
- shelf |= 1;
- else
- goto usage;
- if(*++arg)
- goto usage;
- return(shelf);
-}
//GO.SYSIN DD scsi/sony/shelfside.c
echo scsi/sony/diskid.c 1>&2
sed 's/.//' >scsi/sony/diskid.c <<'//GO.SYSIN DD scsi/sony/diskid.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-sony_diskid(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set6(cmd, 0xC2, iargs[0]<<5, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 1024, err))
- return(n);
- printf("(%d,%d) disk id block:\n", s_id, iargs[0]);
- xd(ret.data, 1024, stdout);
- return(0);
-}
//GO.SYSIN DD scsi/sony/diskid.c
echo scsi/sony/internal.c 1>&2
sed 's/.//' >scsi/sony/internal.c <<'//GO.SYSIN DD scsi/sony/internal.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static
-internal(int n, int b1, int nb, struct scsi_return *ret, char *err)
-{
- struct scsi_cmd cmd;
-
- set6(cmd, 0x1D, b1, 0, 0, 10, 0);
- cmd.data[0] = n;
- cmd.data[1] = b1>>8;
- cmd.data[2] = 0;
- cmd.data[3] = 0;
- cmd.data[4] = 0;
- cmd.data[5] = 0;
- cmd.data[6] = 0;
- cmd.data[7] = 0;
- cmd.data[8] = 0;
- cmd.data[9] = 0;
- if(n = s_io(0, &cmd, 10, ret, 0, err))
- return(n);
- setdiag(cmd, 0, nb);
- if(n = s_io(0, &cmd, 0, ret, nb, err))
- return(n);
- return(0);
-}
-
-static char *cmds[] = {
- "internal command table",
- "error information table",
- "arm controller diagnostics",
- "scsi control board diagnostics",
- "drive controller diagnostics",
- "jukebox status",
- 0
-};
-
-static char *msg1[16] =
-{
- "drive not connected or powered off",
- "drive connected but no disk",
- "diagnostic aborted: write-protect",
- "diagnostic aborted: write area full",
- "urk 4", "urk 5", "urk 6", "urk 7", "urk 8", "urk 9", "urk 10",
- "urk 11", "urk 12", "urk 13", "urk 14", "urk 15"
-};
-
-static char *testn[10] =
-{
- "drive on/off",
- "read disk id",
- "move",
- "seek",
- "blank sector search",
- "written sector search",
- "search writable area",
- "write",
- "ECC margin check",
- "read data compare"
-};
-
-int
-sony_internal(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- register unsigned char *d;
- int i, drive, lower;
- long t1, t2;
- extern char *cmesg[];
- extern char *i0com[], *i1err[], *scsicmd[], *busid[], *scsiident[];
-
-#pragma ref ncargs
-#pragma ref cargs
-
- switch(iargs[0])
- {
- case -1:
- printf("available internal commands:\n");
- for(i = 0; cmds[i]; i++)
- printf("\tinternal %d: %s\n", i, cmds[i]);
- break;
- case 0:
- if(internal(0xE5, 0, 256, &ret, err))
- return(1);
- printf("internal 0 (%s):\n", cmds[iargs[0]]);
- printf("Diagnostic #E5: last 16 internal tasks (drive,shelf)\n");
- for(i = 0, d = ret.data; i < 16; i++, d += 16){
- printf("[%d] %s (%d,%d)\n",
- d[0], i0com[d[1]], d[2], d[3]);
- }
- break;
- case 1:
- if(internal(0xE4, 0, 256, &ret, err))
- return(1);
- printf("internal 1 (%s):\n", cmds[iargs[0]]);
- printf("Diagnostic #E4: last 16 errors; initiator[identify] error[sense] (cmd)\n");
- for(i = 0, d = ret.data; i < 16; i++, d += 16){
- printf("%s[%s]: %s[#%x] (%s)\n",
- busid[d[0]], scsiident[d[1]], i1err[d[14]], d[15], scsicmd[d[4]]);
- }
- break;
- case 2:
- printf("internal 2 (%s):\n", cmds[iargs[0]]);
- fflush(stdout);
- time(&t1);
- if(internal(0x90, 0, 8, &ret, err))
- return(1);
- time(&t2);
- d = ret.data;
- if(d[0] == 0)
- printf("\tended normally");
- else
- printf("\tfailed, error codes=#%x, #%x, #%x",
- d[0], d[1], d[2]);
- printf(" (time: %lds)\n", t2-t1);
- break;
- case 3:
- printf("internal 3 (%s):\n", cmds[iargs[0]]);
- fflush(stdout);
- time(&t1);
- if(internal(0xe0, 0, 8, &ret, err))
- return(1);
- time(&t2);
- d = ret.data;
- if(d[0] == 0)
- printf("\tended normally");
- else
- printf("\tfailed, error codes=#%x, #%x, #%x",
- d[0], d[1], d[2]);
- printf(" (time: %lds)\n", t2-t1);
- break;
- case 4:
- if(niargs == 1)
- iargs[1] = 0; /* zero default */
- drive = iargs[1];
- if(sony_istatus(&ret, err))
- return(1);
- if((ret.data[100]&0x80) && (drive == (ret.data[100]&7)))
- lower = 0x100;
- else if((ret.data[101]&0x80) && (drive == (ret.data[101]&7)))
- lower = 0x200;
- else {
- fprintf(stderr, "drive %d not occupied\n", drive);
- return(1);
- }
- printf("drive %d[%ser]: %s\n", drive, (lower == 0x200)?"low":"upp", cmds[iargs[0]]);
- fflush(stdout);
- time(&t1);
- if(internal(0x18, lower, 256, &ret, err))
- return(1);
- time(&t2);
- d = ret.data;
- if(d[1]&0x80){
- printf("diagnostic result:");
- if((d[1]&0x70) == 0)
- printf(" no faults");
- else {
- if(d[1]&0x10)
- printf(" controller-fault");
- if(d[1]&0x20)
- printf(" drive-fault");
- if(d[1]&0x10)
- printf(" disk-fault");
- printf(" (last error code 0x%2.2ux)", d[4]);
- }
- } else
- printf("diagnostic not performed: %s", msg1[d[1]&0xF]);
- printf(" (time: %lds)\n", t2-t1);
- for(i = 0; i < 10; i++)
- printf("test %d[%s]: %s\n", i, testn[i], cmesg[d[i*8+drive+8]]);
- printf("diagnostic count (drive:avail):");
- for(d += 104, i = 0; i < 8; i++, d += 2)
- printf(" %d:%d", i, d[0]+d[1]*256);
- printf("\n");
- break;
- case 5:
- set10(cmd, 0xD3, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- printf("%s: component(fatal err/err/cmds)\n", cmds[iargs[0]]);
- d = ret.data;
-#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)
-
- ONE("upper drive", 4, ' ');
- ONE("lower drive", 8, ' ');
- ONE("sys control", 12, ' ');
- printf("backup mem(0/%d/%d)\n", d[19]+256*d[18], d[17]+256*d[16]);
- break;
- }
- return(0);
-}
//GO.SYSIN DD scsi/sony/internal.c
echo scsi/sony/i0.tab 1>&2
sed 's/.//' >scsi/sony/i0.tab <<'//GO.SYSIN DD scsi/sony/i0.tab'
-i0com
-00 nop
-01 sense result
-02 version check
-04 recover disk warning
-08 sense alternate information
-0a error margin check
-18 diagnostics
-20 sense drive status
-21 recalibrate
-22 drive on
-23 drive off
-24 disk out
-30 seek
-31 move
-32 read
-a1 disk check
-a2 carrier move
-b1 disk set
-b2 disk release
-b3 disk rotate
//GO.SYSIN DD scsi/sony/i0.tab
echo scsi/sony/i1.tab 1>&2
sed 's/.//' >scsi/sony/i1.tab <<'//GO.SYSIN DD scsi/sony/i1.tab'
-i1err
-94 drive error (SONY)
-a0 invalid command
-a1 invalid LUN
-a2 reserved bit nonzero
-a3 illegal logical address
-a4 illegal shelf number
-a5 illegal parameter length
-a6 illegal parameter
-a7 unacceptable diagnostics parameter
-a8 unit attention
-a9 drive not ready
-aa medium removal prevented
-ab reserved
-ac no disk in LUN
//GO.SYSIN DD scsi/sony/i1.tab
echo scsi/sony/scsi.tab 1>&2
sed 's/.//' >scsi/sony/scsi.tab <<'//GO.SYSIN DD scsi/sony/scsi.tab'
-scsicmd
-00 test unit ready
-01 rezero unit
-03 request sense
-08 read
-0a write
-0b seek
-0c move
-12 inquiry
-15 mode select
-16 reserve
-17 release
-18 copy
-1a mode sense
-1b start/stop unit
-1c receive diagnostics
-1d send diagnostics
-1e prevent/allow medium removal
-25 read capacity
-28 read
-2a write
-2c blank sector search
-2d written sector search
-c0 disk eject
-c2 read disk id
-c3 sense alternate information
-c4 recover disk warning
-d3 request recovered status
-d6 disk set
-d7 disk release
-busid
-01 0
-02 1
-80 7
-scsiident
-80 no dis/reconnect-LUN 0
-81 no dis/reconnect-LUN 1
-82 no dis/reconnect-LUN 2
-83 no dis/reconnect-LUN 3
-84 no dis/reconnect-LUN 4
-85 no dis/reconnect-LUN 5
-86 no dis/reconnect-LUN 6
-87 no dis/reconnect-LUN 7
-c0 dis/reconnect-LUN 0
-c1 dis/reconnect-LUN 1
-c2 dis/reconnect-LUN 2
-c3 dis/reconnect-LUN 3
-c4 dis/reconnect-LUN 4
-c5 dis/reconnect-LUN 5
-c6 dis/reconnect-LUN 6
-c7 dis/reconnect-LUN 7
-cmesg
-0 good
-e0 test not done
-ee diagnostic could not be done
-fe drive not ready (no disk)
-ff not connected or power off
//GO.SYSIN DD scsi/sony/scsi.tab
echo scsi/sony/media.c 1>&2
sed 's/.//' >scsi/sony/media.c <<'//GO.SYSIN DD scsi/sony/media.c'
-#include <stdio.h>
-#include <stddef.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static int cnts[256];
-static char *cmsg[256];
-
-sony_media1(int drive, long lbn, int lower, struct scsi_return *ret, char *err)
-{
- struct scsi_cmd cmd;
- int n;
-
- set6(cmd, 0x1D, drive<<5, 0, 0, 10, 0);
- cmd.data[0] = 0x0A; /* error margin check */
- cmd.data[1] = lower? 2:1;
- cmd.data[2] = 0;
- cmd.data[3] = 0;
- cmd.data[4] = drive;
- cmd.data[5] = lbn;
- cmd.data[6] = lbn>>8;
- cmd.data[7] = lbn>>16;
- cmd.data[8] = 0;
- cmd.data[9] = 0;
- if(n = s_io(0, &cmd, 10, ret, 0, err))
- return(n);
- setdiag(cmd, drive, 256);
- if(n = s_io(0, &cmd, 0, ret, 256, err))
- return(n);
- return(0);
-}
-
-int
-sony_media(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_return ret;
- uchar *d;
- int bn, c;
- char buf[256];
- int lower;
- int nline;
- int cur, curb;
- int drive = iargs[0];
- long lbn = iargs[1];
- int count = iargs[2];
- extern char *strdup(char *);
- int verbose = 0;
- FILE *fp = 0;
-
-#pragma ref niargs
-
- if(ncargs == 1){
- if(strcmp(cargs[0], "-v") == 0)
- verbose = 1;
- else if((fp = fopen(cargs[0], "w")) == NULL){
- pperror(err, cargs[0]);
- return(1);
- }
- }
- if(sony_istatus(&ret, err))
- return(1);
- if((ret.data[100]&0x80) && (drive == (ret.data[100]&7)))
- lower = 0;
- else if((ret.data[101]&0x80) && (drive == (ret.data[101]&7)))
- lower = 1;
- else {
- sprintf(err, "drive %d not occupied and ready\n", drive);
- return(1);
- }
- printf("media margin check for %d blocks [%d-%d] on %s drive (%d,%d):",
- count, lbn, lbn+count-1, lower? "lower":"upper", s_id, drive);
- if(fp)
- printf(" stored in '%s'", cargs[0]);
- putchar('\n');
- if(cmsg[0] == 0){
- for(bn = 0; bn < 256; bn++){
- sprintf(buf, "rare error 0x%x", bn);
- cmsg[bn] = strdup(buf);
- }
- cmsg[0] = "good";
- cmsg[0x40] = "seek error 1 (alternated)";
- cmsg[0x41] = "seek error 2 (alternated)";
- cmsg[0x42] = "seek error 3 (alternated)";
- cmsg[0x44] = "read error 1 (alternated)";
- cmsg[0x45] = "unwritten";
- cmsg[0x46] = "read error 3 (alternated)";
- cmsg[0x81] = "<50% burst";
- cmsg[0x82] = "50-96% burst (alternated)";
- cmsg[0x83] = ">96% burst (alternated)";
- cmsg[0x84] = "uncorrectable (alternated)";
- }
-#define DO(ch,cp) if(fp) putc(ch,fp); else if(ch != cur){\
- int newb = bn+cp-ret.data;\
- if(verbose && (curb>=0)){\
- printf("%d %s@%d, ", newb-curb, cmsg[cur], curb);\
- if(++nline == 5){nline = 0; putchar('\n');}\
- }\
- cur = ch;\
- curb = newb;\
- }
- cur = 256;
- curb = -1;
- nline = 0;
- for(bn = 0; bn < 256; bn++)
- cnts[bn] = 0;
- for(bn = lbn, c = count; c >= 256; c -= 256, bn += 256){
- if(sony_media1(drive, bn, lower, &ret, err))
- return(1);
- for(d = ret.data; d < &ret.data[256];){
- DO(*d, d);
- cnts[*d++]++;
- }
- }
- if(c){
- if(sony_media1(drive, bn, lower, &ret, err))
- return(1);
- for(d = ret.data; c; c--){
- DO(*d, d);
- cnts[*d++]++;
- }
- }
- DO(256, d);
- if(nline)
- putchar('\n');
- printf("\t");
- for(c = 0; c < 256; c++)
- if(cnts[c])
- printf("%d %s, ", cnts[c], cmsg[c]);
- printf("\n");
- return(0);
-}
//GO.SYSIN DD scsi/sony/media.c
echo scsi/sony/readid.c 1>&2
sed 's/.//' >scsi/sony/readid.c <<'//GO.SYSIN DD scsi/sony/readid.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static int
-my_read(int lun, long blk, struct scsi_return *ret, char *err)
-{
- struct scsi_cmd cmd;
- int n;
-
- cmd.bus_id = s_id;
- set10(cmd, 0x28, lun<<5, blk>>24, blk>>16, blk>>8, blk, 0, 0, 1, 0);
- n = ss_io(0, &cmd, 0, ret, 1024, err);
- return(n);
-}
-
-int
-sony_readid(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_return ret;
- char buf[128];
- int drive = iargs[0];
- long blk, lastb;
- int pr = 0;
-
-#pragma ref ncargs
-#pragma ref cargs
-
- buf[0] = 0;
- if(niargs == 2){
- if((blk = iargs[1]) < 0){
- blk = -blk;
- pr = 1;
- }
- } else {
- if(my_read(drive, 0L, &ret, err) == 0)
- goto done;
- blk = 1;
- }
- for(lastb = -1;;){
- if(pr){
- printf("%d: ", blk);
- }
- if(my_read(drive, blk, &ret, err))
- break;
- lastb = blk;
- blk = ((long *)ret.data)[9];
- }
- if(lastb < 0){
- printf("read(blk=%d) failed\n", blk);
- return(1);
- }
- if(my_read(drive, lastb, &ret, err) != 0)
- return(1);
-done:
- strncpy(buf, (char *)&ret.data[42], 128);
- buf[127] = 0;
- printf("(%d,%d): '%s'\n", s_id, drive, buf);
- return(0);
-}
//GO.SYSIN DD scsi/sony/readid.c
echo scsi/sony/copy.c 1>&2
sed 's/.//' >scsi/sony/copy.c <<'//GO.SYSIN DD scsi/sony/copy.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-#define PROGRESS \
- if(sbase/TALK != goo){\
- goo = sbase/TALK;\
- time(&t2);\
- printf("\tdoing block %ld at %s", goo*TALK, ctime(&t2));\
- }
-
-static char good[256]; /* by default, all BAD */
-typedef enum { BAD = 0, GOOD } Searchtype;
-static int copy1(int, int, int, int, int, int, int, char *);
-static int search(int, int, int, int, Searchtype, char *);
-
-int
-sony_copy(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- int n;
- int sdr = iargs[0];
- int sbase = iargs[1];
- int nblocks = iargs[2];
- int ddr = iargs[3];
- int dbase = iargs[4];
- int starget = s_id;
- int dtarget = s_id;
- int wr, unwr;
- long nb = nblocks;
- long t1, t2;
- long goo;
- int lower;
- struct scsi_return ret;
-#define TALK 10000
- extern char *ctime();
-
-#pragma ref niargs
-#pragma ref ncargs
-#pragma ref cargs
-
- printf("copying drive (%d,%d)[%d-%d] to drive (%d,%d)[%d-%d]\n",
- starget, sdr, sbase, sbase+nblocks-1,
- dtarget, ddr, dbase, dbase+nblocks-1);
- if(sony_istatus(&ret, err))
- return(1);
- if((ret.data[100]&0x80) && (sdr == (ret.data[100]&7)))
- lower = 0;
- else if((ret.data[101]&0x80) && (sdr == (ret.data[101]&7)))
- lower = 1;
- else {
- sprintf(err, "drive %d not occupied\n", sdr);
- return(1);
- }
- good[0] = good[0x81] = good[0x82] = good[0x83] = GOOD;
- time(&t1);
- goo = -1;
- while(nblocks > 0){
- /* search for a block to copy */
- while(n = min(256, nblocks)){
- wr = search(sdr, lower, sbase, n, GOOD, err);
- if(wr < 0)
- break;
- sbase += wr;
- dbase += wr;
- nblocks -= wr;
- if(wr < n)
- break;
- PROGRESS
- }
- /* now copy until the first bad block */
- while(n = min(256, nblocks)){
- unwr = search(sdr, lower, sbase, n, BAD, err);
- if(unwr < 0)
- break;
- /*printf("writing %d-%d\n", sbase, sbase+unwr-1);/**/
- if(copy1(starget, sdr, sbase, unwr, dtarget, ddr, dbase, err))
- break;
- sbase += unwr;
- dbase += unwr;
- nblocks -= unwr;
- PROGRESS
- }
- }
- time(&t2);
- t2 -= t1;
- if(t2 == 0) t2 = 1;
- printf("%ds: ", t2);
- if(nblocks){
- printf("copy buggered up: sbase=%d nblks=%d dbase=%d\n",
- sbase, nblocks, dbase);
- return(1);
- }
- printf("%d blocks at %.1fKB/s\n", nb, nb/(float)t2);
- return(0);
-}
-
-static int
-copy1(int st, int sd, int sb, int n, int dt, int dd, int db, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
-
- set6(cmd, 0x18, sd<<5, 0, 0, 20, 0);
- cmd.data[0] = 0x10; /* copy */
- cmd.data[1] = 0;
- cmd.data[2] = 0;
- cmd.data[3] = 0;
- cmd.data[4] = (st<<5)|sd;
- cmd.data[5] = (dt<<5)|dd;
- cmd.data[6] = 0;
- cmd.data[7] = 0;
- cmd.data[8] = n>>24;
- cmd.data[9] = n>>16;
- cmd.data[10] = n>>8;
- cmd.data[11] = n;
- cmd.data[12] = sb>>24;
- cmd.data[13] = sb>>16;
- cmd.data[14] = sb>>8;
- cmd.data[15] = sb;
- cmd.data[16] = db>>24;
- cmd.data[17] = db>>16;
- cmd.data[18] = db>>8;
- cmd.data[19] = db;
- return(s_io(0, &cmd, 20, &ret, 0, err));
-}
-
-static int
-search(int dr, int lower, int sbase, int n, Searchtype s, char *err)
-{
- uchar *cp;
- struct scsi_return ret;
-
- if(n <= 0)
- return(0);
- if(n > 256)
- n = 256;
- if(sony_media1(dr, sbase, lower, &ret, err))
- return(-1);
- for(cp = ret.data; n-- > 0; cp++)
- if(good[*cp] != s)
- break;
- return(cp-ret.data);
-}
//GO.SYSIN DD scsi/sony/copy.c
echo scsi/sony/fns.h 1>&2
sed 's/.//' >scsi/sony/fns.h <<'//GO.SYSIN DD scsi/sony/fns.h'
-extern int sony_inq(int, int *, int, char **, char *);
-extern int sony_alt(int, int *, int, char **, char *);
-extern int sony_conf(int, int *, int, char **, char *);
-extern int sony_status(int, int *, int, char **, char *);
-extern int sony_set(int, int *, int, char **, char *);
-extern int sony_rel(int, int *, int, char **, char *);
-extern int sony_eject(int, int *, int, char **, char *);
-extern int sony_diskid(int, int *, int, char **, char *);
-extern int sony_internal(int, int *, int, char **, char *);
-extern int sony_media(int, int *, int, char **, char *);
-extern int sony_readid(int, int *, int, char **, char *);
-extern int sony_copy(int, int *, int, char **, char *);
-extern int sony_sense(int, int *, int, char **, char *);
-extern void sony_extsense(uchar *, char *, int);
-
-extern int shelfside(char *arg, char *err);
//GO.SYSIN DD scsi/sony/fns.h
echo scsi/sony/sense.c 1>&2
sed 's/.//' >scsi/sony/sense.c <<'//GO.SYSIN DD scsi/sony/sense.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-sony_sense(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- char buf[4096];
-
-#pragma ref ncargs
-#pragma ref cargs
-
- if(niargs == 0)
- iargs[0] = 0;
- set6(cmd, 0x03, iargs[0]<<5, 0, 0, 32, 0);
- if(n = s_io(0, &cmd, 0, &ret, -32, err))
- return(n);
- printf("sense(%d,%d): ", s_id, iargs[0]);
- sony_extsense(ret.data, buf, sizeof buf);
- printf("%s\n", buf);
- return(0);
-}
-
-static char *exstab[16] =
-{
- "no sense",
- "recovered error",
- "not ready",
- "medium error",
- "hardware error",
- "illegal request",
- "unit attention",
- "data protect",
- "blank check",
- "key #9",
- "copy aborted",
- "aborted command",
- "key #c",
- "volume overflow",
- "miscompare",
- "key #f",
-};
-
-void
-sony_extsense(uchar *data, char *dest, int ndata)
-{
- char buf[4096];
- extern char *nesd[];
-
- dest[0] = 0;
- switch(data[2])
- {
- case 0:
- sprintf(dest, "no error");
- break;
- case 0x1: /* recovered error */
- sprintf(dest, "recovered error");
- break;
- case 0xA: /* recovered error */
- sprintf(dest, "recovered error");
- break;
- default:
- if(data[7] != 4)
- sprintf((char *)data, "warning: extra data is %d, not 4! ", data[7]);
- sprintf(buf, "sense: %s", nesd[data[8]&0x7f]);
- strcat(dest, buf);
- if(data[8]&0x80){
- sprintf(buf, " at addr #%x", data[11]+256L*data[10]+256L*256*data[9]);
- strcat(dest, buf);
- }
- sprintf(buf, ", ext sense: %s", exstab[data[2]]);
- strcat(dest, buf);
- if(data[0]&0x80){
- sprintf(buf, " info=#%x", data[6]+256L*data[5]+256L*256L*data[4]+256L*256L*256L*data[3]);
- strcat(dest, buf);
- }
- break;
- }
-}
//GO.SYSIN DD scsi/sony/sense.c
echo scsi/sony/nesd.tab 1>&2
sed 's/.//' >scsi/sony/nesd.tab <<'//GO.SYSIN DD scsi/sony/nesd.tab'
-nesd
-00 no sense
-01 invalid command
-02 recovered error
-03 illegal request
-06 unit attention
-07 parity error
-08 message reject error
-0a copy aborted
-10 ecc trouible occurred
-11 time out error
-12 controller error
-13 SONY I/F II hardware/firmware error
-14 scsi hardware/firmware error
-20 command not terminated
-21 drive interface parity error
-22 loading trouble
-23 focus trouble
-24 tracking trouble
-25 spindle trouble
-26 slide trouible
-27 skew trouble
-28 head lead out
-29 write modulation trouble
-2a under laser power
-2b over laser power
-2f drive error
-30 drive power off
-31 no disk in drive
-32 drive not ready
-38 disk already exists in drive
-39 no disk in drive
-3a disk already exists in shelf
-40 write warning
-41 write error
-42 disk error
-43 cannot read disk id
-44 write protect error 1
-45 write protect error 2
-46 disk warning
-47 alternation trouble
-50 specified address not found
-51 address block not found
-52 all address could not be read
-53 data could not be read
-54 uncorrectable read error
-55 tracking error
-60 no data in specified address
-68 z-axis servo error
-69 roter servo error
-6a hook servo error
-6b i/o shelf error
-6c drive 0 error
-6d drive 1 error
-6e shelf error
-6f carrier error
//GO.SYSIN DD scsi/sony/nesd.tab
echo scsi/lib.c 1>&2
sed 's/.//' >scsi/lib.c <<'//GO.SYSIN DD scsi/lib.c'
-#include <stdio.h>
-#include "scsi.h"
-#include "scsish.h"
-#include "generic/fns.h"
-#include "sony/fns.h"
-
-s_start(int dr, char *err)
-{
- int iargs[1];
- char *cargs[1];
-
- iargs[0] = dr;
- return(gen_start(1, iargs, 0, cargs, err));
-}
-
-s_stop(int dr, char *err)
-{
- int iargs[1];
- char *cargs[1];
-
- iargs[0] = dr;
- return(gen_stop(1, iargs, 0, cargs, err));
-}
-
-s_eject(int dr, char *err)
-{
- int iargs[1];
- char *cargs[1];
-
- iargs[0] = dr;
- return(sony_eject(1, iargs, 0, cargs, err));
-}
//GO.SYSIN DD scsi/lib.c
echo scsi/wren/dev.c 1>&2
sed 's/.//' >scsi/wren/dev.c <<'//GO.SYSIN DD scsi/wren/dev.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-static Function fns[] = {
- { "diag", "diag", "", wr_diag },
- { "extinq", "extinq", "", wr_extinq },
- { "modesense", "modesense", "", wr_modesense },
- { "modeselect", "modeselect er-param er-retries read-recon write-recon cache-enable cache-thr cache-pre cache-size", "IIIIIIIII", wr_modeselect },
- { 0 }
-};
-Device wrendev = {
- "wren", "Wren V/VI/Runner-2",
- gen_extsense,
- fns
-};
//GO.SYSIN DD scsi/wren/dev.c
echo scsi/wren/inq.c 1>&2
sed 's/.//' >scsi/wren/inq.c <<'//GO.SYSIN DD scsi/wren/inq.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-extern char *gen_rmb[2];
-extern char *gen_devtype[256];
-
-int
-wr_extinq(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- char vendor[9], product[17];
-
-#pragma ref niargs
-#pragma ref iargs
-#pragma ref ncargs
-#pragma ref cargs
-
- set6(cmd, 0x12, 0, 0, 0, 96, 0);
- if(n = s_io(0, &cmd, 0, &ret, 96, err))
- return(n);
- fixedstr(&ret.data[8], 8, vendor);
- fixedstr(&ret.data[16], 16, product);
- printf("inq(%d,%d): %s %s, %s/%s rev=%0.4s serial=%0.8s\n",
- s_id, 0, gen_rmb[ret.data[1]>>7], gen_devtype[ret.data[0]],
- vendor, product, &ret.data[32], &ret.data[36]);
- return(0);
-}
//GO.SYSIN DD scsi/wren/inq.c
echo scsi/wren/wmode.c 1>&2
sed 's/.//' >scsi/wren/wmode.c <<'//GO.SYSIN DD scsi/wren/wmode.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref niargs
-#pragma ref ncargs
-#pragma ref cargs
-
- printf("changing modes to ");
- if((iargs[0] < 256) && (iargs[0] >= 0))
- printf("er-param=%d(=#%x), ", iargs[0], iargs[0]);
- if((iargs[1] < 256) && (iargs[1] >= 0))
- printf("er-retries=%d, ", iargs[1]);
- if((iargs[2] < 256) && (iargs[2] >= 0))
- printf("read-recon=%d/256, ", iargs[2]);
- if((iargs[3] < 256) && (iargs[3] >= 0))
- printf("write-recon=%d/256, ", iargs[3]);
- if((iargs[4] < 256) && (iargs[4] >= 0))
- printf("read cache %sable, ", iargs[4]?"dis":"en");
- if((iargs[5] < 256) && (iargs[5] >= 0))
- printf("write cache %sable, ", iargs[5]?"en":"dis");
- if((iargs[6] < 256) && (iargs[6] >= 0))
- printf("cache max prefetch=%d, ", iargs[6]);
- if((iargs[7] < 256) && (iargs[7] >= 0))
- printf("cache size=%d, ", iargs[7]);
- if((iargs[8] < 256) && (iargs[8] >= 0))
- printf("cross cyl %sable, ", iargs[8]?"en":"dis");
- printf("\nsleep(10); kill me if you disagree\n");
- fflush(stdout);
- sleep(10);
- /* do error recovery */
- if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- memcpy(cmd.data, ret.data, 20);
- cmd.data[14] &= ~0x10;
- if((iargs[0] < 256) && (iargs[0] >= 0))
- cmd.data[14] = iargs[0];
- if((iargs[1] < 256) && (iargs[1] >= 0))
- cmd.data[15] = iargs[1];
- set6(cmd, 0x15, 0x11, 0, 0, 20, 0);
- if(n = s_io(0, &cmd, 20, &ret, 0, err))
- return(n);
- }
- /* reconnect */
- if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- memcpy(cmd.data, ret.data, 24);
- if((iargs[2] < 256) && (iargs[2] >= 0))
- cmd.data[14] = iargs[2];
- if((iargs[3] < 256) && (iargs[3] >= 0))
- cmd.data[15] = iargs[3];
- set6(cmd, 0x15, 0x11, 0, 0, 24, 0);
- if(n = s_io(0, &cmd, 24, &ret, 0, err))
- return(n);
- }
- /* do cache params*/
- if(((iargs[4] < 256) && (iargs[4] >= 0))
- || ((iargs[5] < 256) && (iargs[5] >= 0))
- || ((iargs[6] < 65536) && (iargs[6] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x08, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- memcpy(cmd.data, ret.data, 24);
- if((iargs[4] < 256) && (iargs[4] >= 0)){
- cmd.data[14] &= ~0x01;
- cmd.data[14] |= iargs[4];
- }
- if((iargs[5] < 256) && (iargs[5] >= 0)){
- cmd.data[14] &= ~0x04;
- cmd.data[14] |= iargs[5]? 0x04:0;
- }
- if((iargs[6] < 65536) && (iargs[6] >= 0)){
- cmd.data[20] = iargs[6]>>8;
- cmd.data[21] = iargs[6];
- }
- set6(cmd, 0x15, 0x11, 0, 0, 24, 0);
- if(n = s_io(0, &cmd, 24, &ret, 0, err))
- return(n);
- }
- /* do cache control */
- if(((iargs[8] < 256) && (iargs[8] >= 0))
- || ((iargs[7] < 256) && (iargs[7] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- memcpy(cmd.data, ret.data, 28);
- cmd.data[14] &= ~0x80;
- if(iargs[8])
- cmd.data[14] |= 0x80;
- if((iargs[7] < 256) && (iargs[7] >= 0)){
- cmd.data[14] &= 0xF0;
- cmd.data[14] |= iargs[7]&0xF;
- }
- set6(cmd, 0x15, 0x11, 0, 0, 28, 0);
- if(n = s_io(0, &cmd, 28, &ret, 0, err))
- return(n);
- }
- return(0);
-}
//GO.SYSIN DD scsi/wren/wmode.c
echo scsi/wren/diag.c 1>&2
sed 's/.//' >scsi/wren/diag.c <<'//GO.SYSIN DD scsi/wren/diag.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-wr_diag(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- long t;
-
-#pragma ref niargs
-#pragma ref iargs
-#pragma ref ncargs
-#pragma ref cargs
-
- t = time((long *)0);
- set6(cmd, 0x1D, 0x04, 0, 0, 0, 0);
- if(n = s_io(0, &cmd, 0, &ret, 0, err))
- return(n);
- set6(cmd, 0x1C, 0, 0, 0, 8, 0);
- if(n = s_io(0, &cmd, 0, &ret, 8, err))
- return(n);
- t = time((long *)0)-t;
- printf("selftest diagnostic (%ds)\n", t);
- if((ret.data[7] == 0) && (ret.data[2] == 0))
- printf("\tno errors\n");
- else
- printf("\terror==#%x,#%x FRU=(#%x,#%x,#%x,#%x)\n",
- ret.data[6], ret.data[7], ret.data[2],
- ret.data[3], ret.data[4], ret.data[5]);
- return(0);
-}
//GO.SYSIN DD scsi/wren/diag.c
echo scsi/wren/fns.h 1>&2
sed 's/.//' >scsi/wren/fns.h <<'//GO.SYSIN DD scsi/wren/fns.h'
-extern int wr_extinq(int, int *, int, char **, char *);
-extern int wr_modesense(int, int *, int, char **, char *);
-extern int wr_modeselect(int, int *, int, char **, char *);
-extern int wr_diag(int, int *, int, char **, char *);
//GO.SYSIN DD scsi/wren/fns.h
echo scsi/wren/omode.c 1>&2
sed 's/.//' >scsi/wren/omode.c <<'//GO.SYSIN DD scsi/wren/omode.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-#define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1]))
-
-static int
-er(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- printf("error recovery:\n\t");
- for(n = 7; n >= 0; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf("\n\t%d retries, max ecc span=%d\n", ret.data[15], ret.data[16]);
- return(0);
-}
-
-static int
-dr(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x02, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- printf("disconnect/reconnect:\n");
- printf("\tread reconnect=%d/256,", ret.data[14]);
- printf(" write reconnect=%d/256\n", ret.data[15]);
- return(0);
-}
-
-static int
-fp(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x03, 0, 36, 0);
- if(n = s_io(0, &cmd, 0, &ret, 36, err))
- return(n);
- printf("format parameters:\n");
- printf("\tsec=%dB, trk=%d secs, interleave=%d trk skew=%d cyl skew=%d\n",
- SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30));
- printf("\t%d alt sec/%d alt trk per zone(=%d trks), %d alt trks per vol\n",
- SHORT(16), SHORT(18), SHORT(14), SHORT(20));
- printf("\tdrive type:");
- for(n = 7; n >= 3; n--)
- printf(" %s%s", (ret.data[32]&(1<<n))? "":"~", bit[n]);
- printf("\n");
- return(0);
-}
-
-static int
-geom(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0);
- if(n = s_io(0, &cmd, 0, &ret, 32, err))
- return(n);
- printf("drive geometry:\n\t%d cyls, %d heads\n",
- (ret.data[14]<<16)|SHORT(15), ret.data[17]);
- return(0);
-}
-
-static int
-cc(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "", "", "", "", "CacheEnable", "RSVD", "WIE", "RSVD" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- printf("cache control:\n\t");
- for(n = 7; n >= 4; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf(", cache size=%d\n", ret.data[14]&0xF);
- printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n",
- ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]);
- return(0);
-}
-
-int
-wr_modesense(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-#pragma ref niargs
-#pragma ref iargs
-
-#define PCF 0 /* current values */
-
- printf("mode sense(%d,0):\n", s_id);
- if(n = er(PCF, err))
- return(n);
- if(n = dr(PCF, err))
- return(n);
- if(n = fp(PCF, err))
- return(n);
- if(n = geom(PCF, err))
- return(n);
- if(n = cc(PCF, err))
- return(n);
- return(0);
-}
-
-int
-wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref niargs
-#pragma ref ncargs
-#pragma ref cargs
-
- printf("changing modes to ");
- if((iargs[0] < 256) && (iargs[0] >= 0))
- printf("er-param=%d(=#%x), ", iargs[0], iargs[0]);
- if((iargs[1] < 256) && (iargs[1] >= 0))
- printf("er-retries=%d, ", iargs[1]);
- if((iargs[2] < 256) && (iargs[2] >= 0))
- printf("read-recon=%d/256, ", iargs[2]);
- if((iargs[3] < 256) && (iargs[3] >= 0))
- printf("write-recon=%d/256, ", iargs[3]);
- if((iargs[4] < 256) && (iargs[4] >= 0))
- printf("cache %sable, ", iargs[4]?"en":"dis");
- if((iargs[5] < 256) && (iargs[5] >= 0))
- printf("cache threshold=%d, ", iargs[5]);
- if((iargs[6] < 256) && (iargs[6] >= 0))
- printf("cache max prefetch=%d, ", iargs[6]);
- if((iargs[7] < 256) && (iargs[7] >= 0))
- printf("cache size=%d, ", iargs[7]);
- printf("\nsleep(10); kill me if you disagree\n");
- fflush(stdout);
- sleep(10);
- /* do error recovery */
- if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- memcpy(cmd.data, ret.data, 20);
- cmd.data[14] &= ~0x10;
- if((iargs[0] < 256) && (iargs[0] >= 0))
- cmd.data[14] = iargs[0];
- if((iargs[1] < 256) && (iargs[1] >= 0))
- cmd.data[15] = iargs[1];
- set6(cmd, 0x15, 0x11, 0, 0, 20, 0);
- if(n = s_io(0, &cmd, 20, &ret, 0, err))
- return(n);
- }
- /* reconnect */
- if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- memcpy(cmd.data, ret.data, 24);
- if((iargs[3] < 256) && (iargs[3] >= 0))
- cmd.data[14] = iargs[3];
- if((iargs[4] < 256) && (iargs[4] >= 0))
- cmd.data[15] = iargs[4];
- set6(cmd, 0x15, 0x11, 0, 0, 24, 0);
- if(n = s_io(0, &cmd, 24, &ret, 0, err))
- return(n);
- }
- /* do cache control */
- if(((iargs[4] < 256) && (iargs[4] >= 0))
- || ((iargs[5] < 256) && (iargs[5] >= 0))
- || ((iargs[6] < 256) && (iargs[6] >= 0))
- || ((iargs[7] < 256) && (iargs[7] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- memcpy(cmd.data, ret.data, 28);
- cmd.data[14] &= ~0x10;
- if(iargs[4])
- cmd.data[14] |= 0x10;
- if((iargs[7] < 256) && (iargs[7] >= 0)){
- cmd.data[14] &= 0xF0;
- cmd.data[14] |= iargs[7]&0xF;
- }
- if((iargs[5] < 256) && (iargs[5] >= 0))
- cmd.data[15] = iargs[5];
- if((iargs[6] < 256) && (iargs[6] >= 0))
- cmd.data[16] = iargs[6];
- set6(cmd, 0x15, 0x11, 0, 0, 28, 0);
- if(n = s_io(0, &cmd, 28, &ret, 0, err))
- return(n);
- }
- return(0);
-}
//GO.SYSIN DD scsi/wren/omode.c
echo scsi/wren/oomode.c 1>&2
sed 's/.//' >scsi/wren/oomode.c <<'//GO.SYSIN DD scsi/wren/oomode.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-#define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1]))
-
-static int
-er(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- printf("error recovery:\n\t");
- for(n = 7; n >= 0; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf("\n\t%d retries, max ecc span=%d\n", ret.data[15], ret.data[16]);
- return(0);
-}
-
-static int
-dr(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x02, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- printf("disconnect/reconnect:\n");
- printf("\tread reconnect=%d/256,", ret.data[14]);
- printf(" write reconnect=%d/256\n", ret.data[15]);
- return(0);
-}
-
-static int
-fp(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x03, 0, 36, 0);
- if(n = s_io(0, &cmd, 0, &ret, 36, err))
- return(n);
- printf("format parameters:\n");
- printf("\tsec=%dB, trk=%d secs, interleave=%d trk skew=%d cyl skew=%d\n",
- SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30));
- printf("\t%d alt sec/%d alt trk per zone(=%d trks), %d alt trks per vol\n",
- SHORT(16), SHORT(18), SHORT(14), SHORT(20));
- printf("\tdrive type:");
- for(n = 7; n >= 3; n--)
- printf(" %s%s", (ret.data[32]&(1<<n))? "":"~", bit[n]);
- printf("\n");
- return(0);
-}
-
-static int
-geom(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0);
- if(n = s_io(0, &cmd, 0, &ret, 32, err))
- return(n);
- printf("drive geometry:\n\t%d cyls, %d heads\n",
- (ret.data[14]<<16)|SHORT(15), ret.data[17]);
- return(0);
-}
-
-static int
-cc(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "", "", "", "", "CacheEnable", "RSVD", "WIE", "RSVD" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- printf("cache control:\n\t");
- for(n = 7; n >= 4; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf(", cache size=%d\n", ret.data[14]&0xF);
- printf("\tprefetch: thr=%d max=%dx%d min=%dx%d\n",
- ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]);
- return(0);
-}
-
-int
-wr_modesense(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- int n;
-
-#pragma ref ncargs
-#pragma ref cargs
-#pragma ref niargs
-#pragma ref iargs
-
-#define PCF 0 /* current values */
-
- printf("mode sense(%d,0):\n", s_id);
- if(n = er(PCF, err))
- return(n);
- if(n = dr(PCF, err))
- return(n);
- if(n = fp(PCF, err))
- return(n);
- if(n = geom(PCF, err))
- return(n);
- if(n = cc(PCF, err))
- return(n);
- return(0);
-}
-
-int
-wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref niargs
-#pragma ref ncargs
-#pragma ref cargs
-
- printf("changing modes to ");
- if((iargs[0] < 256) && (iargs[0] >= 0))
- printf("er-param=%d(=#%x), ", iargs[0], iargs[0]);
- if((iargs[1] < 256) && (iargs[1] >= 0))
- printf("er-retries=%d, ", iargs[1]);
- if((iargs[2] < 256) && (iargs[2] >= 0))
- printf("read-recon=%d/256, ", iargs[2]);
- if((iargs[3] < 256) && (iargs[3] >= 0))
- printf("write-recon=%d/256, ", iargs[3]);
- if((iargs[4] < 256) && (iargs[4] >= 0))
- printf("cache %sable, ", iargs[4]?"en":"dis");
- printf("\nsleep(10); kill me if you disagree\n");
- fflush(stdout);
- sleep(10);
- /* do error recovery */
- if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- memcpy(cmd.data, ret.data, 20);
- cmd.data[14] &= ~0x10;
- if((iargs[0] < 256) && (iargs[0] >= 0))
- cmd.data[14] = iargs[0];
- if((iargs[1] < 256) && (iargs[1] >= 0))
- cmd.data[15] = iargs[1];
- set6(cmd, 0x15, 0x11, 0, 0, 20, 0);
- if(n = s_io(0, &cmd, 20, &ret, 0, err))
- return(n);
- }
- /* reconnect */
- if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- memcpy(cmd.data, ret.data, 24);
- if((iargs[3] < 256) && (iargs[3] >= 0))
- cmd.data[14] = iargs[3];
- if((iargs[4] < 256) && (iargs[4] >= 0))
- cmd.data[15] = iargs[4];
- set6(cmd, 0x15, 0x11, 0, 0, 24, 0);
- if(n = s_io(0, &cmd, 24, &ret, 0, err))
- return(n);
- }
- /* do cache control */
- if((iargs[4] < 256) && (iargs[4] >= 0)){
- set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- memcpy(cmd.data, ret.data, 28);
- cmd.data[14] &= ~0x10;
- if(iargs[4])
- cmd.data[14] |= 0x10;
- set6(cmd, 0x15, 0x11, 0, 0, 28, 0);
- if(n = s_io(0, &cmd, 28, &ret, 0, err))
- return(n);
- }
- return(0);
-}
//GO.SYSIN DD scsi/wren/oomode.c
echo scsi/wren/rmode.c 1>&2
sed 's/.//' >scsi/wren/rmode.c <<'//GO.SYSIN DD scsi/wren/rmode.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-#define SHORT(n) ((ret.data[n]<<8)|(ret.data[n+1]))
-
-static int
-er_w6(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- printf("error recovery:\n\t");
- for(n = 7; n >= 0; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf("\n\t%d retries, max ecc span=%d, recov tlimit=%d\n",
- ret.data[15], ret.data[16], ret.data[17]);
- return(0);
-}
-
-static int
-dr_w6(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x02, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- printf("disconnect/reconnect:\n");
- printf("\tread reconnect=%d/256 full,", ret.data[14]);
- printf(" write reconnect=%d/256 empty\n", ret.data[15]);
- return(0);
-}
-
-static int
-fp_w6(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "", "", "", "INS", "SURF", "Remove", "HardSec", "SoftSec" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x03, 0, 36, 0);
- if(n = s_io(0, &cmd, 0, &ret, 36, err))
- return(n);
- printf("format parameters:\n");
- printf("\tsec=%d B, trk=%d secs, interleave=%d, trk_skew=%d, cyl_skew=%d\n",
- SHORT(24), SHORT(22), SHORT(26), SHORT(28), SHORT(30));
- printf("\t%d alt_sec/%d alt_trk per zone(=%d trks), %d alt_trk per vol\n",
- SHORT(16), SHORT(18), SHORT(14), SHORT(20));
- printf("\tdrive type:");
- for(n = 7; n >= 3; n--)
- printf(" %s%s", (ret.data[32]&(1<<n))? "":"~", bit[n]);
- printf("\n");
- return(0);
-}
-
-static int
-geom_w6(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0);
- if(n = s_io(0, &cmd, 0, &ret, 32, err))
- return(n);
- printf("drive geometry:\n\t%d cyls, %d heads\n",
- (ret.data[14]<<16)|SHORT(15), ret.data[17]);
- return(0);
-}
-
-static int
-cc_w6(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "", "", "", "", "CacheEnable", "RSVD", "WIE", "RSVD" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- printf("cache control:\n\t");
- for(n = 7; n >= 4; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf(", cache size=%d\n", ret.data[14]&0xF);
- printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n",
- ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]);
- return(0);
-}
-
-static int
-er_wr2(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "DCR", "DTE", "PER", "EEC", "RC", "TB", "ARRE", "AWRE" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- printf("error recovery:\n\t");
- for(n = 7; n >= 0; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf("\n\t%d retries, max ecc span=%d, %d wr retries, recov tlimit=%d\n",
- ret.data[15], ret.data[16], ret.data[20], SHORT(22));
- return(0);
-}
-
-static int
-geom_wr2(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *sspin[4] = {
- "no spindle synch",
- "synch-spindle slave",
- "synch-spindle master",
- "synch-spindle master control",
- };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x04, 0, 32, 0);
- if(n = s_io(0, &cmd, 0, &ret, 32, err))
- return(n);
- printf("drive geometry:\n\t%d cyls, %d heads, %s, rotation rate %d\n",
- (ret.data[14]<<16)|SHORT(15), ret.data[17],
- sspin[ret.data[29]&3], SHORT(32));
- return(0);
-}
-
-static int
-cp_wr2(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "ReadCacheDisable", "", "WriteCacheEnable", "", "", "", "", "" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x08, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- printf("caching parameters:\n\t");
- for(n = 2; n >= 0; n -= 2)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf("\n\tprefetch: min=%d, max=%d, ceiling=%d\n",
- SHORT(18), SHORT(20), SHORT(22));
- return(0);
-}
-
-static int
-cc_wr2(int pcf, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
- static char *bit[8] = { "", "", "", "", "CacheEnable", "SSM", "WIE", "CCEN" };
-
- set6(cmd, 0x1A, 0, (pcf<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- printf("cache control:\n\t");
- for(n = 7; n >= 4; n--)
- printf(" %s%s", (ret.data[14]&(1<<n))? "":"~", bit[n]);
- printf(", cache size=%d\n", ret.data[14]&0xF);
- printf("\tprefetch: thr=%d max=%d(mult %d) min=%d(mult %d)\n",
- ret.data[15], ret.data[16], ret.data[17], ret.data[18], ret.data[19]);
- return(0);
-}
-
-typedef (*Fn)(int, char *);
-static struct Drive
-{
- char *type; /* match inq field */
- char *desc; /* print at the user */
- Fn fns[10];
-} drive[] = { /* first one is default when none match */
- { "94181-15", "Wren VI", er_w6, dr_w6, fp_w6, geom_w6, cc_w6, 0 },
- { "ST4767", "Wren Runner-2", er_wr2, dr_w6, fp_w6, geom_wr2, cp_wr2, cc_wr2, 0 },
- { 0 }
-};
-
-int
-wr_modesense(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- int n, i, retv;
- char product[17];
- int found;
- struct scsi_cmd cmd;
- struct scsi_return ret;
-
-#pragma ref ncargs
-#pragma ref cargs
-#pragma ref niargs
-#pragma ref iargs
-
-#define PCF 0 /* current values */
-
- /* find drive type */
- set6(cmd, 0x12, 0, 0, 0, 32, 0);
- if(n = s_io(0, &cmd, 0, &ret, 32, err))
- return(n);
- fixedstr(&ret.data[16], 16, product);
- for(n = 0, found = 0; drive[n].type; n++)
- if(strcmp(product, drive[n].type) == 0){
- found = 1;
- break;
- }
- if(!found)
- n = 0;
-
- if(found)
- printf("mode sense(%d,0)[%s(%s)]:\n", s_id, drive[n].desc, product);
- else
- printf("mode sense(%d,0)[using %s, found '%s']:\n", s_id, drive[n].desc, product);
- for(i = 0; drive[n].fns[i]; i++)
- if(retv = (*drive[n].fns[i])(PCF, err))
- return(retv);
- return(0);
-}
//GO.SYSIN DD scsi/wren/rmode.c
echo scsi/wren/w6mode.c 1>&2
sed 's/.//' >scsi/wren/w6mode.c <<'//GO.SYSIN DD scsi/wren/w6mode.c'
-#include <stdio.h>
-#include "../scsi.h"
-#include "../scsish.h"
-#include "fns.h"
-
-int
-wr_modeselect(int niargs, int *iargs, int ncargs, char **cargs, char *err)
-{
- struct scsi_cmd cmd;
- struct scsi_return ret;
- int n;
-
-#pragma ref niargs
-#pragma ref ncargs
-#pragma ref cargs
-
- printf("changing modes to ");
- if((iargs[0] < 256) && (iargs[0] >= 0))
- printf("er-param=%d(=#%x), ", iargs[0], iargs[0]);
- if((iargs[1] < 256) && (iargs[1] >= 0))
- printf("er-retries=%d, ", iargs[1]);
- if((iargs[2] < 256) && (iargs[2] >= 0))
- printf("read-recon=%d/256, ", iargs[2]);
- if((iargs[3] < 256) && (iargs[3] >= 0))
- printf("write-recon=%d/256, ", iargs[3]);
- if((iargs[4] < 256) && (iargs[4] >= 0))
- printf("cache %sable, ", iargs[4]?"en":"dis");
- if((iargs[5] < 256) && (iargs[5] >= 0))
- printf("cache threshold=%d, ", iargs[5]);
- if((iargs[6] < 256) && (iargs[6] >= 0))
- printf("cache max prefetch=%d, ", iargs[6]);
- if((iargs[7] < 256) && (iargs[7] >= 0))
- printf("cache size=%d, ", iargs[7]);
- printf("\nsleep(10); kill me if you disagree\n");
- fflush(stdout);
- sleep(10);
- /* do error recovery */
- if(((iargs[0] < 256) && (iargs[0] >= 0)) || ((iargs[1] < 256) && (iargs[1] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x01, 0, 20, 0);
- if(n = s_io(0, &cmd, 0, &ret, 20, err))
- return(n);
- memcpy(cmd.data, ret.data, 20);
- cmd.data[14] &= ~0x10;
- if((iargs[0] < 256) && (iargs[0] >= 0))
- cmd.data[14] = iargs[0];
- if((iargs[1] < 256) && (iargs[1] >= 0))
- cmd.data[15] = iargs[1];
- set6(cmd, 0x15, 0x11, 0, 0, 20, 0);
- if(n = s_io(0, &cmd, 20, &ret, 0, err))
- return(n);
- }
- /* reconnect */
- if(((iargs[2] < 256) && (iargs[2] >= 0)) || ((iargs[3] < 256) && (iargs[3] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x02, 0, 24, 0);
- if(n = s_io(0, &cmd, 0, &ret, 24, err))
- return(n);
- memcpy(cmd.data, ret.data, 24);
- if((iargs[3] < 256) && (iargs[3] >= 0))
- cmd.data[14] = iargs[3];
- if((iargs[4] < 256) && (iargs[4] >= 0))
- cmd.data[15] = iargs[4];
- set6(cmd, 0x15, 0x11, 0, 0, 24, 0);
- if(n = s_io(0, &cmd, 24, &ret, 0, err))
- return(n);
- }
- /* do cache control */
- if(((iargs[4] < 256) && (iargs[4] >= 0))
- || ((iargs[5] < 256) && (iargs[5] >= 0))
- || ((iargs[6] < 256) && (iargs[6] >= 0))
- || ((iargs[7] < 256) && (iargs[7] >= 0))){
- set6(cmd, 0x1A, 0, (0<<6)|0x38, 0, 28, 0);
- if(n = s_io(0, &cmd, 0, &ret, 28, err))
- return(n);
- memcpy(cmd.data, ret.data, 28);
- cmd.data[14] &= ~0x10;
- if(iargs[4])
- cmd.data[14] |= 0x10;
- if((iargs[7] < 256) && (iargs[7] >= 0)){
- cmd.data[14] &= 0xF0;
- cmd.data[14] |= iargs[7]&0xF;
- }
- if((iargs[5] < 256) && (iargs[5] >= 0))
- cmd.data[15] = iargs[5];
- if((iargs[6] < 256) && (iargs[6] >= 0))
- cmd.data[16] = iargs[6];
- set6(cmd, 0x15, 0x11, 0, 0, 28, 0);
- if(n = s_io(0, &cmd, 28, &ret, 0, err))
- return(n);
- }
- return(0);
-}
//GO.SYSIN DD scsi/wren/w6mode.c
echo scsi/nohup.out 1>&2
sed 's/.//' >scsi/nohup.out <<'//GO.SYSIN DD scsi/nohup.out'
//GO.SYSIN DD scsi/nohup.out
echo shipped 1>&2
sed 's/.//' >shipped <<'//GO.SYSIN DD shipped'
//GO.SYSIN DD shipped
echo sym.c 1>&2
sed 's/.//' >sym.c <<'//GO.SYSIN DD sym.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-
-#define NHASH 20011 /* prime please */
-#define HASHMUL 79L /* this is a good value */
-static Symtab *hash[NHASH];
-int sym_mem_fail;
-
-syminit()
-{
- register Symtab **s, *ss;
-
- for(s = hash; s < &hash[NHASH]; s++){
- for(ss = *s; ss; ss = ss->next)
- free((char *)ss);
- *s = 0;
- }
-}
-
-void *
-symlook(sym, space, install)
- char *sym;
- void *install;
-{
- register long h;
- register char *p;
- register Symtab *s;
-
- for(p = sym, h = space; *p; h += *p++)
- h *= HASHMUL;
- if(h < 0)
- h = ~h;
- h %= NHASH;
- for(s = hash[h]; s; s = s->next)
- if((s->space == space) && (strcmp(s->name, sym) == 0)){
- if(install)
- s->value = install;
- return(s->value);
- }
- if(install){
- s = (Symtab *)malloc((unsigned)sizeof(Symtab));
- if(s == 0){
- sym_mem_fail++;
- return(install);
- }
- s->space = space;
- s->name = sym;
- s->value = install;
- s->next = hash[h];
- hash[h] = s;
- }
- return(install);
-}
-
-symdel(sym, space)
- char *sym;
-{
- register long h;
- register char *p;
- register Symtab *s, *ls;
-
- for(p = sym, h = space; *p; h += *p++)
- h *= HASHMUL;
- if(h < 0)
- h = ~h;
- h %= NHASH;
- for(s = hash[h], ls = 0; s; ls = s, s = s->next)
- if((s->space == space) && (strcmp(s->name, sym) == 0)){
- if(ls)
- ls->next = s->next;
- else
- hash[h] = s->next;
- free((char *)s);
- }
-}
-
-symtraverse(space, fn)
- void (*fn)();
-{
- register Symtab **s, *ss, *next;
-
- for(s = hash; s < &hash[NHASH]; s++)
- for(ss = *s; ss; ss = next){
- next = ss->next;
- if(ss->space == space)
- (*fn)(ss->value);
- }
-}
-
-symstat()
-{
- register Symtab **s, *ss;
- int n[NHASH];
- register i, j;
- int tot;
- double d;
-
- for(i = 0; i < NHASH; i++)
- n[i] = 0;
- for(s = hash; s < &hash[NHASH]; s++){
- for(j = 0, ss = *s; ss; ss = ss->next)
- j++;
- n[j]++;
- }
- Fprint(1, "N=%ld mul=%ld\n", NHASH, HASHMUL);
- for(i = 0, d = 0, tot = 0; i < NHASH; i++){
- if(n[i]) Fprint(1, "%d of length %d\n", n[i], i);
- d += n[i]*i;
- if(i) tot += n[i];
- }
- Fprint(1, "ave len = %g\n", d/tot);
-}
-
-symdump(sym, space)
- char *sym;
-{
- register long h;
- register char *p;
- register Symtab *s;
-
- for(p = sym, h = space; *p; h += *p++)
- h *= HASHMUL;
- if(h < 0)
- h = ~h;
- h %= NHASH;
- print("symdump(%s):\n", sym);
- for(s = hash[h]; s; s = s->next)
- print("\t%s: space=%d value=%ld\n", s->name, s->space, s->value);
-}
//GO.SYSIN DD sym.c
echo sym.h 1>&2
sed 's/.//' >sym.h <<'//GO.SYSIN DD sym.h'
-typedef struct Symtab
-{
- short space;
- char *name;
- void *value;
- struct Symtab *next;
-} Symtab;
-extern void *symlook();
-
-#define S_INODE 1
-#define S_UID 2
-#define S_GID 3
-#define S_FAIL 4 /* fetch */
-#define S_TOGO 5 /* wormy */
-
-extern int sym_mem_fail;
//GO.SYSIN DD sym.h
echo t0 1>&2
sed 's/.//' >t0 <<'//GO.SYSIN DD t0'
-
-static Inode *inodes;
-static long ip;
-static long ninodes = 0;
-static char *nameb;
-static long np;
-static long nnameb = 0;
-static long nblocks;
-#define IINC 1024
-#define NINC (64*IINC)
-
-ininit()
-{
- if(nnameb == 0){
- nameb = malloc((unsigned)(nnameb = NINC));
- if(nameb == 0){
- fprint(2, "wmv: malloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- np = 0;
- if(ninodes == 0){
- inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC));
- if(inodes == 0){
- fprint(2, "wmv: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- ip = 0;
-}
-
-inadd(s, i)
- Superblock *s;
- register Inode *i;
-{
- register long len;
-
- len = strlen(i->name.n)+1;
- if(np+len > nnameb){
- while(np+len > nnameb)
- nnameb += NINC;
- nameb = realloc(nameb, (unsigned)nnameb);
- if(nameb == 0){
- fprint(2, "wmv: realloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- strcpy(nameb+np, i->name.n);
- i->name.o = np;
- np += len;
- if(ip == ninodes){
- ninodes += IINC;
- inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode));
- if(inodes == 0){
- fprint(2, "wmv: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- inodes[ip++] = *i;
-}
-
-inwrite(s)
- Superblock *s;
-{
- char *e;
-
- if(e = lkwri(s, inodes, ip, nameb, np, 0L)){
- fprint(2, "%s\n", e);
- return(1);
- }
- return(0);
-}
//GO.SYSIN DD t0
echo t1 1>&2
sed 's/.//' >t1 <<'//GO.SYSIN DD t1'
-
-static Inode *inodes;
-static long ip;
-static long ninodes = 0;
-static char *nameb;
-static long np;
-static long nnameb = 0;
-static long nblocks;
-#define IINC 1024
-#define NINC (64*IINC)
-
-ininit()
-{
- if(nnameb == 0)
- nameb = malloc((unsigned)(nnameb = NINC));
- np = 0;
- if(ninodes == 0)
- inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC));
- ip = 0;
-}
-
-inadd(s, i)
- Superblock *s;
- register Inode *i;
-{
- register long len;
-
- len = strlen(i->name.n)+1;
- if(np+len > nnameb){
- while(np+len > nnameb)
- nnameb += NINC;
- nameb = realloc(nameb, (unsigned)nnameb);
- }
- strcpy(nameb+np, i->name.n);
- i->name.o = np;
- np += len;
- if(ip == ninodes){
- ninodes += IINC;
- inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode));
- }
- inodes[ip++] = *i;
- return(0);
-}
-
-inwrite(s)
- Superblock *s;
-{
- char *e;
-
- if(e = lkwri(s, inodes, ip, nameb, np, 0L)){
- fprint(2, "%s\n", e);
- bad = 1;
- return;
- }
-}
//GO.SYSIN DD t1
echo timenow.c 1>&2
sed 's/.//' >timenow.c <<'//GO.SYSIN DD timenow.c'
-#include <libc.h>
-#include "worm.h"
-
-char *
-timenow()
-{
- long tim;
- char *tims;
-
- time(&tim);
- tims = ctime(&tim);
- tims[19] = 0;
- return(tims);
-}
//GO.SYSIN DD timenow.c
echo vlink.c 1>&2
sed 's/.//' >vlink.c <<'//GO.SYSIN DD vlink.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-
-char *
-lkopi(s, blk, doinodes)
- register Superblock *s;
- long blk;
-{
- register Inode *i;
- short fd = s->fd;
- char *b;
- long nb;
- char *nameb;
- Inode *inodes;
- static char buf[64];
-
- if((b = malloc(s->blocksize)) == 0){
- sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize);
- return(buf);
- }
- numinodes = 0;
- numnamechars = 0;
- for(;;){
- if(s->magic != SMAGIC){
- fprint(2, "bad Superblock at %ld\n", blk);
- exit(1);
- }
- if(s->ninodes){
- numinodes += s->ninodes;
- numnamechars += s->ninochars;
- }
- if(doinodes && s->ninodes){
- nb = (s->ninodes+IPERB-1)/IPERB;
- inodes = (Inode *)malloc((unsigned)(s->blocksize*nb));
- if(inodes == 0){
- sprint(buf, "inode malloc(%d) fail, sbrk=%d\n",
- (s->blocksize*nb), sbrk(0));
- return(buf);
- }
- Seek(s, s->binodes);
- if(Read(s, (char *)inodes, nb))
- goto skip;
- nb = (s->ninochars+s->blocksize-1)/s->blocksize;
- nameb = malloc((unsigned)(s->blocksize*nb));
- if(nameb == 0){
- sprint(buf, "name buffer malloc(%d) fail, sbrk=%d\n",
- (s->blocksize*nb), sbrk(0));
- return(buf);
- }
- if(Read(s, nameb, nb))
- goto skip;
- for(nb = 0, i = inodes; nb < s->ninodes; nb++, i++){
- i->name.n = i->name.o+nameb;
- if(i->block < 0)
- (void)symdel(i->name.n, S_INODE);
- else
- (void)symlook(i->name.n, S_INODE, (void *)i);
- }
- if(sym_mem_fail){
- sprint(buf, "%d inode malloc fails: %d, %d sbrk=%d\n",
- sym_mem_fail, numinodes, s->ninodes, sbrk(0));
- return(buf);
- }
- }
- skip:
- blk = s->nextsb;
- Seek(s, blk);
- if(Read(s, b, 1L))
- break;
- *s = *((Superblock *)b);
- s->fd = fd;
- if(s->myblock == 0)
- s->myblock = blk;
- }
- free(b);
- return((char *)0);
-}
-
-char *
-lkwri(s, i, ni, c, nc, ndata)
- Superblock *s;
- Inode *i;
- long ni, nc, ndata;
- char *c;
-{
- char *b;
- long blk;
- static char buf[256];
- long ib, ic;
-
- s->ninodes = ni;
- s->ninochars = nc;
- ib = (ni+IPERB-1)/IPERB;
- ic = (nc+s->blocksize-1)/s->blocksize;
- if(ndata+ib+ic+1 > s->nfree) /* one for superblock */
- return("not enough space for new files");
- s->binodes = s->nextffree+ndata;
- s->nextffree += ndata+ib+ic;
- s->nfree -= ndata+ib+ic;
-
- if((b = malloc(s->blocksize)) == 0){
- sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize);
- return(buf);
- }
- blk = s->nextsb;
- s->nextsb = s->nextffree++;
- s->nfree--;
- s->myblock = blk;
- time(&s->ctime);
- memset(b, 0, s->blocksize);
- *((Superblock *)b) = *s;
- Seek(s, blk);
- if(Write(s, b, 1L)){
- sprint(buf, "couldn't write superblock at %d", blk);
- return(buf);
- }
- free(b);
- Seek(s, s->binodes);
- if(Write(s, (char *)i, ib))
- return("write1 error");
- if(Write(s, c, ic))
- return("write2 error");
- return((char *)0);
-}
-
-
-char *
-lkwsb(s)
- Superblock *s;
-{
- char *b;
- long blk;
- static char buf[64];
-
- if((b = malloc(s->blocksize)) == 0){
- sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize);
- return(buf);
- }
- blk = s->nextsb;
- s->nextsb = s->nextffree++;
- s->nfree--;
- memset(b, 0, s->blocksize);
- s->myblock = blk;
- *((Superblock *)b) = *s;
- Seek(s, blk);
- if(Write(s, b, 1L))
- return("couldn't write superblock");
- free(b);
- return((char *)0);
-}
-
-Inode *
-vinodefn(s)
- char *s;
-{
- return((Inode *)symlook(s, S_INODE, (void *)0));
-}
-
-void
-vtraverse(fn)
- void (*fn)();
-{
- symtraverse(S_INODE, fn);
-}
//GO.SYSIN DD vlink.c
echo wbtree.c 1>&2
sed 's/.//' >wbtree.c <<'//GO.SYSIN DD wbtree.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fio.h>
-
-Inode **inos;
-long nino;
-int fdT, fdF;
-char *inonames;
-char *timenow();
-char *tmp = "/tmp";
-
-cmp(a, b)
- Inode **a, **b;
-{
- return(strcmp((*a)->name.n, (*b)->name.n));
-}
-
-main(argc, argv)
- char **argv;
-{
- Superblock s, news;
- char *e;
- char *dev = "/dev/worm0";
- int c, fd;
- char dbname[256];
- extern char *optarg;
- extern int optind;
- void blkfn();
-
- while((c = getopt(argc, argv, "t:f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case 't': tmp = optarg; break;
- case '?': usage();
- }
- dev = mapdev(dev);
- if(optind != argc-1)
- usage();
- sprint(dbname, "%s/cbt%d", tmp, getpid());
- fd = dbinit(dbname);
- if((s.fd = open(dev, 2)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- if(strcmp(argv[optind], s.vol_id)){
- fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id);
- exit(1);
- }
- if((inos = (Inode **)malloc(sizeof(inos[0])*(int)numinodes)) == 0){
- fprint(2, "out of memory (%d inodes, %d bytes)\n", numinodes, sizeof(inos[0])*(int)numinodes);
- exit(1);
- }
- nino = 0;
- inodetraverse(blkfn);
- fprint(2, "%s: sorting inodes\n", timenow());
- qsort((char *)inos, (int)nino, sizeof(inos[0]), cmp);
- news = s;
- news.ninodes = nino;
- creatdb(fd, dbname, &news); /* fills in nF, nT, inochars */
- c = NBLKS(&news, news.nF)+NBLKS(&news, news.nT)+NBLKS(&news, news.ninochars);
- if(c > news.nfree){
- fprint(2, "%s: sorry, not enough blocks; %d+%d+%d>%d\n",
- NBLKS(&news, news.nF), NBLKS(&news, news.nT),
- NBLKS(&news, news.ninochars), news.nfree);
- exit(1);
- }
- Seek(&s, news.binodes = s.nextffree);
- fdwrite(&s, fdF, (int)news.nF);
- fdwrite(&s, fdT, (int)news.nT);
- memwrite(&s, inonames, (int)news.ninochars);
- /* set up link ptrs so that zeroing block zero undoes btreeing */
- s.nfree -= c;
- s.nextffree += c;
- s.ninodes = 0;
- if(e = lkwsb(&s))
- fprint(2, "%s\n", e);
- news.nextffree = s.nextffree;
- news.nfree = s.nfree;
- news.myblock = 0;
- news.version = VBTREE;
- news.nextsb = s.myblock;
- time(&news.ctime);
- Seek(&s, news.myblock);
- free((char *)inos);
- e = malloc(news.blocksize);
- if(e == 0){
- fprint(2, "wbtree: unbelievable malloc fail of %d\n", news.blocksize);
- exit(1);
- }
- memset(e, 0, news.blocksize);
- *((Superblock *)e) = news;
- Write(&s, e, 1L);
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: worm btree [-fdevice] [-ttmpdir] vol_id\n");
- exit(2);
-}
-
-dbinit(name)
- char *name;
-{
- char buf[256];
- struct stat sbuf;
- int pid, pip[2];
-
- fprint(2, "%s: init db '%s'\n", timenow(), name);
- sprint(buf, "cbt creat %s", name);
- if(system(buf))
- exit(1);
- pipe(pip);
- pid = fork();
- if(pid < 0){
- perror("fork");
- exit(1);
- }
- if(pid){
- close(pip[0]);
- return(pip[1]);
- } else {
- close(pip[1]);
- dup2(pip[0], 0);
- close(pip[0]);
- execl("/usr/lib/btree/btbuild", "btbuild", name, 0);
- perror("execl");
- exit(1);
- return(0);
- }
-}
-
-creatdb(fd, name, s)
- char *name;
- Superblock *s; /* fills in nF, nT, inochars */
-{
- char buf[256];
- struct stat sbuf;
- int status, i;
- short n;
- char *np;
-
- fprint(2, "%s: creating db '%s'\n", timenow(), name);
- inonames = malloc((int)numnamechars+1024);
- if(inonames == 0){
- sprint(buf, "malloc(%d) namechars failed", numnamechars+1024);
- perror(buf);
- exit(1);
- }
- Finit(fd, (char *)0);
- np = inonames;
- for(i = 0; i < nino; i++){
- n = strlen(inos[i]->name.n);
- Fwrite(fd, (char *)&n, 2L);
- Fwrite(fd, inos[i]->name.n, (long)n);
- memcpy(np, inos[i]->name.n, n+1);
- inos[i]->name.o = np - inonames;
- np += n+1;
- n = sizeof(Inode);
- Fwrite(fd, (char *)&n, 2L);
- Fwrite(fd, (char *)inos[i], (long)n);
- }
- s->ninochars = np-inonames;
- Fflush(fd);
- close(fd);
- if(wait(&status) < 0){
- perror("wbtree: wait");
- exit(1);
- }
- if(status){
- fprint(2, "wbtree: bad status %d from btbuild\n", status);
- exit(1);
- }
- sprint(buf, "%s.F", name);
- if(((fdF = open(buf, 0)) < 0) || (fstat(fdF, &sbuf) < 0)){
- perror(buf);
- exit(1);
- }
- unlink(buf);
- s->nF = sbuf.st_size;
- sprint(buf, "%s.T", name);
- if(((fdT = open(buf, 0)) < 0) || (fstat(fdT, &sbuf) < 0)){
- perror(buf);
- exit(1);
- }
- unlink(buf);
- s->nT = sbuf.st_size;
- fprint(2, "%s: db done\n", timenow());
-}
-
-void
-blkfn(i)
- Inode *i;
-{
- inos[nino++] = i;
-}
-
-fdwrite(s, fd, cnt)
- Superblock *s;
-{
- char b[BIGBLOCK];
- int n;
-
- lseek(fd, 0L, 0);
- while(cnt >= sizeof b){
- n = read(fd, b, sizeof b);
- if(n != sizeof b){
- perror("short read");
- exit(3);
- }
- Write(s, b, NBLKS(s, sizeof b));
- cnt -= sizeof b;
- }
- if(cnt){
- if(read(fd, b, cnt) != cnt){
- perror("short read");
- exit(4);
- }
- memset(b+cnt, 0, sizeof b - cnt);
- Write(s, b, NBLKS(s, cnt));
- }
-}
-
-memwrite(s, base, cnt)
- Superblock *s;
- char *base;
-{
- int chunk = (BIGBLOCK/1024)*s->blocksize;
-
- while(cnt >= chunk){
- Write(s, base, NBLKS(s, chunk));
- cnt -= chunk;
- base += chunk;
- }
- if(cnt)
- Write(s, base, NBLKS(s, cnt));
-}
-
-char *
-timenow()
-{
- long tim;
- char *tims;
-
- time(&tim);
- tims = ctime(&tim);
- tims[19] = 0;
- return(tims);
-}
//GO.SYSIN DD wbtree.c
echo wcat.c 1>&2
sed 's/.//' >wcat.c <<'//GO.SYSIN DD wcat.c'
-#include <libc.h>
-#include "sym.h"
-#include "worm.h"
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e;
- Inode *i;
- int c;
- char *dev = "/dev/worm0";
- extern char *optarg;
- extern int optind;
-
- while((c = getopt(argc, argv, "f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case '?': usage();
- }
- if(optind+2 != argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 0)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- if(strcmp(s.vol_id, argv[optind])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
- exit(1);
- }
- if(i = inodeof(argv[++optind]))
- c = pr(&s, i);
- else {
- fprint(2, "wcat: can't find %s\n", argv[optind]);
- c = 1;
- }
- exit(c);
-}
-
-usage()
-{
- fprint(2, "Usage: worm cat [-fdevice] vol_id file\n");
- exit(1);
-}
-
-pr(s, i)
- Superblock *s;
- register Inode *i;
-{
- char b[BIGBLOCK];
- register long len, n;
- long nb;
- int fd;
-
- fd = 1;
- nb = sizeof b / s->blocksize;
- Seek(s, i->block);
- for(n = i->nbytes, len = nb*s->blocksize; n > 0;){
- if(len > n){
- len = n;
- nb = (len+s->blocksize-1)/s->blocksize;
- }
- Read(s, b, nb);
- if(write(fd, b, (int)len) != len){
- perror("write");
- return(1);
- }
- n -= len;
- }
- close(fd);
- return(0);
-}
//GO.SYSIN DD wcat.c
echo wcopy.c 1>&2
sed 's/.//' >wcopy.c <<'//GO.SYSIN DD wcopy.c'
-#include <libc.h>
-#include <fio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include "worm.h"
-
-long minfree = 40000;
-int verbose = 0;
-
-main(argc, argv)
- char **argv;
-{
- Superblock in, out;
- char *e;
- char buf[4096];
- int n;
- long lineno;
- int c;
- char *dev = "/dev/worm0";
- long tfiles, tbytes;
- int eof;
- char first[4096];
- extern char *optarg;
- extern int optind;
-
- argout = argv[0];
- while((c = getopt(argc, argv, "vm:f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case 'm': minfree = atol(optarg); break;
- case 'v': verbose = 1; break;
- case '?': usage();
- }
-
- if(optind+3 != argc)
- usage();
- e = mapdev(argv[optind+1]);
- if((out.fd = open(e, 2)) < 0){
- perror(e);
- exit(1);
- }
- if(e = openinode(&out, SPIN_DOWN)){
- fprint(2, "%s: %s\n", *argv, e);
- exit(1);
- }
- if(strcmp(out.vol_id, argv[optind+2])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind+2], out.vol_id);
- exit(1);
- }
- if(out.version != VLINK){
- fprint(2, "%s: can't write on a b-tree disk\n", out.vol_id);
- exit(1);
- }
- dev = mapdev(dev);
- if((in.fd = open(dev, 2)) < 0){
- perror(*argv);
- exit(1);
- }
- if(e = openinode(&in, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", *argv, e);
- exit(1);
- }
- if(strcmp(in.vol_id, argv[optind])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], in.vol_id);
- exit(1);
- }
- for(n = 1; n <= NSIG; n++)
- signal(n, SIG_IGN);
- eof = 0;
- tfiles = tbytes = 0;
- lineno = 0;
- while(!eof){
- /* flush seperater lines */
- while(e = Frdline(0)){
- lineno++;
- if(*e)
- break;
- }
- if(e == 0)
- break;
- ininit();
- proc(&out, e);
- strncpy(first, e, sizeof first);
- if(out.nfree < minfree){
- fprint(2, "wcopy: disk %s full before copying group '%s' line %d\n",
- out.vol_id, first, lineno);
- exit(1);
- }
- while(e = Frdline(0)){
- lineno++;
- if(*e == 0)
- break;
- proc(&out, e);
- }
- if(e == 0)
- eof = 1;
- if(bad)
- exit(1);
- nfiles = nbytes = 0;
- blkdone = 0;
- inwrite(&out, &in);
- if(bad)
- exit(1);
- if(verbose)
- fprint(1, "%s group('%s' %d files, %.6fMB) done\n",
- timenow(), first, nfiles, nbytes/1e6);
- tfiles += nfiles;
- tbytes += nbytes;
- }
- if(verbose)
- fprint(1, "%s total: %d files, %.6fMB\n", timenow(), tfiles, tbytes/1e6);
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: worm copy [-v] [-m minfree] [-f src_dev] src_id dest_dev dest_id < files\n");
- exit(1);
-}
-
-proc(s, file)
- Superblock *s;
- char *file;
-{
- struct stat sbuf;
- unsigned short mode;
- Inode i;
- Inode *srci;
-
- if((srci = inodeof(file)) == 0){
- fprint(2, "can't find file '%s'\n", file);
- return;
- }
- memset((char *)&i, 0, sizeof(i));
- i = *srci;
- i.block = 0;
- nbytes += i.nbytes;
- if(inadd(s, &i))
- bad = 1;
-}
-
-writeout(dest, i, blk, src)
- Superblock *dest, *src;
- Inode *i;
- long *blk;
-{
- char b[BIGBLOCK];
- Inode *srci;
- long n, len, blen;
- char *name;
-
- n = (i->nbytes+dest->blocksize-1)/dest->blocksize;
- *blk += n;
- blkdone += n;
- blen = sizeof b/dest->blocksize;
- len = blen*dest->blocksize;
- nbytes += i->nbytes;
- nfiles++;
- name = i->name.n;
- srci = inodeof(name);
- Seek(src, srci->block);
- for(n = i->nbytes; n > len; n -= len){
- if(Read(src, b, blen)){
- out:
- fprint(2, "read problem: seek=%d n=%d blen=%d len=%d; ",
- srci->block, n, blen, len);
- perror(name);
- bad = 1;
- return;
- }
- if(Write(dest, b, blen)){
-fprint(2, "nb=%d, n=%d len=%d blen=%d\n", i->nbytes, n, len, blen);
- perror("data write");
- exit(1);
- }
- }
- if(n){
- n += dest->blocksize-1;
- n /= dest->blocksize;
- if(Read(src, b, n))
- goto out;
- if(Write(dest, b, n)){
- perror("data write");
- exit(1);
- }
- }
-}
//GO.SYSIN DD wcopy.c
echo wdir.c 1>&2
sed 's/.//' >wdir.c <<'//GO.SYSIN DD wdir.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-char *dumpdir();
-int verbose = 0;
-
-main(argc, argv)
- char **argv;
-{
- Superblock s, news;
- char *e;
- char *dev = "/dev/worm0";
- int update = 0;
- int c;
- char buf[1024];
- extern char *optarg;
- extern int optind;
- void blkfn();
-
- while((c = getopt(argc, argv, "f:vu")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case 'u': update = 1; break;
- case 'v': verbose = 1; break;
- case '?': usage();
- }
- dev = mapdev(dev);
- if(optind != argc-1)
- usage();
- if((s.fd = open(dev, 2)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(2);
- }
- if(s.version != VBTREE){
- fprint(2, "%s is not a btree!\n", s.vol_id);
- exit(2);
- }
- if(strcmp(argv[optind], s.vol_id)){
- fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id);
- exit(1);
- }
- if(e = dumpdir(&s, update)){
- fprint(2, "%s: %s\n", dev, e);
- exit(2);
- }
- sprint(buf, "/usr/worm/tmp/%s", s.vol_id);
- unlink(buf);
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: dir [-fdevice] -v] [-u] vol_id\n");
- exit(2);
-}
-
-char *
-dumpdir(s, update)
- register Superblock *s;
-{
- char *b;
- static char buf[64];
- char name[256], buf1[256];
-
- if((b = malloc(s->blocksize)) == 0){
- sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize);
- return(buf);
- }
- numinodes = s->ninodes;
- sprint(name, "/usr/worm/dirs/%s", s->vol_id);
- Seek(s, s->binodes);
- sprint(buf1, "%s.F", name);
- copyout(s, buf1, s->nF, update, verbose);
- sprint(buf1, "%s.T", name);
- copyout(s, buf1, s->nT, update, verbose);
- sprint(buf1, "%s.I", name);
- copyout(s, buf1, s->ninochars, update, verbose);
- free(b);
- return((char *)0);
-}
//GO.SYSIN DD wdir.c
echo wild 1>&2
sed 's/.//' >wild <<'//GO.SYSIN DD wild'
//GO.SYSIN DD wild
echo wls.c 1>&2
sed 's/.//' >wls.c <<'//GO.SYSIN DD wls.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <grp.h>
-
-int lflag = 0;
-int bflag = 0;
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- register Inode *i;
- char *e;
- char *dev = "/dev/worm0";
- int c;
- extern char *optarg;
- extern int optind;
- void pr();
-
- while((c = getopt(argc, argv, "lbf:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case 'l': lflag = 1; break;
- case 'b': bflag = 1; break;
- case '?': usage();
- }
- dev = mapdev(dev);
- if((s.fd = open(dev, 0)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- c = 0;
- if(optind < argc)
- while(optind < argc){
- if(i = inodeof(argv[optind]))
- pr(i);
- else {
- Fprint(2, "%s not found\n", argv[optind]);
- c = 1;
- }
- optind++;
- }
- else
- inodetraverse(pr);
- exit(c);
-}
-
-char *
-suid(n)
-{
- static char buf[24];
- struct passwd *p;
- char *s;
-
- sprint(buf, "#%d", n);
- if(s = (char *)symlook(buf, S_UID, (void *)0))
- strcpy(buf, s);
- else {
- s = strdup(buf);
- if(p = getpwuid(n))
- strcpy(buf, p->pw_name);
- (void)symlook(s, S_UID, (void *)strdup(buf));
- }
- return(buf);
-}
-
-char *
-sgid(n)
-{
- static char buf[24];
- struct group *g;
- char *s;
-
- sprint(buf, "#%d", n);
- if(s = (char *)symlook(buf, S_GID, (void *)0))
- strcpy(buf, s);
- else {
- s = strdup(buf);
- if(g = getgrgid(n))
- strcpy(buf, g->gr_name);
- (void)symlook(s, S_GID, (void *)strdup(buf));
- }
- return(buf);
-}
-
-mode(n, sx)
-{
- Fputc(1, (n&4)? 'r':'-');
- Fputc(1, (n&2)? 'w':'-');
- Fputc(1, (n&1)? sx:'-');
-}
-
-void
-pr(i)
- register Inode *i;
-{
- char *s;
-
- if(lflag){
- Fputc(1, ((i->mode&S_IFMT) == S_IFDIR)? 'd':'-');
- mode(i->mode>>6, ((i->mode&S_IFMT) == S_ISUID)? 's':'x');
- mode(i->mode>>3, ((i->mode&S_IFMT) == S_ISGID)? 's':'x');
- mode(i->mode, 'x');
- Fputc(1, ((i->mode&S_IFMT) == S_IFLNK)? 'L':' ');
- s = ctime(&i->ctime);
- s += 4;
- s[12] = 0;
- Fprint(1, "%2d%8s%7s %6ld %s %s\n", 1, suid(i->uid), sgid(i->gid),
- i->nbytes, s, i->name.n);
- return;
- }
- if(bflag)
- Fprint(1, "%s\t%ld\n", i->name.n, i->block);
- else
- Fprint(1, "%s\n", i->name.n);
-}
-
-usage()
-{
- fprint(2, "Usage: worm ls [-fdevice] [-l] [-b] [files ...]\n");
- exit(2);
-}
//GO.SYSIN DD wls.c
echo wmkfs.c 1>&2
sed 's/.//' >wmkfs.c <<'//GO.SYSIN DD wmkfs.c'
-#include <libc.h>
-#include "worm.h"
-#include <sys/types.h>
-#include <sys/udaioc.h>
-
-usage()
-{
- fprint(2, "Usage: worm mkfs [-fdevice] [-ccomments] [-bblksize] [-nnblks] [-vnewvol_id] vol_id\n");
- fprint(2, "e.g. worm mkfs -f1 -c\"512x512x24 movies\" tdmovies1a\n");
- exit(1);
-}
-
-main(argc, argv)
- char **argv;
-{
- Superblock s, os;
- char *b;
- long sb;
- int c;
- char *volid;
- char *dev = "/dev/worm0";
- char *nblks = 0;
- char *bsize = 0;
- char *nvolid = 0;
- char *comments = 0;
- char *e;
- int virgin;
- extern optind;
- extern char *optarg;
-
- while((c = getopt(argc, argv, "f:n:b:c:v:")) != -1)
- switch(c)
- {
- case 'b': bsize = optarg; break;
- case 'c': comments = optarg; break;
- case 'f': dev = optarg; break;
- case 'n': nblks = optarg; break;
- case 'v': nvolid = optarg; break;
- case '?': usage();
- }
- if(optind != argc-1)
- usage();
- volid = argv[optind];
- if(strlen(volid) > sizeof(s.vol_id)-1)
- volid[sizeof(s.vol_id)-1] = 0;
- c = volid[strlen(volid)-1];
- if((c != 'a') && (c != 'b')){
- if(nvolid == 0){
- fprint(2, "worm mkfs: vol_id '%s' must end in 'a' or 'b'\n", volid);
- exit(1);
- }
- fprint(2, "worm mkfs: warning: vol_id '%s' should end in 'a' or 'b'\n", volid);
- }
- if(nvolid){
- if(strlen(nvolid) > sizeof(s.vol_id)-1)
- nvolid[sizeof(s.vol_id)-1] = 0;
- c = nvolid[strlen(nvolid)-1];
- if((c != 'a') && (c != 'b')){
- fprint(2, "worm mkfs: vol_id '%s' must end in 'a' or 'b'\n", nvolid);
- exit(1);
- }
- }
- dev = mapdev(dev);
- if((s.fd = open(dev, 2)) < 0){
- perror(dev);
- exit(1);
- }
- /*
- now, do we read the current superblock or make one up?
- this is hard to answer in general, push the answer off to virginal()
- */
- virgin = virginal(&s);
- if(virgin){
- setdefaults(&s, nblks);
- if((s.blocksize < 512) || (s.blocksize%512)){
- fprint(2, "worm mkfs: bad blocksize '%s'\n", bsize);
- exit(1);
- }
- strcpy(s.vol_id, volid);
- } else {
- if(strcmp(volid, s.vol_id)){
- fprint(2, "worm mkfs: volid mismatch; expected %s, got %s\n",
- volid, s.vol_id);
- exit(1);
- }
- }
- /* set any new parameters */
- if(nvolid)
- strcpy(s.vol_id, nvolid);
- if(bsize)
- s.blocksize = atoi(bsize);
- if(s.blocksize < 512){
- fprint(2, "wormmkfs: bad nblocks = '%s'\n", nblks);
- exit(1);
- }
- if(s.blocksize % sizeof(Inode)){
- fprint(2, "worm mkfs: sizeof(Inode)=%d does not divide blocksize %d\n",
- sizeof(Inode), s.blocksize);
- exit(1);
- }
- if(comments){
- if(strlen(comments) > sizeof(s.comment)-1)
- comments[sizeof(s.comment)-1] = 0;
- strcpy(s.comment, comments);
- }
- /* only check if we are changing it */
- if(nblks && !virgin){
- s.nblocks = atoi(nblks);
- s.nfree = s.nblocks - s.nextffree;
- if(s.nfree <= 1){
- fprint(2, "worm mkfs: new nblocks(%d) is too small\n", s.nblocks);
- exit(1);
- }
- }
- /* now allocate the new superblock */
- sb = s.nextsb;
- s.myblock = sb;
- s.nextsb = sb+1;
- s.nextffree = sb+2;
- s.nfree -= 1;
- s.ninodes = 0;
- s.ninochars = 0;
- s.binodes = 0;
- time(&s.ctime);
- /* write it */
- if((b = malloc(s.blocksize)) == 0){
- fprint(2, "worm mkfs: cannot malloc buffer %d bytes\n", s.blocksize);
- exit(1);
- }
- memset(b, 0, s.blocksize);
- memcpy(b, (char *)&s, sizeof(s));
- Seek(&s, sb);
- if(Write(&s, b, 1L))
- exit(1);
- ioctl(s.fd, UIOSPDW);
- exit(0);
-}
-
-setdefaults(s, nblks)
- Superblock *s;
- char *nblks;
-{
- struct ud_unit sz;
- char buf[1024];
-
- s->magic = SMAGIC;
- s->blocksize = 1024;
- s->version = VLINK;
- if(nblks){
- s->nblocks = atoi(nblks);
- if(s->nblocks <= 2){
- fprint(2, "worm mkfs: nblocks(%d) too small\n", s->nblocks);
- exit(1);
- }
- } else {
- read(s->fd, buf, sizeof buf); /* ignore error */
- if(ioctl(s->fd, UIOCHAR, &sz) >= 0){
- switch(sz.radsize)
- { /* note below figures/2 used in scsi/volid.c */
- case 3275999: /* sony 12in clv single density */
- s->nblocks = 1600000;
- break;
- case 6551999: /* sony 12in clv double density */
- s->nblocks = 3250000;
- break;
- default:
- fprint(2, "worm mkfs: unknown size %d\n", sz.radsize);
- exit(1);
- }
- } else
- s->nblocks = 1600000;
- fprint(2, "worm mkfs: using disk size %d\n", s->nblocks);
- }
- s->zero = 0;
- s->nfree = s->nblocks-1;
- s->nextffree = 0;
- s->nextsb = 1;
- s->vol_id[0] = 0;
- s->comment[0] = 0;
- s->myblock = 0;
- s->ctime = 0;
-}
-
-virginal(s)
- Superblock *s;
-{
- char buf[1024];
- static char zeros[1024];
- long sb;
- char *e;
- extern char *getenv();
-
- if(e = getenv("WORMZERO"))
- sb = atoi(e);
- else
- sb = 1;
- bigseek(s->fd, sb, 1024, 0);
- errno = 0;
- if(read(s->fd, buf, 1024) == 1024)
- goto valid;
- if((errno != ENXIO) && (errno != 0) && memcmp(buf, zeros, 1024))
- goto invalid;
- errno = 0;
- if(read(s->fd, buf, 1024) == 1024){ /* try next block */
-valid:
- if(e = openinode(s, SPIN_DOWN)){
- fprint(2, "worm mkfs: %s\n", e);
- exit(1);
- }
- return(0);
- } else {
- if((errno == ENXIO) || (errno == 0) || (memcmp(buf, zeros, 1024) == 0))
- return(1);
-invalid:
- perror("worm mkfs: I/O errors probing for superblock");
- exit(1);
- }
-}
//GO.SYSIN DD wmkfs.c
echo wmount.c 1>&2
sed 's/.//' >wmount.c <<'//GO.SYSIN DD wmount.c'
-#include <libc.h>
-#include "worm.h"
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e, *vol_id = 0, *vol;
- char *dev = "/dev/worm0";
- int c;
- long nf = 0;
- char wflag[512];
- char buf[512];
- int i;
- extern char *optarg;
- extern int optind;
- extern long atol();
-
- wflag[0] = 0;
- while((c = getopt(argc, argv, "w:")) != -1)
- switch(c)
- {
- case 'w': sprint(wflag, "-w%s", optarg); break;
- case '?': usage();
- }
- if(optind < argc){
- vol_id = argv[optind++];
- if(optind != argc)
- usage();
- }
- if(vol_id == 0){
- for(i = 0; ; i++){
- sprint(buf, "%d", i);
- dev = mapdev(buf);
- if((s.fd = open(dev, 0)) < 0){
- if(errno == ENOENT)
- break;
- if(errno == ENXIO)
- continue;
- perror(dev);
- exit(2);
- }
- if(e = openinode(&s, SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(2);
- }
- print("%s: %s\n", dev, s.vol_id);
- close(s.fd);
- }
- exit(0);
- }
- if(isjukebox()){
- jload(vol_id, wflag);
- exit(0);
- }
- {
- for(i = 0; ; i++){
- sprint(buf, "%d", i);
- dev = mapdev(buf);
- if((s.fd = open(dev, 0)) < 0){
- if(errno == ENOENT)
- break;
- if(errno == ENXIO)
- continue;
- perror(dev);
- exit(2);
- }
- if(e = openinode(&s, SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(2);
- }
- if(strcmp(vol_id, s.vol_id) == 0){
- print("%s\n", buf);
- exit(0);
- }
- close(s.fd);
- }
- }
- fprint(2, "worm mount: couldn't find %s\n", vol_id);
- exit(1);
-}
-
-usage()
-{
- print("Usage: worm mount [-wsecs] [vol_id]\n");
- exit(2);
-}
-
-/*
- return zero if there isn't a jukebox
-*/
-isjukebox()
-{
- return(access("/dev/scsi", 6) == 0);
-}
-
-/*
- secs is the number of seconds to wait
-*/
-jload(vol, secs)
- char *vol, *secs;
-{
- if(*secs)
- execlp("/usr/lib/worm/jukebox", "jukebox", secs, "-m", vol, (char *)0);
- else
- execlp("/usr/lib/worm/jukebox", "jukebox", "-m", vol, (char *)0);
- perror("execlp(/usr/lib/worm/jukebox)");
- exit(1);
-}
//GO.SYSIN DD wmount.c
echo wmv.c 1>&2
sed 's/.//' >wmv.c <<'//GO.SYSIN DD wmv.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <grp.h>
-#include <signal.h>
-
-int lflag = 0;
-int bflag = 0;
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- register Inode *i;
- Inode newi;
- char *e;
- char *dev = "/dev/worm0";
- int c;
- extern char *optarg;
- extern int optind;
- void pr();
-
- while((c = getopt(argc, argv, "lbf:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case 'l': lflag = 1; break;
- case 'b': bflag = 1; break;
- case '?': usage();
- }
- dev = mapdev(dev);
- if((s.fd = open(dev, 2)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- if(optind != argc-3)
- usage();
- if(strcmp(s.vol_id, argv[optind])){
- fprint(2, "worm mv: vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
- exit(1);
- }
- optind++;
- if((i = inodeof(argv[optind])) == 0){
- Fprint(2, "%s not found\n", argv[optind]);
- exit(1);
- }
- optind++;
- if(strlen(argv[optind]) < 1){
- Fprint(2, "worm mv: destination name is null\n");
- exit(1);
- }
- for(c = 1; c <= NSIG; c++)
- signal(c, SIG_IGN);
- ininit();
- newi = *i;
- i->block = -1;
- inadd(&s, i);
- newi.name.n = argv[optind];
- inadd(&s, &newi);
- if(inwrite(&s))
- exit(1);
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: worm mv [-fdevice] vol_id from to\n");
- exit(2);
-}
-
-static Inode *inodes;
-static long ip;
-static long ninodes = 0;
-static char *nameb;
-static long np;
-static long nnameb = 0;
-static long nblocks;
-#define IINC 1024
-#define NINC (64*IINC)
-
-ininit()
-{
- if(nnameb == 0){
- nameb = malloc((unsigned)(nnameb = NINC));
- if(nameb == 0){
- fprint(2, "wmv: malloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- np = 0;
- if(ninodes == 0){
- inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC));
- if(inodes == 0){
- fprint(2, "wmv: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- ip = 0;
-}
-
-inadd(s, i)
- Superblock *s;
- register Inode *i;
-{
- register long len;
-
- len = strlen(i->name.n)+1;
- if(np+len > nnameb){
- while(np+len > nnameb)
- nnameb += NINC;
- nameb = realloc(nameb, (unsigned)nnameb);
- if(nameb == 0){
- fprint(2, "wmv: realloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- strcpy(nameb+np, i->name.n);
- i->name.o = np;
- np += len;
- if(ip == ninodes){
- ninodes += IINC;
- inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode));
- if(inodes == 0){
- fprint(2, "wmv: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- inodes[ip++] = *i;
-}
-
-inwrite(s)
- Superblock *s;
-{
- char *e;
-
- if(e = lkwri(s, inodes, ip, nameb, np, 0L)){
- fprint(2, "%s\n", e);
- return(1);
- }
- return(0);
-}
//GO.SYSIN DD wmv.c
echo woffline.c 1>&2
sed 's/.//' >woffline.c <<'//GO.SYSIN DD woffline.c'
-#include <libc.h>
-#include "worm.h"
-#include <sys/types.h>
-#include <sys/udaioc.h>
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *vol_id = 0;
- char buf[1024];
- char *dev = "/dev/worm0";
- int c;
- extern char *optarg;
- extern int optind;
-
- while((c = getopt(argc, argv, "f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case '?': usage();
- }
- if(optind != argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 2)) < 0){
- if(!vol_id)
- perror(dev);
- exit(2);
- }
- /* have to read to make ioctl work */
- lseek(s.fd, 1024L, 0);
- read(s.fd, buf, sizeof buf);
- if(ioctl(s.fd, UIOSPDW) < 0){
- perror("ioctl");
- exit(2);
- }
- exit(0);
-}
-
-usage()
-{
- print("Usage: worm offline [-fdevice]\n");
- exit(2);
-}
//GO.SYSIN DD woffline.c
echo worm.h 1>&2
sed 's/.//' >worm.h <<'//GO.SYSIN DD worm.h'
-#include <errno.h>
-
-#define SMAGIC 0x21746967
-#define DMAGIC 0x3A746967
-
-typedef struct Superblock
-{
- long magic; /* magic number for Superblock */
- unsigned short blocksize; /* physical size of blocks */
- short version; /* type of superblock */
- long nblocks; /* number of blocks on device */
- long zero; /* first logical data block */
- long nfree; /* number of free blocks */
- long ninodes; /* number of inodes */
- long ninochars; /* number of bytes of inode names */
- long binodes; /* start of inodes */
- long nextffree; /* next free file block */
- long nextsb; /* next superblock */
- short fd; /* fildes for device (in core) */
- char vol_id[128]; /* name the disk can be mounted as */
- char comment[128]; /* comments */
- long myblock; /* where this superblock is */
- long nF; /* bytes for .F (VBTREE) */
- long nT; /* bytes for .T (VBTREE) */
- long ctime; /* create time for this superblock */
-} Superblock;
-
-typedef struct Inode
-{
- long magic; /* magic number for Dirent */
- long block; /* starting block of file */
- long nbytes; /* bytes in file */
- long ctime; /* creation time */
- union {
- char *n; /* core - name */
- long o; /* disk - offset into chars block */
- } name; /* filename */
- long pad1; /* to 32 bytes */
- short mode; /* a la stat */
- short uid; /* owner */
- short gid; /* owner */
- short pad2; /* to 32 bytes */
-} Inode;
-#define IPERB (s->blocksize/sizeof(Inode))
-
-extern char *openinode(), *lkwri(), *lkwsb();
-extern char *mapdev();
-extern Inode *(*inodefn)();
-extern void (*traversefn)();
-extern long numinodes;
-extern long numnamechars;
-extern char *timenow();
-
-#define inodeof(s) (*inodefn)(s)
-#define inodetraverse(fn) (*traversefn)(fn)
-
-#define VLINK 1 /* linked list version */
-#define VBTREE 2 /* cbt */
-
-#define NBLKS(s, x) (long)(((s)->blocksize-1+(x))/(s)->blocksize)
-
-/*
- flags for openinode
-*/
-#define DO_INODE 1
-#define SPIN_DOWN 2
-
-#define BIGBLOCK (60*1024L) /* max read/write */
-
-/*
- in.c declarations
-*/
-
-extern int bad;
-extern long nbytes;
-extern long blkdone;
-extern long nfiles;
-extern char *argout;
//GO.SYSIN DD worm.h
echo wpoke.c 1>&2
sed 's/.//' >wpoke.c <<'//GO.SYSIN DD wpoke.c'
-#include <libc.h>
-#include "worm.h"
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e, *vol_id = 0;
- char *dev = "/dev/worm0";
- int c;
- long nf = 0;
- int vflag = 0;
- Superblock ss;
- extern char *optarg;
- extern int optind;
- extern long atol();
-
- while((c = getopt(argc, argv, "vF:f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case 'F': nf = atol(optarg); break;
- case 'v': vflag = 1; break;
- case '?': usage();
- }
- if(optind < argc){
- vol_id = argv[optind++];
- if(optind != argc)
- usage();
- }
- dev = mapdev(dev);
- if((s.fd = open(dev, 0)) < 0){
- perror(dev);
- exit(2);
- }
- if(read(s.fd, &ss, sizeof ss) != sizeof ss){
- if(errno == ENXIO)
- print("unwritten block zero\n");
- else
- perror("block zero");
- } else {
- if(ss.magic == SMAGIC){
- print("appears to be a good superblock at zero\n");
- exit(0);
- } else if(ss.magic == 0){
- print("appears to be a zero'ed block at zero.\n");
- } else
- print("ignoring bogus block at zero\n");
- }
- vlink(s.fd, 1);
- exit(0);
-}
-
-usage()
-{
- print("Usage: worm poke [-v] [-fdevice] [-Fnfree] [vol_id]\n");
- exit(2);
-}
-
-vlink(fd, blk)
-{
- Superblock s;
- int i, n;
-
- while(blk < 1650000){
-loop:
-print("reading sb at %d\n", blk);
- bigseek(fd, blk, 1024, 0);
- if(read(fd, &s, sizeof s) == sizeof s){
- if(s.magic == SMAGIC){
- blk = s.nextsb;
- continue;
- }
- print("apparent garbage at supposed superblock@%ld\n", blk);
- } else {
- print("bad read at blk %ld, errno=%d\n", blk, errno);
- lseek(fd, 1024, 1);
- blk++;
- }
- for(i = 0; i < 50; i++){
- n = read(fd, &s, sizeof s);
- if(n < 0){
- lseek(fd, 1024, 1);
- continue;
- }
- if((n == sizeof s) && (s.magic == SMAGIC)){
- blk += i;
- print("after error, skipped %d blocks to apparent superblock at %ld\n", i, blk);
- goto loop;
- }
- }
- print("after error, no superblock after %d tries\n", i);
- blk += i;
- }
-}
//GO.SYSIN DD wpoke.c
echo wread.c 1>&2
sed 's/.//' >wread.c <<'//GO.SYSIN DD wread.c'
-#include <libc.h>
-#include <fio.h>
-#include "sym.h"
-#include "worm.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-
-char *prefix = "";
-int dflag = 0;
-int quiet = 0;
-int mflag = 0;
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e;
- int c;
- char *dev = "/dev/worm0";
- extern char *optarg;
- extern int optind;
-
- while((c = getopt(argc, argv, "dmf:p:s")) != -1)
- switch(c)
- {
- case 'd': dflag = 1; break;
- case 'f': dev = optarg; break;
- case 'm': mflag = 1; break;
- case 'p': prefix = optarg; break;
- case 's': quiet = 1; break;
- case '?': usage();
- }
- if(optind >= argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 0)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- if(strcmp(s.vol_id, argv[optind])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
- exit(1);
- }
- optind++;
- c = 0;
- if(optind >= argc){
- while(e = Frdline(0))
- if(pr(&s, e))
- c = 1;
- } else {
- while(optind < argc)
- if(pr(&s, argv[optind++]))
- c = 1;
- }
- exit(c);
-}
-
-usage()
-{
- fprint(2, "Usage: worm read [-fdevice] [-pprefix] [-dm] vol_id [files ...]\n");
- exit(1);
-}
-
-pr(s, name)
- Superblock *s;
- char *name;
-{
- register Inode *i;
- char b[63*1024L];
- register long len, n;
- long nb;
- int fd;
- char buf[4096];
-
- if((i = inodeof(name)) == 0){
- fprint(2, "%s not found\n", name);
- return(1);
- }
- sprint(buf, "%s%s", prefix, name);
- name = buf;
- if((fd = create(name, i->mode, i->uid, i->gid, i->ctime)) < 0){
- if(dflag){
- createdirs(name);
- fd = create(name, i->mode, i->uid, i->gid, i->ctime);
- }
- if(fd < 0){
- perror(name);
- return(1);
- }
- }
- if(fd == 0) /* a directory */
- return(0);
- nb = sizeof b / s->blocksize;
- Seek(s, i->block);
- for(n = i->nbytes, len = nb*s->blocksize; n > 0;){
- if(len > n){
- len = n;
- nb = (len+s->blocksize-1)/s->blocksize;
- }
- if(Read(s, b, nb)){
- fprint(2, "while writing %s: ", name);
- perror("read");
- exit(1);
- }
- if(write(fd, b, (int)len) != len){
- fprint(2, "while writing %s: ", name);
- perror("write");
- exit(1);
- }
- n -= len;
- }
- close(fd);
- if(mflag){
- time_t tp[2];
-
- tp[0] = tp[1] = i->ctime;
- utime(name, tp);
- }
- return(0);
-}
-
-createdirs(s)
- char *s;
-{
- char *ls, *ss;
-
- for(ls = s; *ls == '/'; ls++)
- ;
- for(; *ls && (ss = strchr(ls, '/')); ls = ss+1){
- *ss = 0;
- if(access(s, 0) < 0){
- if(mkdir(s, 0777) < 0){
- perror(s);
- return;
- } else if(!quiet)
- fprint(2, "created %s\n", s);
- }
- *ss = '/';
- }
-}
-
-create(name, mode, uid, gid, t)
- char *name;
- time_t t;
-{
- time_t tp[2];
-
- tp[0] = tp[1] = t;
- if((mode&S_IFMT) == S_IFDIR){
- if(access(name, 0) >= 0){
- if(chmod(name, mode) < 0){
- perror(name);
- return(-1);
- }
- } else {
- if(mkdir(name, mode) < 0){
- perror(name);
- return(-1);
- }
- }
- chown(name, uid, gid);
- utime(name, tp);
- return(0);
- } else {
- int fd;
-
- if((fd = creat(name, mode)) >= 0){
- chown(name, uid, gid);
- utime(name, tp);
- }
- return(fd);
- }
-}
//GO.SYSIN DD wread.c
echo wreset.c 1>&2
sed 's/.//' >wreset.c <<'//GO.SYSIN DD wreset.c'
-#include <libc.h>
-#include "worm.h"
-#include <sys/types.h>
-#include <sys/udaioc.h>
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e, *vol_id = 0;
- char buf[1024];
- char *dev = "/dev/worm0";
- int c;
- extern char *optarg;
- extern int optind;
-
- while((c = getopt(argc, argv, "f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case '?': usage();
- }
- if(optind != argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 2)) < 0){
- if(!vol_id)
- perror(dev);
- exit(2);
- }
- /*
- normally, you have to read to bring the drive online.
- however, when you are likely to call reset, the drive
- is online and blocked so skip the read
- */
- /*lseek(s.fd, 1024L, 0);
- read(s.fd, buf, sizeof buf);/**/
- if(ioctl(s.fd, UIORST) < 0)
- perror("reset ioctl");
- exit(0);
-}
-
-usage()
-{
- print("Usage: worm reset [-fdevice]\n");
- exit(2);
-}
//GO.SYSIN DD wreset.c
echo wrm.c 1>&2
sed 's/.//' >wrm.c <<'//GO.SYSIN DD wrm.c'
-#include <libc.h>
-#include <fio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include "worm.h"
-
-static int bad = 0;
-static long nbytes;
-static long nfiles;
-char *argout;
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e;
- char buf[4096];
- int n;
- int c;
- char *dev = "/dev/worm0";
- extern char *optarg;
- extern int optind;
-
- argout = argv[0];
- while((c = getopt(argc, argv, "f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case '?': usage();
- }
-
- if(optind >= argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 2)) < 0){
- perror(*argv);
- exit(1);
- }
- if(e = openinode(&s, DO_INODE|SPIN_DOWN)){
- fprint(2, "%s: %s\n", *argv, e);
- exit(1);
- }
- if(strcmp(s.vol_id, argv[optind])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
- exit(1);
- }
- if(s.nfree == 0){
- fprint(2, "%s: can't write any more!\n", dev);
- exit(1);
- }
- if(s.version != VLINK){
- fprint(2, "%s: can't write on a b-tree disk\n", s.vol_id);
- exit(1);
- }
- for(n = 1; n <= NSIG; n++)
- signal(n, SIG_IGN);
- ininit();
- if(++optind < argc)
- while(optind < argc)
- proc(&s, argv[optind++]);
- else
- while(e = Frdline(0))
- proc(&s, e);
- if(bad)
- exit(1);
- inwrite(&s);
- if(bad)
- exit(1);
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: worm rm [-fdevice] vol_id [files]\n");
- exit(1);
-}
-
-proc(s, file)
- Superblock *s;
- char *file;
-{
- Inode i;
-
- if(inodeof(file) == 0){
- fprint(2, "%s: not on worm\n", file);
- return;
- }
- i.magic = DMAGIC;
- i.block = -1;
- i.name.n = file;
- if(inadd(s, &i))
- bad = 1;
-}
-
-static Inode *inodes;
-static long ip;
-static long ninodes = 0;
-static char *nameb;
-static long np;
-static long nnameb = 0;
-static long nblocks;
-#define IINC 1024
-#define NINC (64*IINC)
-
-ininit()
-{
- if(nnameb == 0){
- nameb = malloc((unsigned)(nnameb = NINC));
- if(nameb == 0){
- fprint(2, "wrm: malloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- np = 0;
- if(ninodes == 0){
- inodes = (Inode *)malloc(sizeof(Inode)*(unsigned)(ninodes = IINC));
- if(inodes == 0){
- fprint(2, "wrm: malloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- ip = 0;
-}
-
-inadd(s, i)
- Superblock *s;
- register Inode *i;
-{
- register long len;
-
- len = strlen(i->name.n)+1;
- if(np+len > nnameb){
- while(np+len > nnameb)
- nnameb += NINC;
- nameb = realloc(nameb, (unsigned)nnameb);
- if(nameb == 0){
- fprint(2, "wrm: realloc fail, %d bytes\n", nnameb);
- exit(1);
- }
- }
- strcpy(nameb+np, i->name.n);
- i->name.o = np;
- np += len;
- if(ip == ninodes){
- ninodes += IINC;
- inodes = (Inode *)realloc((char *)inodes, (unsigned)ninodes*sizeof(Inode));
- if(inodes == 0){
- fprint(2, "wrm: realloc fail, %d inodes %d bytes\n", ninodes, ninodes*sizeof(Inode));
- exit(1);
- }
- }
- inodes[ip++] = *i;
- return(0);
-}
-
-inwrite(s)
- Superblock *s;
-{
- char *e;
-
- if(e = lkwri(s, inodes, ip, nameb, np, 0L)){
- fprint(2, "%s\n", e);
- bad = 1;
- return;
- }
-}
//GO.SYSIN DD wrm.c
echo wstat.c 1>&2
sed 's/.//' >wstat.c <<'//GO.SYSIN DD wstat.c'
-#include <libc.h>
-#include "worm.h"
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e, *vol_id = 0;
- char *dev = "/dev/worm0";
- int c;
- long nf = 0;
- int vflag = 0;
- extern char *optarg;
- extern int optind;
- extern long atol();
-
- while((c = getopt(argc, argv, "vF:f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case 'F': nf = atol(optarg); break;
- case 'v': vflag = 1; break;
- case '?': usage();
- }
- if(optind < argc){
- vol_id = argv[optind++];
- if(optind != argc)
- usage();
- }
- dev = mapdev(dev);
- if((s.fd = open(dev, 0)) < 0){
- if(!vol_id && !nf)
- perror(dev);
- exit(2);
- }
- if(e = openinode(&s, SPIN_DOWN)){
- if(!vol_id && !nf)
- fprint(2, "%s: %s\n", dev, e);
- exit(2);
- }
- if(nf){
- if(vol_id)
- if(strcmp(vol_id, s.vol_id) != 0)
- exit(1);
- exit(s.nfree >= nf? 0:3);
- }
- if(vol_id)
- exit(strcmp(vol_id, s.vol_id) != 0);
- if(vflag){
- Fprint(1, "%s: %s, %s\t%ldx%uhd blocks, %ld (=%.1fMB) free, zero=%ld this_sb@%ld next_sb@%ld\n",
- s.vol_id, s.comment, ctime(&s.ctime), s.nblocks, s.blocksize,
- s.nfree, s.nfree*(double)s.blocksize*1e-6, s.zero, s.myblock, s.nextsb);
- } else
- Fprint(1, "%s: %.0f%% used (%.1fMB free)\n", s.vol_id,
- s.nextffree*100.0/s.nblocks, s.nfree*(double)s.blocksize*1e-6);
- exit(0);
-}
-
-usage()
-{
- print("Usage: worm stat [-v] [-fdevice] [-Fnfree] [vol_id]\n");
- exit(2);
-}
//GO.SYSIN DD wstat.c
echo wtmpdir.c 1>&2
sed 's/.//' >wtmpdir.c <<'//GO.SYSIN DD wtmpdir.c'
-#include <libc.h>
-#include "worm.h"
-#include "sym.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <grp.h>
-
-Inode *inodebase, *inext;
-char *namebase, *cnext;
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e;
- char *dev = "/dev/worm0";
- register c, j;
- register Inode *from, *to;
- extern char *optarg;
- extern int optind;
- char *vlk();
- int cmp();
- int fd;
- int verbose = 0;
- char buf[512];
- long ni, nc;
-
- while((c = getopt(argc, argv, "vf:")) != -1)
- switch(c)
- {
- case 'v': verbose = 1; break;
- case 'f': dev = optarg; break;
- case '?': usage();
- }
- dev = mapdev(dev);
- if((s.fd = open(dev, 0)) < 0){
- perror(dev);
- exit(1);
- }
- if(e = openinode(&s, SPIN_DOWN)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- if(s.version != VLINK){
- fprint(2, "%s: not a vlink disk, no action taken.\n", s.vol_id);
- exit(1);
- }
- if(optind != argc-1)
- usage();
- if(strcmp(argv[optind], s.vol_id)){
- fprint(2, "wanted volid '%s'; got '%s'\n", argv[optind], s.vol_id);
- exit(1);
- }
- if(verbose)
- print("%d inodes\n", numinodes);
- if((inodebase = (Inode *)malloc(s.blocksize+(int)numinodes*sizeof(Inode))) == 0){
- fprint(2, "malloc of %ld inodes failed\n", numinodes);
- exit(2);
- }
- if((namebase = malloc(s.blocksize+(int)numnamechars+(int)numinodes)) == 0){
- fprint(2, "malloc of %ld chars failed\n", numnamechars);
- exit(2);
- }
- inext = inodebase;
- cnext = namebase;
- s.ninodes = 0;
- s.nextsb = 2;
- if(e = vlk(&s)){
- fprint(2, "%s: %s\n", dev, e);
- exit(1);
- }
- j = inext-inodebase;
- if(verbose)
- print("%d in base\n", j);
- qsort((char *)inodebase, j, sizeof(*inodebase), cmp);
- for(to = inodebase, from = inodebase+1; from < inext; from++)
- if(strcmp(from->name.o+namebase, from[-1].name.o+namebase))
- *to++ = from[-1];
- else {
- while((++from < inext) && (strcmp(from->name.o+namebase, from[-1].name.o+namebase) == 0))
- ;
- }
- if(from == inext)
- *to++ = from[-1];
- inext = to;
- j = inext-inodebase;
- sprint(buf, "/usr/worm/tmp/%s", s.vol_id);
- if((fd = creat(buf, 0666)) < 0){
- perror(buf);
- exit(1);
- }
- ni = j;
- nc = cnext-namebase;
- write(fd, (char *)&s.ctime, 4);
- write(fd, (char *)&ni, 4);
- write(fd, (char *)inodebase, (int)ni*sizeof(Inode));
- write(fd, (char *)&nc, 4);
- write(fd, namebase, (int)nc);
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: worm tmpdir [-fdevice] vol_id\n");
- exit(2);
-}
-
-cmp(a, b)
- Inode *a, *b;
-{
- return(strcmp(namebase+a->name.o, namebase+b->name.o));
-}
-
-char *
-vlk(s)
- register Superblock *s;
-{
- register Inode *i;
- short fd = s->fd;
- register long j;
- long blk = -1; /* shouldn't be accessed first time through */
- char *b;
- long nb;
- Inode *iend;
- static char buf[64];
-
- if((b = malloc(s->blocksize)) == 0){
- sprint(buf, "couldn't malloc buffer (%d bytes)", s->blocksize);
- return(buf);
- }
- for(;;){
- if(s->magic != SMAGIC){
- fprint(2, "bad Superblock at %ld\n", blk);
- exit(1);
- }
- if(s->ninodes){
- nb = (s->ninodes+IPERB-1)/IPERB;
- Seek(s, s->binodes);
- if(Read(s, (char *)inext, nb))
- goto skip;
- j = cnext-namebase;
- for(i = inext, iend = i+s->ninodes; i < iend; i++)
- i->name.o += j;
- inext += s->ninodes;
- nb = (s->ninochars+s->blocksize-1)/s->blocksize;
- if(Read(s, cnext, nb))
- goto skip;
- cnext += (s->ninochars+1)&~1;
- }
- skip:
- blk = s->nextsb;
- Seek(s, blk);
- if(Read(s, b, 1L))
- break;
- *s = *((Superblock *)b);
- s->fd = fd;
- if(s->myblock == 0)
- s->myblock = blk;
- }
- free(b);
- return((char *)0);
-}
//GO.SYSIN DD wtmpdir.c
echo wwrite.c 1>&2
sed 's/.//' >wwrite.c <<'//GO.SYSIN DD wwrite.c'
-#include <libc.h>
-#include <fio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <signal.h>
-#include "worm.h"
-
-main(argc, argv)
- char **argv;
-{
- Superblock s;
- char *e;
- char buf[4096];
- int n;
- int c;
- char *dev = "/dev/worm0";
- extern char *optarg;
- extern int optind;
-
- argout = argv[0];
- while((c = getopt(argc, argv, "f:")) != -1)
- switch(c)
- {
- case 'f': dev = optarg; break;
- case '?': usage();
- }
-
- if(optind >= argc)
- usage();
- dev = mapdev(dev);
- if((s.fd = open(dev, 2)) < 0){
- perror(*argv);
- exit(1);
- }
- if(e = openinode(&s, SPIN_DOWN)){
- fprint(2, "%s: %s\n", *argv, e);
- exit(1);
- }
- if(strcmp(s.vol_id, argv[optind])){
- fprint(2, "vol_id mismatch: wanted %s, got %s\n", argv[optind], s.vol_id);
- exit(1);
- }
- if(s.nfree == 0){
- fprint(2, "%s: can't write any more!\n", dev);
- exit(1);
- }
- if(s.version != VLINK){
- fprint(2, "%s: can't write on a b-tree disk\n", s.vol_id);
- exit(1);
- }
- for(n = 1; n <= NSIG; n++)
- signal(n, SIG_IGN);
- ininit();
- if(++optind < argc)
- while(optind < argc)
- proc(&s, argv[optind++]);
- else
- while(e = Frdline(0))
- proc(&s, e);
- if(bad)
- exit(1);
- nfiles = nbytes = 0;
- inwrite(&s, (void *)0);
- if(bad)
- exit(1);
- fprint(1, "%d files, %.6fMb\n", nfiles, nbytes/1e6);
- exit(0);
-}
-
-usage()
-{
- fprint(2, "Usage: worm write [-fdevice] vol_id [files]\n");
- exit(1);
-}
-
-proc(s, file)
- Superblock *s;
- char *file;
-{
- struct stat sbuf;
- unsigned short mode;
- Inode i;
-
- memset((char *)&i, 0, sizeof(i));
- if(stat(file, &sbuf) < 0){
- perror(file);
- return;
- }
- mode = sbuf.st_mode&S_IFMT;
- if((mode == S_IFREG) || (mode == S_IFDIR)){
- i.magic = DMAGIC;
- i.block = 0;
- i.nbytes = sbuf.st_size;
- nbytes += i.nbytes;
- i.ctime = sbuf.st_ctime;
- i.name.n = file;
- i.mode = sbuf.st_mode;
- i.uid = sbuf.st_uid;
- i.gid = sbuf.st_gid;
- if(inadd(s, &i))
- bad = 1;
- } else
- fprint(2, "%s is not a file\n", file);
-}
-
-writeout(s, i, blk)
- Superblock *s;
- Inode *i;
- long *blk;
-{
- char b[63*1024L];
- int fd;
- long n, len, blen;
- char *name;
-
- n = (i->nbytes+s->blocksize-1)/s->blocksize;
- *blk += n;
- blkdone += n;
- blen = sizeof b/s->blocksize;
- len = blen*s->blocksize;
- nbytes += i->nbytes;
- nfiles++;
- name = i->name.n;
- if((fd = open(name, 0)) < 0)
- goto out;
- for(n = i->nbytes; n > len; n -= len){
- if(read(fd, (char *)b, (int)len) != len){
- out:
- perror(name);
- bad = 1;
- return;
- }
- if(Write(s, b, blen)){
-fprint(2, "nb=%d, n=%d len=%d blen=%d\n", i->nbytes, n, len, blen);
- perror("data write");
- exit(1);
- }
- }
- if(n){
- memset(b, 0, sizeof b);
- if(read(fd, (char *)b, (int)n) != n)
- goto out;
- n += s->blocksize-1;
- n /= s->blocksize;
- if(Write(s, b, n)){
- perror("data write");
- exit(1);
- }
- }
- close(fd);
-}
//GO.SYSIN DD wwrite.c