shithub: riscv

Download patch

ref: 7d9339f75e21ccfaae85b8d460748412831d1e4d
parent: 9d30b0f32dd9d8219805ed0d3ef04605c5f461cf
parent: 4275c49e72544d5b92512e41ddecbd6af5bee6c3
author: cinap_lenrek <[email protected]>
date: Sat Jun 28 14:11:04 EDT 2014

merge

--- a/rc/bin/nusbrc
+++ b/rc/bin/nusbrc
@@ -7,22 +7,25 @@
 @{
 	rfork ne
 	fn attach {
+		id=$1
+		if(~ $#* 5 && ! test -e /env/nousbhname)
+			id=$1:$5
 		switch($4){
 		case *01
-			nusb/audio $1
+			nusb/audio $id
 		case *02
 			# serial and ethernet
-			nusb/serial $1
+			nusb/serial $id
 			# handled /sys/src/9/boot/nusbrc
-			# nusb/ether $1
+			# nusb/ether $id
 		case *03
 			# handled /sys/src/9/boot/nusbrc
-			# nusb/kb $1
+			# nusb/kb $id
 		case *08
 			# handled /sys/src/9/boot/nusbrc
-			# nusb/disk $1
-		case *10106
-			nusb/ptp $1
+			# nusb/disk $id
+		case 010106
+			nusb/ptp $id
 		}
 	}
 	fn detach {
--- a/sys/man/2/nusb
+++ b/sys/man/2/nusb
@@ -28,6 +28,7 @@
 	Usbdev*	usb;		/* USB description */
 	void*	aux;		/* for the device driver */
 	void	(*free)(void*);	/* idem. to release aux */
+	char*	hname;		/* hash name, uniqueue for device */
 };
 .sp 0.3v
 struct Usbdev {
@@ -119,7 +120,7 @@
 int	unstall(Dev *dev, Dev *ep, int dir);
 int	usbcmd(Dev *d, int type, int req,
 		int value, int index, uchar *data, int count);
-Dev*	getdev(int id);
+Dev*	getdev(char *devid);
 .sp 0.3v
 extern int usbdebug;	/* more messages for bigger values */
 .EE
--- a/sys/man/4/nusb
+++ b/sys/man/4/nusb
@@ -88,23 +88,41 @@
 .B usbevent
 (usually seen as
 .BR /dev/usbevent )
-which, when read, returns a 5 column, space separated line of
+which, when read, returns a 6 column, space separated line of
 text, one for each event. The columns are:
 .B attach
 or
 .B detach
-.I devid
+followed by
+.I addr
 .I vid
 .I did
+.I csp
 and
-.I csp .
-All but
-.I devid
-are formatted as 4 digit hexadecimal. This file is read by
+.I hname .
+The
+.I addr
+is the decimal device address assigned.
+.I Vid
+and
+.I did
+are formatted as 4 digit hexadecimal.
+.I Csp
+is the device class, subclass, protocol indentifier
+formatd as 6 digit hexadecimal.
+.I Usbd
+assigns a stable device uniqueue name based on the
+device descriptor for
+.I hname .
+This information is read by
 .IR nusbrc (8)
 and the
+.I addr
+and
+.I hname
+are passed to a suitable driver as
 .I devid
-is passed to a suitable driver.
+in the form \fIaddr\fB:\fIhname
 .SS Keyboards and mice
 .I Kb
 supports USB keyboards and mice either as separate USB devices
@@ -123,13 +141,10 @@
 provides a file system (usually seen under
 .BR /dev )
 that includes one directory per storage device, named
-.BI sdU N . M
-in correspondence with the usb device number and the storage
-unit number (or LUN).
-For example, LUN number 2 on
-.B /dev/usb/ep3.0
-can be accessed through
-.BR /dev/sdU3.2 .
+.BI sdU N [. M ]
+in correspondence with the usb device uniqueue name
+and the storage unit number (or LUN). The LUN is omited
+for single lun devices.
 .PP
 The storage device directory contains the usual files
 served by
@@ -183,7 +198,7 @@
 that includes one directory per USB serial port, named
 .BI eiaU N
 or
-.BI eiaU N . M.
+.BI eiaU N [. M ].
 In this directory there are two files,
 .BR eiaU ,
 similar to
--- a/sys/man/8/nusbrc
+++ b/sys/man/8/nusbrc
@@ -15,9 +15,21 @@
 .IR cpurc (8)),
 .I nusbrc
 handles the startup and shutdown of usb drivers on physical
-device attach and detach events.
+device attach and detach events by reading
+.B /dev/usbevent
+file.
 .SH SOURCE
 .B /rc/bin/nusbrc
 .B /sys/src/9/boot/nusbrc
 .SH "SEE ALSO"
 .IR nusb (4)
+.SH BUGS
+Usb devices appear as files under
+.B /dev
+and
+.B /shr
+identified by the devices uniqueue name assigned by usbd.
+When the environment variable
+.I nousbhname
+is defined, devies are named by ther dynamically assigned
+usb device address instead. This emulates the old behaviour.
--- a/sys/man/8/plan9.ini
+++ b/sys/man/8/plan9.ini
@@ -812,6 +812,11 @@
 .SS \fLusbwait=\fIvalue\fP
 This changes the sleep time from the default 2 to value in cases of
 USB devices taking a long time to come online.
+.SS \fLnousbhname=\fP
+When defined,
+.IR nusbrc (8)
+will use the dynamically assigned usb device address to name
+usb devices instead of the device uniqueue name.
 .SS VIDEO
 .SS \fLmonitor=\fIvalue\fP
 .SS \fLvgasize=\fIvalue\fP
--- a/sys/src/9/boot/nusbrc
+++ b/sys/src/9/boot/nusbrc
@@ -11,29 +11,33 @@
 @{
 	rfork ne
 	fn attach {
+		id=$1
+		if(~ $#* 5 && ! test -e /env/nousbhname)
+			id=$1:$5
 		switch($2$3){
 		case 0b957720 0b95772a 0db0a877 13b10018 15577720 20013c05 07d13c05 05ac1402
-			nusb/ether -t a88772 $etherargs $1
+			nusb/ether -t a88772 $etherargs $id
 		case 0b951780 14eaab11 17370039 0411006e 050d5055
-			nusb/ether -t a88178 $etherargs $1
+			nusb/ether -t a88178 $etherargs $id
 		case 2001abc1
-			nusb/ether -t aue $etherargs $1
+			nusb/ether -t aue $etherargs $id
 		case 0bda8150
-			nusb/ether -t url $etherargs $1
+			nusb/ether -t url $etherargs $id
 		case 18d14ee3 0bb40003
-			nusb/ether -t rndis $etherargs $1
+			nusb/ether -t rndis $etherargs $id
 		case *
 			switch($4){
 			case *03
-				nusb/kb $1
+				nusb/kb $id
 			case *02
 				# CDC ethernet
-				nusb/ether $etherargs $1
+				nusb/ether $etherargs $id
 			case *08
-				if(nusb/disk $1) {@{
+				if(nusb/disk $id) {@{
 					rfork ne
 					cd '#σ/usb'
-					for(dev in sdU^$1.*) if(test -d $dev) {
+					devs=sdU^($1 $5)
+					for(dev in $devs $devs.*) if(test -d $dev) {
 						diskparts $dev
 						for(part in $dev/dos* $dev/9fat) if(test -r $part) {
 							mkdir -m 0700 '#σc/'^$dev || exit
@@ -45,12 +49,13 @@
 				}&}
 			case *
 				if(~ $2 0424)
-					nusb/ether -t smsc $etherargs $1
+					nusb/ether -t smsc $etherargs $id
 			}
 		}
 	}
 	fn detach {
-		rm -rf '#σc/usb/'^$1.* '#σc/sdU'^$1.* '#σc/usbnet/'^$1.*
+		devs='#σc/sdU'^($1 $5)
+		rm -rf '#σc/usb/'^$1.* '#σc/usbnet/'^$1.* $devs $devs.* 
 	}
 	rc < '#σ/usb/usbevent' &
 }
--- a/sys/src/cmd/iostats/statfs.h
+++ b/sys/src/cmd/iostats/statfs.h
@@ -5,7 +5,7 @@
 #define DEBUGFILE	"iostats.out"
 #define DONESTR		"done"
 #define DEBUG		if(!dbg){}else fprint
-#define MAXPROC		16
+#define MAXPROC		64
 #define FHASHSIZE	64
 #define fidhash(s)	fhash[s%FHASHSIZE]
 
--- a/sys/src/cmd/nusb/audio/audio.c
+++ b/sys/src/cmd/nusb/audio/audio.c
@@ -184,7 +184,7 @@
 	if(argc == 0)
 		usage();
 
-	if((d = getdev(atoi(*argv))) == nil)
+	if((d = getdev(*argv)) == nil)
 		sysfatal("getdev: %r");
 	audiodev = d;
 
--- a/sys/src/cmd/nusb/disk/disk.c
+++ b/sys/src/cmd/nusb/disk/disk.c
@@ -1042,7 +1042,7 @@
 	if(argc != 1)
 		usage();
 	
-	dev = getdev(atoi(*argv));
+	dev = getdev(*argv);
 	if(dev == nil)
 		sysfatal("getdev: %r");
 	ums = dev->aux = emallocz(sizeof(Ums), 1);
@@ -1062,7 +1062,10 @@
 
 	for(i = 0; i <= ums->maxlun; i++){
 		lun = &ums->lun[i];
-		snprint(lun->name, sizeof(lun->name), "sdU%d.%d", dev->id, i);
+		if(ums->maxlun > 0)
+			snprint(lun->name, sizeof(lun->name), "sdU%s.%d", dev->hname, i);
+		else
+			snprint(lun->name, sizeof(lun->name), "sdU%s", dev->hname);
 		makeparts(lun);
 	}
 	snprint(buf, sizeof buf, "%d.disk", dev->id);
--- a/sys/src/cmd/nusb/ether/ether.c
+++ b/sys/src/cmd/nusb/ether/ether.c
@@ -819,7 +819,7 @@
 	if(argc != 1)
 		usage();
 
-	if((d = getdev(atoi(*argv))) == nil)
+	if((d = getdev(*argv)) == nil)
 		sysfatal("getdev: %r");
 	if(findendpoints(d, &ei, &eo) < 0)
 		sysfatal("no endpoints found");
@@ -847,7 +847,7 @@
 
 	atnotify(inote, 1);
 	time0 = time(0);
-	tab[Qiface].name = smprint("etherU%d", d->id);
+	tab[Qiface].name = smprint("etherU%s", d->hname);
 	snprint(s, sizeof(s), "%d.ether", d->id);
 	closedev(d);
 	threadpostsharesrv(&fs, nil, "usbnet", s);
--- a/sys/src/cmd/nusb/joy/joy.c
+++ b/sys/src/cmd/nusb/joy/joy.c
@@ -410,7 +410,7 @@
 	}ARGEND;
 	if(argc != 1)
 		usage();
-	d = getdev(atoi(*argv));
+	d = getdev(*argv);
 	if(d == nil)
 		sysfatal("getdev: %r");
 	ud = d->usb;
--- a/sys/src/cmd/nusb/kb/kb.c
+++ b/sys/src/cmd/nusb/kb/kb.c
@@ -794,7 +794,7 @@
 	}ARGEND;
 	if(argc != 1)
 		usage();
-	d = getdev(atoi(*argv));
+	d = getdev(*argv);
 	if(d == nil)
 		sysfatal("getdev: %r");
 	ud = d->usb;
--- a/sys/src/cmd/nusb/lib/dev.c
+++ b/sys/src/cmd/nusb/lib/dev.c
@@ -121,6 +121,7 @@
 		free(d);
 		return nil;
 	}
+	d->hname = nil;
 	dprint(2, "%s: opendev %#p %s\n", argv0, d, fn);
 	return d;
 }
@@ -323,6 +324,8 @@
 	d->cfd = d->dfd = -1;
 	free(d->dir);
 	d->dir = nil;
+	free(d->hname);
+	d->hname = nil;
 	ud = d->usb;
 	d->usb = nil;
 	if(ud != nil){
@@ -509,12 +512,26 @@
 }
 
 Dev *
-getdev(int id)
+getdev(char *devid)
 {
+	char buf[40], *p;
 	Dev *d;
-	char buf[40];
-	
-	snprint(buf, sizeof buf, "/dev/usb/ep%d.0", id);
+
+	if(devid[0] == '/' || devid[0] == '#'){
+		snprint(buf, sizeof buf, "%s", devid);
+		p = strrchr(buf, '/');
+		if(p != nil){
+			p = strrchr(buf, ':');
+			if(p != nil)
+				*p = 0;
+		}
+	} else {
+		p = nil;
+		snprint(buf, sizeof buf, "/dev/usb/ep%ld.0", strtol(devid, &p, 10));
+		if(*p != ':')
+			p = nil;
+	}
+
 	d = opendev(buf);
 	if(d == nil)
 		return nil;
@@ -522,5 +539,12 @@
 		closedev(d);
 		return nil;
 	}
+
+	if(p == nil){
+		snprint(buf, sizeof buf, ":%d", d->id);
+		p = buf;
+	}
+	d->hname = strdup(p+1);
+
 	return d;
 }
--- a/sys/src/cmd/nusb/lib/usb.h
+++ b/sys/src/cmd/nusb/lib/usb.h
@@ -174,6 +174,7 @@
 	Usbdev*	usb;		/* USB description */
 	void*	aux;		/* for the device driver */
 	void	(*free)(void*);	/* idem. to release aux */
+	char*	hname;		/* hash name, uniqueue for device */
 };
 
 /*
@@ -351,7 +352,7 @@
 int	parsedev(Dev *xd, uchar *b, int n);
 int	unstall(Dev *dev, Dev *ep, int dir);
 int	usbcmd(Dev *d, int type, int req, int value, int index, uchar *data, int count);
-Dev*	getdev(int id);
+Dev*	getdev(char *devid);
 
 extern int usbdebug;	/* more messages for bigger values */
 
--- a/sys/src/cmd/nusb/ptp/ptp.c
+++ b/sys/src/cmd/nusb/ptp/ptp.c
@@ -1011,7 +1011,7 @@
 
 	if(argc == 0)
 		usage();
-	if((d = getdev(atoi(*argv))) == nil)
+	if((d = getdev(*argv)) == nil)
 		sysfatal("opendev: %r");
 	if(findendpoints(d, &epin, &epout, &epint)  < 0)
 		sysfatal("findendpoints: %r");
@@ -1037,7 +1037,7 @@
 
 	time0 = time(0);
 
-	snprint(name, sizeof name, "sdU%d", d->id);
+	snprint(name, sizeof name, "sdU%s", d->hname);
 	snprint(desc, sizeof desc, "%d.ptp", d->id);
 	threadpostsharesrv(&fs, nil, name, desc);
 
--- a/sys/src/cmd/nusb/serial/serial.c
+++ b/sys/src/cmd/nusb/serial/serial.c
@@ -810,7 +810,7 @@
 	}ARGEND
 	if(argc != 1)
 		usage();
-	dev = getdev(atoi(*argv));
+	dev = getdev(*argv);
 	if(dev == nil)
 		sysfatal("getdev: %r");
 
@@ -859,17 +859,10 @@
 		}
 
 		dsprint(2, "serial: adding interface %d, %p\n", p->interfc, p);
-		if(p->isjtag){
-			snprint(p->name, sizeof p->name, "jtag");
-			dsprint(2, "serial: JTAG interface %d %p\n", i, p);
-			snprint(p->name, sizeof p->name, "jtag%d.%d", dev->id, i);
-		} else {
-			snprint(p->name, sizeof p->name, "eiaU");
-			if(i == 0)
-				snprint(p->name, sizeof p->name, "eiaU%d", dev->id);
-			else
-				snprint(p->name, sizeof p->name, "eiaU%d.%d", dev->id, i);
-		}
+		if(ser->nifcs == 1)
+			snprint(p->name, sizeof p->name, "%s%s", p->isjtag ? "jtag" : "eiaU", dev->hname);
+		else
+			snprint(p->name, sizeof p->name, "%s%s.%d", p->isjtag ? "jtag" : "eiaU", dev->hname, i);
 		fprint(2, "%s...", p->name);
 		incref(dev);
 		p->readrend.l = &p->readq;
--- a/sys/src/cmd/nusb/usbd/fns.h
+++ b/sys/src/cmd/nusb/usbd/fns.h
@@ -2,3 +2,4 @@
 void	detachdev(Port*);
 void	work(void);
 Hub*	newhub(char *, Dev *);
+void	hname(char *);
--- /dev/null
+++ b/sys/src/cmd/nusb/usbd/hname.c
@@ -1,0 +1,17 @@
+#include <u.h>
+#include <libc.h>
+#include <mp.h>
+#include <libsec.h>
+
+void
+hname(char *buf)
+{
+	uchar d[SHA1dlen];
+	u32int x;
+	int n;
+
+	n = strlen(buf);
+	sha1((uchar*)buf, n, d, nil);
+	x = d[0] | d[1]<<8 | d[2]<<16;
+	snprint(buf, n+1, "%.5ux", x & 0xfffff);
+}
--- a/sys/src/cmd/nusb/usbd/mkfile
+++ b/sys/src/cmd/nusb/usbd/mkfile
@@ -3,6 +3,7 @@
 OFILES=\
 	usbd.$O\
 	hub.$O\
+	hname.$O\
 
 HFILES=\
 	dat.h\
--- a/sys/src/cmd/nusb/usbd/usbd.c
+++ b/sys/src/cmd/nusb/usbd/usbd.c
@@ -221,8 +221,10 @@
 formatdev(Dev *d, int type)
 {
 	Usbdev *u = d->usb;
-
-	return smprint("%s %d %.4x %.4x %.8lx\n", type ? "detach" : "attach", d->id, u->vid, u->did, u->csp);
+	return smprint("%s %d %.4x %.4x %.6lx %s\n",
+		type ? "detach" : "attach",
+		d->id, u->vid, u->did, u->csp, 
+		d->hname != nil ? d->hname : "");
 }
 
 static void
@@ -335,6 +337,39 @@
 	.destroyfid = usbddestroyfid,
 };
 
+static void
+assignhname(Dev *dev)
+{
+	extern Hub *hubs;
+	char buf[64];
+	Usbdev *ud;
+	Hub *h;
+	int i;
+
+	ud = dev->usb;
+
+	/* build string of device uniqueue stuff */
+	snprint(buf, sizeof(buf), "%.4x%.4x%.4x%.6lx%s",
+		ud->vid, ud->did, ud->dno, ud->csp, ud->serial);
+
+	hname(buf);
+
+	/* check for collisions */
+	for(h = hubs; h != nil; h = h->next){
+		for(i = 1; i <= h->nport; i++){
+			if(h->port[i].dev == nil)
+				continue;
+			if(h->port[i].dev->hname == nil || h->port[i].dev == dev)
+				continue;
+			if(strcmp(h->port[i].dev->hname, buf) == 0){
+				dev->hname = smprint("%s%d", buf, dev->id);
+				return;
+			}
+		}
+	}
+	dev->hname = strdup(buf);
+}
+
 int
 attachdev(Port *p)
 {
@@ -355,6 +390,9 @@
 	/* close control endpoint so driver can open it */
 	close(d->dfd);
 	d->dfd = -1;
+
+	/* assign stable name based on device descriptor */
+	assignhname(d);
 	
 	pushevent(d, formatdev(d, 0));
 	return 0;