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

2001/1120/pc/devusb.c (diff list | history)

2001/1117/sys/src/9/pc/devusb.c:279,2842001/1120/sys/src/9/pc/devusb.c:279,285 (short | long | prev | next)
1999/1005    
 
static	Ctlr	ubus; 
static	char	Estalled[] = "usb endpoint stalled"; 
2001/1120    
static	char	Ebadusbmsg[] = "invalid parameters to USB ctl message"; 
1999/1005    
 
static	QLock	usbstate;	/* protects name space state */ 
static	Udev*	usbdev[32]; 
2001/1117/sys/src/9/pc/devusb.c:287,2922001/1120/sys/src/9/pc/devusb.c:288,329
1999/1005    
	Endpt*	f; 
} activends; 
 
2001/1120    
enum 
{ 
	BCMdisable, 
	BCMenable, 
	BCMreset, 
}; 
 
enum 
{ 
	CMclass, 
	CMdata, 
	CMdebug, 
	CMep, 
	CMmaxpkt, 
	CMspeed, 
	CMunstall, 
}; 
 
static Cmdtab usbbusctlmsg[] = 
{ 
	BCMdisable,	"disable",	2, 
	BCMenable,	"enable",	2, 
	BCMreset,	"reset",	2, 
}; 
 
static Cmdtab usbctlmsg[] = 
{ 
	CMclass,	"class",	4, 
	CMdata,		"data",		3, 
	CMdebug,	"debug",	3, 
	CMep,		"ep",		6, 
	CMmaxpkt,	"maxpkt",	3, 
	CMspeed,	"speed",	2, 
	CMunstall,	"unstall",	2, 
}; 
 
1999/1005    
static long readusb(Endpt*, void*, long); 
static long writeusb(Endpt*, void*, long, int); 
 
2001/1117/sys/src/9/pc/devusb.c:2003,20092001/1120/sys/src/9/pc/devusb.c:2040,2048
2001/0626    
{ 
	Udev *d; 
	Endpt *e; 
	int id, nw, nf, t, i; 
2001/1120    
	Cmdbuf *cb; 
	Cmdtab *ct; 
	int id, nw, t, i; 
2001/0626    
	char cmd[50], *fields[10]; 
 
	if(c->qid.type == QTDIR) 
2001/1117/sys/src/9/pc/devusb.c:2010,20332001/1120/sys/src/9/pc/devusb.c:2049,2078
2001/0626    
		error(Egreg); 
	t = QID(c->qid); 
	if(t == Qbusctl){ 
		if(n >= sizeof(cmd)-1) 
			n = sizeof(cmd)-1; 
		memmove(cmd, a, n); 
		cmd[n] = 0; 
2001/1117    
		nf = tokenize(cmd, fields, nelem(fields)); 
2001/0626    
		if(nf < 2) 
			error(Ebadarg); 
2001/1120    
		cb = parsecmd(a, n); 
		if(waserror()){ 
			free(cb); 
			nexterror(); 
		} 
 
		ct = lookupcmd(cb, usbbusctlmsg, nelem(usbbusctlmsg)); 
2001/0626    
		id = strtol(fields[1], nil, 0); 
		if(id != 1 && id != 2) 
			error(Ebadarg);	/* there are two ports on the root hub */ 
		if(strcmp(fields[0], "reset") == 0) 
			portreset(id); 
		else if(strcmp(fields[0], "enable") == 0) 
			portenable(id, 1); 
		else if(strcmp(fields[0], "disable") == 0) 
2001/1120    
			cmderror(cb, "usb port number not 1 or 2 in"); 
		switch(ct->index){ 
		case BCMdisable: 
2001/0626    
			portenable(id, 0); 
		else 
			error(Ebadarg); 
2001/1120    
			break; 
		case BCMenable: 
			portenable(id, 1); 
			break; 
		case BCMreset: 
			portreset(id); 
			break; 
		} 
	 
		poperror(); 
		free(cb); 
2001/0626    
		return n; 
	} 
	d = usbdevice(c); 
2001/1117/sys/src/9/pc/devusb.c:2034,20952001/1120/sys/src/9/pc/devusb.c:2079,2148
2001/0626    
	t = QID(c->qid); 
	switch(t){ 
	case Qctl: 
		if(n >= sizeof(cmd)-1) 
			n = sizeof(cmd)-1; 
		memmove(cmd, a, n); 
		cmd[n] = 0; 
2001/1117    
		nf = tokenize(cmd, fields, nelem(fields)); 
2001/0626    
		if(nf > 1 && strcmp(fields[0], "speed") == 0){ 
			d->ls = strtoul(fields[1], nil, 0) == 0; 
		} else if(nf > 3 && strcmp(fields[0], "class") == 0){ 
			i = strtoul(fields[2], nil, 0); 
			d->npt = strtoul(fields[1], nil, 0); 
2001/1120    
		cb = parsecmd(a, n); 
		if(waserror()){ 
			free(cb); 
			nexterror(); 
		} 
 
		ct = lookupcmd(cb, usbctlmsg, nelem(usbctlmsg)); 
		switch(ct->index){ 
		case CMspeed: 
			d->ls = strtoul(cb->f[1], nil, 0) == 0; 
			break; 
		case CMclass: 
			i = strtoul(cb->f[2], nil, 0); 
			d->npt = strtoul(cb->f[1], nil, 0); 
2001/0626    
			/* class config# csp ( == class subclass proto) */ 
			if (i < 0 || i >= nelem(d->ep) 
			 || d->npt > nelem(d->ep) || i >= d->npt) 
				error(Ebadarg); 
			if (i == 0) { 
				d->csp = strtoul(fields[3], nil, 0); 
			} 
2001/1120    
				cmderror(cb, Ebadusbmsg); 
			if (i == 0) 
				d->csp = strtoul(cb->f[3], nil, 0); 
2001/0626    
			if(d->ep[i] == nil) 
				d->ep[i] = devendpt(d, i, 1); 
			d->ep[i]->csp = strtoul(fields[3], nil, 0); 
		}else if(nf > 2 && strcmp(fields[0], "data") == 0){ 
			i = strtoul(fields[1], nil, 0); 
2001/1120    
			d->ep[i]->csp = strtoul(cb->f[3], nil, 0); 
			break; 
		case CMdata: 
			i = strtoul(cb->f[1], nil, 0); 
2001/0626    
			if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil) 
				error(Ebadarg); 
2001/1120    
				error(Ebadusbmsg); 
2001/0626    
			e = d->ep[i]; 
			e->data01 = strtoul(fields[2], nil, 0) != 0; 
		}else if(nf > 2 && strcmp(fields[0], "maxpkt") == 0){ 
			i = strtoul(fields[1], nil, 0); 
2001/1120    
			e->data01 = strtoul(cb->f[2], nil, 0) != 0; 
			break; 
		case CMmaxpkt: 
			i = strtoul(cb->f[1], nil, 0); 
2001/0626    
			if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil) 
				error(Ebadarg); 
2001/1120    
				error(Ebadusbmsg); 
2001/0626    
			e = d->ep[i]; 
			e->maxpkt = strtoul(fields[2], nil, 0); 
2001/1120    
			e->maxpkt = strtoul(cb->f[2], nil, 0); 
2001/0626    
			if(e->maxpkt > 1500) 
				e->maxpkt = 1500; 
		}else if(nf > 2 && strcmp(fields[0], "debug") == 0){ 
			i = strtoul(fields[1], nil, 0); 
2001/1120    
			break; 
		case CMdebug: 
			i = strtoul(cb->f[1], nil, 0); 
2001/0626    
			if(i < -1 || i >= nelem(d->ep) || d->ep[i] == nil) 
				error(Ebadarg); 
2001/1120    
				error(Ebadusbmsg); 
2001/0626    
			if (i == -1) 
				debug = 0; 
			else { 
				debug = 1; 
				e = d->ep[i]; 
				e->debug = strtoul(fields[2], nil, 0); 
2001/1120    
				e->debug = strtoul(cb->f[2], nil, 0); 
2001/0626    
			} 
		}else if(nf > 1 && strcmp(fields[0], "unstall") == 0){ 
			i = strtoul(fields[1], nil, 0); 
2001/1120    
			break; 
		case CMunstall: 
			i = strtoul(cb->f[1], nil, 0); 
2001/0626    
			if(i < 0 || i >= nelem(d->ep) || d->ep[i] == nil) 
				error(Ebadarg); 
2001/1120    
				error(Ebadusbmsg); 
2001/0626    
			e = d->ep[i]; 
			e->err = nil; 
		}else if(nf == 6 && strcmp(fields[0], "ep") == 0){ 
2001/1120    
			break; 
		case CMep: 
2001/0916    
			/* ep n `bulk' mode maxpkt nbuf     OR 
2001/1006    
			 * ep n period mode samplesize KHz 
2001/0916    
			 */ 
2001/0626    
			i = strtoul(fields[1], nil, 0); 
2001/1120    
			i = strtoul(cb->f[1], nil, 0); 
2001/0626    
			if(i < 0 || i >= nelem(d->ep)) { 
				XPRINT("field 1: 0 <= %d < %d\n", i, nelem(d->ep)); 
				error(Ebadarg); 
2001/1117/sys/src/9/pc/devusb.c:2104,21102001/1120/sys/src/9/pc/devusb.c:2157,2163
2001/0626    
			} 
2001/1016    
			if (e->active) 
2001/0918    
				error(Eperm); 
2001/0916    
			if(strcmp(fields[2], "bulk") == 0){ 
2001/1120    
			if(strcmp(cb->f[2], "bulk") == 0){ 
2001/0626    
				Ctlr *ub; 
 
2001/0918    
				e->iso = 0; 
2001/1117/sys/src/9/pc/devusb.c:2119,21362001/1120/sys/src/9/pc/devusb.c:2172,2189
2001/0626    
						panic("usbwrite: allocqh"); 
				} 
				queueqh(e->epq); 
2001/0916    
				e->mode = strcmp(fields[3],"r") == 0? OREAD : 
					  	strcmp(fields[3],"w") == 0? OWRITE : ORDWR; 
2001/0626    
				i = strtoul(fields[4], nil, 0); 
2001/1120    
				e->mode = strcmp(cb->f[3],"r") == 0? OREAD : 
					  	strcmp(cb->f[3],"w") == 0? OWRITE : ORDWR; 
				i = strtoul(cb->f[4], nil, 0); 
2001/0916    
				if(i < 8 || i > 1023) 
					i = 8; 
				e->maxpkt = i; 
				i = strtoul(fields[5], nil, 0); 
2001/1120    
				i = strtoul(cb->f[5], nil, 0); 
2001/0916    
				if(i >= 1 && i <= 32) 
					e->nbuf = i; 
			} else { 
				/* ep n period mode samplesize KHz */ 
				i = strtoul(fields[2], nil, 0); 
2001/1120    
				i = strtoul(cb->f[2], nil, 0); 
2001/0916    
				if(i > 0 && i <= 1000){ 
2001/0626    
					e->pollms = i; 
2001/0916    
				}else { 
2001/1117/sys/src/9/pc/devusb.c:2137,21452001/1120/sys/src/9/pc/devusb.c:2190,2198
2001/0626    
					XPRINT("field 4: 0 <= %d <= 1000\n", i); 
					error(Ebadarg); 
				} 
2001/0916    
				e->mode = strcmp(fields[3],"r") == 0? OREAD : 
					  	strcmp(fields[3],"w") == 0? OWRITE : ORDWR; 
				i = strtoul(fields[4], nil, 0); 
2001/1120    
				e->mode = strcmp(cb->f[3],"r") == 0? OREAD : 
					  	strcmp(cb->f[3],"w") == 0? OWRITE : ORDWR; 
				i = strtoul(cb->f[4], nil, 0); 
2001/0916    
				if(i >= 1 && i <= 8){ 
					e->samplesz = i; 
				}else { 
2001/1117/sys/src/9/pc/devusb.c:2146,21522001/1120/sys/src/9/pc/devusb.c:2199,2205
2001/0916    
					XPRINT("field 4: 0 < %d <= 8\n", i); 
					error(Ebadarg); 
				} 
				i = strtoul(fields[5], nil, 0); 
2001/1120    
				i = strtoul(cb->f[5], nil, 0); 
2001/0916    
				if(i >= 1 && i <= 100000){ 
					/* Hz */ 
					e->hz = i; 
2001/1117/sys/src/9/pc/devusb.c:2161,21702001/1120/sys/src/9/pc/devusb.c:2214,2223
2001/0626    
			} 
			poperror(); 
2001/0918    
			qunlock(&usbstate); 
2001/0626    
		}else { 
			XPRINT("command %s, fields %d\n", fields[0], nf); 
			error(Ebadarg); 
		} 
2001/1120    
	 
		poperror(); 
		free(cb); 
2001/0626    
		return n; 
 
	case Qsetup:	/* SETUP endpoint 0 */ 


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