usbxhci: commit work in progress xhci driver, no config yet
This commit is contained in:
parent
990a985836
commit
5e6f1b5769
3 changed files with 1335 additions and 24 deletions
1287
sys/src/9/pc/usbxhci.c
Normal file
1287
sys/src/9/pc/usbxhci.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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:
|
||||||
|
|
|
@ -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) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue