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

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

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

评论

您正在使用哪个版本的Ubuntu?

我尝试了Li Lo和ssokolow的两个解决方案,我得到的只是权限被拒绝,如果我使用usbreset代码或命令行“ echo 0> ...”,我会使用sudo,我的USB设备也归root所有,但我无需管理员权限即可使用它们(相机..)

如果出现读取错误,则可能有一些数据损坏。如果您的相机使用外部存储卡(例如MicroSD),则将其连接到计算机并运行fsck可能是明智的选择。

#1 楼

将以下内容另存为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;
}
 


在终端中运行以下命令:



编译程序:

$ cc usbreset.c -o usbreset



获取所需的USB设备的总线和设备ID要重置:

$ lsusb  
Bus 002 Device 003: ID 0fe9:9010 DVICO  



使我们的编译程序可执行:

$ chmod +x usbreset



以sudo权限执行程序;通过运行<Bus>命令对找到的<Device>lsusb id进行必要的替换:

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




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

评论


这适用于ubuntu 13.10。设备ID可能有所不同。为了获得鼠标,我已经将上面的代码包装在几个shell命令中,回显$(lsusb | grep鼠标)mouse = $(lsusb | grep鼠标| perl -nE“ / \ D +(\ d +)\ D +(\ d +)。 + /;打印qq(\ $ 1 / \ $ 2)“)sudo / path / to / c-program / usbreset / dev / bus / usb / $ mouse

–knb
2013年12月22日11:04



我的外置驱动器似乎变得不可检测(我必须重新连接USB电缆);它是在usb3.0台式机PC端口上连接的usb2.0;当我运行lbreb的2个USB 3.0根集线器之一的usbreset / dev / bus / usb / 011/001时,它出错:“ ioctl中的错误:是目录”,是否存在任何想法?我在两个USB 3.0集线器上都尝试过

–水瓶座力量
14-10-30在3:34



如果有人在Ubuntu 16.04(登录dmesg后用“ input irq status -75”填充dmesg)登录后冻结了(usb)鼠标,那么我可以确认这是唯一对我有用的解决方案。谢谢

–阿古斯丁·贝兹(Agustin Baez)
16年5月2日,12:31

@ Aquarius,我也收到相同的错误“ ioctl中的错误:是目录”。解决了吗?

– ransh
17年2月12日在13:21

请在此处查看我的答案askubuntu.com/a/988297/558070使用与该答案相同的重置方法,但也可以简化设备的列表和搜索。

–麦卡拉
17年12月21日在10:32

#2 楼

我以前在您的特定情况下还没有找到自己,所以不确定它是否能满足要求,但是我发现重置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


评论


sh:1:无法创建/sys/bus/usb/devices/1-3.1:1.0/authorized:目录不存在

–尼古拉斯(Nicolas)
2012年5月31日下午3:22

谢谢您的努力!也许您还应该提到在脚本中执行echo 1> / sys / bus / usb / devices / whatever / authorized以在禁用设备后立即重新启用它。我在鼠标和USB键盘上都做到了这一点,最后得到了一个完全失聪的系统:)

– Avio
13年4月28日在8:43

如果自动将值重新设置为1,这很奇怪,因为将其设置为0告诉系统您不希望设备被“授权”,因此无法访问。

– Tim Tisdall
13-10-18在19:45

给任何尝试切换到|的人的注释。 sudo tee ...特权/ sys的写法:如果您还没有缓存sudo凭据,那将严重中断。当sudo需要提示输入密码时,sudo sh -c“ ...”会按预期工作。

– ssokolow
16年5月5日在10:40

查找/ sys / bus / usb / devices / * / authorized -exec sh -c'echo 0> $ {0}; echo 1> $ {0}'{} \;对我来说就像魅力。 ty指向授权文件。

– Marc Bredt
18 Mar 5 '18在10:46



#3 楼

这将重置所有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端点,则可以使用来自/sys/bus/pci/drivers/ehci_hcd的适当设备ID。

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

评论


您认为唤醒USB存储设备是否可行?

–水瓶座力量 2014年6月30日,下午5:53

尽管我已经收到以下消息:ls:无法访问/ sys / bus / pci / drivers / ehci_hcd /:没有此类文件或目录可以解决此问题,鼠标已立即开始工作。 +1

–阿提拉·富洛普(Attila Fulop)
2014年10月10日在6:16

@Otheus OHCI和UHCI是USB 1.1主机标准,EHCI是USB 2.0主机标准,而XHCI是USB 3.0主机标准。

– ssokolow
16年7月20日在19:02

这是一个很好的解决方案。但是,在以后的一些内核和其他* nix发行版中,您会发现需要将* hci_hcd替换为* hci-pci,因为hci_hcd驱动程序已经编译到内核中。

–not2qubit
17年1月1日在17:14

在Banana Pi上,显然没有PCI总线,我必须使用以下命令:对于/ sys / bus / usb / drivers / * / *:*中的i;做

–马丁·汉森(Martin Hansen)
17-6-29在9:14



#4 楼

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

将以下脚本另存为reset_usb.py或克隆此存储库。

用法:

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)


评论


这是对这个问题的最佳答案。

– kapad
19年4月5日在7:47

#5 楼

我需要在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,这也可能会有所帮助。

评论


在树莓上为我工作

– webo80
16年6月23日在14:36

请在您的解决方案上再说几句话。例如,有关常量USBDEVFS_RESET的信息。所有系统都一样吗?

–not2qubit
17年2月28日在7:25

@ not2qubit USBDEVFS_RESET对于所有系统都是相同的。对于MIPS,它是536892692。

– Yegorich
17年4月21日在9:09

较新版本的lsusb似乎需要-t参数(树模式)以显示此脚本期望的驱动程序信息,但是该脚本随后需要一些更新以解析此生成的不同输出行

–猎豹
17-10-19在18:56



请参阅我的答案askubuntu.com/a/988297/558070,以获取此脚本的改进版本。

–麦卡拉
17年12月21日在10:30

#6 楼

最快的重置方法是重置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找出设备名称。您也可以将其合并到自动化脚本中。

评论


您需要以root / sudo身份运行这些命令,并且在所有系统上都无法运行(在某些系统上,您需要将ehci_hcd替换为ehci-pci。有关此解决方案的更多信息(也许它来自何处?):davidjb .com / blog / 2012/06 /…

–伦巴特
2015年11月5日在17:43



#7 楼

我通过重载模块来使用大锤。
这是我的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在我的diplay管理器启动后运行usb_reset.sh:

[Unit]
Description=usbreset Service
After=gdm.service
Wants=gdm.service

[Service]
Type=oneshot
ExecStart=/path/to/usb_reset.sh


评论


在以下位置使用我的脚本的listpci选项:askubuntu.com/a/988297/558070将帮助识别要重新加载的USB模块(例如xhci_pci,ehci_pci)。

–麦卡拉
18年1月24日在15:14

不幸的是,在我的系统上,这些内核模块不是与内核分开的,因此无法正常工作:rmmod:错误:模块xhci_pci是内置的。

– Unfa
18年6月28日在13:00

#8 楼

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

gphoto2 --reset


也许该问题在2010年不存在。

#9 楼

我制作了一个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()
 


评论


我喜欢这个解决方案!我已经根据自己的喜好对脚本进行了一些调整:gist.github.com/willstott101/7a455817ec6f4b8d89571ce72bdfd34a

– S
19年5月9日在9:58



#10 楼

这是只重置匹配的产品/供应商ID的脚本。

 #!/bin/bash

set -euo pipefail
IFS=$'\n\t'

VENDOR="045e"
PRODUCT="0719"

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 0 > $DIR/authorized
    sleep 0.5
    echo 1 > $DIR/authorized
  fi
done
 


评论


我发现您的脚本很有用。但是,如果$ DIR消失并且设备不可见,该怎么办?

– Eugen Konkov
17-10-13在7:36

#11 楼

尝试一下,这是软件拔出(弹出)。

有时无法简单地将某些设备的设备取消绑定。

示例:

我要删除或弹出我的“ Genius NetScroll 120”。

然后我首先检查我连接的USB设备

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID 03f0:231d Hewlett-Packard 
Bus 001 Device 004: ID 138a:0007 Validity Sensors, Inc. VFS451 Fingerprint Reader
Bus 001 Device 005: ID 04f2:b163 Chicony Electronics Co., Ltd 
Bus 002 Device 009: ID 0458:003a KYE Systems Corp. (Mouse Systems) NetScroll+ Mini Traveler / Genius NetScroll 120  **<----This my Mouse! XDDD**


好,我找到了我的鼠标,它具有总线002,设备009,idVendor 0458和idProduct 003a,因此这是有关鼠标的参考设备信息。

这很重要,总线号是设备的开始名称路径并且我将检查产品ID和供应商,以确保删除正确的设备。

$ ls /sys/bus/usb/drivers/usb/
1-1/    1-1.1/  1-1.3/  1-1.5/  2-1/    2-1.3/  bind    uevent  unbind  usb1/   usb2/


注意文件夹上的内容,检查从2号文件夹开头的内容因为我的总线是002,所以请检查此一项,然后我已经逐一检查了每个文件夹,其中包含有关我的鼠标信息的正确idVendor和idProduct。在这种情况下,我将使用以下命令检索信息:

cat /sys/bus/usb/drivers/usb/2-1.3/idVendor
0458
cat /sys/bus/usb/drivers/usb/2-1.3/idProduct
003a


好,路径/sys/bus/usb/drivers/usb/2-1.3/ match wit我的信息鼠标! XDDD。

是时候卸下设备了!

su -c "echo 1 > /sys/bus/usb/drivers/usb/2-1.3/remove"


再次插入USB设备,它又可以工作了!

评论


如果您无法再次插入该怎么办? (例如,它是内部sdcard读取器)

–aleb
14年6月29日在20:57

#12 楼

有人订购大锤了吗?这是从这里的其他答案中拼凑而成的。

 #!/bin/bash

# Root required
if (( UID )); then
        exec sudo "q4312079q" "$@"
fi

cd /sys/bus/pci/drivers

function reinit {(
        local d=""
        test -e "$d" || return

        rmmod "$d"

        cd "$d"

        for i in $(ls | grep :); do
                echo "$i" > unbind
        done

        sleep 1

        for i in $(ls | grep :); do
                echo "$i" > bind
        done

        modprobe "$d"

)}

for d in ?hci_???; do
        echo " - $d"
        reinit "$d"
done
 


评论


马克,您是否发现解除绑定确实必要,还是只是出于安全考虑?

– ndemou
16年10月10日在14:27

这是一把大锤,可能会做很多不必要的事情

– Mark K Cowan
16年11月10日在14:37

@MarkKCowan,您如何使用它?需要/期望的命令参数是什么?

–not2qubit
17-2-28在7:15



@ not2qubit:不需要命令行参数。 sudo代理中的$ @只是一种习惯,如果以后我决定添加参数(并忘记更新sudo代理),它可以防止错误。

– Mark K Cowan
17年11月21日在14:54

@MarkKCowan Doh!不好意思,朋友!哦,是的诅咒!我不应该在困倦时在此网站上发表评论。已投票!

–not2qubit
17年11月21日在16:29



#13 楼

有时我想在特定设备上执行此操作,如VID(供应商ID)和PID(产品ID)所标识。这是我发现有用的脚本,它使用了漂亮的libusb库。

第一次运行:

sudo apt-get install libusb-dev


然后,此c ++文件的resetDeviceConnection应该执行此任务,以重置由vid和pid标识的设备连接。

 #include <libusb-1.0/libusb.h>

int resetDeviceConnection(UINT_16 vid, UINT_16 pid){
    /*Open libusb*/
    int resetStatus = 0;
    libusb_context * context;
    libusb_init(&context);

    libusb_device_handle * dev_handle = libusb_open_device_with_vid_pid(context,vid,pid);
    if (dev_handle == NULL){
      printf("usb resetting unsuccessful! No matching device found, or error encountered!\n");
      resetStatus = 1;
    }
    else{
      /*reset the device, if one was found*/
      resetStatus = libusb_reset_device(dev_handle);
    }
    /*exit libusb*/
    libusb_exit(context);
    return resetStatus;
}
 


(从我的个人TIL目录中被盗:
https://github.com/Marviel/TIL/blob/master/unix_tools/Reset_specific_USB_Device.md)

评论


请您说明如何运行此脚本。

–乔治·乌多森
16年12月29日在14:28

当然,让我更新。

– Marviel
16/12/29在20:31

@Marviel,我们仍在等待更新...

–not2qubit
17年2月28日在7:18

需要无用票

– Eugen Konkov
17-10-13在7:36

#14 楼

我为重置特定的USB设备制作了一个简单的bash脚本。

 #!/bin/bash
#type lsusb to find "vendor" and "product" ID in terminal
set -euo pipefail
IFS=$'\n\t'

#edit the below two lines of vendor and product values using lsusb result
dev=$(lsusb -t | grep usbdevicename | grep 'If 1' | cut -d' ' -f13|cut -d"," -f1)
#VENDOR=05a3
#PRODUCT=9230
VENDOR=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f1)
PRODUCT=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f2)

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 0 > $DIR/authorized
    sleep 0.5
    echo 1 > $DIR/authorized
  fi
done
 


#15 楼

如果您知道设备名称,则此python脚本将起作用:

 #!/usr/bin/python
"""
USB Reset

Call as "usbreset.py <device_file_path>"

With device_file_path like "/dev/bus/usb/bus_number/device_number"
"""
import fcntl, sys, os

USBDEVFS_RESET = ord('U') << (4*2) | 20

def main():
    fd = os.open(sys.argv[1], os.O_WRONLY)
    if fd < 0: sys.exit(1)
    fcntl.ioctl(fd, USBDEVFS_RESET, 0)
    os.close(fd)
    sys.exit(0)
# end main

if __name__ == '__main__':
    main()
 


#16 楼

也许这也适用于相机:

以下是我身边的USB 3.0(kernel.org)Linux上的饥饿的3.4.42 HDD的恢复。 dmesg告知,它在360秒后超时(抱歉,我无法在此处复制syslog,未连接网络),并且驱动器完全挂起。访问设备的进程被阻止在内核中,这是无法杀死的。 NFS挂起,ZFS挂起,dd挂起。

完成此操作后,一切又恢复了。关于发现的dmesg器件,USB只讲了一行。

我真的不知道以下详细内容。但这有效。

下面的示例输出来自具有2.6.32-5-686内核的Debian Squeeze,所以我认为它适用于2.6及更高版本:

$ ls -al /dev/sdb
brw-rw---T 1 root floppy 8, 16 Jun  3 20:24 /dev/sdb

$ ls -al /sys/dev/block/8:16/device/rescan
--w------- 1 root root 4096 Jun  6 01:46 /sys/dev/block/8:16/device/rescan

$ echo 1 > /sys/dev/block/8:16/device/rescan


如果这不起作用,也许其他人可以弄清楚如何向设备发送真正的重置。

评论


致下降投票者:为什么?如果您对某些措辞不满意,可以随时提出修改建议。另外:请检查发布此消息时在这里的答案。请不要与今天看到的其他版本进行比较,而要与当时看到的其他版本进行比较!非常感谢你。

– Tino
20年2月2日,16:30