5

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

$ echo "1" >/dev/wn0
bash: echo: write error: Broken pipe

该模块的完整代码在这里。然而,有趣的部分是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);

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

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


编辑:这里有一些进一步的信息:

  • lsusb -v输出在这里

  • 类的bDescriptorType成员usb_endpoint_descriptor包含设备公开的单个端点的“5”(bEndpointAddress129- 或0x81十六进制)

  • 是发送到设备的其中一个控制 URB 的屏幕截图

4

2 回答 2

4

usb_control_msg() eventually calls down to usb_submit_urb(). The Documentation/usb/error-codes.txt file describes the errors that this function can return:

-EPIPE          The pipe type specified in the URB doesn't match the
                endpoint's actual type.

If usb_submit_urb() succeeded, then usb_control_msg() returns an urb->status value. This lists under 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.

Have you checked for any messages in the kernel log?

于 2013-01-14T06:10:41.730 回答
2

我感觉这和你的usb_sndctrlpipe电话有关。该函数的定义如下:unsigned int usb_sndctrlpipe(struct usb_device *dev, unsigned int endpoint).

您似乎正确地传递了设备指针,但是您传入0控制端点的值,正如您所提到的,它不是您的端点的地址。我建议在开始时使用端点的十六进制值定义一个常量,并将其传递给您的调用。

但是,我相信你有一个更大的问题。

查看您的 lsusb,您的端点似乎实际上不是控制端点,而是中断端点。这会更改您需要调用以进行通信的函数。例如,usb_sndctrlpipe您需要生成管道而不是usb_rcvintpipe(struct usb_device *dev, unsigned int endpoint)生成管道(因为它是 lsusb 中列出的 IN 端点)并使用不同的函数而不是usb_control_msg. 不幸的是,据我所知,似乎没有可用于自动构造中断 urb 的函数,因此您需要创建一个 urb 结构,如http://www.makelinux.net/ldd3/的第 13.3.2.1 节所述chp-13-sect-3。更糟糕的消息是(除非我遗漏了什么)因为你唯一的端点似乎是中断IN端点,您似乎只能从设备接收中断,而无法向设备发送任何内容。您确定通过 USB 更改灯的颜色是设备支持的功能吗?

更多信息可以在以下位置找到:

于 2013-12-13T11:13:34.683 回答