summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/bcm/usbdwc.c4
-rw-r--r--sys/src/9/pc/usbohci.c6
-rw-r--r--sys/src/9/pc/usbuhci.c2
-rw-r--r--sys/src/9/port/usb.h2
-rw-r--r--sys/src/9/port/usbehci.c12
-rw-r--r--sys/src/cmd/nusb/lib/dev.c2
-rw-r--r--sys/src/cmd/nusb/lib/parse.c33
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;