Linux USB驱动开发:usb_control_msg调用返回错误码-11
问题排查与解决
错误码-11对应EAGAIN/EWOULDBLOCK,通常表示请求无法立即完成或设备未响应导致传输失败。结合你的libusb与内核驱动代码差异,重点排查以下几点:
1. 核心参数不匹配:wValue参数
你的libusb调用中,wValue传入的是变量value,但内核驱动的usb_control_msg里value参数硬编码为0。如果设备需要特定wValue值才能响应IN请求(比如指定读取的寄存器地址),内核传0会导致设备不处理请求,最终返回错误。
修正方式:将内核代码中的value参数替换为和libusb一致的变量值,示例:
status = usb_control_msg(data->udev, usb_rcvctrlpipe(data->udev, 0), 0x10, USB_DIR_IN, target_value, 0, (u8*) &my_data, 2, 100);
(target_value对应libusb里的value变量)
2. RequestType参数不完整
libusb中使用的0x80仅设置了USB_DIR_IN方向位,但自定义厂商请求需要同时指定类型位为USB_TYPE_VENDOR。虽然libusb可能绕过部分检查,但内核USB栈会严格校验请求类型。
正确的requesttype应为USB_DIR_IN | USB_TYPE_VENDOR(即0xC0),修正代码:
status = usb_control_msg(data->udev, usb_rcvctrlpipe(data->udev, 0), 0x10, USB_DIR_IN | USB_TYPE_VENDOR, target_value, 0, (u8*) &my_data, 2, 100);
3. Probe函数中的设备状态问题
驱动probe阶段,设备可能尚未完成配置激活。用户空间libusb会自动处理设备配置和接口激活,但内核驱动需手动确保:
- 设备已设置正确配置(根据设备实际配置调整,示例使用配置1)
- 目标接口已被抢占,避免被其他驱动占用
在调用usb_control_msg前添加以下代码:
// 设置设备配置 int ret = usb_set_configuration(data->udev, 1); if (ret < 0) { dev_err(&intf->dev, "Failed to set configuration: %d\n", ret); return ret; } // 抢占接口 ret = usb_claim_interface(data->udev, intf->cur_altsetting->desc.bInterfaceNumber); if (ret < 0) { dev_err(&intf->dev, "Failed to claim interface: %d\n", ret); return ret; }
4. 设备端代码验证
虽然libusb能正常工作,仍需确认设备端处理逻辑:
- 检查设备是否正确响应
bRequest=0x10、bRequestType=0x80(或0xC0)的请求 - 确认设备收到请求后,是否及时返回2字节的uint16_t数据
内容的提问来源于stack exchange,提问作者johannes4linux
相关产品推荐
相关产品推荐

