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, privacy policy and cookie policy

Browse other questions tagged or ask your own question.