#include <u.h>
#include <libc.h>
#include <thread.h>
-#include <bio.h>
#include "usb.h"
int
return -1;
}
d->csp = CSP(dd->bDevClass, dd->bDevSubClass, dd->bDevProtocol);
- d->ep[0]->maxpkt = xd->maxpkt = dd->bMaxPacketSize0;
+ d->ver = GET2(dd->bcdUSB);
+ xd->isusb3 = (d->ver >= 0x0300);
+ if(xd->isusb3)
+ d->ep[0]->maxpkt = xd->maxpkt = 1<<dd->bMaxPacketSize0;
+ else
+ d->ep[0]->maxpkt = xd->maxpkt = dd->bMaxPacketSize0;
d->class = dd->bDevClass;
d->nconf = dd->bNumConfigurations;
if(d->nconf == 0)
subclass = dip->bInterfaceSubClass;
proto = dip->bInterfaceProtocol;
ip->csp = CSP(class, subclass, proto);
+ if(ip->csp == 0)
+ ip->csp = d->csp;
if(d->csp == 0) /* use csp from 1st iface */
d->csp = ip->csp; /* if device has none */
if(d->class == 0)
static int
parseendpt(Usbdev *d, Conf *c, Iface *ip, Altc *altc, uchar *b, int n, Ep **epp)
{
- int i, dir, epid;
+ int i, dir, epid, type, addr;
Ep *ep;
DEp *dep;
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;
+ 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->dir = Eboth;
+ }else if((ep->addr & 0x80) != (addr & 0x80)){
+ if(ep->type == type && type != Eiso)
+ 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->type = dep->bmAttributes & 0x03;
+ altc->maxpkt = ep->maxpkt;
+ altc->ntds = ep->ntds;
+ ep->addr = addr;
+ ep->type = type;
ep->isotype = (dep->bmAttributes>>2) & 0x03;
ep->conf = c;
ep->iface = ip;