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

1996/0607/port/devsd.c (diff list | history)

1996/0315/sys/src/9/port/devsd.c:47,521996/0607/sys/src/9/port/devsd.c:47,54 (short | long | prev | next)
1994/0913    
	char	vol[NAMELEN]; 
 
	uchar*	inquire; 
1996/0607    
	int	partok; 
	ulong	version; 
1994/0913    
	ulong	size; 
	ulong	bsize; 
 
1996/0315/sys/src/9/port/devsd.c:57,631996/0607/sys/src/9/port/devsd.c:59,65
1994/0913    
int	ndisk; 
Disk	disk[Ndisk]; 
 
static	void	sdrdpart(Disk*); 
1996/0607    
static	int	sdrdpart(Disk*); 
1994/0913    
static	long	sdio(Chan*, int, char*, ulong, ulong); 
 
1995/0722    
static int types[] = 
1996/0315/sys/src/9/port/devsd.c:137,1451996/0607/sys/src/9/port/devsd.c:139,144
1995/0405    
			 * their act together after a reset. 
			 * If 'not ready' comes back, try starting a TypeDA and punt 
			 * the get capacity until the drive is attached. 
			 * It might be possible to be smarter here, and look at the 
			 * response from a test-unit-ready which would show if the 
			 * target was in the process of becoming ready. 
			 */ 
			if(scsicap(d->t, d->lun, &d->size, &d->bsize) != STok) { 
				nbytes = sizeof(scratch); 
1996/0315/sys/src/9/port/devsd.c:187,1941996/0607/sys/src/9/port/devsd.c:186,197
1994/0913    
{ 
1995/0417    
	int i; 
1994/0913    
 
1995/0417    
	for(i = 0; i < ndisk; i++) 
		sdrdpart(&disk[i]); 
1996/0607    
	for(i = 0; i < ndisk; i++){ 
		qlock(&disk[i]); 
		if(disk[i].partok == 0) 
			sdrdpart(&disk[i]); 
		qunlock(&disk[i]); 
	} 
1995/0417    
	 
1994/0913    
	return devattach('w', spec); 
} 
1996/0315/sys/src/9/port/devsd.c:246,2531996/0607/sys/src/9/port/devsd.c:249,260
1994/0913    
 
	d = &disk[DRIVE(c->qid)]; 
	p = &d->table[PART(c->qid)]; 
1995/0325    
	if((c->mode&3) != OREAD && strcmp(p->name, "partition") == 0) 
1996/0607    
	if((c->mode&3) != OREAD && strcmp(p->name, "partition") == 0){ 
		qlock(d); 
		d->partok = 0; 
1995/0325    
		sdrdpart(d); 
1996/0607    
		qunlock(d); 
	} 
1994/0913    
} 
 
long 
1996/0315/sys/src/9/port/devsd.c:268,2731996/0607/sys/src/9/port/devsd.c:275,286
1994/0913    
long 
sdwrite(Chan *c, char *a, long n, ulong offset) 
{ 
1996/0607    
	Disk *d; 
 
	d = &disk[DRIVE(c->qid)]; 
 
	if((d->inquire[0] & 0x1F) == TypeCD) 
		error(Eperm); 
1994/0913    
	return sdio(c, 1, a, n, offset); 
1995/0108    
} 
 
1996/0315/sys/src/9/port/devsd.c:277,2831996/0607/sys/src/9/port/devsd.c:290,296
1995/0108    
	return devbwrite(c, bp, offset); 
1994/0913    
} 
 
static void 
1996/0607    
static int 
1994/0913    
sdrdpart(Disk *d) 
{ 
	Part *p; 
1996/0315/sys/src/9/port/devsd.c:285,3141996/0607/sys/src/9/port/devsd.c:298,333
1994/0913    
	char *b, *line[Npart+2], *field[3]; 
	static char MAGIC[] = "plan9 partitions"; 
 
1996/0607    
	if(d->partok) 
		return STok; 
 
	p = d->table; 
	strcpy(p->name, "disk"); 
	p->beg = 0; 
	p->end = 0; 
	d->npart = 1; 
 
1995/0417    
	/* 
	 * If the drive wasn't ready when we tried to do a 
	 * read-capacity earlier (in sdinit()), try again. 
	 * It might be possible to be smarter here, and look at the 
	 * response from a test-unit-ready which would show if the 
	 * target was in the process of becoming ready. 
1996/0607    
	 * If the drive wasn't ready when a read-capacity was tried 
	 * earlier (in sdinit()), try again. 
1995/0417    
	 */ 
	if(d->size == 0 || d->bsize == 0){ 
		if(scsicap(d->t, d->lun, &d->size, &d->bsize) != STok){ 
1996/0607    
		n = scsicap(d->t, d->lun, &d->size, &d->bsize); 
		if(n != STok){ 
1995/0417    
			d->size = d->bsize = 0; 
			error(Eio); 
1996/0607    
			return scsierrstr(n); 
1995/0417    
		} 
	} 
 
1996/0607    
	p->end = d->size + 1; 
 
	if((d->inquire[0] & 0x1F) == TypeCD) 
		return STok; 
 
1994/0913    
	b = scsialloc(d->bsize); 
	if(b == 0) 
		error(Enomem); 
	qlock(d); 
	                 
	p = d->table; 
1996/0607    
		return scsierrstr(STnomem); 
1994/0913    
 
	strcpy(p->name, "disk"); 
	p->beg = 0; 
	p->end = d->size + 1; 
	p++; 
	strcpy(p->name, "partition"); 
	p->beg = d->table[0].end - 1; 
1996/0315/sys/src/9/port/devsd.c:316,3271996/0607/sys/src/9/port/devsd.c:335,340
1994/0913    
	p++; 
	d->npart = 2; 
 
1995/0403    
	if((d->inquire[0] & 0x1F) == TypeCD){ 
		scsifree(b); 
		qunlock(d); 
		return; 
	} 
                 
1994/0913    
	scsibio(d->t, d->lun, SCSIread, b, 1, d->bsize, d->table[0].end-1); 
	b[d->bsize-1] = '\0'; 
 
1996/0315/sys/src/9/port/devsd.c:331,3561996/0607/sys/src/9/port/devsd.c:344,367
1996/0315    
	n = parsefields(b, line, Npart+2, "\n"); 
1994/0913    
	if(n > 0 && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0) { 
		for(i = 1; i < n; i++) { 
1996/0315    
			switch(parsefields(line[i], field, 3, " ")) { 
1994/0913    
			case 2: 
				if(strcmp(field[0], "unit") == 0) 
					strncpy(d->vol, field[1], NAMELEN); 
				break;	 
			case 3: 
1994/1228    
				if(p >= &d->table[Npart]) 
					break; 
1994/0913    
				strncpy(p->name, field[0], NAMELEN); 
				p->beg = strtoul(field[1], 0, 0); 
				p->end = strtoul(field[2], 0, 0); 
				if(p->beg > p->end || p->beg >= d->table[0].end) 
					break; 
				p++; 
			} 
1996/0607    
			if(parsefields(line[i], field, 3, " ") != 3) 
				break; 
			if(p >= &d->table[Npart]) 
				break; 
			strncpy(p->name, field[0], NAMELEN); 
			p->beg = strtoul(field[1], 0, 0); 
			p->end = strtoul(field[2], 0, 0); 
			if(p->beg > p->end || p->beg >= d->table[0].end) 
				break; 
			p++; 
1994/0913    
		} 
	} 
	d->npart = p - d->table; 
	scsifree(b); 
	qunlock(d); 
1996/0607    
 
	d->partok = 1; 
 
	return STok; 
1994/0913    
} 
 
static long 
1996/0315/sys/src/9/port/devsd.c:364,3721996/0607/sys/src/9/port/devsd.c:375,380
1994/0913    
	d = &disk[DRIVE(c->qid)]; 
	p = &d->table[PART(c->qid)]; 
1995/0403    
 
	if(write && (d->inquire[0] & 0x1F) == TypeCD) 
		error(Eperm); 
1994/0913    
                 
	block = (offset / d->bsize) + p->beg; 
	n = (offset + len + d->bsize - 1) / d->bsize + p->beg - block; 
	max = SCSImaxxfer / d->bsize; 
1996/0315/sys/src/9/port/devsd.c:379,3931996/0607/sys/src/9/port/devsd.c:387,402
1994/0913    
 
	b = scsialloc(n*d->bsize); 
	if(b == 0) 
		error(Enomem); 
	if(waserror()) { 
		scsifree(b); 
		nexterror(); 
	} 
1996/0607    
		return scsierrstr(STnomem); 
 
1994/0913    
	offset %= d->bsize; 
	if(write) { 
		if(offset || len % d->bsize) { 
			x = scsibio(d->t, d->lun, SCSIread, b, n, d->bsize, block); 
1996/0607    
			if(x < 0){ 
				len = -1; 
				goto buggery; 
			} 
1994/0913    
			if(x < n * d->bsize) { 
				n = x / d->bsize; 
				x = n * d->bsize - offset; 
1996/0315/sys/src/9/port/devsd.c:397,4021996/0607/sys/src/9/port/devsd.c:406,415
1994/0913    
		} 
		memmove(b + offset, a, len); 
		x = scsibio(d->t, d->lun, SCSIwrite, b, n, d->bsize, block); 
1996/0607    
		if(x < 0){ 
			len = -1; 
			goto buggery; 
		} 
1994/0913    
		if(x < offset) 
			len = 0; 
		else 
1996/0315/sys/src/9/port/devsd.c:405,4101996/0607/sys/src/9/port/devsd.c:418,427
1994/0913    
	} 
	else { 
		x = scsibio(d->t, d->lun, SCSIread, b, n, d->bsize, block); 
1996/0607    
		if(x < 0){ 
			len = -1; 
			goto buggery; 
		} 
1994/0913    
		if(x < offset) 
			len = 0; 
		else 
1996/0315/sys/src/9/port/devsd.c:412,4181996/0607/sys/src/9/port/devsd.c:429,436
1994/0913    
			len = x - offset; 
		memmove(a, b+offset, len); 
	} 
	poperror(); 
1996/0607    
 
buggery: 
1994/0913    
	scsifree(b); 
	return len; 
} 


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