Browse Source

Plan 9 from Bell Labs 2011-01-06

David du Colombier 13 years ago
parent
commit
a57b1c8ee5

+ 19 - 5
sys/src/9/pc/boot.fs

@@ -168,18 +168,32 @@ rootspec=main/active
 # newns() needs it, among others.
 
 # mount new root
-echo -n mount /srv/boot /root...
-mount -cC /srv/boot /root
-bind -a /root /
+if (test -e /srv/boot)
+	srv=boot
+if not if (test -e /srv/fossil)
+	srv=fossil
+if not if (test -e /srv/fsmain)
+	srv=fsmain
+if not {
+	echo cannot find a root in /srv:
+	ls -l /srv
+}
+echo -n mount -cC /srv/$srv $rootdir...
+	mount -cC /srv/$srv $rootdir
+bind -a $rootdir /
 
-bind -ac /root/mnt /mnt
+if (test -d $rootdir/mnt)
+	bind -ac $rootdir/mnt /mnt
 mount -b /srv/factotum /mnt
 
 # standard bin
+if (! test -d /$cputype) {
+	echo /$cputype missing!
+	exec ./rc -m/boot/rcmain -i
+}
 bind /$cputype/bin /bin
 bind -a /rc/bin /bin
 
-
 # run cpurc
 echo cpurc...
 path=(/bin . /boot)

+ 4 - 3
sys/src/9/port/chan.c

@@ -1013,7 +1013,8 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror)
 				 * mh->mount->to == c, so start at mh->mount->next
 				 */
 				rlock(&mh->lock);
-				for(f = mh->mount->next; f; f = f->next)
+				f = mh->mount;
+				for(f = (f? f->next: f); f; f = f->next)
 					if((wq = ewalk(f->to, nil, names+nhave, ntry)) != nil)
 						break;
 				runlock(&mh->lock);
@@ -1263,7 +1264,7 @@ namelenerror(char *aname, int len, char *err)
 			if(name <= aname)
 				panic("bad math in namelenerror");
 			/* walk out of current UTF sequence */
-			for(i=0; (*name&0xC0)==0x80 && i<3; i++)
+			for(i=0; (*name&0xC0)==0x80 && i<UTFmax; i++)
 				name++;
 		}
 		snprint(up->genbuf, sizeof up->genbuf, "...%.*s",
@@ -1687,7 +1688,7 @@ validname0(char *aname, int slashok, int dup, ulong pc)
 	name = aname;
 	if((ulong)name < KZERO){
 		if(!dup)
-			print("warning: validname called from %lux with user pointer", pc);
+			print("warning: validname called from %#p with user pointer", pc);
 		ename = vmemchr(name, 0, (1<<16));
 	}else
 		ename = memchr(name, 0, (1<<16));

+ 59 - 19
sys/src/cmd/sha1sum.c

@@ -1,3 +1,6 @@
+/*
+ * sha1sum - compute SHA1 or SHA2 digest
+ */
 #include <u.h>
 #include <libc.h>
 #include <bio.h>
@@ -5,16 +8,33 @@
 
 #pragma	varargck	type	"M"	uchar*
 
+typedef struct Sha2 Sha2;
+struct Sha2 {
+	int	bits;
+	int	dlen;
+	DigestState* (*func)(uchar *, ulong, uchar *, DigestState *);
+};
+
+static Sha2 sha2s[] = {
+	224,	SHA2_224dlen,	sha2_224,
+	256,	SHA2_256dlen,	sha2_256,
+	384,	SHA2_384dlen,	sha2_384,
+	512,	SHA2_512dlen,	sha2_512,
+};
+
+static DigestState* (*shafunc)(uchar *, ulong, uchar *, DigestState *);
+static int shadlen;
+
 static int
 digestfmt(Fmt *fmt)
 {
-	char buf[SHA1dlen*2+1];
+	char buf[SHA2_512dlen*2 + 1];
 	uchar *p;
 	int i;
 
 	p = va_arg(fmt->args, uchar*);
-	for(i=0; i<SHA1dlen; i++)
-		sprint(buf+2*i, "%.2ux", p[i]);
+	for(i = 0; i < shadlen; i++)
+		sprint(buf + 2*i, "%.2ux", p[i]);
 	return fmtstrcpy(fmt, buf);
 }
 
@@ -22,46 +42,66 @@ static void
 sum(int fd, char *name)
 {
 	int n;
-	uchar buf[8192], digest[SHA1dlen];
+	uchar buf[8192], digest[SHA2_512dlen];
 	DigestState *s;
 
-	s = sha1(nil, 0, nil, nil);
+	s = (*shafunc)(nil, 0, nil, nil);
 	while((n = read(fd, buf, sizeof buf)) > 0)
-		sha1(buf, n, nil, s);
+		(*shafunc)(buf, n, nil, s);
 	if(n < 0){
-		fprint(2, "reading %s: %r\n", name ? name : "stdin");
+		fprint(2, "reading %s: %r\n", name? name: "stdin");
 		return;
 	}
-	sha1(nil, 0, digest, s);
+	(*shafunc)(nil, 0, digest, s);
 	if(name == nil)
 		print("%M\n", digest);
 	else
 		print("%M\t%s\n", digest, name);
 }
 
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [-2 bits] [file...]\n", argv0);
+	exits("usage");
+}
+
 void
 main(int argc, char *argv[])
 {
-	int i, fd;
+	int i, fd, bits;
+	Sha2 *sha;
 
+	shafunc = sha1;
+	shadlen = SHA1dlen;
 	ARGBEGIN{
+	case '2':
+		bits = atoi(EARGF(usage()));
+		for (sha = sha2s; sha < sha2s + nelem(sha2s); sha++)
+			if (sha->bits == bits)
+				break;
+		if (sha >= sha2s + nelem(sha2s))
+			sysfatal("unknown number of sha2 bits: %d", bits);
+		shafunc = sha->func;
+		shadlen = sha->dlen;
+		break;
 	default:
-		fprint(2, "usage: sha1sum [file...]\n");
-		exits("usage");
+		usage();
 	}ARGEND
 
 	fmtinstall('M', digestfmt);
 
 	if(argc == 0)
 		sum(0, nil);
-	else for(i = 0; i < argc; i++){
-		fd = open(argv[i], OREAD);
-		if(fd < 0){
-			fprint(2, "sha1sum: can't open %s: %r\n", argv[i]);
-			continue;
+	else
+		for(i = 0; i < argc; i++){
+			fd = open(argv[i], OREAD);
+			if(fd < 0){
+				fprint(2, "%s: can't open %s: %r\n", argv0, argv[i]);
+				continue;
+			}
+			sum(fd, argv[i]);
+			close(fd);
 		}
-		sum(fd, argv[i]);
-		close(fd);
-	}
 	exits(nil);
 }

+ 49 - 23
sys/src/cmd/usb/serial/ftdi.c

@@ -211,7 +211,7 @@ enum {
 };
 
 static int
-ftdiread(Serialport *p, int val, int index, int req, uchar *buf)
+ftdiread(Serialport *p, int index, int req, uchar *buf, int len)
 {
 	int res;
 	Serial *ser;
@@ -220,9 +220,9 @@ ftdiread(Serialport *p, int val, int index, int req, uchar *buf)
 
 	if(req != FTGETE2READ)
 		index |= p->interfc + 1;
-	dsprint(2, "serial: ftdiread %#p [%d] req: %#x val: %#x idx:%d buf:%p\n",
-		p, p->interfc, req, val, index, buf);
-	res = usbcmd(ser->dev,  Rd2h | Rftdireq | Rdev, req, val, index, buf, 1);
+	dsprint(2, "serial: ftdiread %#p [%d] req: %#x val: %#x idx:%d buf:%p len:%d\n",
+		p, p->interfc, req, 0, index, buf, len);
+	res = usbcmd(ser->dev,  Rd2h | Rftdireq | Rdev, req, 0, index, buf, len);
 	dsprint(2, "serial: ftdiread res:%d\n", res);
 	return res;
 }
@@ -235,7 +235,8 @@ ftdiwrite(Serialport *p, int val, int index, int req)
 
 	ser = p->s;
 
-	index |= p->interfc + 1;
+	if(req != FTGETE2READ || req != FTSETE2ERASE || req != FTSETBAUDRATE)
+		index |= p->interfc + 1;
 	dsprint(2, "serial: ftdiwrite %#p [%d] req: %#x val: %#x idx:%d\n",
 		p, p->interfc, req, val, index);
 	res = usbcmd(ser->dev, Rh2d | Rftdireq | Rdev, req, val, index, nil, 0);
@@ -263,9 +264,9 @@ ft232ambaudbase2div(int baud, int base)
 	ushort divisor;
 
 	divisor3 = (base / 2) / baud;
- 	if((divisor3 & 7) == 7)
-		divisor3++; 			/* round x.7/8 up to x+1 */
- 	divisor = divisor3 >> 3;
+	if((divisor3 & 7) == 7)
+		divisor3++;			/* round x.7/8 up to x+1 */
+	divisor = divisor3 >> 3;
 	divisor3 &= 7;
 
 	if(divisor3 == 1)
@@ -274,7 +275,7 @@ ft232ambaudbase2div(int baud, int base)
 		divisor |= 0x4000;		/*	0.5	*/
 	else if(divisor3 != 0)
 		divisor |= 0x8000;		/*	0.25	*/
- 	if( divisor == 1)
+	if( divisor == 1)
 		divisor = 0;		/* special case for maximum baud rate */
 	return divisor;
 }
@@ -303,9 +304,9 @@ ft232bmbaudbase2div(int baud, int base)
 	divisor3 = (base / 2) / baud;
 	divisor = divisor3 >> 3 | divfrac[divisor3 & 7] << 14;
 
- 	/* Deal with special cases for highest baud rates. */
- 	if( divisor == 1)
-		divisor = 0; 			/* 1.0 */
+	/* Deal with special cases for highest baud rates. */
+	if( divisor == 1)
+		divisor = 0;			/* 1.0 */
 	else if( divisor == 0x4001)
 		divisor = 1;			/* 1.5 */
 	return divisor;
@@ -341,8 +342,8 @@ ftbaudcalcdiv(Serial *ser, int baud)
 	if(baud == 0)
 		baud = 9600;
 
- 	switch(ser->type) {
- 	case SIO:
+	switch(ser->type) {
+	case SIO:
 		switch(baud) {
 		case 300:
 			divval = FTb300;
@@ -379,12 +380,12 @@ ftbaudcalcdiv(Serial *ser, int baud)
 			break;
 		}
 		break;
- 	case FT8U232AM:
-	 	if(baud <= 3000000)
+	case FT8U232AM:
+		if(baud <= 3000000)
 			divval = ft232ambaud2div(baud);
 		else
 			divval = ft232ambaud2div(9600);
- 		break;
+		break;
 	case FT232BM:
 	case FT2232C:
 	case FTKINDR:
@@ -445,7 +446,7 @@ ftsetparam(Serialport *p)
 		return res;
 
 	bauddiv = ftbaudcalcdiv(p->s, p->baud);
-	res = ftdiwrite(p, bauddiv, (bauddiv>>16) & 1, FTSETBaudRate);
+	res = ftdiwrite(p, bauddiv, (bauddiv>>16) & 1, FTSETBAUDRATE);
 
 	dsprint(2, "serial: setparam res: %d\n", res);
 	return res;
@@ -460,7 +461,7 @@ ftgettype(Serial *ser)
 	Conf *cnf;
 
 	pksz = Packsz;
- 	/* Assume it is not the original SIO device for now. */
+	/* Assume it is not the original SIO device for now. */
 	baudbase = ClockNew / 2;
 	outhdrsz = 0;
 	dno = ser->dev->usb->dno;
@@ -762,11 +763,11 @@ statusreader(void *u)
 		memmove(p->data, pk->b, pk->nb);
 		p->ndata = pk->nb;
 		free(pk);
-		dsprint(2, "serial: status reader %d \n", p->ndata);
+		dsprint(2, "serial %p: status reader %d \n", p, p->ndata);
 		/* consume it all */
 		while(p->ndata != 0){
-			dsprint(2, "serial: status reader to consume: %d\n",
-				p->ndata);
+			dsprint(2, "serial %p: status reader to consume: %d\n",
+				p, p->ndata);
 			cl = recvul(p->w4data);
 			if(cl  < 0)
 				break;
@@ -790,7 +791,7 @@ ftreset(Serial *ser)
 
 	p = ser->p;
 	for(i = 0; i < Maxifc; i++)
-		if(!p[i].isjtag && p[i].s != nil)
+		if(p[i].s != nil)
 			ftdiwrite(&p[i], FTRESETCTLVAL, 0, FTRESET);
 	return 0;
 }
@@ -799,8 +800,33 @@ static int
 ftinit(Serialport *p)
 {
 	Serial *ser;
+	uint timerval;
+	int res;
 
 	ser = p->s;
+	if(p->isjtag){
+		res = ftdiwrite(p, FTSETFLOWCTRL, 0, FTDISABLEFLOWCTRL);
+		if(res < 0)
+			return -1;
+		res = ftdiread(p, FTSETLATENCYTIMER, 0, (uchar *)&timerval,
+			FTLATENCYTIMERSZ);
+		if(res < 0)
+			return -1;
+		dsprint(2, "serial: jtag latency timer is %d\n", timerval);
+		timerval = 2;
+		ftdiwrite(p, FTLATENCYDEFAULT, 0, FTSETLATENCYTIMER);
+		res = ftdiread(p, FTSETLATENCYTIMER, 0, (uchar *)&timerval,
+			FTLATENCYTIMERSZ);
+		if(res < 0)
+			return -1;
+
+		dsprint(2, "serial: jtag latency timer set to %d\n", timerval);
+		/* may be unnecessary */
+		devctl(p->epin,  "timeout 5000");
+		devctl(p->epout, "timeout 5000");
+		/* 0xb is the mask for lines. plug dependant? */
+		ftdiwrite(p, BMMPSSE|0x0b, 0, FTSETBITMODE);
+	}
 	incref(ser->dev);
 	threadcreate(statusreader, p, 8*1024);
 	return 0;

+ 72 - 20
sys/src/cmd/usb/serial/ftdi.h

@@ -7,7 +7,7 @@ enum {
 	FTOpenRDUltDid	= 0x9E90,
 
 	FTSIODid	= 0x8372,	/* Product Id SIO appl'n of 8U100AX */
-	FT8U232AMDid	= 0x6001, 	/* Similar device to SIO above */
+	FT8U232AMDid	= 0x6001,	/* Similar device to SIO above */
 	FT8U232AMALTDid	= 0x6006,	/* FT's alternate Did for above*/
 	FT8U2232CDid	= 0x6010,	/* Dual channel device */
 	FTRELAISDid	= 0xFA10,	/* Relais device */
@@ -385,7 +385,7 @@ enum {
 	 * new high speed devices
 	 */
 	FT4232HDid	= 0x6011,		/* FTDI FT4232H based device */
-	
+
 };
 
 /* Commands */
@@ -393,18 +393,25 @@ enum {
 	FTRESET		= 0,		/* Reset the port */
 	FTSETMODEMCTRL,			/* Set the modem control register */
 	FTSETFLOWCTRL,			/* Set flow control register */
-	FTSETBaudRate,			/* Set baud rate */
+	FTSETBAUDRATE,			/* Set baud rate */
 	FTSETDATA,			/* Set the parameters, parity */
 	FTGETMODEMSTATUS,		/* Retrieve current value of modem ctl */
 	FTSETEVENTCHAR,			/* Set the event character */
 	FTSETERRORCHAR,			/* Set the error character */
+	FTUNKNOWN,
 	FTSETLATENCYTIMER,		/* Set the latency timer */
 	FTGETLATENCYTIMER,		/* Get the latency timer */
-	FTSETBITMODE,			/* Set bigbang mode */
+	FTSETBITMODE,			/* Set bit mode */
 	FTGETPINS,			/* Read pins state */
-	FTGETE2READ	= 0x90,		/* Read an address from EEPROM */
-	FTSETE2WRITE,			/* Write to address on the EEPROM */
-	FTSETE2ERASE,			/* Erase address on the EEPROM */
+	FTGETE2READ	= 0x90,		/* Read address from 128-byte I2C EEPROM */
+	FTSETE2WRITE,			/* Write to address on 128-byte I2C EEPROM */
+	FTSETE2ERASE,			/* Erase address on 128-byte I2C EEPROM */
+};
+
+/* Port Identifier Table, index for interfaces */
+enum {
+	PITDEFAULT = 0,		/* SIOA */
+	PITA,			/* SIOA jtag if there is one */
 };
 
 enum {
@@ -417,22 +424,31 @@ enum {
  * Gets have wValue = 0
  */
 enum {
-	FTGETMODEMSTATUSSZ	= 1,
-	FTGETLATENCYTIMERSZ	= 0,		/* Get the latency timer */
-	FTGETE2READSZ		= 2,		/* Read an address */
+	FTMODEMSTATUSSZ	= 1,
+	FTLATENCYTIMERSZ= 1,
+	FTPINSSZ	= 1,
+	FTE2READSZ	= 2,
 };
 
 /*
  * bRequest: FTGETE2READ
  * wIndex: Address of word to read
- * Data: Will return a word of data from E2Address
+ * Data: Will return a word (2 bytes) of data from E2Address
+ * Results put in the I2C 128 byte EEPROM string eeprom+(2*index)
  */
 
-/* Port Identifier Table */
-enum {
-	PITDEFAULT = 0,		/* SIOA */
-	PITA,			/* SIOA */
-};
+/*
+ * bRequest: FTSETE2WRITE
+ * wIndex: Address of word to read
+ * wValue: Value of the word
+ * Data: Will return a word (2 bytes) of data from E2Address
+ */
+
+/*
+ * bRequest: FTSETE2ERASE
+ * Erases the EEPROM
+ * wIndex: 0
+ */
 
 /*
  * bRequest: FTRESET
@@ -447,7 +463,7 @@ enum {
 
 /*
  * BmRequestType: SET
- * bRequest: FTSETBaudRate
+ * bRequest: FTSETBAUDRATE
  * wValue: BaudDivisor value - see below
  * Bits 15 to 0 of the 17-bit divisor are placed in the request value.
  * Bit 16 is placed in bit 0 of the request index.
@@ -480,6 +496,7 @@ enum {
 /*
  * bRequest: FTSETDATA
  * wValue: Data characteristics
+ *	bits 0-7 number of data bits
  * wIndex: Port
  */
 enum {
@@ -503,7 +520,7 @@ enum {
 /*
  * bRequest: FTSETFLOWCTRL
  * wValue: Xoff/Xon
- * wIndex: Protocol/Port - hIndex is protocl / lIndex is port
+ * wIndex: Protocol/Port - hIndex is protocol; lIndex is port
  */
 enum {
 	FTDISABLEFLOWCTRL= 0,
@@ -519,26 +536,61 @@ enum {
  * Data: latency (on return)
  */
 
+/*
+ * bRequest: FTSETBITMODE
+ * wIndex: Port
+ * either it is big bang mode, in which case
+ * wValue: 1 byte L is the big bang mode BIG*
+ *	or BM is
+ * wValue: 1 byte bitbang mode H, 1 byte bitmask for lines L
+ */
+enum {
+	BMSERIAL	= 0,		/* reset, turn off bit-bang mode */
+
+	BIGBMNORMAL	= 1,		/* normal bit-bang mode */
+	BIGBMSPI	= 2,		/* spi bit-bang mode */
+
+	BMABM		= 1<<8,		/* async mode */
+	BMMPSSE		= 2<<8,
+	BMSYNCBB	= 4<<8,		/* sync bit-bang -- 2232x and R-type */
+	BMMCU		= 8<<8,		/* MCU Host Bus -- 2232x */
+	BMOPTO		= 0x10<<8,	/* opto-isolated<<8, 2232x */
+	BMCBUS		= 0x20<<8,	/* CBUS pins of R-type chips */
+	BMSYNCFF	= 0x40<<8,	/* Single Channel Sync FIFO, 2232H only */
+};
+
 /*
  * bRequest: FTSETLATENCYTIMER
- * wValue: Latency (milliseconds)
+ * wValue: Latency (milliseconds 1-255)
  * wIndex: Port
  */
+enum {
+	FTLATENCYDEFAULT = 2,
+};
 
 /*
  * BmRequestType: SET
  * bRequest: FTSETEVENTCHAR
  * wValue: EventChar
  * wIndex: Port
+ * 0-7 lower bits event char
+ * 8 enable
  */
+enum {
+	FTEVCHARENAB = 1<<8,
+};
 
 /*
  * BmRequestType: SET
  * bRequest: FTSETERRORCHAR
  * wValue: Error Char
  * wIndex: Port
+ * 0-7 lower bits event char
+ * 8 enable
  */
-
+enum {
+	FTERRCHARENAB = 1<<8,
+};
 /*
  * BmRequestType: GET
  * bRequest: FTGETMODEMSTATUS

+ 39 - 29
sys/src/cmd/usb/serial/serial.c

@@ -32,8 +32,8 @@ struct Dirtab {
 
 static Dirtab dirtab[] = {
 	[Qroot]	"/",		DMDIR|0555,
-	[Qdata]	"eiaU",		0660,
-	[Qctl]	"eiaUctl",	0664,
+	[Qdata]	"%s",		0660,
+	[Qctl]	"%sctl",	0664,
 };
 
 static int sdebug;
@@ -49,8 +49,6 @@ serialfatal(Serial *ser)
 
 	for(i = 0; i < ser->nifcs; i++){
 		p = &ser->p[i];
-		if(p->isjtag)
-			continue;
 		usbfsdel(&p->fs);
 		if(p->w4data != nil)
 			chanclose(p->w4data);
@@ -93,8 +91,6 @@ serialreset(Serial *ser)
 	/* cmd for reset */
 	for(i = 0; i < ser->nifcs; i++){
 		p = &ser->p[i];
-		if(p->isjtag)
-			continue;
 		serialdrain(p);
 	}
 	if(ser->reset != nil)
@@ -342,7 +338,7 @@ dwalk(Usbfs *fs, Fid *fid, char *name)
 
 	p = fs->aux;
 	for(i = 1; i < nelem(dirtab); i++){
-		dname = smprint(dirtab[i].name, p->fs.name);
+		dname = smprint(dirtab[i].name, p->name);
 		if(strcmp(name, dname) == 0){
 			qid.path = i | fs->qid;
 			qid.vers = 0;
@@ -401,6 +397,8 @@ dopen(Usbfs *fs, Fid *fid, int)
 		break;
 	case Qctl:
 		dsprint(2, "serial, opened ctl\n");
+		if(p->isjtag)
+			return 0;
 		serialctl(p, "l8 i1");	/* default line parameters */
 		break;
 	}
@@ -409,24 +407,27 @@ dopen(Usbfs *fs, Fid *fid, int)
 
 
 static void
-filldir(Usbfs *fs, Dir *d, Dirtab *tab, int i)
+filldir(Usbfs *fs, Dir *d, Dirtab *tab, int i, void *v)
 {
+	Serialport *p;
+
+	p = v;
 	d->qid.path = i | fs->qid;
 	d->mode = tab->mode;
 	if((d->mode & DMDIR) != 0)
 		d->qid.type = QTDIR;
 	else
 		d->qid.type = QTFILE;
-	d->name = tab->name;
+	sprint(d->name, tab->name, p->name);	/* hope it fits */
 }
 
 static int
-dirgen(Usbfs *fs, Qid, int i, Dir *d, void *)
+dirgen(Usbfs *fs, Qid, int i, Dir *d, void *p)
 {
 	i++;				/* skip root */
 	if(i >= nelem(dirtab))
 		return -1;
-	filldir(fs, d, &dirtab[i], i);
+	filldir(fs, d, &dirtab[i], i, p);
 	return 0;
 }
 
@@ -456,7 +457,7 @@ dread(Usbfs *fs, Fid *fid, void *data, long count, vlong offset)
 	qlock(ser);
 	switch(path){
 	case Qroot:
-		count = usbdirread(fs, q, data, count, offset, dirgen, nil);
+		count = usbdirread(fs, q, data, count, offset, dirgen, p);
 		break;
 	case Qdata:
 		if(count > ser->maxread)
@@ -513,8 +514,10 @@ dread(Usbfs *fs, Fid *fid, void *data, long count, vlong offset)
 		if(offset != 0)
 			count = 0;
 		else {
-			e = serdumpst(p, buf, Serbufsize);
-			count = usbreadbuf(data, count, 0, buf, e - buf);
+			if(!p->isjtag){
+				e = serdumpst(p, buf, Serbufsize);
+				count = usbreadbuf(data, count, 0, buf, e - buf);
+			}
 		}
 		break;
 	}
@@ -533,6 +536,8 @@ altwrite(Serialport *p, uchar *buf, long count)
 
 	ser = p->s;
 	do{
+		dsprint(2, "serial: write to bulk %ld\n", count);
+
 		if(ser->wait4write != nil)
 			/* unlocked inside later */
 			nw = ser->wait4write(p, buf, count);
@@ -543,6 +548,7 @@ altwrite(Serialport *p, uchar *buf, long count)
 			qlock(ser);
 		}
 		rerrstr(err, sizeof err);
+		dsprint(2, "serial: written %s %d\n", err, nw);
 	} while(nw < 0 && strstr(err, "timed out") != nil);
 
 	if(nw != count){
@@ -572,6 +578,8 @@ dwrite(Usbfs *fs, Fid *fid, void *buf, long count, vlong)
 		count = altwrite(p, (uchar *)buf, count);
 		break;
 	case Qctl:
+		if(p->isjtag)
+			break;
 		cmd = emallocz(count+1, 1);
 		memmove(cmd, buf, count);
 		cmd[count] = 0;
@@ -610,8 +618,10 @@ openeps(Serialport *p, int epin, int epout, int epintr)
 		return -1;
 	}
 
-	devctl(p->epin,  "timeout 1000");
-	devctl(p->epout, "timeout 1000");
+	if(!p->isjtag){
+		devctl(p->epin,  "timeout 1000");
+		devctl(p->epout, "timeout 1000");
+	}
 
 	if(ser->hasepintr){
 		p->epintr = openep(ser->dev, epintr);
@@ -646,10 +656,8 @@ findendpoints(Serial *ser, int ifc)
 {
 	int i, epin, epout, epintr;
 	Ep *ep, **eps;
-	///Usbdev *ud;
 
 	epintr = epin = epout = -1;
-	//ud = ser->dev->usb;
 
 	/*
 	 * interfc 0 means start from the start which is equiv to
@@ -798,12 +806,11 @@ serialmain(Dev *dev, int argc, char* argv[])
 	for(i = 0; i < ser->nifcs; i++){
 		p = &ser->p[i];
 		p->interfc = i;
+		p->s = ser;
+		p->fs = serialfs;
 		if(i == ser->jtag){
 			p->isjtag++;
-			continue;
 		}
-		p->s = ser;
-		p->fs = serialfs;
 		if(findendpoints(ser, i) < 0){
 			werrstr("serial: no endpoints found for ifc %d", i);
 			return -1;
@@ -816,10 +823,6 @@ serialmain(Dev *dev, int argc, char* argv[])
 	serialreset(ser);
 	for(i = 0; i < ser->nifcs; i++){
 		p = &ser->p[i];
-		if(p->isjtag){
-			dsprint(2, "serial: ignoring JTAG interface %d %p\n", i, p);
-			continue;
-		}
 		dprint(2, "serial: valid interface, calling serinit\n");
 		if(serinit(p) < 0){
 			dprint(2, "serial: serinit: %r\n");
@@ -827,10 +830,17 @@ serialmain(Dev *dev, int argc, char* argv[])
 		}
 
 		dsprint(2, "serial: adding interface %d, %p\n", p->interfc, p);
-		if(i == 0)
-			snprint(p->fs.name, sizeof p->fs.name, "eiaU%d", devid);
-		else
-			snprint(p->fs.name, sizeof p->fs.name, "eiaU%d.%d", devid, i);
+		if(p->isjtag){
+			snprint(p->name, sizeof p->name, "jtag");
+			dsprint(2, "serial: JTAG interface %d %p\n", i, p);
+			snprint(p->fs.name, sizeof p->fs.name, "jtag%d.%d", devid, i);
+		} else {
+			snprint(p->name, sizeof p->name, "eiaU");
+			if(i == 0)
+				snprint(p->fs.name, sizeof p->fs.name, "eiaU%d", devid);
+			else
+				snprint(p->fs.name, sizeof p->fs.name, "eiaU%d.%d", devid, i);
+		}
 		fprint(2, "%s\n", p->fs.name);
 		p->fs.dev = dev;
 		incref(dev);

+ 1 - 0
sys/src/cmd/usb/serial/serial.h

@@ -24,6 +24,7 @@ enum {
 
 
 struct Serialport {
+	char name[32];
 	Serial	*s;		/* device we belong to */
 	int	isjtag;