Hoe reset je een USB-apparaat vanaf de opdrachtregel?

Is het mogelijk om de aansluiting van een USB-apparaat te resetten, zonder het apparaat fysiek los te koppelen van de PC?

Om precies te zijn, mijn apparaat is een digitale camera. Ik'gebruik gphoto2, maar de laatste tijd krijg ik "device read errors", dus ik'zou willen proberen om een software-reset van de verbinding uit te voeren.

Voor zover ik kan zien, worden er geen kernel modules geladen voor de camera. De enige die er mee te maken lijkt te hebben is usbhid.

Oplossing

Sla het volgende op als 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-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;
}

Voer de volgende commando's uit in terminal:

  1. Compileer het programma:

     $ cc usbreset.c -o usbreset
  2. Vraag de Bus en Device ID op van het USB-apparaat dat je wilt resetten:

     $ lsusb
     Bus 002 Apparaat 003: ID 0fe9:9010 DVICO
  3. Maak ons gecompileerde programma uitvoerbaar:

     $ chmod +x usbreset
  4. Voer het programma uit met sudo privilege; maak de nodige vervanging voor en ids zoals gevonden door het uitvoeren van het lsusb commando:

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

Bron van bovenstaand programma: http://marc.info/?l=linux-usb&m=121459435621262&w=2

Commentaren (8)

Ik heb mezelf nog niet eerder in uw specifieke omstandigheden bevonden, dus ik'ben niet zeker of het genoeg zal doen, maar de eenvoudigste manier die ik'heb gevonden om een USB-apparaat te resetten is dit commando: (Geen externe apps nodig)

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"

Dat's de eigenlijke die ik gebruik om mijn Kinect te resetten sinds libfreenect geen API schijnt te hebben om het terug in slaap te brengen. Het staat op mijn Gentoo box, maar de kernel zou nieuw genoeg moeten zijn om dezelfde padstructuur voor sysfs te gebruiken.

De jouwe zou duidelijk niet 1-4.6 zijn, maar je kunt ofwel dat apparaatpad uit je kernel log halen (dmesg) of je kunt iets als lsusb gebruiken om de leverancier en product ID's te krijgen en dan een snel commando als dit gebruiken om te zien hoe de paden zich verhouden tot verschillende leverancier/product ID paren:

for X in /sys/bus/usb/devices/*; do 
    echo "$X"
    cat "$X/idVendor" 2>/dev/null 
    cat "$X/idProduct" 2>/dev/null
    echo
done
Commentaren (10)

Dit zal alle aangesloten USB1/2/3 poorten[1] resetten:

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

Ik denk dat dit uw probleem zal oplossen. Als u niet alle USB-eindpunten wilt resetten, kunt u het juiste apparaat-ID uit /sys/bus/pci/drivers/ehci_hcd gebruiken


Opmerkingen: [1]: de *hci_hcd kernel drivers besturen meestal de USB poorten. ohci_hcd en uhci_hcd zijn voor USB1.1 poorten, ehci_hcd is voor USB2 poorten en xhci_hcd is voor USB3 poorten. (zie https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire))

Commentaren (11)