Annotation of lucent/sys/src/9/port/devcdrom.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.