> /n/sources/plan9/sys/src/cmd/usb/lib/dev.c:228,233 - dev.c:233,245
>         memset(buf, 0, Ddevlen);
>         if((nr=usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, nr)) < 0)
>                 return -1;
> +       if(nr == 17){
> +               print("%s: langid %.4ux\n", argv0, buf[3]<<8|buf[2]);
> +               if((nr = usbcmd(d, type, Rgetdesc, Ddev<<8|0, 
> buf[3]<<8|buf[2], buf, 18)) < 0)
> +                       return -1;
> +               print("%s: nr = %d; buf[%d] = %.2ux\n", argv0, nr, nr, 
> buf[nr]);
> +       }
> +
> 
> This is in function loaddevdesc which loads a device descriptor, not a
> string descriptor.  The device descriptor doesn't have a language id
> in offset 2:3, it has bcdUSB and bDeviceClass in those fields.  And
> the specification for the Rgetdesc command says "the wIndex field
> specifies the LanguageID for string descriptors or is reset to zero
> for other descriptors".

you're right.  looks like sloppy junk copied in mindlessly.

it seems that asking for exactly 18 bytes is enough.
i wonder if this will work for all devices.  it does work for all
the ones i've got.

/n/sources/plan9/sys/src/cmd/usb/lib/dev.c:218,224 - dev.c:223,229
  int
  loaddevdesc(Dev *d)
  {
-       uchar buf[Ddevlen+255];
+       uchar buf[Ddevlen];
        int nr;
        int type;
        Ep *ep0;
/n/sources/plan9/sys/src/cmd/usb/lib/dev.c:226,245 - dev.c:231,241
        type = Rd2h|Rstd|Rdev;
        nr = sizeof(buf);
        memset(buf, 0, Ddevlen);
-       if((nr=usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, nr)) < 0)
+       if((nr = usbcmd(d, type, Rgetdesc, Ddev<<8|0, 0, buf, Ddevlen)) < 0)
                return -1;
-       /*
-        * Several hubs are returning descriptors of 17 bytes, not 18.
-        * We accept them and leave number of configurations as zero.
-        * (a get configuration descriptor also fails for them!)
-        */
        if(nr < Ddevlen){
-               print("%s: %s: warning: device with short descriptor\n",
-                       argv0, d->dir);
-               if(nr < Ddevlen-1){
-                       werrstr("short device descriptor (%d bytes)", nr);
-                       return -1;
-               }
+               werrstr("short device descriptor (%d bytes)", nr);
+               return -1;
        }
        d->usb = emallocz(sizeof(Usbdev), 1);
        ep0 = mkep(d->usb, 0);

interestingly, on the pc i plugged the imac keyboard into,
usb/kb hung.  this is the kernel stack even *after* pulling
the keyboard.  

acid; stk()
sleep(r=0xf0daba30,arg=0xf0d55680,f=0xf013fc71)+0x16a 
/sys/src/nix/port/proc.c:928
epiowait(io=0xf0dab9e0,hp=0xf0d4d6b0,tmout=0x0,load=0x11)+0x37e 
/sys/src/nix/port/usbehci.c:2289
epio(io=0xf0dab9e0,ep=0xf0dab720,count=0x8,a=0x442917,mustlock=0x1)+0x38e 
/sys/src/nix/port/usbehci.c:2423
epread(ep=0xf0dab720,count=0x8,a=0x442917)+0x16f 
/sys/src/nix/port/usbehci.c:2534
usbread(c=0xf0dab840,a=0x442917,n=0x8,offset=0x0)+0x17d 
/sys/src/nix/port/devusb.c:1070
read(list=0xf056be24,ispread=0x0)+0x269 /sys/src/nix/port/sysfile.c:745
syspread(ar0=0xf0dafa90,list=0xf056be04)+0x1c /sys/src/nix/port/sysfile.c:766
syscall(scallnr=0x32,ureg=0xf0dafad8)+0x22e /sys/src/nix/k10/syscall.c:273
syscallreturn()+0x0 /sys/src/nix/k10/l64syscall.s:52

- erik

Reply via email to