是否有可能重置一个USB设备的连接,而不从PC上断开/连接?
具体来说,我的设备是一个数码相机。我正在使用 "gphoto2",但最近我遇到了 "设备读取错误",所以我想尝试用软件重设连接。
据我所知,没有为相机加载任何内核模块。唯一看起来相关的是 "usbhid"。
将以下内容保存为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
总线 002 设备 003。ID 0fe9:9010 DVICO
3.使我们的编译程序可以执行。
$ chmod +x usbreset
4.用sudo权限执行该程序;对<Bus>
和<Device>
的id进行必要的替换,这些id是通过运行lsusb
命令发现的。
$ sudo ./usbreset /dev/bus/usb/002/003
我以前没有发现自己处于你的特定情况,所以我不确定这是否足够,但我发现重置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
这将重置所有的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。
注意。