usbxhci: commit work in progress xhci driver, no config yet

This commit is contained in:
cinap_lenrek 2017-07-16 22:29:29 +02:00
parent 990a985836
commit 5e6f1b5769
3 changed files with 1335 additions and 24 deletions

1287
sys/src/9/pc/usbxhci.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -160,6 +160,7 @@ static char *ttname[] =
static char *spname[] = static char *spname[] =
{ {
[Superspeed] "super",
[Fullspeed] "full", [Fullspeed] "full",
[Lowspeed] "low", [Lowspeed] "low",
[Highspeed] "high", [Highspeed] "high",
@ -295,6 +296,7 @@ seprintep(char *s, char *se, Ep *ep, int all)
s = seprint(s, se, " hz %ld", ep->hz); s = seprint(s, se, " hz %ld", ep->hz);
s = seprint(s, se, " hub %d", ep->dev->hub); s = seprint(s, se, " hub %d", ep->dev->hub);
s = seprint(s, se, " port %d", ep->dev->port); s = seprint(s, se, " port %d", ep->dev->port);
s = seprint(s, se, " addr %d", ep->dev->addr);
if(ep->inuse) if(ep->inuse)
s = seprint(s, se, " busy"); s = seprint(s, se, " busy");
else else
@ -374,29 +376,33 @@ putep(Ep *ep)
{ {
Udev *d; Udev *d;
if(ep != nil && decref(ep) == 0){ if(ep == nil || decref(ep) > 0)
d = ep->dev; return;
deprint("usb: ep%d.%d %#p released\n", d->nb, ep->nb, ep); d = ep->dev;
qlock(&epslck); deprint("usb: ep%d.%d %#p released\n", d->nb, ep->nb, ep);
eps[ep->idx] = nil; qlock(&epslck);
if(ep->idx == epmax-1) eps[ep->idx] = nil;
epmax--; if(ep->idx == epmax-1)
if(ep == ep->ep0 && ep->dev != nil && ep->dev->nb == usbidgen) epmax--;
usbidgen--; if(ep == ep->ep0 && ep->dev != nil && ep->dev->nb == usbidgen)
qunlock(&epslck); usbidgen--;
if(d != nil){ qunlock(&epslck);
qlock(ep->ep0); if(d != nil){
d->eps[ep->nb] = nil; qlock(ep->ep0);
qunlock(ep->ep0); d->eps[ep->nb] = nil;
} qunlock(ep->ep0);
if(ep->ep0 != ep){
putep(ep->ep0);
ep->ep0 = nil;
}
free(ep->info);
free(ep->name);
free(ep);
} }
if(ep->ep0 != ep){
putep(ep->ep0);
ep->ep0 = nil;
} else if(d != nil){
if(d->free != nil)
(*d->free)(d->aux);
free(d);
}
free(ep->info);
free(ep->name);
free(ep);
} }
static void static void
@ -460,11 +466,15 @@ newdev(Hci *hp, int ishub, int isroot)
ep = epalloc(hp); ep = epalloc(hp);
d = ep->dev = smalloc(sizeof(Udev)); d = ep->dev = smalloc(sizeof(Udev));
d->nb = newusbid(hp); d->nb = newusbid(hp);
d->addr = 0;
d->eps[0] = ep; d->eps[0] = ep;
ep->nb = 0; ep->nb = 0;
ep->toggle[0] = ep->toggle[1] = 0; ep->toggle[0] = ep->toggle[1] = 0;
d->ishub = ishub; d->ishub = ishub;
d->isroot = isroot; d->isroot = isroot;
d->rootport = 0;
d->routestr = 0;
d->depth = 0;
if(hp->highspeed != 0) if(hp->highspeed != 0)
d->speed = Highspeed; d->speed = Highspeed;
else else
@ -1156,8 +1166,11 @@ epctl(Ep *ep, Chan *c, void *a, long n)
nep->dev->speed = l; nep->dev->speed = l;
if(nep->dev->speed != Lowspeed) if(nep->dev->speed != Lowspeed)
nep->maxpkt = 64; /* assume full speed */ nep->maxpkt = 64; /* assume full speed */
nep->dev->hub = d->nb; nep->dev->hub = d->addr;
nep->dev->port = atoi(cb->f[2]); nep->dev->port = atoi(cb->f[2]);
nep->dev->depth = d->depth+1;
nep->dev->rootport = d->depth == 0 ? nep->dev->port : d->rootport;
nep->dev->routestr = d->routestr | ((nep->dev->port&15) << 4*d->depth) >> 4;
/* next read request will read /* next read request will read
* the name for the new endpoint * the name for the new endpoint
*/ */
@ -1265,6 +1278,8 @@ epctl(Ep *ep, Chan *c, void *a, long n)
break; break;
case CMaddress: case CMaddress:
deprint("usb epctl %s\n", cb->f[0]); deprint("usb epctl %s\n", cb->f[0]);
if(ep->dev->addr == 0)
ep->dev->addr = ep->dev->nb;
ep->dev->state = Denabled; ep->dev->state = Denabled;
break; break;
case CMdetach: case CMdetach:

View file

@ -41,6 +41,7 @@ enum
Lowspeed, Lowspeed,
Highspeed, Highspeed,
Nospeed, Nospeed,
Superspeed,
/* request type */ /* request type */
Rh2d = 0<<7, Rh2d = 0<<7,
@ -184,8 +185,16 @@ struct Udev
int ishub; /* hubs can allocate devices */ int ishub; /* hubs can allocate devices */
int isroot; /* is a root hub */ int isroot; /* is a root hub */
int speed; /* Full/Low/High/No -speed */ int speed; /* Full/Low/High/No -speed */
int hub; /* dev number for the parent hub */ int hub; /* device address for the parent hub */
int port; /* port number in the parent hub */ int port; /* port number in the parent hub */
int addr; /* device address */
int depth; /* hub depth from root port */
int rootport; /* port number on root hub */
int routestr; /* route string */
void *aux;
void (*free)(void*);
Ep* eps[Ndeveps]; /* end points for this device (cached) */ Ep* eps[Ndeveps]; /* end points for this device (cached) */
}; };