From bd4a67d71f12e72305d8abdc372f73c30d088dd1 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 1 Sep 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-09-01 --- pc/devfloppy.c | 26 +++--- pc/devhard.c | 22 +++-- port/devcdrom.c | 236 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+), 22 deletions(-) create mode 100644 port/devcdrom.c diff --git a/pc/devfloppy.c b/pc/devfloppy.c index ca23674cc7d732a5a620cc27c48d8c4b06bcc471..e045c723e7eccdf432007a2be5eb65e1660afca6 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -12,6 +12,8 @@ typedef struct Drive Drive; typedef struct Controller Controller; typedef struct Type Type; +#define DPRINT if(0)print + /* bits in the registers */ enum { @@ -552,7 +554,7 @@ floppycmd(void) for(i = 0; i < fl.ncmd; i++){ for(tries = 0; ; tries++){ if(tries > 1000){ -print("cmd %ux can't be sent (%d %ux)\n", fl.cmd[0], i, inb(Pmsr)); + DPRINT("cmd %ux can't be sent (%d %ux)\n", fl.cmd[0], i, inb(Pmsr)); fl.confused = 1; return -1; } @@ -635,7 +637,7 @@ floppysense(void) if(floppycmd() < 0) return -1; if(floppyresult() < 2){ -/*print("can't read sense response\n");/**/ + DPRINT("can't read sense response\n"); fl.confused = 1; return -1; } @@ -682,7 +684,7 @@ floppyrecal(Drive *dp) } dp->cyl = fl.stat[1]/dp->t->steps; if(dp->cyl != 0){ - print("recalibrate went to wrong cylinder %d\n", dp->cyl); + DPRINT("recalibrate went to wrong cylinder %d\n", dp->cyl); dp->confused = 1; return -1; } @@ -732,13 +734,13 @@ floppyseek(Drive *dp, long off) if(dp->cyl == dp->tcyl) return dp->cyl; -/* print("seeking tcyl %d, thead %d\n", dp->tcyl, dp->thead); /**/ + DPRINT("seeking tcyl %d, thead %d\n", dp->tcyl, dp->thead); fl.ncmd = 0; fl.cmd[fl.ncmd++] = Fseek; fl.cmd[fl.ncmd++] = (dp->thead<<2) | dp->dev; fl.cmd[fl.ncmd++] = dp->tcyl * dp->t->steps; if(floppycmd() < 0){ - print("seek cmd failed\n"); + DPRINT("seek cmd failed\n"); return -1; } floppywait(); @@ -747,7 +749,7 @@ floppyseek(Drive *dp, long off) return -1; } if((fl.stat[0] & (Codemask|Seekend)) != Seekend){ - print("seek failed\n"); + DPRINT("seek failed\n"); dp->confused = 1; return -1; } @@ -794,8 +796,8 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) if(floppyseek(dp, off) < 0) error(Eio); -/*print("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n", - dp->tcyl, dp->thead, dp->tsec, a, dp->len);/**/ + DPRINT("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n", + dp->tcyl, dp->thead, dp->tsec, a, dp->len); /* * set up the dma (dp->len may be trimmed) @@ -818,7 +820,7 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) fl.cmd[fl.ncmd++] = 0xFF; if(floppycmd() < 0){ spllo(); -/* print("xfer cmd failed\n");/**/ + DPRINT("xfer cmd failed\n"); error(Eio); } @@ -832,14 +834,14 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) * check for errors */ if(fl.nstat < 7){ -/* print("xfer result failed %lux\n", inb(Pmsr));/**/ + DPRINT("xfer result failed %lux\n", inb(Pmsr)); fl.confused = 1; error(Eio); } if((fl.stat[0] & Codemask)!=0 || fl.stat[1] || fl.stat[2]){ - print("xfer failed %lux %lux %lux\n", fl.stat[0], + DPRINT("xfer failed %lux %lux %lux\n", fl.stat[0], fl.stat[1], fl.stat[2]); - print("offset %lud len %d\n", off, dp->len); + DPRINT("offset %lud len %d\n", off, dp->len); dp->confused = 1; error(Eio); } diff --git a/pc/devhard.c b/pc/devhard.c index 060426b54f6e7ecba18de5ee8aaf144325a81c49..22a641b29e76f71584afb550758f8409678de594 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -6,6 +6,8 @@ #include "io.h" #include "../port/error.h" +#define DPRINT if(0)print + typedef struct Drive Drive; typedef struct Ident Ident; typedef struct Controller Controller; @@ -459,7 +461,7 @@ cmdreadywait(Controller *cp) start = m->ticks; while((inb(cp->pbase+Pstatus) & (Sready|Sbusy)) != Sready) if(TK2MS(m->ticks - start) > 1){ -print("cmdreadywait failed\n"); + DPRINT("cmdreadywait failed\n"); error(Eio); } } @@ -473,7 +475,7 @@ hardrepl(Drive *dp, long bblk) return; for(i = 0; i < dp->repl.nrepl; i++){ if(dp->repl.blk[i] == bblk) - print("found bblk %ld at offset %ld\n", bblk, i); + DPRINT("found bblk %ld at offset %ld\n", bblk, i); } } @@ -559,10 +561,10 @@ hardxfer(Drive *dp, Partition *pp, int cmd, long start, long len, char *buf) sleep(&cp->r, cmddone, cp); if(cp->status & Serr){ - print("hd%d err: lblk %ld status %lux, err %lux\n", + DPRINT("hd%d err: lblk %ld status %lux, err %lux\n", dp-hard, lblk, cp->status, cp->error); - print("\tcyl %d, sec %d, head %d\n", cyl, sec, head); - print("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); + DPRINT("\tcyl %d, sec %d, head %d\n", cyl, sec, head); + DPRINT("\tnsecs %d, sofar %d\n", cp->nsecs, cp->sofar); hardrepl(dp, lblk+cp->sofar); error(Eio); } @@ -597,7 +599,7 @@ hardsetbuf(Drive *dp) sleep(&cp->r, cmddone, cp); if(cp->status & Serr) - print("hd%d setbuf err: status %lux, err %lux\n", + DPRINT("hd%d setbuf err: status %lux, err %lux\n", dp-hard, cp->status, cp->error); poperror(); @@ -632,7 +634,7 @@ hardident(Drive *dp) outb(cp->pbase+Pcmd, Cident); sleep(&cp->r, cmddone, cp); if(cp->status & Serr){ - print("bad disk ident status\n"); + DPRINT("bad disk ident status\n"); error(Eio); } memmove(&dp->id, buf, dp->bytes); @@ -798,7 +800,7 @@ hardintr(Ureg *ur) loop = 0; while((cp->status = inb(cp->pbase+Pstatus)) & Sbusy){ if(++loop > 100) { - print("cmd=%lux status=%lux\n", + DPRINT("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: wait busy"); } @@ -817,7 +819,7 @@ hardintr(Ureg *ur) loop = 0; while(((cp->status = inb(cp->pbase+Pstatus)) & Sdrq) == 0) if(++loop > 100) { - print("cmd=%lux status=%lux\n", + DPRINT("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: write"); } @@ -837,7 +839,7 @@ hardintr(Ureg *ur) loop = 0; while((inb(cp->pbase+Pstatus) & Sdrq) == 0) if(++loop > 10000) { - print("cmd=%lux status=%lux\n", + DPRINT("cmd=%lux status=%lux\n", cp->cmd, inb(cp->pbase+Pstatus)); panic("hardintr: read/ident"); } diff --git a/port/devcdrom.c b/port/devcdrom.c new file mode 100644 index 0000000000000000000000000000000000000000..8823055e07f6772a4643fcf597064a775bf755f9 --- /dev/null +++ b/port/devcdrom.c @@ -0,0 +1,236 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" +#include "devtab.h" +#include "io.h" + +/* + * CD-ROM. Gutted version of devwren. + */ + +#define DATASIZE 2048 /* max in a transfer */ + +typedef struct Drive Drive; + +enum { + Ndisk= 8, /* maximum disks */ + /* file types */ + Qdir= 0, + Qdisk= 1, +}; + +struct Drive +{ + QLock; + ulong blocks; /* blocks on disk */ + ulong bsize; /* bytes per block */ + int drive; +}; + +static Drive cdrom[Ndisk]; + +static void cdromsize(int); +static long cdromio(Chan*, char*, ulong, ulong); + +static char Ecap[] = "CD-ROM device capacity unknown"; +static char EnotCD[] = "not a CD-ROM device"; + +/* + * accepts [0-7]. lun is therefore always zero. + */ +static int +cdromdev(char *p) +{ + int drive; + + if(p == 0 || p[0] == '\0') + error(Ebadarg); + if(p[0] < '0' || p[0] > '7' || p[1]) + error(Ebadarg); + drive = p[0] - '0'; + return (drive << 3) | 0; +} + +static int +cdromgen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) +{ + char name[NAMELEN+4]; + Drive *dp; + + USED(tab, ntab); + if(s != 0) + return -1; + sprint(name, "cd%d", c->dev>>3); + dp = &cdrom[c->dev>>3]; + devdir(c, (Qid){Qdisk, 0}, name, dp->blocks*dp->bsize, eve, 0444, dirp); + return 1; +} + +void +cdromreset(void) +{ +} + +void +cdrominit(void) +{ +} + +/* + * param is #R + */ +Chan* +cdromattach(char *param) +{ + Chan *c; + int drive; + + drive = cdromdev(param); + cdromsize(drive); + c = devattach('R', param); + c->dev = drive; + return c; +} + +Chan* +cdromclone(Chan *c, Chan *nc) +{ + return devclone(c, nc); +} + +int +cdromwalk(Chan *c, char *name) +{ + return devwalk(c, name, 0, 0, cdromgen); +} + +void +cdromstat(Chan *c, char *dp) +{ + devstat(c, dp, 0, 0, cdromgen); +} + +Chan* +cdromopen(Chan *c, int omode) +{ + return devopen(c, omode, 0, 0, cdromgen); +} + +void +cdromcreate(Chan *c, char *name, int omode, ulong perm) +{ + USED(c, name, omode, perm); + error(Eperm); +} + +void +cdromclose(Chan *c) +{ + USED(c); +} + +void +cdromremove(Chan *c) +{ + USED(c); + error(Eperm); +} + +void +cdromwstat(Chan *c, char *dp) +{ + USED(c, dp); + error(Eperm); +} + +long +cdromread(Chan *c, char *a, long n, ulong offset) +{ + if(c->qid.path == CHDIR) + return devdirread(c, a, n, 0, 0, cdromgen); + return cdromio(c, a, n, offset); +} + +long +cdromwrite(Chan *c, char *a, long n, ulong offset) +{ + USED(c, a, n, offset); + error(Eperm); + return 0; +} + +static long +cdromio(Chan *c, char *a, ulong len, ulong offset) +{ + Drive *d; + Scsibuf *b; + ulong block, n, max, x; + + d = &cdrom[c->dev>>3]; + + block = offset / d->bsize; + n = (offset + len + d->bsize - 1) / d->bsize - block; + max = DATASIZE / d->bsize; + if(n > max) + n = max; + if(block + n > d->blocks) + n = d->blocks - block; + if(block >= d->blocks || n == 0) + return 0; + b = scsibuf(); + if(waserror()){ + scsifree(b); + nexterror(); + } + offset %= d->bsize; + x = scsibread(d->drive, b, n, d->bsize, block); + if(x < offset) + len = 0; + else if(len > x - offset) + len = x - offset; + memmove(a, (char*)b->virt + offset, len); + poperror(); + scsifree(b); + return len; +} + +/* + * size disk + */ +static void +cdromsize(int dev) +{ + Drive *dp; + uchar buf[128]; + long nb, bs; + + dp = &cdrom[dev>>3]; + if(waserror()){ + qunlock(dp); + nexterror(); + } + qlock(dp); + scsiready(dev); + scsisense(dev, buf); + /* + * capacity not defined on CD-ROM, but most implement it. + */ + if(scsicap(dev, buf)!=0) + error(Ecap); + nb = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3]<<0); + bs = (buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|(buf[7]<<0); + if(nb==0 || bs==0) + error(Ecap); + + scsiinquiry(dev, buf, sizeof buf); + if(buf[0]!=5 || buf[0]!=4) /* CD-ROM or CD-R writer */ + print("warning: scsi device %d type=%d, not type 4 or 5\n", dev>>3, buf[0]); + dp->drive = dev; + dp->blocks = nb; + dp->bsize = bs; + poperror(); + qunlock(dp); +}