Qtree* tree; /* tree for t Ep i/o */
int ntree; /* number of dummy Eds in tree */
Pcidev* pcidev;
+ uintptr base;
};
#define dqprint if(debug || io && io->debug)print
static void
scanpci(void)
{
- ulong mem;
+ uintptr io;
Ctlr *ctlr;
Pcidev *p;
int i;
/*
* Find Ohci controllers (Programming Interface = 0x10).
*/
- if(p->ccrb != Pcibcserial || p->ccru != Pciscusb ||
- p->ccrp != 0x10)
+ if(p->ccrb != Pcibcserial || p->ccru != Pciscusb || p->ccrp != 0x10)
continue;
- mem = p->mem[0].bar & ~0x0F;
- dprint("ohci: %x/%x port 0x%lux size 0x%x irq %d\n",
- p->vid, p->did, mem, p->mem[0].size, p->intl);
- if(mem == 0){
- print("ohci: failed to map registers\n");
+ io = p->mem[0].bar & ~0x0F;
+ if(io == 0)
continue;
- }
-
+ print("usbohci: %#x %#x: port %#p size %#x irq %d\n",
+ p->vid, p->did, io, p->mem[0].size, p->intl);
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil){
print("ohci: no memory\n");
continue;
}
+ if((ctlr->ohci = vmap(io, p->mem[0].size)) == nil){
+ print("ohci: can't map ohci\n");
+ free(ctlr);
+ continue;
+ }
ctlr->pcidev = p;
- ctlr->ohci = vmap(mem, p->mem[0].size);
+ ctlr->base = io;
dprint("scanpci: ctlr %#p, ohci %#p\n", ctlr, ctlr->ohci);
- pcisetbme(p);
- pcisetpms(p, 0);
for(i = 0; i < Nhcis; i++)
if(ctlrs[i] == nil){
ctlrs[i] = ctlr;
for(i = 0; i < Nhcis && ctlrs[i] != nil; i++){
ctlr = ctlrs[i];
if(ctlr->active == 0)
- if(hp->port == 0 || hp->port == PADDR(ctlr->ohci)){
+ if(hp->port == 0 || hp->port == ctlr->base){
ctlr->active = 1;
break;
}
iunlock(&resetlck);
if(ctlrs[i] == nil || i == Nhcis)
return -1;
- if(ctlr->ohci->control == ~0)
- return -1;
-
p = ctlr->pcidev;
+ pcienable(p);
+
+ if(ctlr->ohci->control == ~0){
+ pcidisable(p);
+ return -1;
+ }
+
hp->aux = ctlr;
- hp->port = PADDR(ctlr->ohci);
+ hp->port = ctlr->base;
hp->irq = p->intl;
hp->tbdf = p->tbdf;
ctlr->nports = hp->nports = ctlr->ohci->rhdesca & 0xff;
ohcireset(ctlr);
ohcimeminit(ctlr);
+ pcisetbme(p);
+
/*
* Linkage to the generic HCI driver.
*/
hp->shutdown = shutdown;
hp->debug = usbdebug;
hp->type = "ohci";
-
- /*
- * IRQ2 doesn't really exist, it's used to gang the interrupt
- * controllers together. A device set to IRQ2 will appear on
- * the second interrupt controller as IRQ9.
- */
- if(hp->irq == 2)
- hp->irq = 9;
intrenable(hp->irq, hp->interrupt, hp, hp->tbdf, hp->type);
return 0;