plan 9 kernel history: overview | file list | diff list

1992/0711/port/devwren.c (diff list | history)

1991/0110/sys/src/9/port/devwren.c:9,311991/0112/sys/src/9/port/devwren.c:9,47 (short | long)
1991/0110    
 
#include	"scsi.h" 
 
1991/0112    
typedef struct Part	Part; 
typedef struct Disk	Disk; 
 
1991/0110    
enum { 
	Qdir, Qdata, Qstruct, 
}; 
1991/0112    
	Npart=		2,	/* maximum partitions per disk */ 
	Ndisk=		64,	/* maximum disks */ 
1991/0110    
 
static Dirtab wrendir[]={ 
	"data",		{Qdata},	0,	0600, 
	"struct",	{Qstruct},	8,	0400, 
1991/0112    
	Qdir=		0, 
	Qdata=		16, 
	Qstruct=	32, 
 
	Mask=		0x7, 
1991/0110    
}; 
 
#define	NWREN	(sizeof wrendir/sizeof(Dirtab)) 
1991/0112    
static Dirtab *wrendir; 
#define	NWREN	(2*(Npart+1)) 
1991/0110    
 
static long	maxblock[64]; 
static long	blocksize[64]; 
1991/0112    
struct Part 
{ 
	ulong 	firstblock; 
	ulong 	maxblock; 
}; 
struct Disk 
{ 
	ulong	blocksize; 
	Part	p[Npart]; 
}; 
1991/0110    
 
static Scsi	staticcmd;		/* BUG */ 
static uchar	datablk[4*512];		/* BUG */ 
1991/0112    
static Disk	wren[Ndisk]; 
1991/0110    
 
1991/0112    
static Scsi	staticcmd;			/* BUG */ 
static uchar	datablk[2*4*512];		/* BUG */ 
 
1991/0110    
/* 
 *  accepts [0-7].[0-7], or abbreviation 
 */ 
1991/0110/sys/src/9/port/devwren.c:50,551991/0112/sys/src/9/port/devwren.c:66,73
1991/0110    
	if (p[3]!=0) 
		goto cant; 
out: 
1991/0112    
	if(dev >= Ndisk) 
		error(Ebadarg); 
1991/0110    
	return dev; 
cant: 
	error(Ebadarg); 
1991/0110/sys/src/9/port/devwren.c:59,711991/0112/sys/src/9/port/devwren.c:77,97
1991/0110    
wrengen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp) 
{ 
	long l; 
	if(tab==0 || s>=ntab) 
1991/0112    
	Part *p; 
	Disk *d; 
 
	if(s >= ntab) 
1991/0110    
		return -1; 
	tab+=s; 
	if (tab->qid.path==Qdata && 0<=c->dev && c->dev<64) 
		l = maxblock[c->dev]*blocksize[c->dev]; 
1991/0112    
	if(c->dev >= Ndisk) 
		return -1; 
 
	tab += s; 
	d = &wren[c->dev]; 
	p = &d->p[tab->qid.path&Mask]; 
	if((tab->qid.path&~Mask) == Qdata) 
		l = d->blocksize * (p->maxblock - p->firstblock); 
1991/0110    
	else 
		l = tab->length; 
1991/0112    
		l = 8; 
1991/0110    
	devdir(c, tab->qid, tab->name, l, tab->perm, dp); 
	return 1; 
} 
1991/0110/sys/src/9/port/devwren.c:72,791991/0112/sys/src/9/port/devwren.c:98,128
1991/0110    
 
void 
wrenreset(void) 
{} 
1991/0112    
{ 
	Dirtab *p; 
	int i; 
1991/0110    
 
1991/0112    
	p = wrendir = ialloc((Npart+1) * 2 * sizeof(Dirtab), 0); 
	for(i = 0; i < Npart; i++){ 
		sprint(p->name, "data%d", i); 
		p->qid.path = Qdata + i; 
		p->perm = 0600; 
		p++->length = 0; 
		strcpy(p->name, "struct%d"); 
		p->qid.path = Qstruct + i; 
		p->perm = 0600; 
		p++->length = 0; 
	} 
	strcpy(p->name, "data"); 
	p->qid.path = Qdata + Npart; 
	p->perm = 0600; 
	p++->length = 0; 
	strcpy(p->name, "struct"); 
	p->qid.path = Qstruct + Npart; 
	p->perm = 0600; 
	p->length = 0; 
} 
 
1991/0110    
void 
wreninit(void) 
{ 
1991/0110/sys/src/9/port/devwren.c:91,961991/0112/sys/src/9/port/devwren.c:140,149
1991/0110    
	uchar buf[32]; 
	int dev; 
	Chan *c; 
1991/0112    
	Disk *d; 
	ulong plen; 
	int i; 
 
1991/0110    
	dev = wrendev(param); 
	scsiready(dev); 
	scsisense(dev, buf); 
1991/0110/sys/src/9/port/devwren.c:97,1041991/0112/sys/src/9/port/devwren.c:150,165
1991/0110    
	scsicap(dev, buf); 
	c = devattach('r', param); 
	c->dev = dev; 
	maxblock[dev] = BGLONG(&buf[0]); 
	blocksize[dev] = BGLONG(&buf[4]); 
1991/0112    
	d = &wren[dev]; 
	d->blocksize = BGLONG(&buf[4]); 
	plen = BGLONG(&buf[0]); 
	d->p[Npart].firstblock = 0; 
	d->p[Npart].maxblock = plen; 
	plen = plen/Npart; 
	for(i = 0; i < Npart; i++){ 
		d->p[i].firstblock = i*plen; 
		d->p[i].maxblock = (i+1)*plen; 
	} 
1991/0110    
	return c; 
} 
 
1991/0110/sys/src/9/port/devwren.c:145,1601991/0112/sys/src/9/port/devwren.c:206,228
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	unsigned long lbn; 
1991/0112    
	Part *p; 
	Disk *d; 
 
1991/0110    
	if (n == 0) 
		return 0; 
	switch ((int)(c->qid.path & ~CHDIR)) { 
	case Qdir: 
1991/0112    
 
	if(c->qid.path == CHDIR) 
1991/0110    
		return devdirread(c, a, n, wrendir, NWREN, wrengen); 
1991/0112    
 
	d = &wren[c->dev]; 
	p = &(d->p[Mask&c->qid.path]); 
	switch ((int)(c->qid.path & ~Mask)) { 
1991/0110    
	case Qdata: 
		if (n % blocksize[c->dev] || c->offset % blocksize[c->dev]) 
1991/0112    
		if (n % d->blocksize || c->offset % d->blocksize) 
1991/0110    
			error(Ebadarg); 
		lbn = c->offset/blocksize[c->dev]; 
		if (lbn >= maxblock[c->dev]) 
1991/0112    
		lbn = (c->offset/d->blocksize) + p->firstblock; 
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
		if (n > sizeof datablk) 
			n = sizeof datablk; 
1991/0110/sys/src/9/port/devwren.c:170,1761991/0112/sys/src/9/port/devwren.c:238,244
1991/0110    
		cmd->cmdblk[1] = lbn>>16; 
		cmd->cmdblk[2] = lbn>>8; 
		cmd->cmdblk[3] = lbn; 
		cmd->cmdblk[4] = n/blocksize[c->dev]; 
1991/0112    
		cmd->cmdblk[4] = n/d->blocksize; 
1991/0110    
		cmd->cmdblk[5] = 0x00; 
		cmd->cmd.lim = &cmd->cmdblk[6]; 
		cmd->data.lim = cmd->data.base + n; 
1991/0110/sys/src/9/port/devwren.c:187,1941991/0112/sys/src/9/port/devwren.c:255,262
1991/0110    
		if (c->offset >= 8) 
			return 0; 
		n = 8; 
		PLONG((uchar *)&a[0], maxblock[c->dev]); 
		PLONG((uchar *)&a[4], blocksize[c->dev]); 
1991/0112    
		PLONG((uchar *)&a[0], p->maxblock - p->firstblock); 
		PLONG((uchar *)&a[4], d->blocksize); 
1991/0110    
		break; 
	default: 
		panic("wrenread"); 
1991/0110/sys/src/9/port/devwren.c:201,2141991/0112/sys/src/9/port/devwren.c:269,288
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	unsigned long lbn; 
1991/0112    
	Part *p; 
	Disk *d; 
 
1991/0110    
	if (n == 0) 
		return 0; 
	switch ((int)(c->qid.path & ~CHDIR)) { 
1991/0112    
 
	d = &wren[c->dev]; 
	p = &(d->p[Mask&c->qid.path]); 
	switch ((int)(c->qid.path & ~Mask)) { 
1991/0110    
	case Qdata: 
		if (n % blocksize[c->dev] || c->offset % blocksize[c->dev]) 
1991/0112    
		if (n % d->blocksize || c->offset % d->blocksize) 
1991/0110    
			error(Ebadarg); 
		lbn = c->offset/blocksize[c->dev]; 
		if (lbn >= maxblock[c->dev]) 
1991/0112    
		lbn = c->offset/d->blocksize + p->firstblock; 
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
		if (n > sizeof datablk) 
			n = sizeof datablk; 
1991/0110/sys/src/9/port/devwren.c:224,2301991/0112/sys/src/9/port/devwren.c:298,304
1991/0110    
		cmd->cmdblk[1] = lbn>>16; 
		cmd->cmdblk[2] = lbn>>8; 
		cmd->cmdblk[3] = lbn; 
		cmd->cmdblk[4] = n/blocksize[c->dev]; 
1991/0112    
		cmd->cmdblk[4] = n/d->blocksize; 
1991/0110    
		cmd->cmdblk[5] = 0x00; 
		cmd->cmd.lim = &cmd->cmdblk[6]; 
		cmd->data.lim = cmd->data.base + n; 
1991/0112/sys/src/9/port/devwren.c:7,141991/0115/sys/src/9/port/devwren.c:7,12 (short | long)
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
#include	"scsi.h" 
                 
1991/0112    
typedef struct Part	Part; 
typedef struct Disk	Disk; 
 
1991/0112/sys/src/9/port/devwren.c:39,471991/0115/sys/src/9/port/devwren.c:37,47
1991/0110    
 
1991/0112    
static Disk	wren[Ndisk]; 
1991/0110    
 
1991/0112    
static Scsi	staticcmd;			/* BUG */ 
static uchar	datablk[2*4*512];		/* BUG */ 
1991/0115    
static Scsi	staticcmd;		/* BUG */ 
static uchar	datablk[BY2PG];		/* BUG */ 
1991/0112    
 
1991/0115    
#define	BGLONG(p)	(((((((p)[0]<<8)|(p)[1])<<8)|(p)[2])<<8)|(p)[3]) 
 
1991/0110    
/* 
 *  accepts [0-7].[0-7], or abbreviation 
 */ 
1991/0112/sys/src/9/port/devwren.c:108,1141991/0115/sys/src/9/port/devwren.c:108,114
1991/0112    
		p->qid.path = Qdata + i; 
		p->perm = 0600; 
		p++->length = 0; 
		strcpy(p->name, "struct%d"); 
1991/0115    
		sprint(p->name, "struct%d", i); 
1991/0112    
		p->qid.path = Qstruct + i; 
		p->perm = 0600; 
		p++->length = 0; 
1991/0115/sys/src/9/port/devwren.c:246,2521991/0318/sys/src/9/port/devwren.c:246,252 (short | long)
1991/0110    
		cmd->save = cmd->data.base; 
		scsiexec(cmd, 1); 
		n = cmd->data.ptr - cmd->data.base; 
		memcpy(a, cmd->data.base, n); 
1991/0318    
		memmove(a, cmd->data.base, n); 
1991/0110    
		qunlock(cmd); 
		break; 
	case Qstruct: 
1991/0115/sys/src/9/port/devwren.c:304,3101991/0318/sys/src/9/port/devwren.c:304,310
1991/0110    
		cmd->data.lim = cmd->data.base + n; 
		cmd->data.ptr = cmd->data.base; 
		cmd->save = cmd->data.base; 
		memcpy(cmd->data.base, a, n); 
1991/0318    
		memmove(cmd->data.base, a, n); 
1991/0110    
		scsiexec(cmd, 0); 
		n = cmd->data.ptr - cmd->data.base; 
		qunlock(cmd); 
1991/0318/sys/src/9/port/devwren.c:202,2081991/0411/sys/src/9/port/devwren.c:202,208 (short | long)
1991/0110    
#define	PSHORT(p, v)		((p)[0]=(v), (p)[1]=((v)>>8)) 
#define	PLONG(p, v)		(PSHORT(p, (v)), PSHORT(p+2, (v)>>16)) 
long 
wrenread(Chan *c, char *a, long n) 
1991/0411    
wrenread(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	unsigned long lbn; 
1991/0318/sys/src/9/port/devwren.c:219,2271991/0411/sys/src/9/port/devwren.c:219,227
1991/0112    
	p = &(d->p[Mask&c->qid.path]); 
	switch ((int)(c->qid.path & ~Mask)) { 
1991/0110    
	case Qdata: 
1991/0112    
		if (n % d->blocksize || c->offset % d->blocksize) 
1991/0411    
		if (n % d->blocksize || offset % d->blocksize) 
1991/0110    
			error(Ebadarg); 
1991/0112    
		lbn = (c->offset/d->blocksize) + p->firstblock; 
1991/0411    
		lbn = (offset/d->blocksize) + p->firstblock; 
1991/0112    
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
		if (n > sizeof datablk) 
1991/0318/sys/src/9/port/devwren.c:252,2581991/0411/sys/src/9/port/devwren.c:252,258
1991/0110    
	case Qstruct: 
		if (n < 8) 
			error(Ebadarg); 
		if (c->offset >= 8) 
1991/0411    
		if (offset >= 8) 
1991/0110    
			return 0; 
		n = 8; 
1991/0112    
		PLONG((uchar *)&a[0], p->maxblock - p->firstblock); 
1991/0318/sys/src/9/port/devwren.c:265,2711991/0411/sys/src/9/port/devwren.c:265,271
1991/0110    
} 
 
long 
wrenwrite(Chan *c, char *a, long n) 
1991/0411    
wrenwrite(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	unsigned long lbn; 
1991/0318/sys/src/9/port/devwren.c:279,2871991/0411/sys/src/9/port/devwren.c:279,287
1991/0112    
	p = &(d->p[Mask&c->qid.path]); 
	switch ((int)(c->qid.path & ~Mask)) { 
1991/0110    
	case Qdata: 
1991/0112    
		if (n % d->blocksize || c->offset % d->blocksize) 
1991/0411    
		if (n % d->blocksize || offset % d->blocksize) 
1991/0110    
			error(Ebadarg); 
1991/0112    
		lbn = c->offset/d->blocksize + p->firstblock; 
1991/0411    
		lbn = offset/d->blocksize + p->firstblock; 
1991/0112    
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
		if (n > sizeof datablk) 
1991/0411/sys/src/9/port/devwren.c:175,1801991/0419/sys/src/9/port/devwren.c:175,186 (short | long)
1991/0110    
	return devwalk(c, name, wrendir, NWREN, wrengen); 
} 
 
1991/0419    
Chan* 
wrenclwalk(Chan *c, char *name) 
{ 
	return devclwalk(c, name); 
} 
 
1991/0110    
void 
wrenstat(Chan *c, char *db) 
{ 
1991/0419/sys/src/9/port/devwren.c:37,441991/0423/sys/src/9/port/devwren.c:37,43 (short | long)
Created.
rsc Fri Mar 4 12:44:25 2005
1991/0110    
 
1991/0112    
static Disk	wren[Ndisk]; 
1991/0110    
 
1991/0115    
static Scsi	staticcmd;		/* BUG */ 
static uchar	datablk[BY2PG];		/* BUG */ 
1991/0423    
#define	DATASIZE	(8*1024)	/* BUG */ 
1991/0112    
 
1991/0115    
#define	BGLONG(p)	(((((((p)[0]<<8)|(p)[1])<<8)|(p)[2])<<8)|(p)[3]) 
 
1991/0419/sys/src/9/port/devwren.c:125,1351991/0423/sys/src/9/port/devwren.c:124,130
1991/0112    
 
1991/0110    
void 
wreninit(void) 
{ 
	Scsi *cmd = &staticcmd; 
	cmd->cmd.base = cmd->cmdblk; 
	cmd->data.base = datablk; 
} 
1991/0423    
{} 
1991/0110    
 
/* 
 *  param is #r<target>.<lun> 
1991/0419/sys/src/9/port/devwren.c:210,2171991/0423/sys/src/9/port/devwren.c:205,212
1991/0110    
long 
1991/0411    
wrenread(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	unsigned long lbn; 
1991/0423    
	Scsi *cmd; 
	ulong lbn; 
1991/0112    
	Part *p; 
	Disk *d; 
 
1991/0419/sys/src/9/port/devwren.c:230,2551991/0423/sys/src/9/port/devwren.c:225,241
1991/0411    
		lbn = (offset/d->blocksize) + p->firstblock; 
1991/0112    
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
		if (n > sizeof datablk) 
			n = sizeof datablk; 
		qlock(cmd); 
1991/0423    
		if (n > DATASIZE) 
			n = DATASIZE; 
		cmd = scsicmd(c->dev, 0x08, n); 
1991/0110    
		if (waserror()) { 
			qunlock(cmd); 
			nexterror(); 
		} 
		cmd->target = c->dev>>3; 
		cmd->lun = c->dev&7; 
		cmd->cmd.ptr = cmd->cmd.base; 
		cmd->cmdblk[0] = 0x08; 
		cmd->cmdblk[1] = lbn>>16; 
		cmd->cmdblk[2] = lbn>>8; 
		cmd->cmdblk[3] = lbn; 
1991/0112    
		cmd->cmdblk[4] = n/d->blocksize; 
1991/0110    
		cmd->cmdblk[5] = 0x00; 
		cmd->cmd.lim = &cmd->cmdblk[6]; 
		cmd->data.lim = cmd->data.base + n; 
		cmd->data.ptr = cmd->data.base; 
		cmd->save = cmd->data.base; 
		scsiexec(cmd, 1); 
		n = cmd->data.ptr - cmd->data.base; 
1991/0318    
		memmove(a, cmd->data.base, n); 
1991/0419/sys/src/9/port/devwren.c:273,2801991/0423/sys/src/9/port/devwren.c:259,266
1991/0110    
long 
1991/0411    
wrenwrite(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
	Scsi *cmd = &staticcmd; 
	unsigned long lbn; 
1991/0423    
	Scsi *cmd; 
	ulong lbn; 
1991/0112    
	Part *p; 
	Disk *d; 
 
1991/0419/sys/src/9/port/devwren.c:290,3151991/0423/sys/src/9/port/devwren.c:276,292
1991/0411    
		lbn = offset/d->blocksize + p->firstblock; 
1991/0112    
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
		if (n > sizeof datablk) 
			n = sizeof datablk; 
		qlock(cmd); 
1991/0423    
		if (n > DATASIZE) 
			n = DATASIZE; 
		cmd = scsicmd(c->dev, 0x0a, n); 
1991/0110    
		if (waserror()) { 
			qunlock(cmd); 
			nexterror(); 
		} 
		cmd->target = c->dev>>3; 
		cmd->lun = c->dev&7; 
		cmd->cmd.ptr = cmd->cmd.base; 
		cmd->cmdblk[0] = 0x0a; 
		cmd->cmdblk[1] = lbn>>16; 
		cmd->cmdblk[2] = lbn>>8; 
		cmd->cmdblk[3] = lbn; 
1991/0112    
		cmd->cmdblk[4] = n/d->blocksize; 
1991/0110    
		cmd->cmdblk[5] = 0x00; 
		cmd->cmd.lim = &cmd->cmdblk[6]; 
		cmd->data.lim = cmd->data.base + n; 
		cmd->data.ptr = cmd->data.base; 
		cmd->save = cmd->data.base; 
1991/0318    
		memmove(cmd->data.base, a, n); 
1991/0110    
		scsiexec(cmd, 0); 
		n = cmd->data.ptr - cmd->data.base; 
1991/0423/sys/src/9/port/devwren.c:170,1811991/0427/sys/src/9/port/devwren.c:170,175 (short | long)
1991/0110    
	return devwalk(c, name, wrendir, NWREN, wrengen); 
} 
 
1991/0419    
Chan* 
wrenclwalk(Chan *c, char *name) 
{ 
	return devclwalk(c, name); 
} 
                 
1991/0110    
void 
wrenstat(Chan *c, char *db) 
{ 
1991/0427/sys/src/9/port/devwren.c:147,1521991/0429/sys/src/9/port/devwren.c:147,155 (short | long)
1991/0110    
	c->dev = dev; 
1991/0112    
	d = &wren[dev]; 
	d->blocksize = BGLONG(&buf[4]); 
1991/0429    
 
print("Block size %lux capacity %lux\n", d->blocksize, BGLONG(&buf[0])); 
 
1991/0112    
	plen = BGLONG(&buf[0]); 
	d->p[Npart].firstblock = 0; 
	d->p[Npart].maxblock = plen; 
1991/0429/sys/src/9/port/devwren.c:148,1551991/0530/sys/src/9/port/devwren.c:148,153 (short | long)
1991/0112    
	d = &wren[dev]; 
	d->blocksize = BGLONG(&buf[4]); 
1991/0429    
 
print("Block size %lux capacity %lux\n", d->blocksize, BGLONG(&buf[0])); 
                 
1991/0112    
	plen = BGLONG(&buf[0]); 
	d->p[Npart].firstblock = 0; 
	d->p[Npart].maxblock = plen; 
1991/0530/sys/src/9/port/devwren.c:37,421991/0603/sys/src/9/port/devwren.c:37,44 (short | long)
1991/0110    
 
1991/0112    
static Disk	wren[Ndisk]; 
1991/0110    
 
1991/0603    
void	wrenint(uchar*, ulong); 
 
1991/0423    
#define	DATASIZE	(8*1024)	/* BUG */ 
1991/0112    
 
1991/0115    
#define	BGLONG(p)	(((((((p)[0]<<8)|(p)[1])<<8)|(p)[2])<<8)|(p)[3]) 
1991/0530/sys/src/9/port/devwren.c:195,2021991/0603/sys/src/9/port/devwren.c:197,202
1991/0110    
wrenclose(Chan *c) 
{} 
 
#define	PSHORT(p, v)		((p)[0]=(v), (p)[1]=((v)>>8)) 
#define	PLONG(p, v)		(PSHORT(p, (v)), PSHORT(p+2, (v)>>16)) 
long 
1991/0411    
wrenread(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
1991/0530/sys/src/9/port/devwren.c:237,2491991/0603/sys/src/9/port/devwren.c:237,249
1991/0110    
		qunlock(cmd); 
		break; 
	case Qstruct: 
		if (n < 8) 
1991/0603    
		if (n < 2*sizeof(ulong)) 
1991/0110    
			error(Ebadarg); 
1991/0411    
		if (offset >= 8) 
1991/0603    
		if (offset >= 2*sizeof(ulong)) 
1991/0110    
			return 0; 
		n = 8; 
1991/0112    
		PLONG((uchar *)&a[0], p->maxblock - p->firstblock); 
		PLONG((uchar *)&a[4], d->blocksize); 
1991/0603    
		n = 2*sizeof(ulong); 
		wrenint((uchar*)a, p->maxblock - p->firstblock); 
		wrenint((uchar*)a+sizeof(ulong), d->blocksize); 
1991/0110    
		break; 
	default: 
		panic("wrenread"); 
1991/0530/sys/src/9/port/devwren.c:303,3061991/0603/sys/src/9/port/devwren.c:303,315
1991/0110    
wrenwstat(Chan *c, char *dp) 
{ 
	error(Eperm); 
1991/0603    
} 
 
void 
wrenint(uchar *a, ulong x) 
{ 
	a[0] = x >> 24; 
	a[1] = x >> 16; 
	a[2] = x >> 8; 
	a[3] = x; 
1991/0110    
} 
1991/0603/sys/src/9/port/devwren.c:235,2401991/0604/sys/src/9/port/devwren.c:235,241 (short | long)
1991/0110    
		n = cmd->data.ptr - cmd->data.base; 
1991/0318    
		memmove(a, cmd->data.base, n); 
1991/0110    
		qunlock(cmd); 
1991/0604    
		poperror(); 
1991/0110    
		break; 
	case Qstruct: 
1991/0603    
		if (n < 2*sizeof(ulong)) 
1991/0603/sys/src/9/port/devwren.c:286,2911991/0604/sys/src/9/port/devwren.c:287,293
1991/0110    
		scsiexec(cmd, 0); 
		n = cmd->data.ptr - cmd->data.base; 
		qunlock(cmd); 
1991/0604    
		poperror(); 
1991/0110    
		break; 
	default: 
		panic("wrenwrite"); 
1991/0604/sys/src/9/port/devwren.c:150,1561991/0615/sys/src/9/port/devwren.c:150,156 (short | long)
1991/0112    
	d = &wren[dev]; 
	d->blocksize = BGLONG(&buf[4]); 
1991/0429    
 
1991/0112    
	plen = BGLONG(&buf[0]); 
1991/0615    
	plen = BGLONG(&buf[0])+1; 
1991/0112    
	d->p[Npart].firstblock = 0; 
	d->p[Npart].maxblock = plen; 
	plen = plen/Npart; 
1991/0615/sys/src/9/port/devwren.c:150,1561991/0705/sys/src/9/port/devwren.c:150,156 (short | long)
1991/0112    
	d = &wren[dev]; 
	d->blocksize = BGLONG(&buf[4]); 
1991/0429    
 
1991/0615    
	plen = BGLONG(&buf[0])+1; 
1991/0705    
	plen = BGLONG(&buf[0]); 
1991/0112    
	d->p[Npart].firstblock = 0; 
	d->p[Npart].maxblock = plen; 
	plen = plen/Npart; 
1991/0705/sys/src/9/port/devwren.c:150,1561991/0706/sys/src/9/port/devwren.c:150,156 (short | long)
1991/0112    
	d = &wren[dev]; 
	d->blocksize = BGLONG(&buf[4]); 
1991/0429    
 
1991/0705    
	plen = BGLONG(&buf[0]); 
1991/0706    
	plen = BGLONG(&buf[0])+1; 
1991/0112    
	d->p[Npart].firstblock = 0; 
	d->p[Npart].maxblock = plen; 
	plen = plen/Npart; 
1991/0706/sys/src/9/port/devwren.c:7,471991/0823/sys/src/9/port/devwren.c:7,47 (short | long)
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
1991/0112    
typedef struct Part	Part; 
typedef struct Disk	Disk; 
1991/0823    
typedef struct Partition	Partition; 
typedef struct Drive		Drive; 
1991/0112    
 
1991/0110    
enum { 
1991/0112    
	Npart=		2,	/* maximum partitions per disk */ 
1991/0823    
	Npart=		8+2,	/* 8 sub partitions, disk, and partition */ 
1991/0112    
	Ndisk=		64,	/* maximum disks */ 
1991/0110    
 
1991/0823    
	/* file types */ 
1991/0112    
	Qdir=		0, 
	Qdata=		16, 
	Qstruct=	32, 
                 
	Mask=		0x7, 
1991/0110    
}; 
1991/0823    
#define PART(x)		((x)&0xF) 
#define DRIVE(x)	(((x)>>4)&0x7) 
#define MKQID(d,p)	(((d)<<4) | (p)) 
1991/0110    
 
1991/0112    
static Dirtab *wrendir; 
#define	NWREN	(2*(Npart+1)) 
1991/0110    
                 
1991/0112    
struct Part 
1991/0823    
struct Partition 
1991/0112    
{ 
	ulong 	firstblock; 
	ulong 	maxblock; 
1991/0823    
	ulong	start; 
	ulong	end; 
	char	name[NAMELEN+1]; 
1991/0112    
}; 
struct Disk 
1991/0823    
 
struct Drive 
1991/0112    
{ 
	ulong	blocksize; 
	Part	p[Npart]; 
1991/0823    
	ulong		bytes;			/* bytes per block */ 
	int		npart;			/* actual number of partitions */ 
	int		drive; 
	Partition	p[Npart]; 
1991/0112    
}; 
1991/0110    
 
1991/0112    
static Disk	wren[Ndisk]; 
1991/0823    
static Drive	wren[Ndisk]; 
1991/0110    
 
1991/0603    
void	wrenint(uchar*, ulong); 
                 
1991/0423    
#define	DATASIZE	(8*1024)	/* BUG */ 
1991/0112    
 
1991/0115    
#define	BGLONG(p)	(((((((p)[0]<<8)|(p)[1])<<8)|(p)[2])<<8)|(p)[3]) 
1991/0823    
static void	wrenpart(int); 
static long	wrenio(Drive *, Partition *, int, char *, ulong, ulong); 
1991/0115    
 
1991/0110    
/* 
 *  accepts [0-7].[0-7], or abbreviation 
1991/0706/sys/src/9/port/devwren.c:50,701991/0823/sys/src/9/port/devwren.c:50,71
1991/0110    
wrendev(char *p) 
{ 
	int dev = 0; 
	if (p==0 || p[0]==0) 
1991/0823    
 
	if(p == 0 || p[0] == 0) 
1991/0110    
		goto out; 
	if (p[0]<'0' || p[0]>'7') 
1991/0823    
	if(p[0] < '0' || p[0] > '7') 
1991/0110    
		goto cant; 
	dev = (p[0]-'0')<<3; 
	if (p[1]==0) 
1991/0823    
	dev = (p[0] - '0') << 3; 
	if(p[1] == 0) 
1991/0110    
		goto out; 
	if (p[1]!='.') 
1991/0823    
	if(p[1] != '.') 
1991/0110    
		goto cant; 
	if (p[2]==0) 
1991/0823    
	if(p[2] == 0) 
1991/0110    
		goto out; 
	if (p[2]<'0' || p[2]>'7') 
1991/0823    
	if(p[2] < '0' || p[2] > '7') 
1991/0110    
		goto cant; 
	dev |= p[2]-'0'; 
	if (p[3]!=0) 
1991/0823    
	dev |= p[2] - '0'; 
	if(p[3] != 0) 
1991/0110    
		goto cant; 
out: 
1991/0112    
	if(dev >= Ndisk) 
1991/0706/sys/src/9/port/devwren.c:75,991991/0823/sys/src/9/port/devwren.c:76,106
1991/0110    
} 
 
static int 
wrengen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp) 
1991/0823    
wrengen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) 
1991/0110    
{ 
	long l; 
1991/0112    
	Part *p; 
	Disk *d; 
1991/0823    
	Qid qid; 
	int drive; 
	char name[NAMELEN+4]; 
	Drive *dp; 
	Partition *pp; 
	ulong l; 
1991/0112    
 
	if(s >= ntab) 
1991/0823    
	qid.vers = 0; 
	drive = s/Npart; 
	s = s % Npart; 
	if(drive >= Ndisk) 
1991/0110    
		return -1; 
1991/0112    
	if(c->dev >= Ndisk) 
		return -1; 
1991/0823    
	dp = &wren[drive]; 
1991/0112    
 
	tab += s; 
	d = &wren[c->dev]; 
	p = &d->p[tab->qid.path&Mask]; 
	if((tab->qid.path&~Mask) == Qdata) 
		l = d->blocksize * (p->maxblock - p->firstblock); 
1991/0110    
	else 
1991/0112    
		l = 8; 
1991/0110    
	devdir(c, tab->qid, tab->name, l, tab->perm, dp); 
1991/0823    
	if(s >= dp->npart) 
		return 0; 
 
	pp = &dp->p[s]; 
	sprint(name, "hd%d%s", drive, pp->name); 
	name[NAMELEN] = 0; 
	qid.path = MKQID(drive, s); 
	l = (pp->end - pp->start) * dp->bytes; 
	devdir(c, qid, name, l, 0600, dirp); 
1991/0110    
	return 1; 
} 
 
1991/0706/sys/src/9/port/devwren.c:100,1321991/0823/sys/src/9/port/devwren.c:107,118
1991/0110    
void 
wrenreset(void) 
1991/0112    
{ 
	Dirtab *p; 
	int i; 
1991/0110    
                 
1991/0112    
	p = wrendir = ialloc((Npart+1) * 2 * sizeof(Dirtab), 0); 
	for(i = 0; i < Npart; i++){ 
		sprint(p->name, "data%d", i); 
		p->qid.path = Qdata + i; 
		p->perm = 0600; 
		p++->length = 0; 
1991/0115    
		sprint(p->name, "struct%d", i); 
1991/0112    
		p->qid.path = Qstruct + i; 
		p->perm = 0600; 
		p++->length = 0; 
	} 
	strcpy(p->name, "data"); 
	p->qid.path = Qdata + Npart; 
	p->perm = 0600; 
	p++->length = 0; 
	strcpy(p->name, "struct"); 
	p->qid.path = Qstruct + Npart; 
	p->perm = 0600; 
	p->length = 0; 
} 
 
1991/0110    
void 
wreninit(void) 
1991/0423    
{} 
1991/0823    
{ 
} 
1991/0110    
 
/* 
 *  param is #r<target>.<lun> 
1991/0706/sys/src/9/port/devwren.c:134,1671991/0823/sys/src/9/port/devwren.c:120,136
1991/0110    
Chan * 
wrenattach(char *param) 
{ 
	uchar buf[32]; 
	int dev; 
	Chan *c; 
1991/0112    
	Disk *d; 
	ulong plen; 
	int i; 
1991/0823    
	int drive; 
1991/0112    
 
1991/0110    
	dev = wrendev(param); 
	scsiready(dev); 
	scsisense(dev, buf); 
	scsicap(dev, buf); 
1991/0823    
	drive = wrendev(param); 
	wrenpart(drive); 
1991/0110    
	c = devattach('r', param); 
	c->dev = dev; 
1991/0112    
	d = &wren[dev]; 
	d->blocksize = BGLONG(&buf[4]); 
1991/0429    
                 
1991/0706    
	plen = BGLONG(&buf[0])+1; 
1991/0112    
	d->p[Npart].firstblock = 0; 
	d->p[Npart].maxblock = plen; 
	plen = plen/Npart; 
	for(i = 0; i < Npart; i++){ 
		d->p[i].firstblock = i*plen; 
		d->p[i].maxblock = (i+1)*plen; 
	} 
1991/0823    
	c->dev = drive; 
1991/0110    
	return c; 
} 
 
Chan * 
1991/0823    
Chan* 
1991/0110    
wrenclone(Chan *c, Chan *nc) 
{ 
	return devclone(c, nc); 
1991/0706/sys/src/9/port/devwren.c:170,1901991/0823/sys/src/9/port/devwren.c:139,157
1991/0110    
int 
wrenwalk(Chan *c, char *name) 
{ 
	return devwalk(c, name, wrendir, NWREN, wrengen); 
1991/0823    
	return devwalk(c, name, 0, 0, wrengen); 
1991/0110    
} 
 
void 
wrenstat(Chan *c, char *db) 
1991/0823    
wrenstat(Chan *c, char *dp) 
1991/0110    
{ 
	devstat(c, db, wrendir, NWREN, wrengen); 
1991/0823    
	devstat(c, dp, 0, 0, wrengen); 
1991/0110    
} 
 
Chan * 
1991/0823    
Chan* 
1991/0110    
wrenopen(Chan *c, int omode) 
{ 
	if (c->qid.path == Qdata && scsiready(c->dev) != 0) 
		error(Eio); 
	return devopen(c, omode, wrendir, NWREN, wrengen); 
1991/0823    
	return devopen(c, omode, 0, 0, wrengen); 
1991/0110    
} 
 
void 
1991/0706/sys/src/9/port/devwren.c:195,3171991/0823/sys/src/9/port/devwren.c:162,325
1991/0110    
 
void 
wrenclose(Chan *c) 
{} 
1991/0823    
{ 
} 
1991/0110    
 
1991/0823    
void 
wrenremove(Chan *c) 
{ 
	error(Eperm); 
} 
 
void 
wrenwstat(Chan *c, char *dp) 
{ 
	error(Eperm); 
} 
 
1991/0110    
long 
1991/0411    
wrenread(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
1991/0423    
	Scsi *cmd; 
	ulong lbn; 
1991/0112    
	Part *p; 
	Disk *d; 
1991/0823    
	Drive *d; 
	Partition *p; 
1991/0112    
 
1991/0110    
	if (n == 0) 
		return 0; 
1991/0112    
 
	if(c->qid.path == CHDIR) 
1991/0110    
		return devdirread(c, a, n, wrendir, NWREN, wrengen); 
1991/0823    
		return devdirread(c, a, n, 0, 0, wrengen); 
1991/0112    
 
	d = &wren[c->dev]; 
	p = &(d->p[Mask&c->qid.path]); 
	switch ((int)(c->qid.path & ~Mask)) { 
1991/0110    
	case Qdata: 
1991/0411    
		if (n % d->blocksize || offset % d->blocksize) 
1991/0110    
			error(Ebadarg); 
1991/0411    
		lbn = (offset/d->blocksize) + p->firstblock; 
1991/0112    
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
1991/0423    
		if (n > DATASIZE) 
			n = DATASIZE; 
		cmd = scsicmd(c->dev, 0x08, n); 
1991/0110    
		if (waserror()) { 
			qunlock(cmd); 
			nexterror(); 
		} 
		cmd->cmdblk[1] = lbn>>16; 
		cmd->cmdblk[2] = lbn>>8; 
		cmd->cmdblk[3] = lbn; 
1991/0112    
		cmd->cmdblk[4] = n/d->blocksize; 
1991/0110    
		scsiexec(cmd, 1); 
		n = cmd->data.ptr - cmd->data.base; 
1991/0318    
		memmove(a, cmd->data.base, n); 
1991/0110    
		qunlock(cmd); 
1991/0604    
		poperror(); 
1991/0110    
		break; 
	case Qstruct: 
1991/0603    
		if (n < 2*sizeof(ulong)) 
1991/0110    
			error(Ebadarg); 
1991/0603    
		if (offset >= 2*sizeof(ulong)) 
1991/0110    
			return 0; 
1991/0603    
		n = 2*sizeof(ulong); 
		wrenint((uchar*)a, p->maxblock - p->firstblock); 
		wrenint((uchar*)a+sizeof(ulong), d->blocksize); 
1991/0110    
		break; 
	default: 
		panic("wrenread"); 
	} 
	return n; 
1991/0823    
	d = &wren[DRIVE(c->qid.path)]; 
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 0, a, n, offset); 
1991/0110    
} 
 
long 
1991/0411    
wrenwrite(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
1991/0823    
	Drive *d; 
	Partition *p; 
 
	d = &wren[DRIVE(c->qid.path)]; 
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 1, a, n, offset); 
} 
 
static long 
wrenio(Drive *d, Partition *p, int write, char *a, ulong n, ulong offset) 
{ 
1991/0423    
	Scsi *cmd; 
	ulong lbn; 
1991/0112    
	Part *p; 
	Disk *d; 
1991/0823    
	void *b; 
	ulong block; 
1991/0112    
 
1991/0110    
	if (n == 0) 
1991/0823    
	if(n % d->bytes || offset % d->bytes) 
		error(Ebadarg); 
	block = offset / d->bytes + p->start; 
	if(block >= p->end) 
1991/0110    
		return 0; 
1991/0112    
                 
	d = &wren[c->dev]; 
	p = &(d->p[Mask&c->qid.path]); 
	switch ((int)(c->qid.path & ~Mask)) { 
1991/0110    
	case Qdata: 
1991/0411    
		if (n % d->blocksize || offset % d->blocksize) 
1991/0110    
			error(Ebadarg); 
1991/0411    
		lbn = offset/d->blocksize + p->firstblock; 
1991/0112    
		if (lbn >= p->maxblock) 
1991/0110    
			error(Ebadarg); 
1991/0423    
		if (n > DATASIZE) 
			n = DATASIZE; 
		cmd = scsicmd(c->dev, 0x0a, n); 
1991/0110    
		if (waserror()) { 
			qunlock(cmd); 
			nexterror(); 
		} 
		cmd->cmdblk[1] = lbn>>16; 
		cmd->cmdblk[2] = lbn>>8; 
		cmd->cmdblk[3] = lbn; 
1991/0112    
		cmd->cmdblk[4] = n/d->blocksize; 
1991/0318    
		memmove(cmd->data.base, a, n); 
1991/0110    
		scsiexec(cmd, 0); 
		n = cmd->data.ptr - cmd->data.base; 
1991/0823    
	if(n > DATASIZE) 
		n = DATASIZE; 
	n /= d->bytes; 
	if(block + n > p->end) 
		n = p->end - block; 
	if(n == 0) 
		return 0; 
	if(write) 
		cmd = scsicmd(d->drive, 0x0a, n*d->bytes); 
	else 
		cmd = scsicmd(d->drive, 0x08, n*d->bytes); 
	if(waserror()){ 
1991/0110    
		qunlock(cmd); 
1991/0604    
		poperror(); 
1991/0110    
		break; 
	default: 
		panic("wrenwrite"); 
1991/0823    
		nexterror(); 
1991/0110    
	} 
1991/0823    
	cmd->cmdblk[1] = block>>16; 
	cmd->cmdblk[2] = block>>8; 
	cmd->cmdblk[3] = block; 
	cmd->cmdblk[4] = n; 
	if(write) 
		memmove(cmd->data.base, a, n*d->bytes); 
	scsiexec(cmd, !write); 
	n = cmd->data.ptr - cmd->data.base; 
	if(!write) 
		memmove(a, cmd->data.base, n); 
	qunlock(cmd); 
	poperror(); 
1991/0110    
	return n; 
} 
 
void 
wrenremove(Chan *c) 
1991/0823    
/* 
 *  read partition table.  The partition table is just ascii strings. 
 */ 
#define MAGIC "plan9 partitions" 
static void 
wrenpart(int dev) 
1991/0110    
{ 
	error(Eperm); 
} 
1991/0823    
	Scsi *cmd; 
	Drive *dp; 
	Partition *pp; 
	uchar buf[32]; 
	char *b; 
	char *line[Npart+1]; 
	char *field[3]; 
	ulong n; 
	int i; 
1991/0110    
 
void 
wrenwstat(Chan *c, char *dp) 
{ 
	error(Eperm); 
1991/0603    
} 
1991/0823    
	scsiready(dev); 
	scsisense(dev, buf); 
	scsicap(dev, buf); 
	dp = &wren[dev]; 
	dp->drive = dev; 
	if(dp->npart) 
		return; 
	/* 
	 *  we always have a partition for the whole disk 
	 *  and one for the partition table 
	 */ 
	dp->bytes = (buf[4]<<24)+(buf[5]<<16)+(buf[6]<<8)+(buf[7]); 
	pp = &dp->p[0]; 
	strcpy(pp->name, "disk"); 
	pp->start = 0; 
	pp->end = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]) + 1; 
	pp++; 
	strcpy(pp->name, "partition"); 
	pp->start = dp->p[0].end - 1; 
	pp->end = dp->p[0].end; 
	dp->npart = 2; 
1991/0603    
 
void 
wrenint(uchar *a, ulong x) 
{ 
	a[0] = x >> 24; 
	a[1] = x >> 16; 
	a[2] = x >> 8; 
	a[3] = x; 
1991/0823    
	/* 
	 *  read partition table from disk, null terminate 
	 */ 
	cmd = scsicmd(dev, 0x08, dp->bytes); 
	if(waserror()){ 
		qunlock(cmd); 
		nexterror(); 
	} 
	n = dp->p[0].end-1; 
	cmd->cmdblk[1] = n>>16; 
	cmd->cmdblk[2] = n>>8; 
	cmd->cmdblk[3] = n; 
	cmd->cmdblk[4] = 1; 
	scsiexec(cmd, 1); 
	cmd->data.base[dp->bytes-1] = 0; 
 
	/* 
	 *  parse partition table. 
	 */ 
	n = getfields((char *)cmd->data.base, line, Npart+1, '\n'); 
	if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) != 0) 
		goto out; 
	for(i = 1; i < n; i++){ 
		pp++; 
		if(getfields(line[i], field, 3, ' ') != 3){ 
			break; 
		} 
		strncpy(pp->name, field[0], NAMELEN); 
		pp->start = strtoul(field[1], 0, 0); 
		pp->end = strtoul(field[2], 0, 0); 
		if(pp->start > pp->end || pp->start >= dp->p[0].end){ 
			break; 
		} 
		dp->npart++; 
	} 
out: 
	qunlock(cmd); 
	poperror(); 
1991/0110    
} 
1991/0823/sys/src/9/port/devwren.c:125,1311991/0921/sys/src/9/port/devwren.c:125,131 (short | long)
1991/0112    
 
1991/0823    
	drive = wrendev(param); 
	wrenpart(drive); 
1991/0110    
	c = devattach('r', param); 
1991/0921    
	c = devattach('w', param); 
1991/0823    
	c->dev = drive; 
1991/0110    
	return c; 
} 
1991/0921/sys/src/9/port/devwren.c:7,241991/0927/sys/src/9/port/devwren.c:7,26 (short | long)
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
1991/0927    
#define DATASIZE	(8*1024) 
 
1991/0823    
typedef struct Partition	Partition; 
typedef struct Drive		Drive; 
1991/0112    
 
1991/0110    
enum { 
1991/0823    
	Npart=		8+2,	/* 8 sub partitions, disk, and partition */ 
1991/0112    
	Ndisk=		64,	/* maximum disks */ 
1991/0927    
	Ndisk=		64,	/* maximum disks; must be power of 2 or change DRIVE */ 
1991/0110    
 
1991/0823    
	/* file types */ 
1991/0112    
	Qdir=		0, 
1991/0110    
}; 
1991/0823    
#define PART(x)		((x)&0xF) 
#define DRIVE(x)	(((x)>>4)&0x7) 
1991/0927    
#define DRIVE(x)	(((x)>>4)&(Ndisk-1)) 
1991/0823    
#define MKQID(d,p)	(((d)<<4) | (p)) 
1991/0110    
 
1991/0823    
struct Partition 
1991/0921/sys/src/9/port/devwren.c:38,451991/0927/sys/src/9/port/devwren.c:40,45
1991/0110    
 
1991/0823    
static Drive	wren[Ndisk]; 
1991/0110    
 
1991/0423    
#define	DATASIZE	(8*1024)	/* BUG */ 
1991/0112    
                 
1991/0823    
static void	wrenpart(int); 
static long	wrenio(Drive *, Partition *, int, char *, ulong, ulong); 
1991/0115    
 
1991/0921/sys/src/9/port/devwren.c:86,1021991/0927/sys/src/9/port/devwren.c:86,104
1991/0823    
	ulong l; 
1991/0112    
 
1991/0823    
	qid.vers = 0; 
	drive = s/Npart; 
	s = s % Npart; 
1991/0927    
	drive = c->dev; 
1991/0823    
	if(drive >= Ndisk) 
1991/0110    
		return -1; 
1991/0823    
	dp = &wren[drive]; 
1991/0112    
 
1991/0823    
	if(s >= dp->npart) 
		return 0; 
1991/0927    
		return -1; 
1991/0823    
 
	pp = &dp->p[s]; 
	sprint(name, "hd%d%s", drive, pp->name); 
1991/0927    
	if(drive & 7) 
		sprint(name, "hd%d.%d%s", drive>>3, drive&7, pp->name); 
	else 
		sprint(name, "hd%d%s", drive>>3, pp->name); 
1991/0823    
	name[NAMELEN] = 0; 
	qid.path = MKQID(drive, s); 
	l = (pp->end - pp->start) * dp->bytes; 
1991/0921/sys/src/9/port/devwren.c:188,1931991/0927/sys/src/9/port/devwren.c:190,197
1991/0823    
		return devdirread(c, a, n, 0, 0, wrengen); 
1991/0112    
 
1991/0823    
	d = &wren[DRIVE(c->qid.path)]; 
1991/0927    
	if(d->npart == 0) 
		errors("bad drive"); 
1991/0823    
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 0, a, n, offset); 
1991/0110    
} 
1991/0921/sys/src/9/port/devwren.c:199,2041991/0927/sys/src/9/port/devwren.c:203,210
1991/0823    
	Partition *p; 
 
	d = &wren[DRIVE(c->qid.path)]; 
1991/0927    
	if(d->npart == 0) 
		errors("bad drive"); 
1991/0823    
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 1, a, n, offset); 
} 
1991/0921/sys/src/9/port/devwren.c:206,2131991/0927/sys/src/9/port/devwren.c:212,218
1991/0823    
static long 
wrenio(Drive *d, Partition *p, int write, char *a, ulong n, ulong offset) 
{ 
1991/0423    
	Scsi *cmd; 
1991/0823    
	void *b; 
1991/0927    
	Scsibuf *b; 
1991/0823    
	ulong block; 
1991/0112    
 
1991/0823    
	if(n % d->bytes || offset % d->bytes) 
1991/0921/sys/src/9/port/devwren.c:222,2471991/0927/sys/src/9/port/devwren.c:227,246
1991/0823    
		n = p->end - block; 
	if(n == 0) 
		return 0; 
	if(write) 
		cmd = scsicmd(d->drive, 0x0a, n*d->bytes); 
	else 
		cmd = scsicmd(d->drive, 0x08, n*d->bytes); 
1991/0927    
	b = scsibuf(); 
1991/0823    
	if(waserror()){ 
1991/0110    
		qunlock(cmd); 
1991/0927    
		scsifree(b); 
1991/0823    
		nexterror(); 
1991/0110    
	} 
1991/0823    
	cmd->cmdblk[1] = block>>16; 
	cmd->cmdblk[2] = block>>8; 
	cmd->cmdblk[3] = block; 
	cmd->cmdblk[4] = n; 
	if(write) 
		memmove(cmd->data.base, a, n*d->bytes); 
	scsiexec(cmd, !write); 
	n = cmd->data.ptr - cmd->data.base; 
	if(!write) 
		memmove(a, cmd->data.base, n); 
	qunlock(cmd); 
1991/0927    
	if(write){ 
		memmove(b->virt, a, n*d->bytes); 
		n = scsibwrite(d->drive, b, n, d->bytes, block); 
	}else{ 
		n = scsibread(d->drive, b, n, d->bytes, block); 
		memmove(a, b->virt, n); 
	} 
1991/0823    
	poperror(); 
1991/0927    
	scsifree(b); 
1991/0110    
	return n; 
} 
 
1991/0921/sys/src/9/port/devwren.c:252,2641991/0927/sys/src/9/port/devwren.c:251,261
1991/0823    
static void 
wrenpart(int dev) 
1991/0110    
{ 
1991/0823    
	Scsi *cmd; 
	Drive *dp; 
	Partition *pp; 
	uchar buf[32]; 
	char *b; 
	char *line[Npart+1]; 
	char *field[3]; 
1991/0927    
	Scsibuf *b; 
	char *rawpart, *line[Npart+1], *field[3]; 
1991/0823    
	ulong n; 
	int i; 
1991/0110    
 
1991/0921/sys/src/9/port/devwren.c:267,2741991/0927/sys/src/9/port/devwren.c:264,270
1991/0823    
	scsicap(dev, buf); 
	dp = &wren[dev]; 
	dp->drive = dev; 
	if(dp->npart) 
		return; 
1991/0927    
 
1991/0823    
	/* 
	 *  we always have a partition for the whole disk 
	 *  and one for the partition table 
1991/0921/sys/src/9/port/devwren.c:287,3251991/0927/sys/src/9/port/devwren.c:283,316
1991/0823    
	/* 
	 *  read partition table from disk, null terminate 
	 */ 
	cmd = scsicmd(dev, 0x08, dp->bytes); 
1991/0927    
	b = scsibuf(); 
1991/0823    
	if(waserror()){ 
		qunlock(cmd); 
1991/0927    
		scsifree(b); 
1991/0823    
		nexterror(); 
	} 
	n = dp->p[0].end-1; 
	cmd->cmdblk[1] = n>>16; 
	cmd->cmdblk[2] = n>>8; 
	cmd->cmdblk[3] = n; 
	cmd->cmdblk[4] = 1; 
	scsiexec(cmd, 1); 
	cmd->data.base[dp->bytes-1] = 0; 
1991/0927    
	scsibread(dev, b, 1, dp->bytes, dp->p[0].end-1); 
	rawpart = b->virt; 
	rawpart[dp->bytes-1] = 0; 
1991/0823    
 
	/* 
	 *  parse partition table. 
	 */ 
	n = getfields((char *)cmd->data.base, line, Npart+1, '\n'); 
	if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) != 0) 
		goto out; 
	for(i = 1; i < n; i++){ 
		pp++; 
		if(getfields(line[i], field, 3, ' ') != 3){ 
			break; 
1991/0927    
	n = getfields(rawpart, line, Npart+1, '\n'); 
	if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ 
		for(i = 1; i < n; i++){ 
			pp++; 
			if(getfields(line[i], field, 3, ' ') != 3){ 
				break; 
			} 
			strncpy(pp->name, field[0], NAMELEN); 
			pp->start = strtoul(field[1], 0, 0); 
			pp->end = strtoul(field[2], 0, 0); 
			if(pp->start > pp->end || pp->start >= dp->p[0].end){ 
				break; 
			} 
			dp->npart++; 
1991/0823    
		} 
		strncpy(pp->name, field[0], NAMELEN); 
		pp->start = strtoul(field[1], 0, 0); 
		pp->end = strtoul(field[2], 0, 0); 
		if(pp->start > pp->end || pp->start >= dp->p[0].end){ 
			break; 
		} 
		dp->npart++; 
	} 
out: 
	qunlock(cmd); 
	poperror(); 
1991/0927    
	scsifree(b); 
1991/0110    
} 
1991/0927/sys/src/9/port/devwren.c:14,201991/1019/sys/src/9/port/devwren.c:14,21 (short | long)
1991/0112    
 
1991/0110    
enum { 
1991/0823    
	Npart=		8+2,	/* 8 sub partitions, disk, and partition */ 
1991/0927    
	Ndisk=		64,	/* maximum disks; must be power of 2 or change DRIVE */ 
1991/1019    
	Ndisk=		64,	/* maximum disks; if you change it, you must 
				   map from dev to disk */ 
1991/0110    
 
1991/0823    
	/* file types */ 
1991/0112    
	Qdir=		0, 
1991/0927/sys/src/9/port/devwren.c:49,781991/1019/sys/src/9/port/devwren.c:50,69
1991/0110    
static int 
wrendev(char *p) 
{ 
	int dev = 0; 
1991/1019    
	int drive, unit; 
1991/0823    
 
	if(p == 0 || p[0] == 0) 
1991/0110    
		goto out; 
1991/1019    
	if(p == 0 || p[0] == '\0') 
		return 0; 
1991/0823    
	if(p[0] < '0' || p[0] > '7') 
1991/0110    
		goto cant; 
1991/0823    
	dev = (p[0] - '0') << 3; 
	if(p[1] == 0) 
1991/0110    
		goto out; 
1991/0823    
	if(p[1] != '.') 
1991/0110    
		goto cant; 
1991/0823    
	if(p[2] == 0) 
1991/0110    
		goto out; 
1991/0823    
	if(p[2] < '0' || p[2] > '7') 
1991/0110    
		goto cant; 
1991/0823    
	dev |= p[2] - '0'; 
	if(p[3] != 0) 
1991/0110    
		goto cant; 
out: 
1991/0112    
	if(dev >= Ndisk) 
		error(Ebadarg); 
1991/0110    
	return dev; 
cant: 
	error(Ebadarg); 
1991/1019    
		errors("bad scsi drive specifier"); 
	drive = p[0] - '0'; 
	unit = 0; 
	if(p[1]){ 
		if(p[1] != '.' || p[2] < '0' || p[2] > '7' || p[3] != '\0') 
			errors("bad scsi unit specifier"); 
		unit = p[2] - '0'; 
	} 
	return (drive << 3) | unit; 
1991/0110    
} 
 
static int 
1991/0927/sys/src/9/port/devwren.c:191,1971991/1019/sys/src/9/port/devwren.c:182,188
1991/0112    
 
1991/0823    
	d = &wren[DRIVE(c->qid.path)]; 
1991/0927    
	if(d->npart == 0) 
		errors("bad drive"); 
1991/1019    
		errors("drive repartitioned"); 
1991/0823    
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 0, a, n, offset); 
1991/0110    
} 
1991/0927/sys/src/9/port/devwren.c:204,2101991/1019/sys/src/9/port/devwren.c:195,201
1991/0823    
 
	d = &wren[DRIVE(c->qid.path)]; 
1991/0927    
	if(d->npart == 0) 
		errors("bad drive"); 
1991/1019    
		errors("drive repartitioned"); 
1991/0823    
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 1, a, n, offset); 
} 
1991/0927/sys/src/9/port/devwren.c:216,2221991/1019/sys/src/9/port/devwren.c:207,213
1991/0823    
	ulong block; 
1991/0112    
 
1991/0823    
	if(n % d->bytes || offset % d->bytes) 
		error(Ebadarg); 
1991/1019    
		errors("io not block aligned"); 
1991/0823    
	block = offset / d->bytes + p->start; 
	if(block >= p->end) 
1991/0110    
		return 0; 
1991/1019/sys/src/9/port/devwren.c:93,991991/1109/sys/src/9/port/devwren.c:93,99 (short | long)
1991/0823    
	name[NAMELEN] = 0; 
	qid.path = MKQID(drive, s); 
	l = (pp->end - pp->start) * dp->bytes; 
	devdir(c, qid, name, l, 0600, dirp); 
1991/1109    
	devdir(c, qid, name, l, eve, 0600, dirp); 
1991/0110    
	return 1; 
} 
 
1991/1109/sys/src/9/port/devwren.c:93,991991/1112/sys/src/9/port/devwren.c:93,99 (short | long)
1991/0823    
	name[NAMELEN] = 0; 
	qid.path = MKQID(drive, s); 
	l = (pp->end - pp->start) * dp->bytes; 
1991/1109    
	devdir(c, qid, name, l, eve, 0600, dirp); 
1991/1112    
	devdir(c, qid, name, l, eve, 0666, dirp); 
1991/0110    
	return 1; 
} 
 
1991/1112/sys/src/9/port/devwren.c:42,481991/1203/sys/src/9/port/devwren.c:42,48 (short | long)
1991/0823    
static Drive	wren[Ndisk]; 
1991/0110    
 
1991/0823    
static void	wrenpart(int); 
static long	wrenio(Drive *, Partition *, int, char *, ulong, ulong); 
1991/1203    
static long	wrenio(Chan*, int, char*, ulong, ulong); 
1991/0115    
 
1991/0110    
/* 
 *  accepts [0-7].[0-7], or abbreviation 
1991/1112/sys/src/9/port/devwren.c:173,2221991/1203/sys/src/9/port/devwren.c:173,210
1991/0110    
long 
1991/0411    
wrenread(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
1991/0823    
	Drive *d; 
	Partition *p; 
1991/0112    
                 
                 
	if(c->qid.path == CHDIR) 
1991/0823    
		return devdirread(c, a, n, 0, 0, wrengen); 
1991/0112    
                 
1991/0823    
	d = &wren[DRIVE(c->qid.path)]; 
1991/0927    
	if(d->npart == 0) 
1991/1019    
		errors("drive repartitioned"); 
1991/0823    
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 0, a, n, offset); 
1991/1203    
	return wrenio(c, 0, a, n, offset); 
1991/0110    
} 
 
long 
1991/0411    
wrenwrite(Chan *c, char *a, long n, ulong offset) 
1991/0110    
{ 
1991/1203    
	return wrenio(c, 1, a, n, offset); 
} 
 
static long 
wrenio(Chan *c, int write, char *a, ulong len, ulong offset) 
{ 
1991/0823    
	Drive *d; 
	Partition *p; 
1991/1203    
	Scsibuf *b; 
	ulong block, n, max, x; 
1991/0823    
 
	d = &wren[DRIVE(c->qid.path)]; 
1991/0927    
	if(d->npart == 0) 
1991/1019    
		errors("drive repartitioned"); 
1991/0823    
	p = &d->p[PART(c->qid.path)]; 
	return wrenio(d, p, 1, a, n, offset); 
} 
 
static long 
wrenio(Drive *d, Partition *p, int write, char *a, ulong n, ulong offset) 
{ 
1991/0927    
	Scsibuf *b; 
1991/0823    
	ulong block; 
1991/0112    
                 
1991/0823    
	if(n % d->bytes || offset % d->bytes) 
1991/1019    
		errors("io not block aligned"); 
1991/0823    
	block = offset / d->bytes + p->start; 
	if(block >= p->end) 
1991/0110    
		return 0; 
1991/0823    
	if(n > DATASIZE) 
		n = DATASIZE; 
	n /= d->bytes; 
1991/1203    
	n = (offset + len + d->bytes - 1) / d->bytes + p->start - block; 
	max = DATASIZE / d->bytes; 
	if(n > max) 
		n = max; 
1991/0823    
	if(block + n > p->end) 
		n = p->end - block; 
	if(n == 0) 
1991/1203    
	if(block >= p->end || n == 0) 
1991/0823    
		return 0; 
1991/0927    
	b = scsibuf(); 
1991/0823    
	if(waserror()){ 
1991/1112/sys/src/9/port/devwren.c:223,2381991/1203/sys/src/9/port/devwren.c:211,244
1991/0927    
		scsifree(b); 
1991/0823    
		nexterror(); 
1991/0110    
	} 
1991/1203    
	offset %= d->bytes; 
1991/0927    
	if(write){ 
		memmove(b->virt, a, n*d->bytes); 
		n = scsibwrite(d->drive, b, n, d->bytes, block); 
1991/1203    
		if(offset || len % d->bytes){ 
			x = scsibread(d->drive, b, n, d->bytes, block); 
			if(x < n * d->bytes){ 
				n = x / d->bytes; 
				x = n * d->bytes - offset; 
				if(len > x) 
					len = x; 
			} 
		} 
		memmove((char*)b->virt + offset, a, len); 
		x = scsibwrite(d->drive, b, n, d->bytes, block); 
		if(x < offset) 
			len = 0; 
		else if(len > x - offset) 
			len = x - offset; 
1991/0927    
	}else{ 
		n = scsibread(d->drive, b, n, d->bytes, block); 
		memmove(a, b->virt, n); 
1991/1203    
		x = scsibread(d->drive, b, n, d->bytes, block); 
		if(x < offset) 
			len = 0; 
		else if(len > x - offset) 
			len = x - offset; 
		memmove(a, (char*)b->virt + offset, len); 
1991/0927    
	} 
1991/0823    
	poperror(); 
1991/0927    
	scsifree(b); 
1991/0110    
	return n; 
1991/1203    
	return len; 
1991/0110    
} 
 
1991/0823    
/* 
1991/1203/sys/src/9/port/devwren.c:150,1551991/1210/sys/src/9/port/devwren.c:150,156 (short | long)
1991/0110    
void 
wrencreate(Chan *c, char *name, int omode, ulong perm) 
{ 
1991/1210    
	USED(c, name, omode, perm); 
1991/0110    
	error(Eperm); 
} 
 
1991/1203/sys/src/9/port/devwren.c:156,1661991/1210/sys/src/9/port/devwren.c:157,169
1991/0110    
void 
wrenclose(Chan *c) 
1991/0823    
{ 
1991/1210    
	USED(c); 
1991/0823    
} 
1991/0110    
 
1991/0823    
void 
wrenremove(Chan *c) 
{ 
1991/1210    
	USED(c); 
1991/0823    
	error(Eperm); 
} 
 
1991/1203/sys/src/9/port/devwren.c:167,1721991/1210/sys/src/9/port/devwren.c:170,176
1991/0823    
void 
wrenwstat(Chan *c, char *dp) 
{ 
1991/1210    
	USED(c, dp); 
1991/0823    
	error(Eperm); 
} 
 
1991/1210/sys/src/9/port/devwren.c:262,2681991/1220/sys/src/9/port/devwren.c:262,269 (short | long)
1991/0110    
 
1991/0823    
	scsiready(dev); 
	scsisense(dev, buf); 
	scsicap(dev, buf); 
1991/1220    
	if (scsicap(dev, buf)) 
		error(Eio); 
1991/0823    
	dp = &wren[dev]; 
	dp->drive = dev; 
1991/0927    
 
1991/1220/sys/src/9/port/devwren.c:298,3041992/0109/sys/src/9/port/devwren.c:298,304 (short | long)
1991/0823    
	 *  parse partition table. 
	 */ 
1991/0927    
	n = getfields(rawpart, line, Npart+1, '\n'); 
	if(strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ 
1992/0109    
	if(n > 0 && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ 
1991/0927    
		for(i = 1; i < n; i++){ 
			pp++; 
			if(getfields(line[i], field, 3, ' ') != 3){ 
1992/0109/sys/src/9/port/devwren.c:3,91992/0111/sys/src/9/port/devwren.c:3,9 (short | long)
Move error.h to ../port. Change errors to actual strings.
rsc Fri Mar 4 12:44:25 2005
1991/0110    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"errno.h" 
1992/0111    
#include	"../port/error.h" 
1991/0110    
#include	"devtab.h" 
#include	"io.h" 
 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)