diff -N /sys/src/cmd/nusb/serial/cdc.c nusb/serial/cdc.c 0a1,148 > #include > #include > #include > #include > #include <9p.h> > #include "usb.h" > #include "serial.h" > > enum { > ScACM = 2, > AT = 1, > None = 0, > }; > > static int > cdcsetparam(Serialport *p) > { > int res; > uchar vals[7]; > Serial *ser; > > ser = p->s; > > PUT4(vals, p->baud); > > vals[4] = 0; > if(p->stop == 1) > vals[4] = 0; > if(p->stop == 15) > vals[4] = 1; > if(p->stop == 2) > vals[4] = 2; > > vals[5] = p->parity; > > vals[6] = p->bits; > > res = usbcmd(ser->dev, Rh2d | Rclass | Riface, 0x20, 0, 0, vals, 7); > > return res; > } > > static int > cdcinit(Serialport *p) > { > Serial *ser; > > p->baud = 115200; > p->bits = 8; > p->parity = 0; > p->stop = 1; > > ser = p->s; > > cdcsetparam(p); > incref(ser->dev); > return 0; > } > > static int > cdcsetbreak(Serialport *p, int val) > { > Serial *ser; > > ser = p->s; > return usbcmd(ser->dev, Rh2d | Rclass | Riface, 0x23, (val != 0? 0xffff: 0x0000), 0, nil, 0); > } > > static int > cdcsendlines(Serialport *p) > { > if(p->rts) > p->ctlstate |= 0x0002; > else > p->ctlstate &= ~0x0002; > if(p->dtr) > p->ctlstate |= 0x0001; > else > p->ctlstate &= ~0x0001; > > return usbcmd(p->s->dev, Rh2d | Rclass | Riface, 0x22, p->ctlstate, 0, nil, 0); > } > > static int > cdcclearpipes(Serialport *p) > { > Serial *ser; > > ser = p->s; > > if(unstall(ser->dev, p->epout, Eout) < 0) > dprint(2, "serial: unstall epout: %r\n"); > if(unstall(ser->dev, p->epin, Ein) < 0) > dprint(2, "serial: unstall epin: %r\n"); > if(unstall(ser->dev, p->epintr, Ein) < 0) > dprint(2, "serial: unstall epintr: %r\n"); > > return 0; > } > > static int > cdcwait4data(Serialport *p, uchar *data, int count) > { > int n; > > qunlock(p->s); > while ((n = read(p->epin->dfd, data, count)) == 0) > ; > qlock(p->s); > > return n; > } > > static Serialops cdcops = { > .init = cdcinit, > .setparam = cdcsetparam, > .setbreak = cdcsetbreak, > .sendlines = cdcsendlines, > .clearpipes = cdcclearpipes, > .wait4data = cdcwait4data, > }; > > int > cdcprobe(Serial *ser) > { > int i, c; > ulong csp; > Usbdev *ud = ser->dev->usb; > Ep *ep; > > c = 0; > for (i = 0; i < nelem(ud->ep); i++) { > if ((ep = ud->ep[i]) == nil) > continue; > csp = ep->iface->csp; > if (Class(csp) == Clcomms && Subclass(csp) == ScACM && Proto(csp) == AT) > c++; > } > > if (c == 0) > return -1; > > ser->nifcs = 1; > ser->outhdrsz = 0; > ser->hasepintr = 1; > ser->Serialops = cdcops; > return 0; > } diff -N /sys/src/cmd/nusb/serial/mkfile nusb/serial/mkfile 4c4 < OFILES=ftdi.$O serial.$O prolific.$O ucons.$O silabs.$O ch340.$O --- > OFILES=ftdi.$O serial.$O prolific.$O ucons.$O silabs.$O ch340.$O cdc.$O diff -N /sys/src/cmd/nusb/serial/serial.c nusb/serial/serial.c 623a624 > int oifc; 624a626 > oifc = ifc; 631c633,634 < eps = ser->dev->usb->conf[0]->iface[ifc]->ep; --- > do { > eps = ser->dev->usb->conf[0]->iface[oifc]->ep; 633,643c636,647 < for(i = 0; i < Nep; i++){ < if((ep = eps[i]) == nil) < continue; < if(ser->hasepintr && ep->type == Eintr && < ep->dir == Ein && epintr == -1) < epintr = ep->id; < if(ep->type == Ebulk){ < if((ep->dir == Ein || ep->dir == Eboth) && epin == -1) < epin = ep->id; < if((ep->dir == Eout || ep->dir == Eboth) && epout == -1) < epout = ep->id; --- > for(i = 0; i < Nep; i++){ > if((ep = eps[i]) == nil) > continue; > if(ser->hasepintr && ep->type == Eintr && > ep->dir == Ein && epintr == -1) > epintr = ep->id; > if(ep->type == Ebulk){ > if((ep->dir == Ein || ep->dir == Eboth) && epin == -1) > epin = ep->id; > if((ep->dir == Eout || ep->dir == Eboth) && epout == -1) > epout = ep->id; > } 645c649 < } --- > } while((epin == -1 || epout == -1 || (ser->hasepintr && epintr == -1)) && ++oifc < Niface); 716a721 > extern int cdcprobe(Serial *ser); 753c758,759 < && chprobe(ser)) --- > && chprobe(ser) > && cdcprobe(ser))