Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/devcdrom.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## 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

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.