当我尝试写入设备时,为什么我的内核模块会抛出“管道中断”错误?

Nat*_*man 5 usb kernel-module linux-kernel

我目前正在用C编写Linux内核模块。该模块为USB灯(该设备由三个彩色LED组成)提供了非常基本的驱动程序。我设法得到没有问题的驱动程序加载和卸载,并创建设备(/dev/wn0/dev/wn1,等)。但是,尝试写入设备时,我总是收到错误消息:

$ echo "1" >/dev/wn0
bash: echo: write error: Broken pipe
Run Code Online (Sandbox Code Playgroud)

模块的完整代码在这里。但是,有趣的部分是wn_set_color()函数:

/* Create the data buffer to be sent to the device. */
u8 buf[8] = {
    red, green, blue, 0, 0, 0, 0x1F, 0x05
};

/* Send the data to the device. */
return usb_control_msg(udev,
                       usb_sndctrlpipe(udev, 0),
                       0, 0, 0, 0,
                       buf, 8, 0);
Run Code Online (Sandbox Code Playgroud)

由于某种原因,它返回-32而不是将数据发送到设备。

我是Linux内核编程的新手,所以我可能做一些愚蠢的事情。如果您能对此有所了解,将不胜感激。


编辑:这是一些更多信息:

  • lsusb -v输出在这里

  • 所述bDescriptorType的的构件usb_endpoint_descriptor类包含“5”由设备露出的单个端点(bEndpointAddress129-或0x81十六进制)

  • 是发送到设备的控制URB之一的屏幕抓图

caf*_*caf 4

usb_control_msg()最终调用到usb_submit_urb(). Documentation /usb/error-codes.txt文件描述了此函数可能返回的错误:

-EPIPE          The pipe type specified in the URB doesn't match the
                endpoint's actual type.
Run Code Online (Sandbox Code Playgroud)

如果usb_submit_urb()成功,则usb_control_msg()返回一个urb->status值。该列表如下EPIPE

-EPIPE (**)             Endpoint stalled.  For non-control endpoints,
                        reset this status with usb_clear_halt().

(**) This is also one of several codes that different kinds of host
controller use to indicate a transfer has failed because of device
disconnect.  In the interval before the hub driver starts disconnect
processing, devices may receive such fault reports for every request.
Run Code Online (Sandbox Code Playgroud)

您检查过内核日志中的任何消息吗?