diff options
| -rw-r--r-- | sys/src/9/bcm/usbdwc.c | 4 | ||||
| -rw-r--r-- | sys/src/9/pc/usbohci.c | 6 | ||||
| -rw-r--r-- | sys/src/9/pc/usbuhci.c | 2 | ||||
| -rw-r--r-- | sys/src/9/port/usb.h | 2 | ||||
| -rw-r--r-- | sys/src/9/port/usbehci.c | 12 | ||||
| -rw-r--r-- | sys/src/cmd/nusb/lib/dev.c | 2 | ||||
| -rw-r--r-- | sys/src/cmd/nusb/lib/parse.c | 33 |
7 files changed, 37 insertions, 24 deletions
diff --git a/sys/src/9/bcm/usbdwc.c b/sys/src/9/bcm/usbdwc.c index 652b2ceea..a7292ba5f 100644 --- a/sys/src/9/bcm/usbdwc.c +++ b/sys/src/9/bcm/usbdwc.c @@ -115,10 +115,10 @@ chansetup(Hostchan *hc, Ep *ep) hcc = 0; break; default: - hcc = ep->dev->nb<<ODevaddr; + hcc = (ep->dev->nb&Devmax)<<ODevaddr; break; } - hcc |= ep->maxpkt | 1<<OMulticnt | ep->nb<<OEpnum; + hcc |= ep->maxpkt | 1<<OMulticnt | (ep->nb&Epmax)<<OEpnum; switch(ep->ttype){ case Tctl: hcc |= Epctl; diff --git a/sys/src/9/pc/usbohci.c b/sys/src/9/pc/usbohci.c index d1068378d..fed5a0f2c 100644 --- a/sys/src/9/pc/usbohci.c +++ b/sys/src/9/pc/usbohci.c @@ -1719,7 +1719,7 @@ epctlio(Ep *ep, Ctlio *cio, void *a, long count) /* set the address if unset and out of configuration state */ if(ep->dev->state != Dconfig && ep->dev->state != Dreset) if(cio->usbid == 0){ - cio->usbid = (ep->nb<<7)|(ep->dev->nb & Devmax); + cio->usbid = (ep->nb&Epmax)<<7 | (ep->dev->nb&Devmax); edsetaddr(cio->ed, cio->usbid); } /* adjust maxpkt if the user has learned a different one */ @@ -1986,7 +1986,7 @@ isoopen(Ctlr *ctlr, Ep *ep) int i; iso = ep->aux; - iso->usbid = (ep->nb<<7)|(ep->dev->nb & Devmax); + iso->usbid = (ep->nb&Epmax)<<7 | (ep->dev->nb&Devmax); iso->bw = ep->hz * ep->samplesz; /* bytes/sec */ if(ep->mode != OWRITE){ print("ohci: bug: iso input streams not implemented\n"); @@ -2067,7 +2067,7 @@ epopen(Ep *ep) case Tintr: io = ep->aux = smalloc(sizeof(Qio)*2); io[OREAD].debug = io[OWRITE].debug = ep->debug; - usbid = (ep->nb<<7)|(ep->dev->nb & Devmax); + usbid = (ep->nb&Epmax)<<7 | (ep->dev->nb&Devmax); if(ep->mode != OREAD){ if(ep->toggle[OWRITE] != 0) io[OWRITE].toggle = Tddata1; diff --git a/sys/src/9/pc/usbuhci.c b/sys/src/9/pc/usbuhci.c index 986a91c9e..8b5d54b75 100644 --- a/sys/src/9/pc/usbuhci.c +++ b/sys/src/9/pc/usbuhci.c @@ -1791,7 +1791,7 @@ epopen(Ep *ep) case Tintr: io = ep->aux = smalloc(sizeof(Qio)*2); io[OREAD].debug = io[OWRITE].debug = ep->debug; - usbid = ((ep->nb&Epmax)<<7)|(ep->dev->nb &Devmax); + usbid = ((ep->nb&Epmax)<<7)|(ep->dev->nb&Devmax); if(ep->mode != OREAD){ if(ep->toggle[OWRITE] != 0) io[OWRITE].toggle = Tddata1; diff --git a/sys/src/9/port/usb.h b/sys/src/9/port/usb.h index 5758bdd20..8ee5e5138 100644 --- a/sys/src/9/port/usb.h +++ b/sys/src/9/port/usb.h @@ -17,7 +17,7 @@ typedef struct Hciimpl Hciimpl; /* Link to the controller impl. */ enum { /* fundamental constants */ - Ndeveps = 16, /* max nb. of endpoints per device */ + Ndeveps = 32, /* max nb. of endpoints per device (16 in + 16 out) */ /* tunable parameters */ Nhcis = 16, /* max nb. of HCIs */ diff --git a/sys/src/9/port/usbehci.c b/sys/src/9/port/usbehci.c index 45b48145a..2db838780 100644 --- a/sys/src/9/port/usbehci.c +++ b/sys/src/9/port/usbehci.c @@ -2578,7 +2578,7 @@ epctlio(Ep *ep, Ctlio *cio, void *a, long count) /* set the address if unset and out of configuration state */ if(ep->dev->state != Dconfig && ep->dev->state != Dreset) if(cio->usbid == 0){ - cio->usbid = (ep->nb&Epmax) << 7 | ep->dev->nb&Devmax; + cio->usbid = (ep->nb&Epmax)<<7 | (ep->dev->nb&Devmax); coherence(); qhsetaddr(cio->qh, cio->usbid); } @@ -2688,8 +2688,8 @@ isofsinit(Ep *ep, Isoio *iso) td->data = iso->data + i * ep->maxpkt; td->epc = ep->dev->port << Stdportshift; td->epc |= ep->dev->hub << Stdhubshift; - td->epc |= ep->nb << Stdepshift; - td->epc |= ep->dev->nb << Stddevshift; + td->epc |= (ep->nb&Epmax) << Stdepshift; + td->epc |= (ep->dev->nb&Devmax) << Stddevshift; td->mfs = 034 << Stdscmshift | 1 << Stdssmshift; if(ep->mode == OREAD){ td->epc |= Stdin; @@ -2743,7 +2743,7 @@ isohsinit(Ep *ep, Isoio *iso) td->buffer[p] = pa; pa += 0x1000; } - td->buffer[0] |= ep->nb << Itdepshift | ep->dev->nb << Itddevshift; + td->buffer[0] |= (ep->nb&Epmax)<<Itdepshift | (ep->dev->nb&Devmax)<<Itddevshift; if(ep->mode == OREAD) td->buffer[1] |= Itdin; else @@ -2789,7 +2789,7 @@ isoopen(Ctlr *ctlr, Ep *ep) default: error("iso i/o is half-duplex"); } - iso->usbid = ep->nb << 7 | ep->dev->nb & Devmax; + iso->usbid = (ep->nb&Epmax)<<7 | (ep->dev->nb&Devmax); iso->state = Qidle; coherence(); iso->debug = ep->debug; @@ -2926,7 +2926,7 @@ epopen(Ep *ep) case Tintr: io = ep->aux = smalloc(sizeof(Qio)*2); io[OREAD].debug = io[OWRITE].debug = ep->debug; - usbid = (ep->nb&Epmax) << 7 | ep->dev->nb &Devmax; + usbid = (ep->nb&Epmax)<<7 | (ep->dev->nb&Devmax); assert(ep->pollival != 0); if(ep->mode != OREAD){ if(ep->toggle[OWRITE] != 0) diff --git a/sys/src/cmd/nusb/lib/dev.c b/sys/src/cmd/nusb/lib/dev.c index 8f8a64277..60d327e87 100644 --- a/sys/src/cmd/nusb/lib/dev.c +++ b/sys/src/cmd/nusb/lib/dev.c @@ -481,7 +481,7 @@ unstall(Dev *dev, Dev *ep, int dir) else dir = 0; r = Rh2d|Rstd|Rep; - if(usbcmd(dev, r, Rclearfeature, Fhalt, ep->id|dir, nil, 0)<0){ + if(usbcmd(dev, r, Rclearfeature, Fhalt, (ep->id&0xF)|dir, nil, 0)<0){ werrstr("unstall: %s: %r", ep->dir); return -1; } diff --git a/sys/src/cmd/nusb/lib/parse.c b/sys/src/cmd/nusb/lib/parse.c index cf942ed7c..d9c61f2b9 100644 --- a/sys/src/cmd/nusb/lib/parse.c +++ b/sys/src/cmd/nusb/lib/parse.c @@ -96,7 +96,7 @@ extern Ep* mkep(Usbdev *, int); static int parseendpt(Usbdev *d, Conf *c, Iface *ip, Altc *altc, uchar *b, int n, Ep **epp) { - int i, dir, epid, type; + int i, dir, epid, type, addr; Ep *ep; DEp *dep; @@ -109,25 +109,38 @@ parseendpt(Usbdev *d, Conf *c, Iface *ip, Altc *altc, uchar *b, int n, Ep **epp) altc->attrib = dep->bmAttributes; /* here? */ altc->interval = dep->bInterval; - epid = dep->bEndpointAddress & 0xF; - assert(epid < nelem(d->ep)); - if(dep->bEndpointAddress & 0x80) + type = dep->bmAttributes & 0x03; + addr = dep->bEndpointAddress; + if(addr & 0x80) dir = Ein; else dir = Eout; - type = dep->bmAttributes & 0x03; + epid = addr & 0xF; /* default map to 0..15 */ + assert(epid < nelem(d->ep)); ep = d->ep[epid]; if(ep == nil){ ep = mkep(d, epid); ep->dir = dir; - }else if((ep->addr & 0x80) != (dep->bEndpointAddress & 0x80) && ep->type == type) - ep->dir = Eboth; - else - ep->dir = dir; + }else if((ep->addr & 0x80) != (addr & 0x80)){ + if(ep->type == type) + ep->dir = Eboth; + else { + /* + * resolve conflict when same endpoint number + * is used for different input and output types. + * map input endpoint to 16..31 and output to 0..15. + */ + ep->id = ((ep->addr & 0x80) != 0)<<4 | (ep->addr & 0xF); + d->ep[ep->id] = ep; + epid = ep->id ^ 0x10; + ep = mkep(d, epid); + ep->dir = dir; + } + } ep->maxpkt = GET2(dep->wMaxPacketSize); ep->ntds = 1 + ((ep->maxpkt >> 11) & 3); ep->maxpkt &= 0x7FF; - ep->addr = dep->bEndpointAddress; + ep->addr = addr; ep->type = type; ep->isotype = (dep->bmAttributes>>2) & 0x03; ep->conf = c; |
