usbdwc: preserve Prtpwr bit for portstatus, turn off power by default, handle channel timeout

preserve the Prtpwr bit in portstatus instead of
unconditionally setting it.

turn off port powert on init. (let usbd will turn it on).

make chanio() halt the channel and error out
when interrupt status is 0 after timout.

this happens when the port is powered off.
This commit is contained in:
cinap_lenrek 2024-12-16 05:14:45 +00:00
parent 5028b882da
commit 837c596bdf

View file

@ -234,14 +234,20 @@ chanwait(Ep *ep, Ctlr *ctlr, Hostchan *hc, int mask)
int intr, ointr, chan; int intr, ointr, chan;
ulong start, now; ulong start, now;
if(waserror()){
chanhalt(ep, hc);
nexterror();
}
chan = hc - ctlr->regs->hchan; chan = hc - ctlr->regs->hchan;
for(;;){ for(;;){
restart: restart:
tsleep(&ctlr->chanintr[chan], chandone, hc, 1000); tsleep(&ctlr->chanintr[chan], chandone, hc, 1000);
if((intr = hc->hcint) == 0) if((intr = hc->hcint) == 0)
goto restart; error("channel timeout");
if(intr & Chhltd) if(intr & Chhltd){
poperror();
return intr; return intr;
}
ointr = intr; ointr = intr;
now = start = fastticks(0); now = start = fastticks(0);
do{ do{
@ -252,6 +258,7 @@ restart:
(now - start) > 60) (now - start) > 60)
dprint("ep%d.%d await %x after %ldµs %x -> %x\n", dprint("ep%d.%d await %x after %ldµs %x -> %x\n",
ep->dev->nb, ep->nb, mask, now - start, ointr, intr); ep->dev->nb, ep->nb, mask, now - start, ointr, intr);
poperror();
return intr; return intr;
} }
if((intr & mask) == 0){ if((intr & mask) == 0){
@ -686,7 +693,7 @@ init(Hci *hp)
dprint("usbdwc: FIFO depth %d sizes rx/nptx/ptx %8.8ux %8.8ux %8.8ux\n", dprint("usbdwc: FIFO depth %d sizes rx/nptx/ptx %8.8ux %8.8ux %8.8ux\n",
n, r->grxfsiz, r->gnptxfsiz, r->hptxfsiz); n, r->grxfsiz, r->gnptxfsiz, r->hptxfsiz);
r->hport0 = Prtpwr|Prtconndet|Prtenchng|Prtovrcurrchng; r->hport0 = Prtconndet|Prtenchng|Prtovrcurrchng;
r->gintsts = ~0; r->gintsts = ~0;
r->gintmsk = Hcintr; r->gintmsk = Hcintr;
r->gahbcfg |= Glblintrmsk; r->gahbcfg |= Glblintrmsk;
@ -982,7 +989,7 @@ portstatus(Hci *hp, int)
s = r->hport0; s = r->hport0;
b = s & (Prtconndet|Prtenchng|Prtovrcurrchng); b = s & (Prtconndet|Prtenchng|Prtovrcurrchng);
if(b != 0) if(b != 0)
r->hport0 = Prtpwr | b; r->hport0 = (s & Prtpwr) | b;
b = 0; b = 0;
if(s & Prtconnsts) if(s & Prtconnsts)
b |= HPpresent; b |= HPpresent;