Ist es möglich, die Verbindung eines USB-Geräts zurückzusetzen, ohne es physisch vom PC zu trennen/abzuschließen?
Genauer gesagt, ist mein Gerät eine Digitalkamera. Ich benutze gphoto2
, aber in letzter Zeit bekomme ich "device read errors", so I' d like to try to do a software-reset of the connection.
Soweit ich das beurteilen kann, werden keine Kernelmodule für die Kamera geladen. Das einzige Modul, das damit in Verbindung zu stehen scheint, ist usbhid
.
Speichern Sie das Folgende als "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;
}
Führen Sie die folgenden Befehle im Terminal aus:
Kompilieren Sie das Programm:
$ cc usbreset.c -o usbreset
Ermitteln Sie die Bus- und Geräte-ID des USB-Geräts, das Sie zurücksetzen möchten:
$ lsusb
Bus 002 Gerät 003: ID 0fe9:9010 DVICO
Machen Sie unser kompiliertes Programm ausführbar:
$ chmod +x usbreset
Führen Sie das Programm mit sudo-Rechten aus; nehmen Sie die notwendigen Ersetzungen für die <Bus>
- und <Device>
-IDs vor, wie sie durch die Ausführung des lsusb
-Befehls gefunden wurden:
$ sudo ./usbreset /dev/bus/usb/002/003
Quelle des obigen Programms: http://marc.info/?l=linux-usb&m=121459435621262&w=2
Ich habe't fand mich in Ihren spezifischen Umständen vor, so I'm nicht sicher, wenn it'll genug tun, aber die einfachste Weise I've gefunden, um ein USB-Gerät zurückzusetzen ist dieser Befehl: (Keine externen Anwendungen notwendig)
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"
Das ist der Befehl, den ich benutze, um meine Kinect zurückzusetzen, da libfreenect keine API zu haben scheint, um sie wieder in den Ruhezustand zu versetzen. Es ist auf meiner Gentoo-Box, aber der Kernel sollte neu genug sein, um die gleiche Pfadstruktur für sysfs zu verwenden.
Ihrer wäre offensichtlich nicht 1-4.6
, aber Sie können entweder den Gerätepfad aus dem Kernelprotokoll (dmesg
) ziehen oder Sie können etwas wie lsusb
benutzen, um die Hersteller- und Produkt-IDs zu erhalten und dann einen schnellen Befehl wie diesen benutzen, um aufzulisten, wie sich die Pfade auf verschiedene Hersteller-/Produkt-ID-Paare beziehen:
for X in /sys/bus/usb/devices/*; do
echo "$X"
cat "$X/idVendor" 2>/dev/null
cat "$X/idProduct" 2>/dev/null
echo
done
Dadurch werden alle an USB1/2/3 angeschlossenen Ports zurückgesetzt[1]:
for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
[ -e "$i" ] || continue
echo "${i##*/}" > "${i%/*}/unbind"
echo "${i##*/}" > "${i%/*}/bind"
done
Ich glaube, dass dies Ihr Problem lösen wird. Wenn Sie nicht alle USB-Endpunkte zurücksetzen wollen, können Sie die entsprechende Geräte-ID aus /sys/bus/pci/drivers/ehci_hcd
verwenden
Anmerkungen:
[1]: Die Kernel-Treiber *hci_hcd
kontrollieren normalerweise die USB-Ports. ohci_hcd
und uhci_hcd
sind für USB1.1 Ports, ehci_hcd
ist für USB2 Ports und xhci_hcd
ist für USB3 Ports. (siehe https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire))