AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 645
Accepted
cmcginty
cmcginty
Asked: 2010-08-02 11:46:45 +0800 CST2010-08-02 11:46:45 +0800 CST 2010-08-02 11:46:45 +0800 CST

如何从命令行重置 USB 设备?

  • 772

是否可以在不物理断开/连接 PC 的情况下重置 USB 设备的连接?

具体来说,我的设备是数码相机。我正在使用gphoto2,但最近我收到“设备读取错误”,所以我想尝试对连接进行软件重置。

据我所知,没有为相机加载内核模块。唯一看起来相关的是usbhid.

command-line usb
  • 18 18 个回答
  • 571347 Views

18 个回答

  • Voted
  1. Best Answer
    Li Lo
    2010-08-02T18:27:03+08:002010-08-02T18:27:03+08:00

    将以下内容另存为usbreset.c

    /* usbreset -- send a USB port reset to a USB device */
    
    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <sys/ioctl.h>
    
    #include <linux/usbdevice_fs.h>
    
    
    int main(int argc, char **argv)
    {
        const char *filename;
        int fd;
        int rc;
    
        if (argc != 2) {
            fprintf(stderr, "Usage: usbreset device-filename\n");
            return 1;
        }
        filename = argv[1];
    
        fd = open(filename, O_WRONLY);
        if (fd < 0) {
            perror("Error opening output file");
            return 1;
        }
    
        printf("Resetting USB device %s\n", filename);
        rc = ioctl(fd, USBDEVFS_RESET, 0);
        if (rc < 0) {
            perror("Error in ioctl");
            return 1;
        }
        printf("Reset successful\n");
    
        close(fd);
        return 0;
    }
    

    在终端中运行以下命令:

    1. 编译程序:

      $ cc usbreset.c -o usbreset
      
    2. 获取要重置的 USB 设备的总线和设备 ID:

      $ lsusb  
      Bus 002 Device 003: ID 0fe9:9010 DVICO  
      
    3. 使我们编译的程序可执行:

      $ chmod +x usbreset
      
    4. 以 sudo 权限执行程序;通过运行以下命令对找到的<Bus>和id进行必要的替换:<Device>lsusb

      $ sudo ./usbreset /dev/bus/usb/002/003  
      

    上述程序来源:http ://marc.info/?l=linux-usb&m=121459435621262&w=2

    • 163
  2. ssokolow
    2011-09-13T22:56:24+08:002011-09-13T22:56:24+08:00

    我以前没有在你的具体情况下发现自己,所以我不确定它是否足够,但我发现重置 USB 设备的最简单方法是这个命令:(不需要外部应用程序)

    sudo sh -c "echo 0 > /sys/bus/usb/devices/1-4.6/authorized"
    sudo sh -c "echo 1 > /sys/bus/usb/devices/1-4.6/authorized"
    

    那是我用来重置我的 Kinect 的实际方法,因为 libfreenect 似乎没有让它重新进入睡眠状态的 API。它在我的 Gentoo 机器上,但内核应该足够新,可以为 sysfs 使用相同的路径结构。

    您的显然不会,1-4.6但您可以从内核日志 ( dmesg) 中提取该设备路径,或者您可以使用诸如lsusb获取供应商和产品 ID 之类的东西,然后使用这样的快速命令来列出路径与不同供应商的关系/产品 ID 对:

    for X in /sys/bus/usb/devices/*; do 
        echo "$X"
        cat "$X/idVendor" 2>/dev/null 
        cat "$X/idProduct" 2>/dev/null
        echo
    done
    
    • 93
  3. Tamás Tapsonyi
    2013-05-05T03:02:04+08:002013-05-05T03:02:04+08:00

    这将重置所有 USB1/2/3 连接的端口[1]:

    for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
      [ -e "$i" ] || continue
      echo "${i##*/}" > "${i%/*}/unbind"
      echo "${i##*/}" > "${i%/*}/bind"
    done
    

    我相信这会解决你的问题。如果您不想重置所有 USB 端点,您可以使用适当的设备 ID 从/sys/bus/pci/drivers/ehci_hcd


    注: [1]:*hci_hcd内核驱动程序通常控制 USB 端口。ohci_hcd和uhci_hcd用于 USB1.1 端口,ehci_hcd用于 USB2 端口和xhci_hcd用于 USB3 端口。(参见https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire))

    • 78
  4. mcarans
    2017-12-22T02:15:26+08:002017-12-22T02:15:26+08:00

    我创建了一个 Python 脚本,可根据此处的答案简化整个过程。

    将下面的脚本另存为 reset_usb.py 或克隆此 repo。

    用法:

    python reset_usb.py help  # Show this help
    sudo python reset_usb.py list  # List all USB devices
    sudo python reset_usb.py path /dev/bus/usb/XXX/YYY  # Reset USB device using path /dev/bus/usb/XXX/YYY
    sudo python reset_usb.py search "search terms"  # Search for USB device using the search terms within the search string returned by list and reset matching device
    sudo python reset_usb.py listpci  # List all PCI USB devices
    sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X  # Reset PCI USB device using path /sys/bus/pci/drivers/.../XXXX:XX:XX.X
    sudo python reset_usb.py searchpci "search terms"  # Search for PCI USB device using the search terms within the search string returned by listpci and reset matching device
    

    脚本:

    #!/usr/bin/env python
    import os
    import sys
    from subprocess import Popen, PIPE
    import fcntl
    
    instructions = '''
    Usage: python reset_usb.py help : Show this help
           sudo python reset_usb.py list : List all USB devices
           sudo python reset_usb.py path /dev/bus/usb/XXX/YYY : Reset USB device using path /dev/bus/usb/XXX/YYY
           sudo python reset_usb.py search "search terms" : Search for USB device using the search terms within the search string returned by list and reset matching device
           sudo python reset_usb.py listpci : List all PCI USB devices
           sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X : Reset PCI USB device using path
           sudo python reset_usb.py searchpci "search terms" : Search for PCI USB device using the search terms within the search string returned by listpci and reset matching device       
           '''
    
    
    if len(sys.argv) < 2:
        print(instructions)
        sys.exit(0)
    
    option = sys.argv[1].lower()
    if 'help' in option:
        print(instructions)
        sys.exit(0)
    
    
    def create_pci_list():
        pci_usb_list = list()
        try:
            lspci_out = Popen('lspci -Dvmm', shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().decode('utf-8')
            pci_devices = lspci_out.split('%s%s' % (os.linesep, os.linesep))
            for pci_device in pci_devices:
                device_dict = dict()
                categories = pci_device.split(os.linesep)
                for category in categories:
                    key, value = category.split('\t')
                    device_dict[key[:-1]] = value.strip()
                if 'USB' not in device_dict['Class']:
                    continue
                for root, dirs, files in os.walk('/sys/bus/pci/drivers/'):
                    slot = device_dict['Slot']
                    if slot in dirs:
                        device_dict['path'] = os.path.join(root, slot)
                        break
                pci_usb_list.append(device_dict)
        except Exception as ex:
            print('Failed to list pci devices! Error: %s' % ex)
            sys.exit(-1)
        return pci_usb_list
    
    
    def create_usb_list():
        device_list = list()
        try:
            lsusb_out = Popen('lsusb -v', shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().decode('utf-8')
            usb_devices = lsusb_out.split('%s%s' % (os.linesep, os.linesep))
            for device_categories in usb_devices:
                if not device_categories:
                    continue
                categories = device_categories.split(os.linesep)
                device_stuff = categories[0].strip().split()
                bus = device_stuff[1]
                device = device_stuff[3][:-1]
                device_dict = {'bus': bus, 'device': device}
                device_info = ' '.join(device_stuff[6:])
                device_dict['description'] = device_info
                for category in categories:
                    if not category:
                        continue
                    categoryinfo = category.strip().split()
                    if categoryinfo[0] == 'iManufacturer':
                        manufacturer_info = ' '.join(categoryinfo[2:])
                        device_dict['manufacturer'] = manufacturer_info
                    if categoryinfo[0] == 'iProduct':
                        device_info = ' '.join(categoryinfo[2:])
                        device_dict['device'] = device_info
                path = '/dev/bus/usb/%s/%s' % (bus, device)
                device_dict['path'] = path
    
                device_list.append(device_dict)
        except Exception as ex:
            print('Failed to list usb devices! Error: %s' % ex)
            sys.exit(-1)
        return device_list
    
    
    if 'listpci' in option:
        pci_usb_list = create_pci_list()
        for device in pci_usb_list:
            print('path=%s' % device['path'])
            print('    manufacturer=%s' % device['SVendor'])
            print('    device=%s' % device['SDevice'])
            print('    search string=%s %s' % (device['SVendor'], device['SDevice']))
        sys.exit(0)
    
    if 'list' in option:
        usb_list = create_usb_list()
        for device in usb_list:
            print('path=%s' % device['path'])
            print('    description=%s' % device['description'])
            print('    manufacturer=%s' % device['manufacturer'])
            print('    device=%s' % device['device'])
            print('    search string=%s %s %s' % (device['description'], device['manufacturer'], device['device']))
        sys.exit(0)
    
    if len(sys.argv) < 3:
        print(instructions)
        sys.exit(0)
    
    option2 = sys.argv[2]
    
    print('Resetting device: %s' % option2)
    
    
    # echo -n "0000:39:00.0" | tee /sys/bus/pci/drivers/xhci_hcd/unbind;echo -n "0000:39:00.0" | tee /sys/bus/pci/drivers/xhci_hcd/bind
    def reset_pci_usb_device(dev_path):
        folder, slot = os.path.split(dev_path)
        try:
            fp = open(os.path.join(folder, 'unbind'), 'wt')
            fp.write(slot)
            fp.close()
            fp = open(os.path.join(folder, 'bind'), 'wt')
            fp.write(slot)
            fp.close()
            print('Successfully reset %s' % dev_path)
            sys.exit(0)
        except Exception as ex:
            print('Failed to reset device! Error: %s' % ex)
            sys.exit(-1)
    
    
    if 'pathpci' in option:
        reset_pci_usb_device(option2)
    
    
    if 'searchpci' in option:
        pci_usb_list = create_pci_list()
        for device in pci_usb_list:
            text = '%s %s' % (device['SVendor'], device['SDevice'])
            if option2 in text:
                reset_pci_usb_device(device['path'])
        print('Failed to find device!')
        sys.exit(-1)
    
    
    def reset_usb_device(dev_path):
        USBDEVFS_RESET = 21780
        try:
            f = open(dev_path, 'w', os.O_WRONLY)
            fcntl.ioctl(f, USBDEVFS_RESET, 0)
            print('Successfully reset %s' % dev_path)
            sys.exit(0)
        except Exception as ex:
            print('Failed to reset device! Error: %s' % ex)
            sys.exit(-1)
    
    
    if 'path' in option:
        reset_usb_device(option2)
    
    
    if 'search' in option:
        usb_list = create_usb_list()
        for device in usb_list:
            text = '%s %s %s' % (device['description'], device['manufacturer'], device['device'])
            if option2 in text:
                reset_usb_device(device['path'])
        print('Failed to find device!')
        sys.exit(-1)
    
    • 16
  5. Peter
    2015-03-03T12:38:44+08:002015-03-03T12:38:44+08:00

    我需要在 python 脚本中自动执行此操作,因此我将 LiLo 的非常有用的答案改编为以下内容:

    #!/usr/bin/env python
    import os
    import sys
    from subprocess import Popen, PIPE
    import fcntl
    driver = sys.argv[-1]
    print "resetting driver:", driver
    USBDEVFS_RESET= 21780
    
    try:
        lsusb_out = Popen("lsusb | grep -i %s"%driver, shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().split()
        bus = lsusb_out[1]
        device = lsusb_out[3][:-1]
        f = open("/dev/bus/usb/%s/%s"%(bus, device), 'w', os.O_WRONLY)
        fcntl.ioctl(f, USBDEVFS_RESET, 0)
    except Exception, msg:
        print "failed to reset device:", msg
    

    就我而言,它是 cp210x 驱动程序(我可以从中看出lsmod | grep usbserial),因此您可以将上面的代码段保存为 reset_usb.py,然后执行以下操作:

    sudo python reset_usb.py cp210x
    

    如果您的系统上还没有 ac 编译器设置,这也可能会有所帮助,但您确实有 python。

    • 11
  6. panticz
    2021-08-02T12:03:20+08:002021-08-02T12:03:20+08:00

    Since the APT package usbutils provides the usbreset binary you can just reset the USB device by:

    usbreset ${USB_ID}
    
    e.g.
    usbreset 0d8c:0102
    
    • 6
  7. Ulrich-Lorenz Schlüter
    2016-01-10T02:18:26+08:002016-01-10T02:18:26+08:00

    我通过重新加载模块来使用一种大锤。这是我的 usb_reset.sh 脚本:

    #!/bin/bash
    
    # USB drivers
    rmmod xhci_pci
    rmmod ehci_pci
    
    # uncomment if you have firewire
    #rmmod ohci_pci
    
    modprobe xhci_pci
    modprobe ehci_pci
    
    # uncomment if you have firewire
    #modprobe ohci_pci
    

    这是我的系统服务文件 /usr/lib/systemd/system/usbreset.service 在我的显示管理器启动后运行 usb_reset.sh :

    [Unit]
    Description=usbreset Service
    After=gdm.service
    Wants=gdm.service
    
    [Service]
    Type=oneshot
    ExecStart=/path/to/usb_reset.sh
    
    • 6
  8. chandank
    2014-11-25T11:34:38+08:002014-11-25T11:34:38+08:00

    最快的重置方法是重置 USB 控制器本身。这样做将强制 udev 在断开连接时取消注册设备,并在启用后重新注册。

    echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci_hcd/unbind
    echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci_hcd/unbind
    echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci_hcd/bind
    echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci_hcd/bind
    

    这应该适用于大多数 PC 环境。但是,如果您使用一些自定义硬件,您可以简单地遍历设备名称。使用此方法,您无需通过 lsusb 查找设备名称。您也可以合并到自动化脚本中。

    • 6
  9. mviereck
    2016-09-01T05:19:31+08:002016-09-01T05:19:31+08:00

    由于问题的特殊情况是 gphoto2 与 USB 上的相机的通信问题,因此 gphoto2 中有一个选项可以重置其 USB 连接:

    gphoto2 --reset
    

    也许这个选项在 2010 年问这个问题时不存在。

    • 5
  10. Raghu
    2016-09-08T03:42:05+08:002016-09-08T03:42:05+08:00

    我制作了一个 python 脚本,它将根据设备号重置特定的 USB 设备。您可以通过命令 lsusb 找到设备号。

    例如:

    $ lsusb
    
    Bus 002 Device 004: ID 046d:c312 Logitech, Inc. DeLuxe 250 Keyboard
    

    在这个字符串中 004 是设备号

    import os
    import argparse
    import subprocess
    
    path='/sys/bus/usb/devices/'
    
    def runbash(cmd):
        p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        out = p.stdout.read().strip()
        return out
    
    def reset_device(dev_num):
        sub_dirs = []
        for root, dirs, files in os.walk(path):
                for name in dirs:
                        sub_dirs.append(os.path.join(root, name))
    
        dev_found = 0
        for sub_dir in sub_dirs:
                if True == os.path.isfile(sub_dir+'/devnum'):
                        fd = open(sub_dir+'/devnum','r')
                        line = fd.readline()
                        if int(dev_num) == int(line):
                                print ('Your device is at: '+sub_dir)
                                dev_found = 1
                                break
    
                        fd.close()
    
        if dev_found == 1:
                reset_file = sub_dir+'/authorized'
                runbash('echo 0 > '+reset_file) 
                runbash('echo 1 > '+reset_file) 
                print ('Device reset successful')
    
        else:
                print ("No such device")
    
    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument('-d', '--devnum', dest='devnum')
        args = parser.parse_args()
    
        if args.devnum is None:
                print('Usage:usb_reset.py -d <device_number> \nThe device    number can be obtained from lsusb command result')
                return
    
        reset_device(args.devnum)
    
    if __name__=='__main__':
        main()
    
    • 5

相关问题

  • 如何从命令行仅安装安全更新?关于如何管理更新的一些提示

  • 如何从命令行刻录双层 dvd iso

  • 如何从命令行判断机器是否需要重新启动?

  • 文件权限如何工作?文件权限用户和组

  • 如何在 Vim 中启用全彩支持?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何安装 .run 文件?

    • 7 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    如何获得 CPU 温度?

    • 21 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Marko Smith

    如何使用命令行将用户添加为新的 sudoer?

    • 7 个回答
  • Marko Smith

    更改文件夹权限和所有权

    • 9 个回答
  • Marko Smith

    你如何重新启动Apache?

    • 13 个回答
  • Marko Smith

    如何卸载软件?

    • 11 个回答
  • Marko Smith

    如何删除 PPA?

    • 26 个回答
  • Martin Hope
    NES 如何启用或禁用服务? 2010-12-30 13:03:32 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    Olivier Lalonde 如何在结束 ssh 会话后保持进程运行? 2010-10-22 04:09:13 +0800 CST
  • Martin Hope
    David B 如何使用命令行将用户添加为新的 sudoer? 2010-10-16 04:02:45 +0800 CST
  • Martin Hope
    Hans 如何删除旧内核版本以清理启动菜单? 2010-08-21 19:37:01 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve