henesyinit from p9fd787fda5 years agoHistory
1925 lines · 36.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h> #include "scsireq.h" #define MIN(a, b)	((a) < (b) ? (a): (b)) Biobuf bin, bout;static char rwbuf[MaxIOsize];static int verbose = 1;long maxiosize = MaxIOsize; typedef struct {	char *name;	long (*f)(ScsiReq *, int, char *[]);	int open;	char *help;} ScsiCmd;static ScsiCmd scsicmd[]; static longcmdready(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRready(rp);} static longcmdrewind(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRrewind(rp);} static longcmdreqsense(ScsiReq *rp, int argc, char *argv[]){	long nbytes; 	USED(argc, argv);	if((nbytes = SRreqsense(rp)) != -1)		makesense(rp);	return nbytes;} static longcmdformat(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRformat(rp);} static longcmdrblimits(ScsiReq *rp, int argc, char *argv[]){	uchar l[6];	long n; 	USED(argc, argv);	if((n = SRrblimits(rp, l)) == -1)		return -1;	Bprint(&bout, " %2.2uX %2.2uX %2.2uX %2.2uX %2.2uX %2.2uX\n",		l[0], l[1], l[2], l[3], l[4], l[5]);	return n;} static intmkfile(char *file, int omode, int *pid){	int fd[2]; 	if(*file != '|'){		*pid = -1;		if(omode == OWRITE)			return create(file, OWRITE, 0666);		else if(omode == OREAD)			return open(file, OREAD);		return -1;	} 	file++;	if(*file == 0 || pipe(fd) == -1)		return -1;	if((*pid = fork()) == -1){		close(fd[0]);		close(fd[1]);		return -1;	}	if(*pid == 0){		switch(omode){ 		case OREAD:			dup(fd[0], 1);			break; 		case OWRITE:			dup(fd[0], 0);			break;		}		close(fd[0]);		close(fd[1]);		execl("/bin/rc", "rc", "-c", file, 0);		exits("exec");	}	close(fd[0]);	return fd[1];} intwaitfor(int pid){	int msg;	Waitmsg *w; 	while((w = wait()) != nil){		if(w->pid != pid){			free(w);			continue;		}		msg = (w->msg[0] != '\0');		free(w);		return msg;	}	return -1;} static longcmdread(ScsiReq *rp, int argc, char *argv[]){	long n, iosize;	vlong nbytes, total;	int fd, pid;	char *p; 	iosize = maxiosize;	nbytes = 0x7FFFFFFFFFFFULL & ~iosize;	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		nbytes = strtoll(argv[1], &p, 0);		if(nbytes == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/ 	case 1:		if((fd = mkfile(argv[0], OWRITE, &pid)) == -1){			rp->status = Status_BADARG;			return -1;		}		break;	}	print("bsize=%lud\n", rp->lbsize);	total = 0;	while(nbytes){		n = iosize;		if(n > nbytes)			n = nbytes;		if((n = SRread(rp, rwbuf, n)) <= 0){			if(total == 0)				total = -1;			break;		}		if(write(fd, rwbuf, n) != n){			if(total == 0)				total = -1;			if(rp->status == STok)				rp->status = Status_SW;			break;		}		nbytes -= n;		total += n;	}	close(fd);	if(pid >= 0 && waitfor(pid)){		rp->status = Status_SW;		return -1;	}	return total;} static longcmdwrite(ScsiReq *rp, int argc, char *argv[]){	long n;	vlong nbytes, total;	int fd, pid;	char *p; 	nbytes = 0x7FFFFFFF & ~maxiosize;	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		nbytes = strtoll(argv[1], &p, 0);		if(nbytes == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/ 	case 1:		if((fd = mkfile(argv[0], OREAD, &pid)) == -1){			rp->status = Status_BADARG;			return -1;		}		break;	}	total = 0;	while(nbytes){		n = maxiosize;		if(n > nbytes)			n = nbytes;		if((n = readn(fd, rwbuf, n)) <= 0){			if(total == 0)				total = -1;			break;		}		if(SRwrite(rp, rwbuf, n) != n){			if(total == 0)				total = -1;			if(rp->status == STok)				rp->status = Status_SW;			break;		}		nbytes -= n;		total += n;	}	close(fd);	if(pid >= 0 && waitfor(pid)){		rp->status = Status_SW;		return -1;	}	return total;} static longcmdseek(ScsiReq *rp, int argc, char *argv[]){	char *p;	long offset;	int type; 	type = 0;	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		if((type = strtol(argv[1], &p, 0)) == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/ 	case 1:		if((offset = strtol(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		break;	}	return SRseek(rp, offset, type);} static longcmdfilemark(ScsiReq *rp, int argc, char *argv[]){	char *p;	ulong howmany; 	howmany = 1;	if(argc && (howmany = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){		rp->status = Status_BADARG;		return -1;	}	return SRfilemark(rp, howmany);} static longcmdspace(ScsiReq *rp, int argc, char *argv[]){	uchar code;	long howmany;	char option, *p; 	code = 0x00;	howmany = 1;	while(argc && (*argv)[0] == '-'){		while(option = *++argv[0]){			switch(option){ 			case '-':				break; 			case 'b':				code = 0x00;				break; 			case 'f':				code = 0x01;				break; 			default:				rp->status = Status_BADARG;				return -1;			}			break;		}		argc--; argv++;		if(option == '-')			break;	}	if(argc && ((howmany = strtol(argv[0], &p, 0)) == 0 && p == argv[0])){		rp->status = Status_BADARG;		return -1;	}	return SRspace(rp, code, howmany);} static longcmdinquiry(ScsiReq *rp, int argc, char *argv[]){	long status;	int i, n;	uchar *p; 	USED(argc, argv);	if((status = SRinquiry(rp)) != -1){		n = rp->inquiry[4]+4;		for(i = 0; i < MIN(8, n); i++)			Bprint(&bout, " %2.2uX", rp->inquiry[i]);		p = &rp->inquiry[8];		n = MIN(n, sizeof(rp->inquiry)-8);		while(n && (*p == ' ' || *p == '\t' || *p == '\n')){			n--;			p++;		}		Bprint(&bout, "\t%.*s\n", n, (char*)p);	}	return status;} static longcmdmodeselect6(ScsiReq *rp, int argc, char *argv[]){	uchar list[MaxDirData];	long nbytes, ul;	char *p; 	memset(list, 0, sizeof(list));	for(nbytes = 0; argc; argc--, argv++, nbytes++){		if((ul = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		list[nbytes] = ul; 	}	if(!(rp->flags & Finqok) && SRinquiry(rp) == -1)		Bprint(&bout, "warning: couldn't determine whether SCSI-1/SCSI-2 mode");	return SRmodeselect6(rp, list, nbytes);} static longcmdmodeselect10(ScsiReq *rp, int argc, char *argv[]){	uchar list[MaxDirData];	long nbytes, ul;	char *p; 	memset(list, 0, sizeof(list));	for(nbytes = 0; argc; argc--, argv++, nbytes++){		if((ul = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		list[nbytes] = ul; 	}	if(!(rp->flags & Finqok) && SRinquiry(rp) == -1)		Bprint(&bout, "warning: couldn't determine whether SCSI-1/SCSI-2 mode");	return SRmodeselect10(rp, list, nbytes);} static longcmdmodesense6(ScsiReq *rp, int argc, char *argv[]){	uchar list[MaxDirData], *lp, page;	long i, n, nbytes, status;	char *p; 	nbytes = sizeof(list);	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		if((nbytes = strtoul(argv[1], &p, 0)) == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/ 	case 1:		if((page = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		break; 	case 0:		page = 0x3F;		break;	}	if((status = SRmodesense6(rp, page, list, nbytes)) == -1)		return -1;	lp = list;	nbytes = list[0];	Bprint(&bout, " Header\n   ");	for(i = 0; i < 4; i++){				/* header */		Bprint(&bout, " %2.2uX", *lp);		lp++;	}	Bputc(&bout, '\n'); 	if(list[3]){					/* block descriptors */		for(n = 0; n < list[3]/8; n++){			Bprint(&bout, " Block %ld\n   ", n);			for(i = 0; i < 8; i++)				Bprint(&bout, " %2.2uX", lp[i]);			Bprint(&bout, "    (density %2.2uX", lp[0]);			Bprint(&bout, " blocks %d", (lp[1]<<16)|(lp[2]<<8)|lp[3]);			Bprint(&bout, " length %d)", (lp[5]<<16)|(lp[6]<<8)|lp[7]);			lp += 8;			nbytes -= 8;			Bputc(&bout, '\n');		}	} 	while(nbytes > 0){				/* pages */		i = *(lp+1);		nbytes -= i+2;		Bprint(&bout, " Page %2.2uX %d\n   ", *lp & 0x3F, *(lp+1));		lp += 2;		for(n = 0; n < i; n++){			if(n && ((n & 0x0F) == 0))				Bprint(&bout, "\n   ");			Bprint(&bout, " %2.2uX", *lp);			lp++;		}		if(n && (n & 0x0F))			Bputc(&bout, '\n');	}	return status;} static longcmdmodesense10(ScsiReq *rp, int argc, char *argv[]){	uchar *list, *lp, page;	long blen, i, n, nbytes, status;	char *p; 	nbytes = MaxDirData;	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		if((nbytes = strtoul(argv[1], &p, 0)) == 0 && p == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/ 	case 1:		if((page = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){			rp->status = Status_BADARG;			return -1;		}		break; 	case 0:		page = 0x3F;

Lines 1–500 of 1925.