a bit of an update, disabling one of the usb ehci devies "fixed" things
but i get a number of errors and warnings from epiowait() with this
format: "ehci %#p: io %#p qh %#p timed out (no intr?)\n".
things are not right, but at least the machine is working as a terminal.

i added some general code to disable arbitrary ehci devices.
also, i noticed that there's a smalloc() that really can't be counted
on as we're holding an ilock.  i'd rather panic on nil indirection
than just hang.

- erik

----

; 9diff usbehcipc.c
post...
/n/sources/plan9//sys/src/9/pc/usbehcipc.c:142,179 - usbehcipc.c:142,192
        iunlock(ctlr);
  }
  
+ static int
+ checkdev(Pcidev *p)
+ {
+       char *conf, *s, dev[32];
+ 
+       conf = getconf("*badehci");
+       if(conf == nil)
+               return 0;
+       snprint(dev, sizeof dev, "%.4ux/%.4ux", p->vid, p->did);
+ 
+       s = strstr(conf, dev);
+       if(s != nil && (s[9] == 0 || s[9] == ' '))
+               return -1;
+       return 0;
+ }
+       
  static void
  scanpci(void)
  {
-       static int already = 0;
        int i;
        ulong io;
        Ctlr *ctlr;
        Pcidev *p;
        Ecapio *capio;
+       static int already;
  
        if(already)
                return;
        already = 1;
-       p = nil;
-       while ((p = pcimatch(p, 0, 0)) != nil) {
+       i = 0;
+       for(p = nil; (p = pcimatch(p, 0, 0)) != nil; ) {
                /*
                 * Find EHCI controllers (Programming Interface = 0x20).
                 */
-               if(p->ccrb != Pcibcserial || p->ccru != Pciscusb)
+               if(p->ccrb != Pcibcserial || p->ccru != Pciscusb || p->ccrp != 
0x20)
                        continue;
-               switch(p->ccrp){
-               case 0x20:
-                       io = p->mem[0].bar & ~0x0f;
-                       break;
-               default:
+               if(i == Nhcis){
+                       print("ehci: bug: more than %d controllers\n", Nhcis);
                        continue;
                }
-               if(0 && p->vid == Vintel && p->did == 0x3b34) {
-                       print("usbehci: ignoring known bad ctlr %#ux/%#ux\n",
-                               p->vid, p->did);
+               if(checkdev(p) == -1){
+                       print("usbehci: ignore %.4ux/%.4ux\n", p->vid, p->did);
                        continue;
                }
+               io = p->mem[0].bar & ~0x0f;
                if(io == 0){
                        print("usbehci: %x %x: failed to map registers\n",
                                p->vid, p->did);
/n/sources/plan9//sys/src/9/pc/usbehcipc.c:186,204 - usbehcipc.c:199,210
                dprint("usbehci: %#x %#x: port %#lux size %#x irq %d\n",
                        p->vid, p->did, io, p->mem[0].size, p->intl);
  
-               ctlr = smalloc(sizeof(Ctlr));
+               ctlr = malloc(sizeof(Ctlr));
                ctlr->pcidev = p;
                capio = ctlr->capio = vmap(io, p->mem[0].size);
                ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
                pcisetbme(p);
                pcisetpms(p, 0);
-               for(i = 0; i < Nhcis; i++)
-                       if(ctlrs[i] == nil){
-                               ctlrs[i] = ctlr;
-                               break;
-                       }
-               if(i >= Nhcis)
-                       print("ehci: bug: more than %d controllers\n", Nhcis);
  
                /*
                 * currently, if we enable a second ehci controller on zt
/n/sources/plan9//sys/src/9/pc/usbehcipc.c:208,215 - usbehcipc.c:214,225
                if (i >= maxehci) {
                        print("usbehci: ignoring controllers after first %d, "
                                "at %#p\n", maxehci, io);
-                       ctlrs[i] = nil;
+                       pciclrbme(p);
+                       vunmap(capio, p->mem[0].size);
+                       free(ctlr);
+                       continue;
                }
+               ctlrs[i++] = ctlr;
        }
  }
  

Reply via email to