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;
20 /* Isn't this cap list search in a helper function? */
26 ptr = (ctlr->capio->capparms >> Ceecpshift) & Ceecpmask;
27 for(; ptr != 0; ptr = pcicfgr8(ctlr->pcidev, ptr+1)){
28 if(ptr < 0x40 || (ptr & ~0xFC))
30 cap = pcicfgr8(ctlr->pcidev, ptr);
33 sem = pcicfgr8(ctlr->pcidev, ptr+CLbiossem);
36 pcicfgw8(ctlr->pcidev, ptr+CLossem, 1);
37 for(i = 0; i < 100; i++){
38 if(pcicfgr8(ctlr->pcidev, ptr+CLbiossem) == 0)
43 dprint("ehci %#p: bios timed out\n", ctlr->capio);
44 pcicfgw32(ctlr->pcidev, ptr+CLcontrol, 0); /* no SMIs */
45 ctlr->opio->config = 0;
58 dprint("ehci %#p reset\n", ctlr->capio);
62 * Turn off legacy mode. Some controllers won't
63 * interrupt us as expected otherwise.
66 pcicfgw16(ctlr->pcidev, 0xc0, 0x2000);
73 /* clear high 32 bits of address signals if it's 64 bits capable.
74 * This is probably not needed but it does not hurt and others do it.
76 if((ctlr->capio->capparms & C64) != 0){
77 dprint("ehci: 64 bits\n");
82 if(ehcidebugcapio != ctlr->capio){
83 opio->cmd |= Chcreset; /* controller reset */
85 for(i = 0; i < 100; i++){
86 if((opio->cmd & Chcreset) == 0)
91 print("ehci %#p controller reset timed out\n", ctlr->capio);
93 opio->cmd |= Citc1; /* 1 intr. per µframe */
95 switch(opio->cmd & Cflsmask){
106 panic("ehci: unknown fls %ld", opio->cmd & Cflsmask);
108 dprint("ehci: %d frames\n", ctlr->nframes);
113 setdebug(Hci*, int d)
128 opio->cmd |= Chcreset; /* controller reset */
130 for(i = 0; i < 100; i++){
131 if((opio->cmd & Chcreset) == 0)
136 print("ehci %#p controller reset timed out\n", ctlr->capio);
146 static int already = 0;
157 while ((p = pcimatch(p, 0, 0)) != nil) {
159 * Find EHCI controllers (Programming Interface = 0x20).
161 if(p->ccrb != Pcibcserial || p->ccru != Pciscusb)
165 io = p->mem[0].bar & ~0x0f;
171 print("usbehci: %x %x: failed to map registers\n",
175 if(p->intl == 0xff || p->intl == 0) {
176 print("usbehci: no irq assigned for port %#lux\n", io);
179 dprint("usbehci: %#x %#x: port %#lux size %#x irq %d\n",
180 p->vid, p->did, io, p->mem[0].size, p->intl);
182 ctlr = malloc(sizeof(Ctlr));
184 print("usbehci: no memory\n");
188 capio = ctlr->capio = vmap(io, p->mem[0].size);
189 ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
192 for(i = 0; i < Nhcis; i++)
198 print("ehci: bug: more than %d controllers\n", Nhcis);
201 * currently, if we enable a second ehci controller,
202 * we'll wedge solid after iunlock in init for the second one.
205 iprint("usbehci: ignoring controllers after first %d, "
206 "at %#p\n", maxehci, io);
220 static Lock resetlck;
222 s = getconf("*maxehci");
223 if (s != nil && s[0] >= '0' && s[0] <= '9')
225 if(maxehci == 0 || getconf("*nousbehci"))
231 * Any adapter matches if no hp->port is supplied,
232 * otherwise the ports must match.
235 for(i = 0; i < Nhcis && ctlrs[i] != nil; i++){
237 if(ctlr->active == 0)
238 if(hp->port == 0 || hp->port == (uintptr)ctlr->capio){
244 if(i >= Nhcis || ctlrs[i] == nil)
249 hp->port = (uintptr)ctlr->capio;
254 hp->nports = capio->parms & Cnports;
256 ddprint("echi: %s, ncc %lud npcc %lud\n",
257 capio->parms & 0x10000 ? "leds" : "no leds",
258 (capio->parms >> 12) & 0xf, (capio->parms >> 8) & 0xf);
259 ddprint("ehci: routing %s, %sport power ctl, %d ports\n",
260 capio->parms & 0x40 ? "explicit" : "automatic",
261 capio->parms & 0x10 ? "" : "no ", hp->nports);
267 * Linkage to the generic HCI driver.
270 hp->shutdown = shutdown;
271 hp->debug = setdebug;
278 addhcitype("ehci", reset);