Thank you for the explanation, Alan. Please find my questions below: On Fri, Apr 10, 2009 at 10:19 AM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: > On Thu, 9 Apr 2009, Aniruddha Marathe wrote: > >> Hi All, >> >> I am trying to understand how usb.c, the only working user mode driver >> example that I found on the net that uses gadgetfs. Using that code as >> the base I am trying to write a HID keyboard driver (user mode) with >> Net2280 peripheral device controller to simulate working of a >> keyboard. I referred to the following discussion that happened almost >> half a decade ago but didn't lead to any useful conclusions (but did >> help me find answers to some of my questions): >> >> http://www.mail-archive.com/linux-usb-devel@xxxxxxxxxxxxxxxxxxxxx/msg20380.html >> >> I am running Wireshark with USB support on the host to see what's >> going on. I've attached the traces of real keyboard and my simulation >> keyboard with this email. > > My copy of Wireshark doesn't display the contents of the URBs > correctly. Can you provide output from usbmon instead? Please find attached usbmon output for real keyboard (kbd2.dump) and my keyboard (mykbd2.dump). > >> Based on that I have the following (newbie) >> questions: >> >> 1. After the response to 'GET DEVICE DESCRIPTOR' request, the trace of >> simulation driver shows that the host sends a 'GET DESCRIPTOR DEVICE >> QUALIFIER' request. I do not see such request in the trace for the >> real keyboard. > > Get-Device-Qualifier is sent only to USB-2.0 devices. No doubt your > real keyboard is USB-1.1. > Thanks for clearing that out. I am specifying the device type as USB 1.1. However, I see USB 2.0 type of device when I list the device on the host. Here are the device and hid descriptors I use for the device: static struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = 1, .bcdUSB = __constant_cpu_to_le16(0x0110), .bDeviceClass = 0, .bDeviceSubClass = 0, .bDeviceProtocol = 0, .idVendor = __constant_cpu_to_le16(KEYBOARD_VENDOR_NUM), .idProduct = __constant_cpu_to_le16(KEYBOARD_PRODUCT_NUM), .bcdDevice = 0x0100, .iManufacturer = STRING_MANUFACTURER, .iProduct = STRING_PRODUCT, .iSerialNumber = STRING_SERIALNUM, .bNumConfigurations = 1 }; static struct hid_descriptor hid_config_desc = { .bLength = sizeof(hid_config_desc), .bDescriptorType = 0x21, .bcdHID = 0x0110, .bCountryCode = 0, .bNumDescriptors = 1, .desc[0].wDescriptorLength = sizeof(ReportDescriptor), .desc[0].bDescriptorType = 0x22 }; [aniruddha@localhost ~]$ cat /proc/bus/usb/devices T: Bus=04 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 7 Spd=12 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=4242 ProdID=0110 Rev= 1.00 S: Manufacturer=Microsoft Corporation S: Product=Microsoft Natural Keyboard Pro C: #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 1 Cls=03(HID ) Sub=00 Prot=00 Driver= E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=3ms I am not sure why it shows Ver= 2.00, even though I specify 1.1. >> What is the meaning of this request? > > It is documented in the USB 2.0 specification (which you should be > familiar with if you are going to write a USB driver). It asks for a > device descriptor appropriate to the "other" speed: If the connection > is running at full speed then it asks the device to send its high-speed > device descriptor, and vice versa. > Thanks for the explanation. >> Was the response >> to the earlier 'GET DEVICE DESCRIPTOR' request malformed (the sniffer >> doesn't indicate that, however)? > > I can't tell since Wireshark doesn't display the response data > properly. > >> Simulation keyboard trace: >> >> -------------------------------------------------------------------------------------------------- >> Source Destination Protocol Info >> -------------------------------------------------------------------------------------------------- >> host 23.0 USB GET DESCRIPTOR Request >> DEVICE QUALIFIER >> >> >> 2. My simulation keyboard driver stops responding after the following request: >> >> ------------------------------------------------------------------------------- >> Source Destination Protocol Info >> ------------------------------------------------------------------------------- >> host 3.0 USB SET CONFIGURATION Request >> >> What should my driver send as a response back to the host? > > Set-Configuration doesn't have a response, only an acknowledgement. > You really should read through the descriptions of the standard > requests in Chapter 9 of the USB 2.0 specification; if you don't > understand them then you can't possibly write a USB driver. > >> I saw that >> the real keyboard just sends a response with 0's filled in it. > > No it doesn't. You're probably seeing an artifact introduced by > Wireshark. There's no response, only an acknowledgement. > >> Is this >> what it is supposed to send? Keyboard simulator creates a new thread >> for 'ep-a' management and writes the endpoint descriptor into ep-a's >> file descriptor. But the host doesn't seem to get it (can't see it >> on Wireshark). What I see is a (probable) timeout after 5 sec and 0's >> filled in 'SET CONFIGURATION' response. Also after this, the host >> doesn't send a request for reports, like it does in case of the real >> keyboard. Why does this happen? > > Probably because your program isn't sending the acknowledgement. You > should do more or less the same thing as the usb.c demo program. > >> 3. The real keyboard has an IN endpoint of type interrupt. As far as I >> understand, this is the endpoint that should be sending the report >> descriptors to the host. > > No. The interrupt-IN endpoint is used for sending the reports > themselves; the report _descriptor_ is sent via endpoint 0. > Ahh.. Two different things.. >> However, in Wireshark I see that when the >> host sends a 'GET DESCRIPTOR RPIPE' request the ep0 of the real >> keyboard sends the report instead of ep1. Here is the trace (I assume >> '3.0' means ep0): >> >> ------------------------------------------------------------------------------------- >> Source Destination Protocol Info >> ------------------------------------------------------------------------------------- >> host 3.0 USB GET DESCRIPTOR Request RPIPE > > What do you think "RPIPE" means? Some sort of shorthand for "Report"? > Wireshark is weird... > I confused report descriptor with the report itself. Here, I correlated USB_DT_RPIPE which is 0x22 with RPIPE request seen in Wireshark. >> Since ep1 is interrupt type, shouldn't it send the report when the >> host sends an 'IN' token packet to ep0 instead of ep0 sending it when >> the host sends 'GET DESCRIPTOR RPIPE' to ep0? > > Endpoints don't respond to packets sent to other endpoints. So if the > host sends a token packet to ep0, there won't be a response from ep1. > If the host had sent a token packet to _ep1_ then you would expect to > see a report sent back from ep1. > > Furthermore, "GET DESCRIPTOR RPIPE" (whatever else it is) clearly is a > control transfer, not an interrupt transaction. As such it has to use > ep0, not ep1. > >> 4. Is there any other documentation available on gadgetfs and usb.c >> apart from the source code itself? > > No, not really. > > Alan Stern > > Thanks, Aniruddha
Attachment:
mykbd2.dump
Description: Binary data
Attachment:
kbd2.dump
Description: Binary data