This should fix the problem with usb/kb regarding hot plug of ps2 adapters. I include some other minor changes (two of them are style and comments clarified, the other one is to remove the assumption of extra allocated data in Dev.dir in one function that previously made that assumption.) Reference: /n/sources/patch/applied/kbandotherfixes Date: Fri Jun 26 12:18:00 CES 2009 Signed-off-by: nemo@lsub.org --- /sys/src/cmd/usb/kb/kb.c Fri Jun 26 12:13:10 2009 +++ /sys/src/cmd/usb/kb/kb.c Fri Jun 26 12:13:06 2009 @@ -120,14 +120,17 @@ Dev *dev; if(sts != nil) - fprint(2, "kd: %s: fatal: %s\n", kd->ep->dir, sts); - dev = kd->dev; - devctl(dev, "detach"); + fprint(2, "kb: fatal: %s\n", sts); + else + fprint(2, "kb: exiting\n"); if(kd->repeatc != nil) - sendul(kd->repeatc, Diemsg); - closedev(kd->ep); - kd->ep = nil; + nbsendul(kd->repeatc, Diemsg); + dev = kd->dev; kd->dev = nil; + if(kd->ep != nil) + closedev(kd->ep); + kd->ep = nil; + devctl(dev, "detach"); closedev(dev); /* * free(kd); done by closedev. @@ -197,12 +200,16 @@ mfd = f->in->fd; if(f->ep->maxpkt < 3 || f->ep->maxpkt > sizeof buf) - kbfatal(f, "weird maxpkt"); + kbfatal(f, "weird mouse maxpkt"); for(;;){ memset(buf, 0, sizeof buf); + if(f->ep == nil) + kbfatal(f, nil); c = read(ptrfd, buf, f->ep->maxpkt); + assert(f->dev != nil); + assert(f->ep != nil); if(c < 0) - fprint(2, "kb: %s: read: %r\n", f->ep->dir); + dprint(2, "kb: mouse: %s: read: %r\n", f->ep->dir); if(c <= 0) kbfatal(f, nil); if(c < 3) @@ -220,12 +227,10 @@ if(c > 3 && buf[3] == -1) /* down */ b |= 0x10; if(kbdebug) - fprint(2, "%s: ptr: m%11d %11d %11d\n", argv0, x, y, b); + fprint(2, "kb: m%11d %11d %11d\n", x, y, b); seprint(mbuf, mbuf+sizeof(mbuf), "m%11d %11d %11d", x, y,b); - if(write(mfd, mbuf, strlen(mbuf)) < 0){ - fprint(2, "%s: #m/mousein: write: %r", argv0); - kbfatal(f, "mousein"); - } + if(write(mfd, mbuf, strlen(mbuf)) < 0) + kbfatal(f, "mousein i/o"); if(hipri == 0){ sethipri(); hipri = 1; @@ -414,10 +419,12 @@ for(;;){ memset(buf, 0, sizeof buf); c = read(kbdfd, buf, f->ep->maxpkt); + assert(f->dev != nil); + assert(f->ep != nil); if(c < 0) - fprint(2, "%s: %s: read: %r\n", argv0, f->ep->dir); + dprint(2, "kb: %s: read: %r\n", f->ep->dir); if(c <= 0) - kbfatal(f, "eof"); + kbfatal(f, nil); if(c < 3) continue; if(kbdbusy(buf + 2, c - 2)) @@ -457,6 +464,7 @@ } qunlock(&inlck); } + dprint(2, "freekdev\n"); free(kd); } @@ -474,20 +482,15 @@ return; } } + in->ref++; /* for kd->in = in */ qunlock(&inlck); - kd = d->aux; - if(kd == nil){ - kd = d->aux = emallocz(sizeof(KDev), 1); - d->free = freekdev; - kd->in = in; - qlock(&inlck); - kd->in->ref++; - qunlock(&inlck); - kd->dev = d; - if(setbootproto(kd, ep->id) < 0){ - fprint(2, "kb: %s: bootproto: %r\n", d->dir); - return; - } + kd = d->aux = emallocz(sizeof(KDev), 1); + d->free = freekdev; + kd->in = in; + kd->dev = d; + if(setbootproto(kd, ep->id) < 0){ + fprint(2, "kb: %s: bootproto: %r\n", d->dir); + return; } kd->accel = accel; kd->ep = openep(d, ep->id); --- /sys/src/cmd/usb/lib/dev.c Fri Jun 26 12:13:14 2009 +++ /sys/src/cmd/usb/lib/dev.c Fri Jun 26 12:13:12 2009 @@ -100,7 +100,13 @@ l = strlen(fn); d->dfd = -1; - d->dir = emallocz(l + strlen("/data") + 1, 0); + /* + * +30 to allocate extra size to concat "/" + * we should probably remove that feature from the manual + * and from the code after checking out that nobody relies on + * that. + */ + d->dir = emallocz(l + 30, 0); strcpy(d->dir, fn); strcpy(d->dir+l, "/ctl"); d->cfd = open(d->dir, ORDWR|OCEXEC); @@ -119,12 +125,10 @@ int opendevdata(Dev *d, int mode) { - int l; + char buf[80]; /* more than enough for a usb path */ - l = strlen(d->dir); - strcpy(d->dir+l, "/data"); - d->dfd = open(d->dir, mode|OCEXEC); - d->dir[l] = 0; + seprint(buf, buf+sizeof(buf), "%s/data", d->dir); + d->dfd = open(buf, mode|OCEXEC); return d->dfd; } --- /sys/src/cmd/usb/lib/usb.h Fri Jun 26 12:13:19 2009 +++ /sys/src/cmd/usb/lib/usb.h Fri Jun 26 12:13:16 2009 @@ -19,7 +19,7 @@ Nconf = 16, /* max. configurations per usb device */ Nddesc = 8*Nep, /* max. device-specific descriptors per usb device */ Niface = 16, /* max. interfaces per configuration */ - Naltc = 16, /* max. channels per interface */ + Naltc = 16, /* max. alt configurations per interface */ Uctries = 4, /* no. of tries for usbcmd */ Ucdelay = 50, /* delay before retrying */ --- /sys/src/cmd/usb/usbd/dev.c Fri Jun 26 12:13:23 2009 +++ /sys/src/cmd/usb/usbd/dev.c Fri Jun 26 12:13:21 2009 @@ -144,7 +144,7 @@ fprint(2, "%s: %s: not found. can't exec\n", argv0, dt->name); sendul(sa->rc, -1); threadexits("exec"); - }else { + }else{ sa->pp->dev = opendev(d->dir); sendul(sa->rc, 0); if(dt->init(d, argc, argv) < 0){ @@ -227,7 +227,7 @@ /* * From here on the device is for the driver. * When we return pp->dev contains a Dev just for us - * with only the ctl open. Both released on the last closedev, + * with only the ctl open. Both devs are released on the last closedev: * driver's upon I/O errors and ours upon port dettach. */ if(dt->name == nil){