## diffname power/devhs.c 1990/0227 ## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/devhsvme.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #include "devtab.h" #include "io.h" enum { Maxtxburst= 1024, /* maximum transmit burst size */ Vmevec= 0xd0, /* vme vector for interrupts */ Intlevel= 5, /* level to interrupt on */ }; struct hsvmestats { ulong parity; ulong rintr; ulong tintr; } hsvmestats; #define ALIVE 0x0001 #define IENABLE 0x0004 #define EXOFLOW 0x0008 #define IRQ 0x0010 #define EMUTE 0x0020 #define EPARITY 0x0040 #define EFRAME 0x0080 #define EROFLOW 0x0100 #define REF 0x0800 #define XFF 0x4000 #define XHF 0x8000 #define FORCEW 0x0008 #define IPL(x) ((x)<<5) #define NORESET 0xFF00 #define RESET 0x0000 #define CTL 0x0100 #define CHNO 0x0200 #define TXEOD 0x0400 #define NND 0x8000 Rendez hsvmer; #define DELAY(n) { \ register int N = 12*(n); \ while (--N > 0); \ } static void hsvmeintr(int); void hsvmerestart(struct hsvme *addr) { addr->csr = RESET; wbflush(); DELAY(20000); /* * set interrupt vector * turn on addrice * set forcew to a known value * interrupt on level `Intlevel' */ addr->vector = 0xd0; addr->csr = NORESET|IPL(Intlevel)|IENABLE|ALIVE; wbflush(); DELAY(500); addr->csr = NORESET|IPL(Intlevel)|FORCEW|IENABLE|ALIVE; wbflush(); DELAY(500); } void hsvmereset(void) { struct hsvme *addr; addr = HSVME; addr->csr = RESET; wbflush(); DELAY(20000); /* * routine to call on interrupt */ setvmevec(Vmevec, hsvmeintr); } void hsvmeinit(void) { } /* * enable the device for interrupts */ static int never(void *arg) { return 0; } Chan* hsvmeattach(char *spec) { struct hsvme *addr; addr = HSVME; hsvmerestart(addr); print("hsvme csr %ux\n", addr->csr); return devattach('h', spec); } Chan* hsvmeclone(Chan *c, Chan *nc) { return devclone(c, nc); } int hsvmewalk(Chan *c, char *name) { if(c->qid != CHDIR) return 0; if(strcmp(name, "hsvme") == 0){ c->qid = 1; return 1; } return 0; } void hsvmestat(Chan *c, char *dp) { print("hsvmestat\n"); error(0, Egreg); } Chan* hsvmeopen(Chan *c, int omode) { c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; return c; } void hsvmecreate(Chan *c, char *name, int omode, ulong perm) { error(0, Eperm); } void hsvmeclose(Chan *c) { } long hsvmeread(Chan *c, void *buf, long n) { error(0, Egreg); return 0; } long hsvmewrite(Chan *c, void *buf, long n) { error(0, Egreg); return 0; } void hsvmeremove(Chan *c) { error(0, Eperm); } void hsvmewstat(Chan *c, char *dp) { error(0, Eperm); } void hsvmeuserstr(Error *e, char *buf) { consuserstr(e, buf); } void hsvmeerrstr(Error *e, char *buf) { rooterrstr(e, buf); } static void hsvmeintr(int vec) { ushort csr; struct hsvme *addr; print("hsvme intr\n"); addr = HSVME; wbflush(); csr = addr->csr; do { if (addr->csr & REF) { hsvmestats.rintr++; print("hsvme rintr\n"); } if (addr->csr & XHF) { hsvmestats.tintr++; print("hsvme tintr\n"); } if ((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)) { hsvmestats.parity++; hsvmerestart(addr); print("hsvme %ux: reset, csr = 0x%x\n", HSVME, csr); } wbflush(); } while ((csr = addr->csr) & REF); } . ## diffname power/devhs.c 1990/0312 ## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0312/sys/src/9/mips/devhsvme.c 225,226c if(bp->rptr >= bp->wptr){ if(bp->flags & S_DELIM){ freeb(bp); break; } freeb(bp); bp = getq(q); } } /* * send the control byte if there is one */ if(ctl){ /* print("->%.2uo\n", CTL|ctl); /**/ addr->data = CTL|ctl; } /* * start the fifo emptying */ /* print("->%.2uo\n", TXEOD); /**/ addr->data = TXEOD; qunlock(&hp->xmit); } /* * return true if the input fifo is non-empty */ static int notempty(void *arg) { Device *addr; addr = (Device *)arg; return addr->csr & REF; } /* * fill a block with what is currently buffered and send it upstream */ static void upstream(Hsvme *hp, unsigned int ctl) { int n; Block *bp; n = hp->wptr - hp->buf; bp = allocb(3 + n); bp->wptr[0] = hp->chan; bp->wptr[1] = hp->chan>>8; bp->wptr[2] = ctl; if(n) memcpy(&bp->wptr[3], hp->buf, n); bp->wptr += 3 + n; bp->flags |= S_DELIM; PUTNEXT(hp->rq, bp); hp->wptr = hp->buf; } /* * Read bytes from the input fifo. Since we take an interrupt every * time the fifo goes non-empty, we need to waste time to let the * fifo fill up. */ static void hsvmekproc(void *arg) { Hsvme *hp; Device *addr; unsigned int c; hp = (Hsvme *)arg; addr = hp->addr; hp->kstarted = 1; hp->wptr = hp->buf; for(;;){ /* * die if the device is closed */ qlock(hp); if(hp->rq == 0){ qunlock(hp); hp->kstarted = 0; wakeup(&hp->r); return; } /* * let the fifo fill a bit */ delay(1); /* * 0xFFFF means an empty fifo */ while ((c = addr->data) != 0xFFFF) { /* print(" %.2uo<-\n", c); /**/ if(c & CHNO){ c &= 0x1FF; if(hp->chan == c) continue; /* * new channel, put anything saved upstream */ if(hp->wptr - hp->buf != 0) upstream(hp, 0); hp->chan = c; } else if(c & NND){ /* * ctl byte, this ends a message */ upstream(hp, c); } else { /* * data byte, put in local buffer */ *hp->wptr++ = c; if(hp->wptr == &hp->buf[sizeof hp->buf]) upstream(hp, 0); } } qunlock(hp); /* * sleep if input fifo empty */ if(!notempty(addr)) sleep(&hp->kr, notempty, addr); } } /* * only one flavor interrupt. we have to use the less than half full * and not empty bits to figure out whom to wake. */ static void hsvmeintr(int vec) { ushort csr; Device *addr; Hsvme *hp; hp = &hsvme[vec - Vmevec]; if(hp < hsvme || hp > &hsvme[Nhsvme]){ print("bad hsvme vec\n"); return; } csr = hp->addr->csr; if (csr & REF) { hp->rintr++; wakeup(&hp->kr); } if (csr & XHF) { hp->tintr++; wakeup(&hp->r); } if ((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)) { hp->parity++; hsvmerestart(hp); print("hsvme %d: reset, csr = 0x%ux\n", HSVME, csr); } . 219,223c n = bp->wptr - bp->rptr; if(n > burst) n = burst; burst -= n; while(n--){ /* print("->%.2uo\n", *bp->rptr); /**/ addr->data = *bp->rptr++; . 215,217c freeb(bp); } } /* * return true if the output fifo is at least half empty. * the implication is that it can take at least another 1000 byte burst. */ static int halfempty(void *arg) { Device *addr; addr = (Device*)arg; return addr->csr & XHF; } /* * output a block * * the first 2 bytes of every message are the channel number, * low order byte first. the third is a possible trailing control * character. */ void hsvmeoput(Queue *q, Block *bp) { Device *addr; Hsvme *hp; int burst; int chan; int ctl; int n; if(bp->type != M_DATA){ freeb(bp); return; } /* * get a whole message before handing bytes to the device */ if(!putq(q, bp)) return; /* * one transmitter at a time */ hp = (Hsvme *)q->ptr; qlock(&hp->xmit); addr = hp->addr; /* * parse message */ bp = getq(q); if(bp->wptr - bp->rptr < 3){ freemsg(q, bp); qunlock(&hp->xmit); return; } chan = CHNO | *bp->rptr++ | (*bp->rptr++<<8); ctl = *bp->rptr++; /* * send the 8 bit data, burst are up to Maxburst (9-bit) bytes long */ if(!(addr->csr & XHF)) sleep(&hp->r, halfempty, addr); /* print("->%.2uo\n", CHNO|chan);/**/ addr->data = CHNO|chan; burst = Maxburst; while(bp){ if(burst == 0){ addr->data = TXEOD; /* print("->%.2uo\n", TXEOD); /**/ if(!(addr->csr & XHF)) sleep(&hp->r, halfempty, addr); /* print("->%.2uo\n", CHNO|chan); /**/ addr->data = CHNO|chan; burst = Maxburst; . 206,213c hp = &hsvme[s->dev]; sprint(name, "**hsvme%d**", s->dev); q->ptr = q->other->ptr = hp; hp->rq = q; kproc(name, hsvmekproc, hp); } /* * kill off the kernel process */ static int kdead(void *arg) { Hsvme *hp; hp = (Hsvme *)arg; return hp->kstarted == 0; } static void hsvmestclose(Queue * q) { Hsvme *hp; hp = (Hsvme *)q->ptr; qlock(hp); hp->rq = 0; qunlock(hp); wakeup(&hp->kr); sleep(&hp->r, kdead, hp); } /* * free all blocks of a message in `q', `bp' is the first block * of the message */ static void freemsg(Queue *q, Block *bp) { for(; bp; bp = getq(q)){ if(bp->flags & S_DELIM){ freeb(bp); return; . 203,204c Hsvme *hp; char name[32]; . 201c hsvmestopen(Queue *q, Stream *s) . 199a /* * the stream routines */ /* * create the kernel process for input */ . 172,173c return streamwrite(c, buf, n, 0); . 165,166c return streamread(c, buf, n); . 159a if(c->qid != CHDIR) streamclose(c); . 144a if(c->qid == CHDIR){ if(omode != OREAD) error(0, Eperm); }else streamopen(c, &hsvmeinfo); . 138,139c devstat(c, dp, 0, 0, streamgen); . 126,132c return devwalk(c, name, 0, 0, streamgen); . 114c c = devattach('h', spec); c->dev = i; c->qid = CHDIR; return c; . 110,112c i = strtoul(spec, 0, 0); if(i >= Nhsvme) error(0, Ebadarg); hp = &hsvme[i]; hsvmerestart(hp); print("hsvme [%d] csr %ux\n", i, hp->addr->csr); . 108c Hsvme *hp; int i; Chan *c; . 100,104d 98c * enable the device for interrupts, spec is the device number . 84,89c delay(20); . 81,82c for(i=0; icsr = RESET; setvmevec(hsvme[i].vec, hsvmeintr); } . 79c int i; Hsvme *hp; . 75a /* * reset all vme boards */ . 73c delay(1); . 70c delay(1); . 67c addr->vector = hp->vec; . 59c delay(20); . 56a Device *addr; addr = hp->addr; . 55c hsvmerestart(Hsvme *hp) . 53a /* * hsvme stream module definition */ static void hsvmeoput(Queue*, Block*); static void hsvmestopen(Queue*, Stream*); static void hsvmestclose(Queue*); Qinfo hsvmeinfo = { nullput, hsvmeoput, hsvmestopen, hsvmestclose, "hsvme" }; /* * restart a VME board */ . 52a static void hsvmekproc(void*); . 45,51d 22a struct Hsvme { QLock; QLock xmit; Device *addr; int vec; /* interupt vector */ Rendez r; /* output process */ Rendez kr; /* input kernel process */ int chan; /* current input channel */ Queue *rq; /* read queue */ uchar buf[1024]; /* bytes being collected */ uchar *wptr; /* pointer into buf */ int kstarted; /* true if kernel process started */ /* statistics */ ulong parity; /* parity errors */ ulong rintr; /* rcv interrupts */ ulong tintr; /* transmit interrupts */ ulong in; /* bytes in */ ulong out; /* bytes out */ }; Hsvme hsvme[Nhsvme]; . 17,21c /* * hsvme datakit board */ struct Device { ushort version; ushort pad0x02; ushort vector; ushort pad0x06; ushort csr; ushort pad0x0A; ushort data; }; #define HSVME VMEA24SUP(Device, 0xF90000) . 14a Nhsvme= 1, . 12c Maxburst= 1023, /* maximum transmit burst size */ . 10a typedef struct Hsvme Hsvme; typedef struct Device Device; . ## diffname power/devhs.c 1990/0315 ## diff -e /n/bootesdump/1990/0312/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0315/sys/src/9/mips/devhsvme.c 367,368c chan = CHNO | bp->rptr[0] | (bp->rptr[1]<<8); ctl = bp->rptr[2]; bp->rptr += 3; . ## diffname power/devhs.c 1990/0403 ## diff -e /n/bootesdump/1990/0315/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0403/sys/src/9/mips/devhsvme.c 519a } . 496c miss = 0; . 490,491c for(miss = 0; miss < 10; miss++){ . 488c * if we loop many times without finding a character, sleep . 468a int miss; . 161d ## diffname power/devhs.c 1990/0722 ## diff -e /n/bootesdump/1990/0403/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0722/sys/src/9/mips/devhsvme.c 263c sprint(name, "hsvme%d", s->dev); . ## diffname power/devhs.c 1990/0816 ## diff -e /n/bootesdump/1990/0722/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0816/sys/src/9/mips/devhsvme.c 519d 488,491d ## diffname power/devhs.c 1990/0826 ## diff -e /n/bootesdump/1990/0816/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0826/sys/src/9/mips/devhsvme.c 490a hp->in++; . ## diffname power/devhs.c 1990/0930 ## diff -e /n/bootesdump/1990/0826/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/0930/sys/src/9/mips/devhsvme.c 557c vec - Vmevec, csr); . ## diffname power/devhs.c 1990/1101 ## diff -e /n/bootesdump/1990/0930/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/1101/sys/src/9/mips/devhsvme.c 517a locked = 0; . 479a locked = 1; . 474a locked = 0; if(waserror()){ if(locked) qunlock(hp); hp->kstarted = 0; wakeup(&hp->r); return; } . 468a int locked; . ## diffname power/devhs.c 1990/11151 ## diff -e /n/bootesdump/1990/1101/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/11151/sys/src/9/mips/devhsvme.c 91c Qinfo hsvmeinfo = { nullput, hsvmeoput, hsvmestopen, hsvmestclose, "hsvme" }; . ## diffname power/devhs.c 1990/11211 ## diff -e /n/bootesdump/1990/11151/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/11211/sys/src/9/mips/devhsvme.c 241,253c error(Eperm); . 235c error(Eperm); . 216c if(c->qid.path != CHDIR) . 210c error(Eperm); . 198c error(Eperm); . 196c if(c->qid.path == CHDIR){ . 171c c->qid.path = CHDIR; . 165c error(Ebadarg); . ## diffname power/devhs.c 1990/1214 ## diff -e /n/bootesdump/1990/11211/sys/src/9/mips/devhsvme.c /n/bootesdump/1990/1214/sys/src/9/mips/devhsvme.c 522a USED(locked); . 498d 489a poperror(); . 483a USED(locked); /* so locked = 0 and locked = 1 stay */ . 463d ## diffname power/devhs.c 1991/0318 ## diff -e /n/bootesdump/1991/0201/sys/src/9/mips/devhsvme.c /n/bootesdump/1991/0318/sys/src/9/power/devhsvme.c 445c memmove(&bp->wptr[3], hp->buf, n); . ## diffname power/devhs.c 1991/0411 ## diff -e /n/bootesdump/1991/0318/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0411/sys/src/9/power/devhsvme.c 227c hsvmewrite(Chan *c, void *buf, long n, ulong offset) . 221c hsvmeread(Chan *c, void *buf, long n, ulong offset) . ## diffname power/devhs.c 1991/0419 ## diff -e /n/bootesdump/1991/0411/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0419/sys/src/9/power/devhsvme.c 186a Chan* hsvmeclwalk(Chan *c, char *name) { return devclwalk(c, name); } . ## diffname power/devhs.c 1991/0427 ## diff -e /n/bootesdump/1991/0419/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0427/sys/src/9/power/devhsvme.c 187,192d ## diffname power/devhs.c 1991/0921 ## diff -e /n/bootesdump/1991/0427/sys/src/9/power/devhsvme.c /n/bootesdump/1991/0921/sys/src/9/power/devhsvme.c 167c if(!hp->started) hsvmerestart(hp); . 126a hp->started = 1; . 47a int started; . ## diffname power/devhs.c 1991/1214 ## diff -e /n/bootesdump/1991/0921/sys/src/9/power/devhsvme.c /n/bootesdump/1991/1214/sys/src/9/power/devhsvme.c 243a USED(c); . 237a USED(c); . 212a USED(c); . ## diffname power/devhs.c 1992/0111 ## diff -e /n/bootesdump/1991/1214/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0111/sys/src/9/power/devhsvme.c 6c #include "../port/error.h" . ## diffname power/devhs.c 1992/0117 ## diff -e /n/bootesdump/1992/0111/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0117/sys/src/9/power/devhsvme.c 421a poperror(); . 354a if(waserror()){ qunlock(&hp->xmit); nexterror(); } . ## diffname power/devhs.c 1992/0123 ## diff -e /n/bootesdump/1992/0117/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0123/sys/src/9/power/devhsvme.c 541,542c if(!(addr->csr & REF)){ if(hp->wptr == hp->buf) sleep(&hp->kr, notempty, addr); else tsleep(&hp->kr, notempty, addr, 100); } . 539c * Sleep if input fifo empty. Make sure we don't hold onto * any byte for more tha 1/10 second. . 533a if(hp->time && NOW >= hp->time) upstream(hp, 0); . 528a if(hp->time == 0) hp->time = NOW + 100; . 460a hp->time = 0; . 46a ulong time; /* time byte in buf[0] arrived */ . 20a #define NOW (MACHP(0)->ticks*MS2HZ) . ## diffname power/devhs.c 1992/0321 ## diff -e /n/bootesdump/1992/0123/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0321/sys/src/9/power/devhsvme.c 2c #include "../port/lib.h" . ## diffname power/devhs.c 1992/0612 ## diff -e /n/bootesdump/1992/0612/sys/src/9/power/devhsvme.c /n/bootesdump/1992/0612/sys/src/9/power/devhs.c 587,589c hsrestart(hp); print("hs %d: reset, csr = 0x%ux\n", vec - Intvec, csr); . 585c if((csr^XFF) & (XFF|EROFLOW|EFRAME|EPARITY|EXOFLOW)){ . 581c if(csr & XHF){ . 577c if(csr & REF){ . 570,572c hp = &hs[vec - Intvec]; if(hp < hs || hp > &hs[Nhs]){ print("bad hs vec\n"); . 567,568c HSdev *addr; Hs *hp; . 564c hsintr(int vec) . 512c while((c = addr->data) != 0xFFFF){ . 480c hp = (Hs *)arg; . 475,476c Hs *hp; HSdev *addr; . 473c hskproc(void *arg) . 448c upstream(Hs *hp, unsigned int ctl) . 440c addr = (HSdev *)arg; . 438c HSdev *addr; . 371a poperror(); . 362d 357c hp = (Hs *)q->ptr; qlock(&hp->xmit); . 336,337c HSdev *addr; Hs *hp; . 334c hsoput(Queue *q, Block *bp) . 322c addr = (HSdev*)arg; . 320c HSdev *addr; . 293,294c while(waserror()) ; while(hp->kstarted){ wakeup(&hp->kr); sleep(&hp->r, kdead, hp); } poperror(); . 289c hp = (Hs *)q->ptr; . 287c Hs *hp; . 285c hsstclose(Queue * q) . 281c hp = (Hs *)arg; . 279c Hs *hp; . 274c * ask kproc to die and wait till it happens . 270c kproc(name, hskproc, hp); . 266,267c hp = &hs[s->dev]; sprint(name, "hs%d", s->dev); . 263c Hs *hp; . 261c hsstopen(Queue *q, Stream *s) . 247c hswstat(Chan *c, char *dp) . 240c hsremove(Chan *c) . 234c hswrite(Chan *c, void *buf, long n, ulong offset) . 228c hsread(Chan *c, void *buf, long n, ulong offset) . 221c hsclose(Chan *c) . 214c hscreate(Chan *c, char *name, int omode, ulong perm) . 206c streamopen(c, &hsinfo); . 200c hsopen(Chan *c, int omode) . 194c hsstat(Chan *c, char *dp) . 188c hswalk(Chan *c, char *name) . 182c hsclone(Chan *c, Chan *nc) . 173c hsrestart(hp); . 171c hp = &hs[i]; . 169c if(i >= Nhs) . 164c Hs *hp; . 162c hsattach(char *spec) . 154c hsinit(void) . 143,147c for(i=0; iaddr = HSDEV+i; hp->vec = Intvec+i; hp->addr->csr = RESET; setvmevec(hp->vec, hsintr); . 141c Hs *hp; . 138c hsreset(void) . 120c * turn on device . 110c HSdev *addr; . 108c hsrestart(Hs *hp) . 104,106d 98,101c hsoput, hsstopen, hsstclose, "hs" . 92,95c static void hsoput(Queue*, Block*); static void hsstopen(Queue*, Stream*); static void hsstclose(Queue*); Qinfo hsinfo = . 90c * hs stream module definition . 76,88d 64,74c static void hsintr(int); static void hskproc(void*); . 62c Hs hs[Nhs]; . 41c HSdev *addr; . 37c #define NOW (MACHP(0)->ticks*MS2HZ) #define IPL(x) ((x)<<5) struct Hs { . 35d 23,33c /* * csr reset flags */ FORCEW = 0x0008, NORESET = 0xFF00, RESET = 0x0000, /* * data flags */ CTL = 0x0100, CHNO = 0x0200, TXEOD = 0x0400, NND = 0x8000, . 21c /* * csr flags */ ALIVE = 0x0001, IENABLE = 0x0004, EXOFLOW = 0x0008, IRQ = 0x0010, EMUTE = 0x0020, EPARITY = 0x0040, EFRAME = 0x0080, EROFLOW = 0x0100, REF = 0x0800, XFF = 0x4000, XHF = 0x8000, . 18,19c Nhs= 1, . 16c Intvec= 0xd0, /* vme vector for interrupts */ . 11,12c typedef struct Hs Hs; . ## diffname power/devhs.c 1992/0623 ## diff -e /n/bootesdump/1992/0612/sys/src/9/power/devhs.c /n/bootesdump/1992/0623/sys/src/9/power/devhs.c 366,371d 343a if(BLEN(bp) < 3){ bp = pullup(bp, 3); if(bp == 0){ print("hsoput pullup failed\n"); return; } } . ## diffname power/devhs.c 1992/0703 ## diff -e /n/bootesdump/1992/0623/sys/src/9/power/devhs.c /n/bootesdump/1992/0703/sys/src/9/power/devhs.c 551c tsleep(&hp->kr, notempty, addr, 2000); . 547c * any byte for more than 1/10 second. . ## diffname power/devhs.c 1992/0711 ## diff -e /n/bootesdump/1992/0703/sys/src/9/power/devhs.c /n/bootesdump/1992/0711/sys/src/9/power/devhs.c 566d 241a USED(dp); . 227a USED(offset); . 221a USED(offset); . 208a USED(name); USED(omode); USED(perm); . ## diffname power/devhs.c 1993/0806 # deleted ## diff -e /n/bootesdump/1992/0711/sys/src/9/power/devhs.c /n/fornaxdump/1993/0806/sys/src/brazil/power/devhs.c 1,595d