## diffname port/devcdrom.c 1992/0901
## diff -e /dev/null /n/bootesdump/1992/0901/sys/src/9/port/devcdrom.c
0a
#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);
}
.
## diffname port/devcdrom.c 1992/0902
## diff -e /n/bootesdump/1992/0901/sys/src/9/port/devcdrom.c /n/bootesdump/1992/0902/sys/src/9/port/devcdrom.c
229,230d
## diffname port/devcdrom.c 1993/1124 # deleted
## diff -e /n/bootesdump/1992/0902/sys/src/9/port/devcdrom.c /n/fornaxdump/1993/1124/sys/src/brazil/port/devcdrom.c
1,234d
|