linux - usb_control_msg 返回 -EAGAIN
问题描述
我有一个通过 USB 接口的定制板。我正在编写 USB Linux 驱动程序。
当我在我的虚拟机上测试它时一切正常.. 但是当我切换到真实硬件并在硬件上使用 Yocto 并运行以下代码.. 它失败并显示 -EAGAIN..
retval = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
CP210X_GET_MDMSTS,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0,
i,
(void *)&modem_status,
1,
USB_CTRL_SET_TIMEOUT);
retval 返回 -11。我不确定为什么虚拟机上没有发生这种情况,因为唯一的区别是 PIC 板连接到 X86 定制板并运行 linux ..
dmesg 输出:
transfer buffer not dma capable
------------[ cut here ]------------
WARNING: CPU: 1 PID: 754 at /usr/src/kernel/drivers/usb/core/hcd.c:1595 usb_hcd_map_urb_for_dma+0x3e6/0x5b0
Modules linked in: cp2108(O)
CPU: 1 PID: 754 Comm: test_quad Tainted: G O 4.14.68-intel-pk-standard #1
task: ffff9a33b7d4a4c0 task.stack: ffff9ce5c0130000
RIP: 0010:usb_hcd_map_urb_for_dma+0x3e6/0x5b0
RSP: 0018:ffff9ce5c0133b08 EFLAGS: 00010296
RAX: 000000000000001f RBX: ffff9a33b7d89780 RCX: 0000000000000000
RDX: ffff9a33bfc9d680 RSI: ffff9a33bfc95598 RDI: ffff9a33bfc95598
RBP: ffff9ce5c0133b28 R08: 0000000000000001 R09: 0000000000000328
R10: ffff9a33ba840068 R11: 0000000000000000 R12: ffff9a33ba2ea000
R13: 00000000fffffff5 R14: 0000000001400000 R15: 0000000000000200
FS: 00007fac9eeed4c0(0000) GS:ffff9a33bfc80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000003c334e3cb0 CR3: 0000000179498000 CR4: 00000000003406e0
Call Trace:
usb_hcd_submit_urb+0x420/0xa00
? tty_port_open+0xa7/0xd0
? tty_ldisc_unlock+0x1a/0x20
? tty_open_proc_set_tty+0x7f/0xb0
? tty_unlock+0x29/0x40
? tty_open+0x38e/0x450
usb_submit_urb+0x364/0x550
usb_start_wait_urb+0x5f/0xe0
usb_control_msg+0xc5/0x110
cp210x_ioctl+0x4d2/0xe20 [cp2108]
? filemap_map_pages+0x129/0x290
? do_filp_open+0xa0/0xf0
serial_ioctl+0x46/0x50
tty_ioctl+0xe7/0x870
do_vfs_ioctl+0x99/0x5e0
? putname+0x4c/0x60
SyS_ioctl+0x79/0x90
你们能否提供一个提示让我尝试.. 感谢您的时间和努力。
解决方案
我得到了解决方案Kernel >= 4.9 不再接受任何静态分配的缓冲区。
修改代码以使用动态内存并且它工作。
modem_status = kmalloc(sizeof(unsigned long), GFP_KERNEL);
if (!modem_status)
return -ENOMEM;
for (i = 0; i < MAX_CP210x_INTERFACE_NUM; i++) {
retval = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
CP210X_GET_MDMSTS,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0,
i,
(void *)modem_status,
1,
USB_CTRL_SET_TIMEOUT);
推荐阅读
- reactjs - 使用 useState 和 useContext React Hooks 持久化 localStorage
- java - 从不同的 API 拉取数据
- c# - 按下键,中止线程
- javascript - 如何使引导导航栏的背景透明?
- google-cloud-firestore - 使用纪元时间戳对时间戳字段进行 Firestore 集合查询
- json - 颤振应用程序中的“方法'[]'在null上被调用”并且数据未显示
- javascript - 使用 html 和 JS 查看所有当前打开的标签
- java - 我正在尝试访问导航抽屉,以便当我单击应用栏的左上角时,我可以访问新活动中的设置
- c - vm_offset_t、(void *) 和 mach_vm_size_t 之间的区别
- android - Google play billing API:如何了解用户是否订阅?