3 * USB Enhanced Host Controller Interface (EHCI) driver
8 #include "../port/lib.h"
13 #include "../port/error.h"
14 #include "../port/usb.h"
17 static Ctlr* ctlrs[Nhcis];
18 static int maxehci = Nhcis;
21 ehciecap(Ctlr *ctlr, int cap)
25 off = (ctlr->capio->capparms >> Ceecpshift) & Ceecpmask;
27 if(off < 0x40 || (off & 3) != 0)
29 if(pcicfgr8(ctlr->pcidev, off) == cap)
31 off = pcicfgr8(ctlr->pcidev, off+1);
41 off = ehciecap(ctlr, Clegacy);
44 if(pcicfgr8(ctlr->pcidev, off+CLbiossem) != 0){
45 dprint("ehci %#p: bios active, taking over...\n", ctlr->capio);
46 pcicfgw8(ctlr->pcidev, off+CLossem, 1);
47 for(i = 0; i < 100; i++){
48 if(pcicfgr8(ctlr->pcidev, off+CLbiossem) == 0)
53 print("ehci %#p: bios timed out\n", ctlr->capio);
55 pcicfgw32(ctlr->pcidev, off+CLcontrol, 0); /* no SMIs */
65 dprint("ehci %#p reset\n", ctlr->capio);
74 * halt and route ports to companion controllers
81 /* clear high 32 bits of address signals if it's 64 bits capable.
82 * This is probably not needed but it does not hurt and others do it.
84 if((ctlr->capio->capparms & C64) != 0){
85 dprint("ehci: 64 bits\n");
90 if(ehcidebugcapio != ctlr->capio){
91 opio->cmd |= Chcreset; /* controller reset */
93 for(i = 0; i < 100; i++){
94 if((opio->cmd & Chcreset) == 0)
99 print("ehci %#p controller reset timed out\n", ctlr->capio);
101 opio->cmd |= Citc1; /* 1 intr. per µframe */
103 switch(opio->cmd & Cflsmask){
105 ctlr->nframes = 1024;
114 panic("ehci: unknown fls %ld", opio->cmd & Cflsmask);
116 dprint("ehci: %d frames\n", ctlr->nframes);
121 setdebug(Hci*, int d)
136 opio->cmd |= Chcreset; /* controller reset */
138 for(i = 0; i < 100; i++){
139 if((opio->cmd & Chcreset) == 0)
144 print("ehci %#p controller reset timed out\n", ctlr->capio);
154 static int already = 0;
165 while ((p = pcimatch(p, 0, 0)) != nil) {
167 * Find EHCI controllers (Programming Interface = 0x20).
169 if(p->ccrb != Pcibcserial || p->ccru != Pciscusb)
173 io = p->mem[0].bar & ~0x0f;
181 print("usbehci: %#x %#x: port %#p size %#x irq %d\n",
182 p->vid, p->did, io, p->mem[0].size, p->intl);
184 ctlr = malloc(sizeof(Ctlr));
186 print("usbehci: no memory\n");
191 capio = ctlr->capio = vmap(io, p->mem[0].size);
192 ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
195 for(i = 0; i < Nhcis; i++)
201 print("ehci: bug: more than %d controllers\n", Nhcis);
204 * currently, if we enable a second ehci controller,
205 * we'll wedge solid after iunlock in init for the second one.
208 iprint("usbehci: ignoring controllers after first %d, "
209 "at %#p\n", maxehci, io);
223 static Lock resetlck;
225 s = getconf("*maxehci");
226 if (s != nil && s[0] >= '0' && s[0] <= '9')
228 if(maxehci == 0 || getconf("*nousbehci"))
234 * Any adapter matches if no hp->port is supplied,
235 * otherwise the ports must match.
238 for(i = 0; i < Nhcis && ctlrs[i] != nil; i++){
240 if(ctlr->active == 0)
241 if(hp->port == 0 || hp->port == ctlr->base){
247 if(i >= Nhcis || ctlrs[i] == nil)
252 hp->port = ctlr->base;
257 hp->nports = capio->parms & Cnports;
259 ddprint("echi: %s, ncc %lud npcc %lud\n",
260 capio->parms & 0x10000 ? "leds" : "no leds",
261 (capio->parms >> 12) & 0xf, (capio->parms >> 8) & 0xf);
262 ddprint("ehci: routing %s, %sport power ctl, %d ports\n",
263 capio->parms & 0x40 ? "explicit" : "automatic",
264 capio->parms & 0x10 ? "" : "no ", hp->nports);
270 * Linkage to the generic HCI driver.
273 hp->shutdown = shutdown;
274 hp->debug = setdebug;
275 intrenable(hp->irq, hp->interrupt, hp, hp->tbdf, hp->type);
283 addhcitype("ehci", reset);