usbohci: use 64-bit io base address, disable interrupts before reset, remove resetlck

This commit is contained in:
cinap_lenrek 2021-01-17 11:51:59 +01:00
parent 82c892a697
commit 87b1d454ed

View file

@ -351,7 +351,7 @@ struct Ctlr
Qtree* tree; /* tree for t Ep i/o */ Qtree* tree; /* tree for t Ep i/o */
int ntree; /* number of dummy Eds in tree */ int ntree; /* number of dummy Eds in tree */
Pcidev* pcidev; Pcidev* pcidev;
uintptr base; uvlong base;
}; };
#define dqprint if(debug || io && io->debug)print #define dqprint if(debug || io && io->debug)print
@ -366,7 +366,6 @@ static char* iosname[] = { "idle", "install", "run", "done", "close", "FREE" };
static int debug; static int debug;
static Edpool edpool; static Edpool edpool;
static Tdpool tdpool; static Tdpool tdpool;
static Ctlr* ctlrs[Nhcis];
static char EnotWritten[] = "usb write unfinished"; static char EnotWritten[] = "usb write unfinished";
static char EnotRead[] = "usb read unfinished"; static char EnotRead[] = "usb read unfinished";
@ -2377,18 +2376,19 @@ init(Hci *hp)
dumpohci(ctlr); dumpohci(ctlr);
} }
static void
static Ctlr*
scanpci(void) scanpci(void)
{ {
uintptr io; static Ctlr *first, **lastp;
Ctlr *ctlr; Ctlr *ctlr;
Pcidev *p; Pcidev *p;
int i; uvlong io;
static int already = 0;
if(lastp != nil)
return first;
lastp = &first;
if(already)
return;
already = 1;
p = nil; p = nil;
while(p = pcimatch(p, 0, 0)) { while(p = pcimatch(p, 0, 0)) {
/* /*
@ -2396,10 +2396,12 @@ scanpci(void)
*/ */
if(p->ccrb != Pcibcserial || p->ccru != Pciscusb || p->ccrp != 0x10) if(p->ccrb != Pcibcserial || p->ccru != Pciscusb || p->ccrp != 0x10)
continue; continue;
io = p->mem[0].bar & ~0x0F; if(p->mem[0].bar & 1)
continue;
io = p->mem[0].bar & ~0xFULL;
if(io == 0) if(io == 0)
continue; continue;
print("usbohci: %#x %#x: port %#p size %#x irq %d\n", print("usbohci: %#x %#x: port %llux size %#x irq %d\n",
p->vid, p->did, io, p->mem[0].size, p->intl); p->vid, p->did, io, p->mem[0].size, p->intl);
ctlr = malloc(sizeof(Ctlr)); ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil){ if(ctlr == nil){
@ -2414,14 +2416,12 @@ scanpci(void)
ctlr->pcidev = p; ctlr->pcidev = p;
ctlr->base = io; ctlr->base = io;
dprint("scanpci: ctlr %#p, ohci %#p\n", ctlr, ctlr->ohci); dprint("scanpci: ctlr %#p, ohci %#p\n", ctlr, ctlr->ohci);
for(i = 0; i < Nhcis; i++)
if(ctlrs[i] == nil){ *lastp = ctlr;
ctlrs[i] = ctlr; lastp = &ctlr->next;
break;
}
if(i == Nhcis)
print("ohci: bug: no more controllers\n");
} }
return first;
} }
static void static void
@ -2527,12 +2527,13 @@ ohcireset(Ctlr *ctlr)
* Is this needed? * Is this needed?
*/ */
delay(100); delay(100);
ctlr->ohci->intrdisable = Mie;
ctlr->ohci->intrenable = 0;
ctlr->ohci->control = 0; ctlr->ohci->control = 0;
delay(100); delay(100);
/* legacy support register: turn off lunacy mode */ /* legacy support register: turn off lunacy mode */
pcicfgw16(ctlr->pcidev, 0xc0, 0x2000); pcicfgw16(ctlr->pcidev, 0xc0, 0x2000);
iunlock(ctlr); iunlock(ctlr);
} }
@ -2554,31 +2555,24 @@ shutdown(Hci *hp)
static int static int
reset(Hci *hp) reset(Hci *hp)
{ {
int i;
Ctlr *ctlr; Ctlr *ctlr;
Pcidev *p; Pcidev *p;
static Lock resetlck;
if(getconf("*nousbohci")) if(getconf("*nousbohci"))
return -1; return -1;
ilock(&resetlck);
scanpci();
/* /*
* Any adapter matches if no hp->port is supplied, * Any adapter matches if no hp->port is supplied,
* otherwise the ports must match. * otherwise the ports must match.
*/ */
ctlr = nil; for(ctlr = scanpci(); ctlr != nil; ctlr = ctlr->next){
for(i = 0; i < Nhcis && ctlrs[i] != nil; i++){
ctlr = ctlrs[i];
if(ctlr->active == 0) if(ctlr->active == 0)
if(hp->port == 0 || hp->port == ctlr->base){ if(hp->port == 0 || hp->port == ctlr->base){
ctlr->active = 1; ctlr->active = 1;
break; break;
} }
} }
iunlock(&resetlck); if(ctlr == nil)
if(ctlrs[i] == nil || i == Nhcis)
return -1; return -1;
p = ctlr->pcidev; p = ctlr->pcidev;
@ -2617,6 +2611,7 @@ reset(Hci *hp)
hp->shutdown = shutdown; hp->shutdown = shutdown;
hp->debug = usbdebug; hp->debug = usbdebug;
hp->type = "ohci"; hp->type = "ohci";
intrenable(hp->irq, hp->interrupt, hp, hp->tbdf, hp->type); intrenable(hp->irq, hp->interrupt, hp, hp->tbdf, hp->type);
return 0; return 0;