diff options
| -rw-r--r-- | sys/src/9/pc/usbehci.h | 2 | ||||
| -rw-r--r-- | sys/src/9/pc/usbehcipc.c | 58 |
2 files changed, 34 insertions, 26 deletions
diff --git a/sys/src/9/pc/usbehci.h b/sys/src/9/pc/usbehci.h index f3bf0f760..1c833b06b 100644 --- a/sys/src/9/pc/usbehci.h +++ b/sys/src/9/pc/usbehci.h @@ -36,7 +36,7 @@ enum Cdbgportmask = 0xF, C64 = 1, /* 64-bits, in Ecapio capparms. */ Ceecpshift = 8, /* extended capabilities ptr. in */ - Ceecpmask = 8, /* the Ecapio capparms reg. */ + Ceecpmask = 0xFF, /* the Ecapio capparms reg. */ Clegacy = 1, /* legacy support cap. id */ CLbiossem = 2, /* legacy cap. bios sem. */ CLossem = 3, /* legacy cap. os sem */ diff --git a/sys/src/9/pc/usbehcipc.c b/sys/src/9/pc/usbehcipc.c index 20b09e3f9..89c0b112c 100644 --- a/sys/src/9/pc/usbehcipc.c +++ b/sys/src/9/pc/usbehcipc.c @@ -17,35 +17,42 @@ static Ctlr* ctlrs[Nhcis]; static int maxehci = Nhcis; -/* Isn't this cap list search in a helper function? */ +static int +ehciecap(Ctlr *ctlr, int cap) +{ + int i, off; + + off = (ctlr->capio->capparms >> Ceecpshift) & Ceecpmask; + for(i=0; i<48; i++){ + if(off < 0x40 || (off & 3) != 0) + break; + if(pcicfgr8(ctlr->pcidev, off) == cap) + return off; + off = pcicfgr8(ctlr->pcidev, off+1); + } + return -1; +} + static void getehci(Ctlr* ctlr) { - int i, ptr, cap, sem; + int i, off; - ptr = (ctlr->capio->capparms >> Ceecpshift) & Ceecpmask; - for(; ptr != 0; ptr = pcicfgr8(ctlr->pcidev, ptr+1)){ - if(ptr < 0x40 || (ptr & ~0xFC)) - break; - cap = pcicfgr8(ctlr->pcidev, ptr); - if(cap != Clegacy) - continue; - sem = pcicfgr8(ctlr->pcidev, ptr+CLbiossem); - if(sem == 0) - continue; - pcicfgw8(ctlr->pcidev, ptr+CLossem, 1); + off = ehciecap(ctlr, Clegacy); + if(off == -1) + return; + if(pcicfgr8(ctlr->pcidev, off+CLbiossem) != 0){ + dprint("ehci %#p: bios active, taking over...\n", ctlr->capio); + pcicfgw8(ctlr->pcidev, off+CLossem, 1); for(i = 0; i < 100; i++){ - if(pcicfgr8(ctlr->pcidev, ptr+CLbiossem) == 0) + if(pcicfgr8(ctlr->pcidev, off+CLbiossem) == 0) break; delay(10); } if(i == 100) - dprint("ehci %#p: bios timed out\n", ctlr->capio); - pcicfgw32(ctlr->pcidev, ptr+CLcontrol, 0); /* no SMIs */ - ctlr->opio->config = 0; - coherence(); - return; + print("ehci %#p: bios timed out\n", ctlr->capio); } + pcicfgw32(ctlr->pcidev, off+CLcontrol, 0); /* no SMIs */ } static void @@ -59,16 +66,17 @@ ehcireset(Ctlr *ctlr) opio = ctlr->opio; /* - * Turn off legacy mode. Some controllers won't - * interrupt us as expected otherwise. + * reclaim from bios */ - ehcirun(ctlr, 0); - pcicfgw16(ctlr->pcidev, 0xc0, 0x2000); + getehci(ctlr); /* - * reclaim from bios + * halt and route ports to companion controllers + * until we are setup */ - getehci(ctlr); + ehcirun(ctlr, 0); + opio->config = 0; + coherence(); /* clear high 32 bits of address signals if it's 64 bits capable. * This is probably not needed but it does not hurt and others do it. |
