|
|
1.1 ! root 1: #include "u.h" ! 2: #include "../port/lib.h" ! 3: #include "mem.h" ! 4: #include "dat.h" ! 5: #include "fns.h" ! 6: #include "../port/error.h" ! 7: #include "devtab.h" ! 8: #include "io.h" ! 9: ! 10: /* ! 11: * CD-ROM. Gutted version of devwren. ! 12: */ ! 13: ! 14: #define DATASIZE 2048 /* max in a transfer */ ! 15: ! 16: typedef struct Drive Drive; ! 17: ! 18: enum { ! 19: Ndisk= 8, /* maximum disks */ ! 20: /* file types */ ! 21: Qdir= 0, ! 22: Qdisk= 1, ! 23: }; ! 24: ! 25: struct Drive ! 26: { ! 27: QLock; ! 28: ulong blocks; /* blocks on disk */ ! 29: ulong bsize; /* bytes per block */ ! 30: int drive; ! 31: }; ! 32: ! 33: static Drive cdrom[Ndisk]; ! 34: ! 35: static void cdromsize(int); ! 36: static long cdromio(Chan*, char*, ulong, ulong); ! 37: ! 38: static char Ecap[] = "CD-ROM device capacity unknown"; ! 39: static char EnotCD[] = "not a CD-ROM device"; ! 40: ! 41: /* ! 42: * accepts [0-7]. lun is therefore always zero. ! 43: */ ! 44: static int ! 45: cdromdev(char *p) ! 46: { ! 47: int drive; ! 48: ! 49: if(p == 0 || p[0] == '\0') ! 50: error(Ebadarg); ! 51: if(p[0] < '0' || p[0] > '7' || p[1]) ! 52: error(Ebadarg); ! 53: drive = p[0] - '0'; ! 54: return (drive << 3) | 0; ! 55: } ! 56: ! 57: static int ! 58: cdromgen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) ! 59: { ! 60: char name[NAMELEN+4]; ! 61: Drive *dp; ! 62: ! 63: USED(tab, ntab); ! 64: if(s != 0) ! 65: return -1; ! 66: sprint(name, "cd%d", c->dev>>3); ! 67: dp = &cdrom[c->dev>>3]; ! 68: devdir(c, (Qid){Qdisk, 0}, name, dp->blocks*dp->bsize, eve, 0444, dirp); ! 69: return 1; ! 70: } ! 71: ! 72: void ! 73: cdromreset(void) ! 74: { ! 75: } ! 76: ! 77: void ! 78: cdrominit(void) ! 79: { ! 80: } ! 81: ! 82: /* ! 83: * param is #R<target> ! 84: */ ! 85: Chan* ! 86: cdromattach(char *param) ! 87: { ! 88: Chan *c; ! 89: int drive; ! 90: ! 91: drive = cdromdev(param); ! 92: cdromsize(drive); ! 93: c = devattach('R', param); ! 94: c->dev = drive; ! 95: return c; ! 96: } ! 97: ! 98: Chan* ! 99: cdromclone(Chan *c, Chan *nc) ! 100: { ! 101: return devclone(c, nc); ! 102: } ! 103: ! 104: int ! 105: cdromwalk(Chan *c, char *name) ! 106: { ! 107: return devwalk(c, name, 0, 0, cdromgen); ! 108: } ! 109: ! 110: void ! 111: cdromstat(Chan *c, char *dp) ! 112: { ! 113: devstat(c, dp, 0, 0, cdromgen); ! 114: } ! 115: ! 116: Chan* ! 117: cdromopen(Chan *c, int omode) ! 118: { ! 119: return devopen(c, omode, 0, 0, cdromgen); ! 120: } ! 121: ! 122: void ! 123: cdromcreate(Chan *c, char *name, int omode, ulong perm) ! 124: { ! 125: USED(c, name, omode, perm); ! 126: error(Eperm); ! 127: } ! 128: ! 129: void ! 130: cdromclose(Chan *c) ! 131: { ! 132: USED(c); ! 133: } ! 134: ! 135: void ! 136: cdromremove(Chan *c) ! 137: { ! 138: USED(c); ! 139: error(Eperm); ! 140: } ! 141: ! 142: void ! 143: cdromwstat(Chan *c, char *dp) ! 144: { ! 145: USED(c, dp); ! 146: error(Eperm); ! 147: } ! 148: ! 149: long ! 150: cdromread(Chan *c, char *a, long n, ulong offset) ! 151: { ! 152: if(c->qid.path == CHDIR) ! 153: return devdirread(c, a, n, 0, 0, cdromgen); ! 154: return cdromio(c, a, n, offset); ! 155: } ! 156: ! 157: long ! 158: cdromwrite(Chan *c, char *a, long n, ulong offset) ! 159: { ! 160: USED(c, a, n, offset); ! 161: error(Eperm); ! 162: return 0; ! 163: } ! 164: ! 165: static long ! 166: cdromio(Chan *c, char *a, ulong len, ulong offset) ! 167: { ! 168: Drive *d; ! 169: Scsibuf *b; ! 170: ulong block, n, max, x; ! 171: ! 172: d = &cdrom[c->dev>>3]; ! 173: ! 174: block = offset / d->bsize; ! 175: n = (offset + len + d->bsize - 1) / d->bsize - block; ! 176: max = DATASIZE / d->bsize; ! 177: if(n > max) ! 178: n = max; ! 179: if(block + n > d->blocks) ! 180: n = d->blocks - block; ! 181: if(block >= d->blocks || n == 0) ! 182: return 0; ! 183: b = scsibuf(); ! 184: if(waserror()){ ! 185: scsifree(b); ! 186: nexterror(); ! 187: } ! 188: offset %= d->bsize; ! 189: x = scsibread(d->drive, b, n, d->bsize, block); ! 190: if(x < offset) ! 191: len = 0; ! 192: else if(len > x - offset) ! 193: len = x - offset; ! 194: memmove(a, (char*)b->virt + offset, len); ! 195: poperror(); ! 196: scsifree(b); ! 197: return len; ! 198: } ! 199: ! 200: /* ! 201: * size disk ! 202: */ ! 203: static void ! 204: cdromsize(int dev) ! 205: { ! 206: Drive *dp; ! 207: uchar buf[128]; ! 208: long nb, bs; ! 209: ! 210: dp = &cdrom[dev>>3]; ! 211: if(waserror()){ ! 212: qunlock(dp); ! 213: nexterror(); ! 214: } ! 215: qlock(dp); ! 216: scsiready(dev); ! 217: scsisense(dev, buf); ! 218: /* ! 219: * capacity not defined on CD-ROM, but most implement it. ! 220: */ ! 221: if(scsicap(dev, buf)!=0) ! 222: error(Ecap); ! 223: nb = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3]<<0); ! 224: bs = (buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|(buf[7]<<0); ! 225: if(nb==0 || bs==0) ! 226: error(Ecap); ! 227: ! 228: scsiinquiry(dev, buf, sizeof buf); ! 229: dp->drive = dev; ! 230: dp->blocks = nb; ! 231: dp->bsize = bs; ! 232: poperror(); ! 233: qunlock(dp); ! 234: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.