usbdwc: sync with sources (Raspberry Pi Model A support)
This commit is contained in:
parent
03f364d167
commit
82f9f3df72
1 changed files with 63 additions and 42 deletions
|
@ -77,7 +77,7 @@ chanalloc(Ep *ep)
|
||||||
bitmap = ctlr->chanbusy;
|
bitmap = ctlr->chanbusy;
|
||||||
for(i = 0; i < ctlr->nchan; i++)
|
for(i = 0; i < ctlr->nchan; i++)
|
||||||
if((bitmap & (1<<i)) == 0){
|
if((bitmap & (1<<i)) == 0){
|
||||||
ctlr->chanbusy = bitmap | 1 << i;
|
ctlr->chanbusy = bitmap | 1<<i;
|
||||||
qunlock(&ctlr->chanlock);
|
qunlock(&ctlr->chanlock);
|
||||||
return &ctlr->regs->hchan[i];
|
return &ctlr->regs->hchan[i];
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ chanrelease(Ep *ep, Hostchan *chan)
|
||||||
ctlr = ep->hp->aux;
|
ctlr = ep->hp->aux;
|
||||||
i = chan - ctlr->regs->hchan;
|
i = chan - ctlr->regs->hchan;
|
||||||
qlock(&ctlr->chanlock);
|
qlock(&ctlr->chanlock);
|
||||||
ctlr->chanbusy &= ~(1 << i);
|
ctlr->chanbusy &= ~(1<<i);
|
||||||
qunlock(&ctlr->chanlock);
|
qunlock(&ctlr->chanlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,9 +138,12 @@ chansetup(Hostchan *hc, Ep *ep)
|
||||||
hcc |= Lspddev;
|
hcc |= Lspddev;
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case Fullspeed:
|
case Fullspeed:
|
||||||
hc->hcsplt = Spltena | POS_ALL | ep->dev->hub << OHubaddr |
|
if(ep->dev->hub > 1){
|
||||||
|
hc->hcsplt = Spltena | POS_ALL | ep->dev->hub<<OHubaddr |
|
||||||
ep->dev->port;
|
ep->dev->port;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
hc->hcsplt = 0;
|
hc->hcsplt = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -168,7 +171,7 @@ sofwait(Ctlr *ctlr, int n)
|
||||||
do{
|
do{
|
||||||
r->gintsts = Sofintr;
|
r->gintsts = Sofintr;
|
||||||
x = splfhi();
|
x = splfhi();
|
||||||
ctlr->sofchan |= 1 << n;
|
ctlr->sofchan |= 1<<n;
|
||||||
r->gintmsk |= Sofintr;
|
r->gintmsk |= Sofintr;
|
||||||
sleep(&ctlr->chanintr[n], sofdone, r);
|
sleep(&ctlr->chanintr[n], sofdone, r);
|
||||||
splx(x);
|
splx(x);
|
||||||
|
@ -181,6 +184,8 @@ chandone(void *a)
|
||||||
Hostchan *hc;
|
Hostchan *hc;
|
||||||
|
|
||||||
hc = a;
|
hc = a;
|
||||||
|
if(hc->hcint == (Chhltd|Ack))
|
||||||
|
return 0;
|
||||||
return (hc->hcint & hc->hcintmsk) != 0;
|
return (hc->hcint & hc->hcintmsk) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +201,7 @@ chanwait(Ep *ep, Ctlr *ctlr, Hostchan *hc, int mask)
|
||||||
for(;;){
|
for(;;){
|
||||||
restart:
|
restart:
|
||||||
x = splfhi();
|
x = splfhi();
|
||||||
r->haintmsk |= 1 << n;
|
r->haintmsk |= 1<<n;
|
||||||
hc->hcintmsk = mask;
|
hc->hcintmsk = mask;
|
||||||
sleep(&ctlr->chanintr[n], chandone, hc);
|
sleep(&ctlr->chanintr[n], chandone, hc);
|
||||||
hc->hcintmsk = 0;
|
hc->hcintmsk = 0;
|
||||||
|
@ -218,7 +223,8 @@ restart:
|
||||||
return intr;
|
return intr;
|
||||||
}
|
}
|
||||||
if((intr & mask) == 0){
|
if((intr & mask) == 0){
|
||||||
dprint("ep%d.%d await %x intr %x -> %x\n", ep->dev->nb, ep->nb, mask, ointr, intr);
|
dprint("ep%d.%d await %x intr %x -> %x\n",
|
||||||
|
ep->dev->nb, ep->nb, mask, ointr, intr);
|
||||||
goto restart;
|
goto restart;
|
||||||
}
|
}
|
||||||
now = fastticks(0);
|
now = fastticks(0);
|
||||||
|
@ -248,7 +254,7 @@ chanintr(Ctlr *ctlr, int n)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
hc = &ctlr->regs->hchan[n];
|
hc = &ctlr->regs->hchan[n];
|
||||||
if(ctlr->debugchan & (1 << n))
|
if(ctlr->debugchan & (1<<n))
|
||||||
clog(nil, hc);
|
clog(nil, hc);
|
||||||
if((hc->hcsplt & Spltena) == 0)
|
if((hc->hcsplt & Spltena) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -340,7 +346,7 @@ chanio(Ep *ep, Hostchan *hc, int dir, int pid, void *a, int len)
|
||||||
n = ROUND(len, ep->maxpkt);
|
n = ROUND(len, ep->maxpkt);
|
||||||
else
|
else
|
||||||
n = len;
|
n = len;
|
||||||
hc->hctsiz = n | npkt << OPktcnt | pid;
|
hc->hctsiz = n | npkt<<OPktcnt | pid;
|
||||||
hc->hcdma = PADDR(a);
|
hc->hcdma = PADDR(a);
|
||||||
|
|
||||||
nleft = len;
|
nleft = len;
|
||||||
|
@ -389,7 +395,7 @@ chanio(Ep *ep, Hostchan *hc, int dir, int pid, void *a, int len)
|
||||||
if((i & Xfercomp) == 0 && i != (Chhltd|Ack) && i != Chhltd){
|
if((i & Xfercomp) == 0 && i != (Chhltd|Ack) && i != Chhltd){
|
||||||
if(i & Stall)
|
if(i & Stall)
|
||||||
error(Estalled);
|
error(Estalled);
|
||||||
if(i & Nyet)
|
if(i & (Nyet|Frmovrun))
|
||||||
continue;
|
continue;
|
||||||
if(i & Nak){
|
if(i & Nak){
|
||||||
if(ep->ttype == Tintr)
|
if(ep->ttype == Tintr)
|
||||||
|
@ -398,6 +404,7 @@ chanio(Ep *ep, Hostchan *hc, int dir, int pid, void *a, int len)
|
||||||
tsleep(&up->sleep, return0, 0, 1);
|
tsleep(&up->sleep, return0, 0, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
logdump(ep);
|
||||||
print("usbotg: ep%d.%d error intr %8.8ux\n",
|
print("usbotg: ep%d.%d error intr %8.8ux\n",
|
||||||
ep->dev->nb, ep->nb, i);
|
ep->dev->nb, ep->nb, i);
|
||||||
if(i & ~(Chhltd|Ack))
|
if(i & ~(Chhltd|Ack))
|
||||||
|
@ -407,31 +414,33 @@ chanio(Ep *ep, Hostchan *hc, int dir, int pid, void *a, int len)
|
||||||
hcdma, hc->hcdma, i, hc->hcint);
|
hcdma, hc->hcdma, i, hc->hcint);
|
||||||
}
|
}
|
||||||
n = hc->hcdma - hcdma;
|
n = hc->hcdma - hcdma;
|
||||||
if(n == 0)
|
if(n == 0){
|
||||||
if((hc->hctsiz & Pktcnt) != (hctsiz & Pktcnt))
|
if((hc->hctsiz & Pktcnt) != (hctsiz & Pktcnt))
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if(dir == Epin && ep->ttype == Tbulk && n == nleft){
|
if(dir == Epin && ep->ttype == Tbulk && n == nleft){
|
||||||
nt = (hctsiz & Xfersize) - (hc->hctsiz & Xfersize);
|
nt = (hctsiz & Xfersize) - (hc->hctsiz & Xfersize);
|
||||||
if(nt != n)
|
if(nt != n){
|
||||||
if(n == ((nt+3) & ~3))
|
if(n == ROUND(nt, 4))
|
||||||
n = nt;
|
n = nt;
|
||||||
else
|
else
|
||||||
print("usbotg: intr %8.8ux dma "
|
print("usbotg: intr %8.8ux "
|
||||||
"%8.8ux-%8.8ux hctsiz "
|
"dma %8.8ux-%8.8ux "
|
||||||
"%8.8ux-%8.ux\n",
|
"hctsiz %8.8ux-%8.ux\n",
|
||||||
i, hcdma, hc->hcdma, hctsiz,
|
i, hcdma, hc->hcdma, hctsiz,
|
||||||
hc->hctsiz);
|
hc->hctsiz);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if(n > nleft){
|
if(n > nleft){
|
||||||
if(n != ((nleft+3) & ~3))
|
if(n != ROUND(nleft, 4))
|
||||||
dprint("too much: wanted %d got %d\n",
|
dprint("too much: wanted %d got %d\n",
|
||||||
len, len - nleft + n);
|
len, len - nleft + n);
|
||||||
n = nleft;
|
n = nleft;
|
||||||
}
|
}
|
||||||
nleft -= n;
|
nleft -= n;
|
||||||
if(nleft == 0 || n % maxpkt != 0)
|
if(nleft == 0 || (n % maxpkt) != 0)
|
||||||
break;
|
break;
|
||||||
if((i & Xfercomp) && ep->ttype != Tctl)
|
if((i & Xfercomp) && ep->ttype != Tctl)
|
||||||
break;
|
break;
|
||||||
|
@ -443,6 +452,24 @@ chanio(Ep *ep, Hostchan *hc, int dir, int pid, void *a, int len)
|
||||||
return len - nleft;
|
return len - nleft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
multitrans(Ep *ep, Hostchan *hc, int rw, void *a, long n)
|
||||||
|
{
|
||||||
|
long sofar, m;
|
||||||
|
|
||||||
|
sofar = 0;
|
||||||
|
do{
|
||||||
|
m = n - sofar;
|
||||||
|
if(m > ep->maxpkt)
|
||||||
|
m = ep->maxpkt;
|
||||||
|
m = chanio(ep, hc, rw == Read? Epin : Epout, ep->toggle[rw],
|
||||||
|
(char*)a + sofar, m);
|
||||||
|
ep->toggle[rw] = hc->hctsiz & Pid;
|
||||||
|
sofar += m;
|
||||||
|
}while(sofar < n && m == ep->maxpkt);
|
||||||
|
return sofar;
|
||||||
|
}
|
||||||
|
|
||||||
static long
|
static long
|
||||||
eptrans(Ep *ep, int rw, void *a, long n)
|
eptrans(Ep *ep, int rw, void *a, long n)
|
||||||
{
|
{
|
||||||
|
@ -464,22 +491,10 @@ eptrans(Ep *ep, int rw, void *a, long n)
|
||||||
nexterror();
|
nexterror();
|
||||||
}
|
}
|
||||||
chansetup(hc, ep);
|
chansetup(hc, ep);
|
||||||
if(rw == Read && ep->ttype == Tbulk){
|
if(rw == Read && ep->ttype == Tbulk)
|
||||||
long sofar, m;
|
n = multitrans(ep, hc, rw, a, n);
|
||||||
|
else{
|
||||||
sofar = 0;
|
n = chanio(ep, hc, rw == Read? Epin : Epout, ep->toggle[rw],
|
||||||
do{
|
|
||||||
m = n - sofar;
|
|
||||||
if(m > ep->maxpkt)
|
|
||||||
m = ep->maxpkt;
|
|
||||||
m = chanio(ep, hc, Epin, ep->toggle[rw],
|
|
||||||
(char*)a + sofar, m);
|
|
||||||
ep->toggle[rw] = hc->hctsiz & Pid;
|
|
||||||
sofar += m;
|
|
||||||
}while(sofar < n && m == ep->maxpkt);
|
|
||||||
n = sofar;
|
|
||||||
}else{
|
|
||||||
n = chanio(ep, hc, rw == Read? Epin: Epout, ep->toggle[rw],
|
|
||||||
a, n);
|
a, n);
|
||||||
ep->toggle[rw] = hc->hctsiz & Pid;
|
ep->toggle[rw] = hc->hctsiz & Pid;
|
||||||
}
|
}
|
||||||
|
@ -529,6 +544,10 @@ ctltrans(Ep *ep, uchar *req, long n)
|
||||||
chansetup(hc, ep);
|
chansetup(hc, ep);
|
||||||
chanio(ep, hc, Epout, SETUP, req, Rsetuplen);
|
chanio(ep, hc, Epout, SETUP, req, Rsetuplen);
|
||||||
if(req[Rtype] & Rd2h){
|
if(req[Rtype] & Rd2h){
|
||||||
|
if(ep->dev->hub <= 1){
|
||||||
|
ep->toggle[Read] = DATA1;
|
||||||
|
b->wp += multitrans(ep, hc, Read, data, datalen);
|
||||||
|
}else
|
||||||
b->wp += chanio(ep, hc, Epin, DATA1, data, datalen);
|
b->wp += chanio(ep, hc, Epin, DATA1, data, datalen);
|
||||||
chanio(ep, hc, Epout, DATA1, nil, 0);
|
chanio(ep, hc, Epout, DATA1, nil, 0);
|
||||||
n = Rsetuplen;
|
n = Rsetuplen;
|
||||||
|
@ -602,7 +621,7 @@ init(Hci *hp)
|
||||||
tx = 0x100;
|
tx = 0x100;
|
||||||
ptx = 0x200;
|
ptx = 0x200;
|
||||||
r->grxfsiz = rx;
|
r->grxfsiz = rx;
|
||||||
r->gnptxfsiz = rx | tx << ODepth;
|
r->gnptxfsiz = rx | tx<<ODepth;
|
||||||
tsleep(&up->sleep, return0, 0, 1);
|
tsleep(&up->sleep, return0, 0, 1);
|
||||||
r->hptxfsiz = (rx + tx) | ptx << ODepth;
|
r->hptxfsiz = (rx + tx) | ptx << ODepth;
|
||||||
greset(r, Rxfflsh);
|
greset(r, Rxfflsh);
|
||||||
|
@ -639,9 +658,11 @@ fiqintr(Ureg*, void *a)
|
||||||
if(intr & Hcintr){
|
if(intr & Hcintr){
|
||||||
haint = r->haint & r->haintmsk;
|
haint = r->haint & r->haintmsk;
|
||||||
for(i = 0; haint; i++){
|
for(i = 0; haint; i++){
|
||||||
if(haint & 1 && chanintr(ctlr, i) == 0){
|
if(haint & 1){
|
||||||
r->haintmsk &= ~(1 << i);
|
if(chanintr(ctlr, i) == 0){
|
||||||
wakechan |= 1 << i;
|
r->haintmsk &= ~(1<<i);
|
||||||
|
wakechan |= 1<<i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
haint >>= 1;
|
haint >>= 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue