~kris/9p

9hist

bf5a5d018c79bb458493aa7732f4aa8f5f221396 — David du Colombier 31 years ago f588189
Plan 9 from Bell Labs 1995-04-05
3 files changed, 80 insertions(+), 57 deletions(-)

M pc/scsi.c
M port/devsd.c
M port/portfns.h
M pc/scsi.c => pc/scsi.c +34 -27
@@ 136,7 136,9 @@ scsiprobe(Ctlr *ctlr)
		 * Determine if the drive exists and is not ready or
		 * is simply not responding
		 */
		if((s = scsireqsense(t, 0, 0)) != STok){
		nbytes = Nscratch;
		s = scsireqsense(t, 0, t->scratch, &nbytes, 0);
		if(s != STok){
			print("scsi%d: unit %d unavailable, status %d\n", t->ctlrno, i, s);
			continue;
		}


@@ 152,7 154,7 @@ scsiprobe(Ctlr *ctlr)
			print("scsi%d: unit %d inquire failed, status %d\n", t->ctlrno, i, s);
			continue;
		}
		print("scsi%d: unit %d:%2.2ux: %s\n", t->ctlrno, i, t->inq[0], t->inq+8);
		print("scsi%d: unit %d: %s\n", t->ctlrno, i, t->inq+8);
		t->ok = 1;
	}
}


@@ 260,15 262,12 @@ scsicap(Target *t, char lun, ulong *size, ulong *bsize)
		return -1;

	nbytes = 8;
	s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes);
	if(s < 0) {
		free(d);
		return s;
	if((s = scsiexec(t, SCSIread, cmd, sizeof(cmd), d, &nbytes)) == STok){
		*size  = (d[0]<<24)|(d[1]<<16)|(d[2]<<8)|(d[3]<<0);
		*bsize = (d[4]<<24)|(d[5]<<16)|(d[6]<<8)|(d[7]<<0);
	}
	*size  = (d[0]<<24)|(d[1]<<16)|(d[2]<<8)|(d[3]<<0);
	*bsize = (d[4]<<24)|(d[5]<<16)|(d[6]<<8)|(d[7]<<0);
	free(d);
	return 0;
	return s;
}

int


@@ 304,7 303,8 @@ scsibio(Target *t, char lun, int dir, void *b, long n, long bsize, long bno)
	nbytes = n*bsize;
	s = scsiexec(t, dir, cmd, cdbsiz, b, &nbytes);
	if(s < 0) {
		scsireqsense(t, lun, 0);
		nbytes = Nscratch;
		scsireqsense(t, lun, t->scratch, &nbytes, 0);
		return -1;
	}
	return nbytes;


@@ 331,37 331,44 @@ static char *key[] =
};

int
scsireqsense(Target *t, char lun, int quiet)
scsireqsense(Target *t, char lun, void *data, int *nbytes, int quiet)
{
	char *s;
	int sr, try, nbytes;
	int status, try;
	uchar cmd[6], *sense;

	sense = t->scratch;
	sense = malloc(*nbytes);

	for(try = 0; try < 5; try++) {
		memset(cmd, 0, sizeof(cmd));
		cmd[0] = CMDreqsense;
		cmd[1] = lun<<5;
		cmd[4] = Nscratch;
		memset(sense, 0, sizeof(sense));
		cmd[4] = *nbytes;
		memset(sense, 0, *nbytes);

		nbytes = Nscratch;
		sr = scsiexec(t, SCSIread, cmd, sizeof(cmd), sense, &nbytes);
		if(sr != STok)
			return sr;
		status = scsiexec(t, SCSIread, cmd, sizeof(cmd), sense, nbytes);
		if(status != STok){
			free(sense);
			return status;
		}
		*nbytes = sense[0x07]+8;
		memmove(data, sense, *nbytes);

		/*
		 * Unit attention. We can handle that.
		 */
		if((sense[2] & 0x0F) == 0x00 || (sense[2] & 0x0F) == 0x06)
		if((sense[2] & 0x0F) == 0x00 || (sense[2] & 0x0F) == 0x06){
			free(sense);
			return STok;
		}

		/*
		 * Recovered error. Why bother telling me.
		 */
		if((sense[2] & 0x0F) == 0x01)
		if((sense[2] & 0x0F) == 0x01){
			free(sense);
			return STok;
		}

		/*
		 * Unit is becoming ready


@@ 372,12 379,12 @@ scsireqsense(Target *t, char lun, int quiet)
		delay(5000);
	}

	if(quiet)
		return STcheck;

	s = key[sense[2]&0xf];
	print("scsi%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n",
		t->ctlrno, t->target, s, sense[12], sense[13]);
	if(quiet == 0){
		s = key[sense[2]&0x0F];
		print("scsi%d: unit %d reqsense: '%s' code #%2.2ux #%2.2ux\n",
			t->ctlrno, t->target, s, sense[12], sense[13]);
	}
	free(sense);
	return STcheck;
}


M port/devsd.c => port/devsd.c +45 -29
@@ 100,8 100,7 @@ void
sdinit(void)
{
	Disk *d;
	ulong s, b;
	uchar inq[255];
	uchar scratch[0xFF], type;
	int dev, i, nbytes;

	dev = 0;


@@ 111,43 110,48 @@ sdinit(void)
		if(dev < 0)
			break;

		if(scsitest(d->t, 0) < 0)
			scsireqsense(d->t, 0, 0);
		if(scsistart(d->t, 0, 1) < 0)
			scsireqsense(d->t, 0, 0);
print("sd1|");

		/* Search for other lun's */
		/*
		 * Search for all the lun's.
		 */
		for(i = 0; i < Nlun; i++) {
			d->lun = i;
print("sd2|");

			/*
			 * A SCSI target does not support a lun if the
			 * the peripheral device type and qualifier fields
			 * in the response to an inquiry command are 0x7F.
			 */
			memset(inq, 0, sizeof(inq));
			nbytes = sizeof(inq);
			if(scsiinquiry(d->t, d->lun, inq, &nbytes) != STok || inq[0] == 0x7F)
			nbytes = sizeof(scratch);
			memset(scratch, 0, nbytes);
			if(scsiinquiry(d->t, d->lun, scratch, &nbytes) != STok)
				continue;
print("sd3|");

			s = 0;
			b = 0;
			if(scsicap(d->t, d->lun, &s, &b) != STok) {
				scsireqsense(d->t, 0, 0);
			if(scratch[0] == 0x7F)
				continue;
			}
print("sd4/%d/%d|", s, b);
			type = scratch[0] & 0x1F;

			if(s == 0 || b == 0)
				continue;
print("sd5/0x%2.2ux|", d->inquire[0]);
			/*
			 * Read-capacity is mandatory for TypeDA, TypeMO and TypeCD.
			 * It may return 'not ready' if TypeDA is not spun up,
			 * TypeMO or TypeCD are not loaded or just plain slow getting
			 * 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);
				memset(scratch, 0, nbytes);
				scsireqsense(d->t, 0, scratch, &nbytes, 1);
				if((scratch[2] & 0x0F) != 0x02)
					continue;
				if(type == TypeDA)
					scsistart(d->t, d->lun, 0);
				d->size = d->bsize = 0;
			}

			d->size = s;
			d->bsize = b;
			switch(d->inquire[0] & 0x1F){
			switch(type){

			case TypeDA:
			case TypeMO:


@@ 161,7 165,6 @@ print("sd5/0x%2.2ux|", d->inquire[0]);
			default:
				continue;
			}
print("sd6|");

			if(++ndisk >= Ndisk)
				break;


@@ 281,10 284,23 @@ sdrdpart(Disk *d)
	char *b, *line[Npart+2], *field[3];
	static char MAGIC[] = "plan9 partitions";

	/*
	 * 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.
	 */
	if(d->size == 0 || d->bsize == 0){
		if(scsicap(d->t, d->lun, &d->size, &d->bsize) != STok){
			d->size = d->bsize = 0;
			error(Eio);
		}
	}

	b = scsialloc(d->bsize);
	if(b == 0)
		error(Enomem);

	qlock(d);
	
	p = d->table;

M port/portfns.h => port/portfns.h +1 -1
@@ 241,7 241,7 @@ int		scsiexec(Target*, int, uchar*, int, void*, int*);
#define		scsifree(p)	free(p)
int		scsiinquiry(Target*, char, void*, int*);
int		scsiinv(int, int*, Target**, uchar**, char*);
int		scsireqsense(Target*, char, int);
int		scsireqsense(Target*, char, void*, int*, int);
int		scsistart(Target*, char, int);
int		scsitest(Target*, char);
Target*		scsiunit(int, int);