0

I am reading the source code of Linux driver about usbhid and usbkbd:

if (interface->desc.bNumEndpoints != 1)
    return -ENODEV;

endpoint = &interface->endpoint[0].desc;
if (!usb_endpoint_is_int_in(endpoint))
    return -ENODEV;

Here you can see in the usbkbd that it can only deal with single endpoint, but in hid-core.c, it can deal with all endpoints about interrupt. I am wondering why, could anyone tell me about that? And more history about usbhid vs usbkbd?

Edit:

Is the reason that my keyboard has the feature of update firmware? Not traditional keyboard? Maybe the OUT endpoint is used for PC sending firmware or other settings to my keyboard?

What's your keyboard endpoints situation?

My keyboare detail by lsusb -v:

Bus 001 Device 006: ID 04d9:a293 Holtek Semiconductor, Inc. OBINS
AnnePro2
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x04d9 Holtek Semiconductor, Inc.
  idProduct          0xa293 
  bcdDevice            1.00
  iManufacturer           1 OBINS
  iProduct                2 OBINS
AnnePro2
  iSerial                 3 00000000000000000000000000000000
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x007b
    bNumInterfaces          4
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode           33 US
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      79
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval              10
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0025  1x 37 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode           33 US
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      27
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              10
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval              10
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode           33 US
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     161
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x85  EP 5 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0014  1x 20 bytes
        bInterval              10
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        3
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode           33 US
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      73
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x86  EP 6 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10
Device Status:     0x0000
  (Bus Powered)
0andriy
  • 4,183
  • 1
  • 24
  • 37
Ma Paul
  • 19
  • 2
  • A hub has multiple endpoints. What would it mean for a keyboard to have multiple endpoints? – stark Aug 21 '22 at 20:48
  • I don't know about the endpoints function for my keyboard, but it has 4 interface, and interface 0 and interface 1 have two endpoints and just one IN endpoints. usbhid can deal with keyboard because it deal with all endpoints, but why usbkbd can not. I think you read it wrong? :) it's hid not hub. – Ma Paul Aug 22 '22 at 06:58
  • 1
    The USB KBD Boot Protocol driver has always assumed the device has a single endpoint. When the driver was first implemented in kernel 2.2.7 it used endpoint 0, but it did not check bNumEndpoints until kernel 2.2.18. – Ian Abbott Aug 22 '22 at 10:56
  • Perhaps you could show the lsusb -v output for your USB keyboard. – Ian Abbott Aug 22 '22 at 15:34
  • thanks dude, I have update lsusb detail to the question – Ma Paul Aug 22 '22 at 17:18
  • 1
    It looks like interface 0 supports the boot protocol, but it has 2 endpoints so it would fail the check in the usbkbd driver. Perhaps the driver should be checking for one endpoint in the input direction rather than one endpoint in total. – Ian Abbott Aug 23 '22 at 09:04
  • As @IanAbbott said, try to replace last three lines in your excerpt with `error = usb_find_common_endpoints(interface, &endpoint, NULL, NULL, NULL); if (error) return error;` and see if it helps. Note, patches are welcome in upstream (linux-usb@ mailing list). – 0andriy Aug 23 '22 at 22:23
  • @0andriy Close, but I think it should be looking for the "interrupt-in" endpoint rather than the "bulk-in" endpoint - `(interface, NULL, &endpoint, NULL)`. – Ian Abbott Aug 24 '22 at 09:36
  • Yeah, Thanks. The main reason is that my device has 2 endpoints in interface 0 , so it failed to bind with the usbkbd driver, as @IanAbbott said It's about interrupt in endpoint, so the code maybe `usb_find_common_endpoints(interface,NULL, NULL, &endpoint, NULL)`. And now I am wondering why the usbkbd driver still exist while usbhid can even deal with all the hid devices, when to use that ? – Ma Paul Aug 24 '22 at 15:26
  • 1
    I guess some things use usbkbd, but as it says in menuconfig for `CONFIG_USB_KBD`: **Say Y here only if you are absolutely sure that you don't want to use the generic HID driver for your USB keyboard and prefer to use the keyboard in its limited Boot Protocol mode instead. This is almost certainly not what you want. This is mostly useful for embedded applications or simple keyboards.** – Ian Abbott Aug 24 '22 at 16:36

0 Answers0