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

1991/0927/port/devwren.c (diff list | history)

1991/0921/sys/src/9/port/devwren.c:7,241991/0927/sys/src/9/port/devwren.c:7,26 (short | long | prev | next)
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    
} 


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