重置USB设备

@TOC





问题:

是否可以重置USB设备的连接,而无需从计算机断开连接/连接?

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

我可以看出,摄像头没有加载内核模块。 唯一看上去相关的是 usbhid


回答 1:

将以下内容保存为 usbreset.c

复制代码
/* usbreset – send a USB port reset to a USB device /
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
const char filename;
int fd;
int rc;
if (argc!= 2) {
fprintf
(stderr,“Usage: usbreset device-filenamen”);
return 1;
}
filename
= argv[1];
fd
= open(filename, O_WRONLY);
if (fd <0) {
perror
(“Error opening output file”);
return 1;
}
printf
(“Resetting USB device %sn”, filename);
rc
= ioctl(fd, USBDEVFS_RESET, 0);
if (rc <0) {
perror
(“Error in ioctl”);
return 1;
}
printf
(“Reset successfuln”);
close
(fd);
return 0;
}

在终端中运行以下命令:

  • 编译程序:

    复制代码
    $ cc usbreset.c -o usbreset
  • 获取要重置的USB设备的总线和设备 ID:

    复制代码
    $ lsusb
    Bus 002 Device 003: ID 0fe9:9010 DVICO
  • 使编译后的程序成为可执行文件:

    复制代码
    $ chmod +x usbreset
  • 使用sudo特权执行程序,在运行 lsusb 命令时,对 id进行必要的替换:

    复制代码
    $ sudo./usbreset/dev/bus/usb/002/003 
  • 上程序来源:http://marc.info/?l=linux-usb&m=121459435621262&w=2


回答 2:

我没有在你的特定情况下找到自己,所以我不确定它是否能够做到,但是我找到了 ( 无需外部应用)

复制代码
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"

这是我用来重置我的for的实际方法,因为libfreenect似乎没有将它放回睡眠的API 。 它在我的foaf框中,但内核应该足够新,以使用相同的路径结构。

当然,我们可以使用 1-4.6 来获取供应商和产品 ID,然后使用像这样的快速命令来列出供应商和产品 ID,以列出路径与不同厂商/产品ID对的关系:

复制代码
for X in/sys/bus/usb/devices/; do
echo" X " c a t " X" cat" X"cat"X/idVendor" 2>/dev/null
cat"KaTeX parse error: Expected 'EOF', got '&' at position 15: X/idProduct" 2&̲gt;/dev/null e…i"
] || continue
echo
"KaTeX parse error: Expected '}', got '#' at position 3: {i#̲#*/}"{i%/}/unbind"
echo
"KaTeX parse error: Expected '}', got '#' at position 3: {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 用于usb端口。 ( 请参阅 https://en.wikipedia.org/wiki/Host_controller_interface_(USB,Firewire) )


回答 4:

我需要在 python 脚本中自动化这个问题,因这里我适合于以下方面的基本应答:

复制代码
#!/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

如果你的系统上没有c 编译器设置,这也可以能会有帮助,但是你有 python 。


回答 5:

我正在用一种锤子重新加载模块。 这是我的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

这是我的systemd服务文件/usr/lib/systemd/system/usbreset. 服务,它在我的diplay管理器启动后运行 usb_reset.sh:

复制代码
[Unit]
Description=usbreset Service
After=gdm.service
Wants=gdm.service
[Service]
Type=oneshot
ExecStart=/path/to/usb_reset.sh

回答 6:

重置的最快方式是重置USB控制器本身。 这样做将强制udev在断开连接时注销设备,并且 register 在你启用它后返回。

复制代码
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

这对于大多数电脑环境都适用。 但是,如果你使用的是一些定制硬件,你可以简单地迭代设备名称。 使用这里方法,你不需要通过lsusb查找设备 NAME 。 你也可以在自动脚本中加入。


回答 7:

问题的特殊情况是gphoto2在USB上的通信问题,在gphoto2中有一个选项可以重置它的USB连接:

复制代码
gphoto2 reset

可能这里选项在询问问题时不存在于 2010中。


回答 8:

我制作了一个 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 nThe device number can be obtained from lsusb command result’)
return
reset_device
(args.devnum)
if namemain:
main
()

回答 9:

下面的脚本将只重置匹配的产品/供应商 ID 。

复制代码
#!/bin/bash
set -euo pipefail
IFS
=$‘nt’
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

回答 10:

有人订购了sledgehammer? 这是由不同的答案拼凑在一起的。

复制代码
#!/bin/bash
# Root required
if (( UID )); then
exec sudo
" 0 " " 0"" 0""@"
fi
cd
/sys/bus/pci/drivers
function reinit {(
local d= 1 " < / s p a n > < s p a n c l a s s = " p l n " > t e s t < / s p a n > < s p a n c l a s s = " p u n " > − < / s p a n > < s p a n c l a s s = " p l n " > e < / s p a n > < s p a n c l a s s = " s t r " > " 1"</span><span class="pln"> test </span><span class="pun">-</span><span class="pln">e</span><span class="str">" 1"</span><spanclass="pln">test</span><spanclass="pun"></span><spanclass="pln">e</span><spanclass="str">"d” || return
rmmod
" d " < / s p a n > < s p a n c l a s s = " p l n " > c d < / s p a n > < s p a n c l a s s = " s t r " > " d"</span><span class="pln"> cd</span><span class="str">" d"</span><spanclass="pln">cd</span><spanclass="str">"d"
for i in < / s p a n > < s p a n c l a s s = " p u n " > ( < / s p a n > < s p a n c l a s s = " p l n " > l s < / s p a n > < s p a n c l a s s = " p u n " > ∣ < / s p a n > < s p a n c l a s s = " p l n " > g r e p < / s p a n > < s p a n c l a s s = " p u n " > : ) ; < / s p a n > < s p a n c l a s s = " p l n " > < / s p a n > < s p a n c l a s s = " k w d " > d o < / s p a n > < s p a n c l a s s = " p l n " > e c h o < / s p a n > < s p a n c l a s s = " s t r " > " </span><span class="pun">(</span><span class="pln">ls </span><span class="pun">|</span><span class="pln"> grep </span><span class="pun">:);</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> echo</span><span class="str">" </span><spanclass="pun">(</span><spanclass="pln">ls</span><spanclass="pun"></span><spanclass="pln">grep</span><spanclass="pun">:);</span><spanclass="pln"></span><spanclass="kwd">do</span><spanclass="pln">echo</span><spanclass="str">"i"> unbind
done
sleep
1
for i in < / s p a n > < s p a n c l a s s = " p u n " > ( < / s p a n > < s p a n c l a s s = " p l n " > l s < / s p a n > < s p a n c l a s s = " p u n " > ∣ < / s p a n > < s p a n c l a s s = " p l n " > g r e p < / s p a n > < s p a n c l a s s = " p u n " > : ) ; < / s p a n > < s p a n c l a s s = " p l n " > < / s p a n > < s p a n c l a s s = " k w d " > d o < / s p a n > < s p a n c l a s s = " p l n " > e c h o < / s p a n > < s p a n c l a s s = " s t r " > " </span><span class="pun">(</span><span class="pln">ls </span><span class="pun">|</span><span class="pln"> grep </span><span class="pun">:);</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> echo</span><span class="str">" </span><spanclass="pun">(</span><spanclass="pln">ls</span><spanclass="pun"></span><spanclass="pln">grep</span><spanclass="pun">:);</span><spanclass="pln"></span><spanclass="kwd">do</span><spanclass="pln">echo</span><spanclass="str">"i"> bind
done
modprobe
"$d"
)}
for d in?hci???; do
echo
" - d " < / s p a n > < s p a n c l a s s = " p l n " > r e i n i t < / s p a n > < s p a n c l a s s = " s t r " > " d"</span><span class="pln"> reinit</span><span class="str">" d"</span><spanclass="pln">reinit</span><spanclass="str">"d"
done


你可能感兴趣的:(android-usb)