简体   繁体   English

尝试访问嵌入式 ZEDC9F0A5A5D57797BF68E3736474383 上的 USB 设备 [/dev/bus/usb/001/001] 时 Python “[Errno 21] 是一个目录”

[英]Python "[Errno 21] Is a directory" when trying access USB device [/dev/bus/usb/001/001] on embedded Linux device

I have a device that is running a custom Linux distro that has two USB devices set up on bus 001.我有一个运行自定义 Linux 发行版的设备,该发行版在总线 001 上设置了两个 USB 设备。

ln -s functions/rndis.usb0 configs/c.1
ln -s functions/mass_storage.0 configs/c.1

These show up under lsusb:这些显示在 lsusb 下:

Bus 001 Device 002: ID 1eab:1a10
Bus 001 Device 001: ID 1d6b:0002

The issue is that the device sometimes gets stuck in USB Default mode - my understanding is that it is not being enumerated by Linux for some reason.问题是设备有时会卡在 USB 默认模式 - 我的理解是由于某种原因它没有被 Linux 枚举。 I want to try and fix this by sending a reset command to the device - however - that is when I run into Error 21:我想尝试通过向设备发送重置命令来解决此问题 - 但是 - 当我遇到错误 21 时:

import os
import sys
import fcntl

USB_RESET = 21780

fd = os.open("/dev/bus/usb/001/001", os.O_WRONLY)
try:
        fcntl.ioctl(fd, USB_RESET, 0)
except Exception as e:
        print("Error: "+str(e))
        sys.exit(1)
finally:
        os.close(fd)

The strange thing is that this works on /dev/bus/usb/001/002 When I send the command to 002 I get the output in dmesg:奇怪的是,这适用于 /dev/bus/usb/001/002 当我将命令发送到 002 时,我在 dmesg 中得到 output:

usb 1-1: reset full-speed USB device number 2 using ci_hdrc

the 'file' command suggests that they are the same type of file: 'file' 命令表明它们是相同类型的文件:

001: character special
002: character special

By digging around a little bit, I determined that the ioctl number 21780 that you are sending to the kernel is known as USBDEVFS_RESET in the kernel.通过稍微挖掘,我确定您发送到 kernel 的 ioctl 编号 21780 在 kernel 中称为USBDEVFS_RESET (If you already knew that, it would have been really good info to include in your question.) (如果您已经知道这一点,那么将其包含在您的问题中将是非常好的信息。)

Using elixir.bootlin.com , I was able to track down the code that runs in the Linux kernel when you send that ioctl and look for cases that cause it to return the "is directory" error. Using elixir.bootlin.com , I was able to track down the code that runs in the Linux kernel when you send that ioctl and look for cases that cause it to return the "is directory" error. In the usb_reset_device function in hub.c, I found this code :usb_reset_device的 usb_reset_device function 中,我找到了这段代码

    if (!udev->parent) {
        /* this requires hcd-specific logic; see ohci_restart() */
        dev_dbg(&udev->dev, "%s for root hub!\n", __func__);
        return -EISDIR;
    }

What that code shows us if that if you attempt to reset a USB device that is actually the USB root hub (because it has no parent), that is not supported.如果您尝试重置实际上是 USB 根集线器的 USB 设备(因为它没有父集线器),那么该代码向我们展示了什么,这是不受支持的。 I think you are attempting to reset the USB root hub instead of the actual device that is having trouble, and Linux is telling you that it does not know how to do that.我认为您正在尝试重置 USB 根集线器而不是有问题的实际设备,并且 Linux 告诉您它不知道该怎么做。

Note that if your USB device is in the Default state as defined by the USB specification then it has not yet been assigned an address and it is just using address 0. So we wouldn't expect either of the two devices in your lsusb output to correspond to that device, because they have addresses 1 and 2. Note that if your USB device is in the Default state as defined by the USB specification then it has not yet been assigned an address and it is just using address 0. So we wouldn't expect either of the two devices in your lsusb output to对应于该设备,因为它们具有地址 1 和 2。

I think maybe what you are looking for is a way to talk to whatever hub your device is connected to and tell it to reset the appropriate port.我想也许您正在寻找一种与您的设备连接的任何集线器通信并告诉它重置适当端口的方法。 I don't think you can really talk to the device if Linux is so confused about it that it got stuck in the default state.如果 Linux 对此感到非常困惑以至于卡在默认的 state 中,我认为您无法真正与设备交谈。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM