henesyinit from p9fce6d0435 years agoHistory
1087 lines · 19.2 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h> #include "scsireq.h" #define MIN(a, b)	((a) < (b) ? (a): (b)) int bus;Biobuf bin, bout;static char rwbuf[MaxIOsize];static int verbose = 1; 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]);		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 rpid;	Waitmsg w; 	while((rpid = wait(&w)) != pid && rpid != -1)		;	return w.msg[0];} static longcmdread(ScsiReq *rp, int argc, char *argv[]){	long n, nbytes, total, iosize;	int fd, pid;	char *p; 	iosize = MaxIOsize;	nbytes = 0x7FFFFFFF & ~iosize;	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		if((nbytes = strtol(argv[1], &p, 0)) == 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=%d\n", rp->lbsize);	total = 0;	while(nbytes){		n = MIN(nbytes, iosize);		if((n = SRread(rp, rwbuf, n)) == -1){			if(total == 0)				total = -1;			break;		}		if(write(fd, rwbuf, n) != n){			if(total == 0)				total = -1;			if(rp->status == Status_OK)				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, nbytes, total;	int fd, pid;	char *p; 	nbytes = 0x7FFFFFFF & ~MaxIOsize;	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		if((nbytes = strtol(argv[1], &p, 0)) == 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 = MIN(nbytes, MaxIOsize);		if((n = read(fd, rwbuf, n)) == -1){			if(total == 0)				total = -1;			break;		}		if(SRwrite(rp, rwbuf, n) != n){			if(total == 0)				total = -1;			if(rp->status == Status_OK)				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])){		USED(howmany);		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, p);	}	return status;} static longcmdmodeselect(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;	}	return SRmodeselect(rp, list, nbytes);} static longcmdmodesense(ScsiReq *rp, int argc, char *argv[]){	uchar list[MaxDirData], *lp, page;	long i, 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 = SRmodesense(rp, page, list, nbytes)) == -1)		return -1;	lp = list;	nbytes = list[0]-1;	for(i = 0; i < 4; i++){				/* header */		Bprint(&bout, " %2.2ux", *lp);		lp++;	}	nbytes -= 4;	Bputc(&bout, '\n');	for(i = 0; i < 8; i++){				/* block descriptor */		Bprint(&bout, " %2.2ux", *lp);		lp++;	}	nbytes -= 8;	Bputc(&bout, '\n');	while(nbytes > 0){		i = *(lp+1);		nbytes -= i+2;		Bprint(&bout, " %2.2ux %2.2ux", *lp, *(lp+1));		lp += 2;		while(i--){			Bprint(&bout, " %2.2ux", *lp);			lp++;		}		Bputc(&bout, '\n');	}	return status;} static longstart(ScsiReq *rp, int argc, char *argv[], uchar code){	char *p; 	if(argc && (code = strtoul(argv[0], &p, 0)) == 0 && p == argv[0]){		rp->status = Status_BADARG;		return -1;	}	return SRstart(rp, code);} static longcmdstart(ScsiReq *rp, int argc, char *argv[]){	return start(rp, argc, argv, 1);} static longcmdstop(ScsiReq *rp, int argc, char *argv[]){	return start(rp, argc, argv, 0);} static longcmdeject(ScsiReq *rp, int argc, char *argv[]){	return start(rp, argc, argv, 2);} static longcmdcapacity(ScsiReq *rp, int argc, char *argv[]){	uchar d[6];	long n; 	USED(argc, argv);	if((n = SRrcapacity(rp, d)) == -1)		return -1;	Bprint(&bout, " %ld %ld\n", d[0]<<24|d[1]<<16|d[2]<<8|d[3],		 d[4]<<24|d[5]<<16|d[6]<<8|d[7]);	return n;} static longcmdflushcache(ScsiReq *rp, int argc, char *argv[]){	USED(argc, argv);	return SRflushcache(rp);} static longcmdrdiscinfo(ScsiReq *rp, int argc, char *argv[]){	uchar d[MaxDirData], ses, track, *p;	char *sp;	long n, nbytes; 	ses = track = 0;	switch(argc){ 	default:		rp->status = Status_BADARG;		return -1; 	case 2:		if((ses = strtoul(argv[1], &sp, 0)) == 0 && sp == argv[1]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/ 	case 1:		if((track = strtoul(argv[0], &sp, 0)) == 0 && sp == argv[0]){			rp->status = Status_BADARG;			return -1;		}		/*FALLTHROUGH*/ 	case 0:		break;

Lines 1–500 of 1087.