M pc/devfloppy.c => pc/devfloppy.c +14 -12
@@ 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);
}
M pc/devhard.c => pc/devhard.c +12 -10
@@ 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");
}
A port/devcdrom.c => port/devcdrom.c +236 -0
@@ 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<target>
+ */
+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);
+}