I'm making a Linux module (my first one) for a closed-source, enclosed (no hardware access) device. Using Wireshark I found what to send and where, so I tried the following command in user space Python and it works:

handle._controlTransfer(0x21, 0x09, 0x0300, 3, data, 8, 0) #packet sent, device reacts

Sadly I can't get it to work in the kernel module:

usb_control_msg(dev, usb_sndctrlpipe(dev, 0), 0x09, 0x21, 0x0300, 3, data, 8, 0); //packet sent, device doesn't react

even by creating the urb myself:

urb = usb_alloc_urb(0, GFP_KERNEL);
cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL);
cr->bRequest = 0x09;
cr->wValue = cpu_to_le16(0x0300);
cr->wIndex = cpu_to_le16(3);
cr->wLength = cpu_to_le16(8);
usb_fill_control_urb(urb, dev, usb_sndctrlpipe(dev, 0), (void *)cr, data, 8, urb_callback, context);
usb_submit_urb(urb, GFP_ATOMIC);
//packet sent, device doesn't react

When I say the device "reacts" I mean it flashes with another color so there is no ambiguity in the success of the command.

I logged everything with Wireshark and the packets are identical (except for urb_id and urb_ts_*)

Would you have any advice for me? Something I forgot or how to debug more?


Full working Python code

context = usb1.USBContext()
handle = context.openByVendorIDAndProductID(VENDOR_ID, PRODUCT_ID)
usb1.libusb1.libusb_set_auto_detach_kernel_driver(handle._USBDeviceHandle__handle, 0)
usb1.libusb1.libusb_set_auto_detach_kernel_driver(handle._USBDeviceHandle__handle, 3)
handle._controlTransfer(0x21, 0x09, 0x0300, 3, data, 8, 0)
  • Do you have any logic analyser to check if the packets are indeed the same?
    – morsisko
    Jun 20, 2020 at 0:56
  • No, that's what I mean by no hardware access: it's an USB chip inside a laptop I can't open
    – PeterHerb
    Jun 20, 2020 at 1:15
  • Do you think it is possible for Wireshark to display identical packets whereas the physical data is different? I don't think this is the problem because every single test with Python works and every single test in the kernel driver fails
    – PeterHerb
    Jun 20, 2020 at 18:35
  • Yeah it is very unlikely that the problem is on hardware side if wireshark shows identical data, however I would check it anyway just to be sure, but as I understand in your situation it is not possible. Maybe the problem isn't with the data itself, maybe the device need to be initializated somehow before sending the payload?
    – morsisko
    Jun 20, 2020 at 18:47
  • I thought about that too so I edited the usbhid driver (the original driver of the device) in order to be sure any initialization would be the same. I put some logs and the usb_control_msg line above but got the same results. Also I realised something new, with Python there is another packet prior to the correct one : an interrupt coming from the device right after the first interface is claimed. I don't think it's relevant though.
    – PeterHerb
    Jun 20, 2020 at 21:15


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.