Wie kann ein USB-Gerät über die Befehlszeile zurückgesetzt werden?


164

Ist es möglich, die Verbindung eines USB-Geräts zurückzusetzen, ohne die Verbindung zum PC physisch zu trennen / herzustellen?

Insbesondere ist mein Gerät eine Digitalkamera. Ich verwende gphoto2, aber in letzter Zeit erhalte ich "Geräte-Lesefehler", daher möchte ich versuchen, die Verbindung per Software zurückzusetzen.

Soweit ich weiß, sind keine Kernelmodule für die Kamera geladen. Der einzige, der verwandt aussieht, ist usbhid.


Welche Ubuntu-Version verwendest du?
User

ich habe beide lösungen von li lo und ssokolow ausprobiert, alles was ich bekomme ist die erlaubnis verweigert, nomatter wenn ich den usbreset code oder die befehlszeile "echo 0> ..." benutze ich sudo, auch meine usb geräte gehören root aber i können sie ohne Administratorrechte (Kameras ..) verwenden

1
Wenn Lesefehler auftreten, können Daten beschädigt werden. Wenn Ihre Kamera eine externe Speicherkarte (z. B. MicroSD) verwendet, ist es möglicherweise ratsam, diese an den Computer anzuschließen und fsck auszuführen.
TSJNachos117

Antworten:


118

Speichern Sie Folgendes 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 im Terminal die folgenden Befehle aus:

  1. Kompilieren Sie das Programm:

    $ cc usbreset.c -o usbreset
    
  2. Rufen Sie die Bus- und Geräte-ID des USB-Geräts ab, das Sie zurücksetzen möchten:

    $ lsusb  
    Bus 002 Device 003: ID 0fe9:9010 DVICO  
    
  3. Machen Sie unser kompiliertes Programm ausführbar:

    $ chmod +x usbreset
    
  4. Führen Sie das Programm mit sudo-Berechtigung aus. Ersetzen Sie <Bus>und <Device>ids nach Bedarf , indem Sie den folgenden lsusbBefehl ausführen :

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

Quelle des obigen Programms: http://marc.info/?l=linux-usb&m=121459435621262&w=2


3
Dies funktioniert mit Ubuntu 13.10. Die Geräte-ID kann variieren. Um es für die Maus zu bekommen, habe ich den obigen Code in einige Shell-Befehle echo $(lsusb | grep Mouse) mouse=$( lsusb | grep Mouse | perl -nE "/\D+(\d+)\D+(\d+).+/; print qq(\$1/\$2)") sudo /path/to/c-program/usbreset /dev/bus/usb/$mouse
eingebunden

1
Mein externes Laufwerk scheint nicht mehr zu erkennen zu sein (ich muss das USB-Kabel wieder fest anschließen). Es ist ein USB2.0-Anschluss an einem USB3.0-Desktop-PC-Anschluss. wenn ich laufe usbreset /dev/bus/usb/011/001, ist das einer der 2 usb 3.0 root hubs bei lsusb, er fehler: "fehler in ioctl: ist ein verzeichnis", irgendein ideia? Ich habe es auf beiden USB 3.0-Hubs versucht
Aquarius Power

1
Wenn jemand, der dies liest, nach der Anmeldung unter Ubuntu 16.04 (mit dmesg gefüllt mit "input irq status -75") ein (USB-) Einfrieren der Maus hat, kann ich bestätigen, dass dies die einzige Lösung ist, die für mich funktioniert hat. Vielen Dank
Agustin Baez

1
@ Wassermann, ich bekomme auch den gleichen Fehler "Fehler in ioctl: Ist ein Verzeichnis". Ist es gelöst?
ransh

1
Siehe meine Antwort hier askubuntu.com/a/988297/558070 , die dieselbe Methode zum Zurücksetzen wie diese Antwort verwendet, aber auch eine vereinfachte Auflistung und Suche nach Geräten ermöglicht.
mcarans

58

Ich habe mich unter Ihren speziellen Umständen noch nicht wiedergefunden, daher bin ich mir nicht sicher, ob dies ausreichen wird. Der einfachste Weg, ein USB-Gerät zurückzusetzen, ist jedoch der folgende Befehl: (Keine externen Apps erforderlich)

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"

Dies ist die tatsächliche Einstellung, mit der ich meinen Kinect zurücksetze, da libfreenect anscheinend keine API hat, um ihn wieder in den Ruhezustand zu versetzen. Es befindet sich auf meiner Gentoo-Box, aber der Kernel sollte neu genug sein, um dieselbe Pfadstruktur für sysfs zu verwenden.

Mit freundlichen Grüßen, 1-4.6aber Sie können diesen Gerätepfad entweder aus Ihrem Kernel-Protokoll ( dmesg) abrufen oder lsusbdie Hersteller- und Produkt-IDs abrufen und dann mit einem kurzen Befehl wie diesem auflisten, wie sich die Pfade auf verschiedene Hersteller beziehen / Produkt-ID-Paare:

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: kann nicht erstellen /sys/bus/usb/devices/1-3.1:1.0/authorized: Verzeichnis nicht vorhanden
Nicolas Marchildon

Es sieht so aus, als hätten sie das Layout des usbfs-Dateisystems geändert. Ich werde versuchen herauszufinden, was die neue Art zu tun auf Ubuntu ist, wenn ich nicht so müde bin.
ssokolow

9
Danke, dass du großartig gearbeitet hast! Vielleicht sollten Sie auch erwähnen, echo 1 > /sys/bus/usb/devices/whatever/authorizedein Skript auszuführen, um das Gerät wieder zu aktivieren, sobald es deaktiviert wurde. Ich habe es sowohl mit meiner Maus als auch mit meiner USB-Tastatur gemacht und hatte ein völlig taubes System :)
Avio

1
Es ist äußerst seltsam, wenn der Wert automatisch auf 1 zurückgesetzt wird, da dies dem System mitteilt, dass das Gerät nicht "autorisiert" und daher nicht zugänglich sein soll.
Tim Tisdall

2
Ein Hinweis für alle, die versuchen, auf den | sudo tee ...Ansatz für privilegierte /sysSchreibvorgänge umzusteigen: Dies funktioniert nicht richtig, wenn Ihre sudo-Anmeldeinformationen nicht bereits zwischengespeichert sind. sudo sh -c "..."funktioniert wie erwartet, wenn sudo nach einem Passwort fragen muss.
Ssokolow

51

Dies setzt alle angeschlossenen USB1 / 2/3-Ports zurück [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, das wird dein Problem lösen. Wenn Sie nicht alle USB-Endpunkte zurücksetzen möchten, können Sie die entsprechende Geräte-ID von verwenden/sys/bus/pci/drivers/ehci_hcd


Anmerkungen: [1]: Die *hci_hcdKerneltreiber steuern normalerweise die USB-Anschlüsse. ohci_hcdund uhci_hcdsind für USB1.1-Ports, ehci_hcdist für USB2-Ports und xhci_hcdist für USB3-Ports. (siehe https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire) )


Glauben Sie, es könnte funktionieren, einen USB-Speicher aufzuwecken ?
Aquarius Power

2
Obwohl die folgende Meldung angezeigt wurde: ls: cannot access /sys/bus/pci/drivers/ehci_hcd/: No such file or directoryDas Problem wurde behoben, die Maus hat sofort funktioniert. +1
Attila Fulop

2
@Otheus OHCI und UHCI sind die USB 1.1-Hoststandards, EHCI ist der USB 2.0-Hoststandard und XHCI ist der USB 3.0-Hoststandard.
ssokolow

2
Das ist eine schöne Lösung. Jedoch auf einigen späteren Kernel und andere * nix - Distributionen, werden Sie feststellen , dass Sie brauchen ersetzen *hci_hcdmit *hci-pci, wie der hci_hcd Treiber bereits in den Kernel kompiliert wird.
not2qubit

1
Auf einem Bananen-Pi gibt es anscheinend keinen PCI-Bus, ich musste folgendes verwenden:for i in /sys/bus/usb/drivers/*/*:*; do
Martin Hansen

10

Ich musste dies in einem Python-Skript automatisieren, daher passte ich die äußerst hilfreiche Antwort von LiLo an Folgendes an:

#!/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

In meinem Fall war es der cp210x-Treiber (von dem ich erzählen konnte lsmod | grep usbserial), so dass Sie das obige Snippet als reset_usb.py speichern und dies dann tun konnten:

sudo python reset_usb.py cp210x

Dies kann auch hilfreich sein, wenn Sie noch kein AC-Compiler-Setup auf Ihrem System haben, aber Python.


arbeitete für mich an einer Himbeere
webo80

1
Bitte noch ein paar Worte zu Ihrer Lösung. Zum Beispiel etwas über die Konstante USBDEVFS_RESET. Ist es immer für alle Systeme gleich?
not2qubit

@ not2qubit USBDEVFS_RESETist für alle Systeme gleich. Für MIPS ist es 536892692.
Yegorich

Neuere Versionen von lsusb benötigen anscheinend das -tArgument (Tree-Modus), um die von diesem Skript erwarteten Treiberinformationen anzuzeigen. Das Skript benötigt jedoch einige Aktualisierungen, um die verschiedenen Ausgabezeilen zu analysieren, die dadurch generiert werden
Cheetah,

Siehe meine Antwort hier askubuntu.com/a/988297/558070 für eine deutlich verbesserte Version dieses Skripts.
mcarans

8

Ich habe ein Python-Skript erstellt, das den gesamten Prozess anhand der hier gegebenen Antworten vereinfacht.

Speichern Sie das folgende Skript als reset_usb.py oder klonen Sie dieses Repo .

Verwendungszweck:

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

Skript:

#!/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)

Dies ist die beste Antwort auf diese Frage.
Kapad

4

Da es sich bei dem Sonderfall um ein Kommunikationsproblem von gphoto2 mit einer Kamera auf USB handelt, gibt es in gphoto2 die Möglichkeit, die USB-Verbindung zurückzusetzen:

gphoto2 --reset

Vielleicht gab es diese Option 2010 nicht, als die Frage gestellt wurde.


3

Die schnellste Möglichkeit zum Zurücksetzen besteht darin, den USB-Controller selbst zurückzusetzen. Wenn Sie dies tun, wird udev dazu gezwungen, die Registrierung des Geräts beim Trennen der Verbindung aufzuheben, und die Registrierung wird wiederhergestellt, sobald Sie sie aktivieren.

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

Dies sollte für die meisten PC-Umgebungen funktionieren. Wenn Sie jedoch eine benutzerdefinierte Hardware verwenden, können Sie einfach die Gerätenamen durchlaufen. Bei dieser Methode muss der Gerätename nicht von lsusb ermittelt werden. Sie können auch in ein automatisiertes Skript einbinden.


1
Sie müssen diese Befehle als root / sudo laufen, und es wird auf allen Systemen (auf einige nicht funktionieren, werden Sie ersetzen müssen ehci_hcdmit ehci-pciWeitere Informationen zu dieser Lösung (vielleicht , woher es kam . ):? Davidjb.com/blog / 2012/06 /…
Lambart

3

Ich benutze eine Art Vorschlaghammer, indem ich die Module neu lade. Dies ist mein Skript 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

Und dies ist meine systemd-Servicedatei /usr/lib/systemd/system/usbreset.service, die usb_reset.sh ausführt, nachdem mein Anzeigemanager gestartet wurde:

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

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

Wenn Sie die listpci-Option meines Skripts hier verwenden: askubuntu.com/a/988297/558070 hilft Ihnen dabei, herauszufinden, welches USB-Modul neu geladen werden soll (z. B. xhci_pci, ehci_pci).
mcarans

2
Leider sind diese Kernelmodule auf meinem System nicht vom Kernel getrennt, so dass dies nicht funktioniert:rmmod: ERROR: Module xhci_pci is builtin.
am

3

Ich habe ein Python-Skript erstellt, das ein bestimmtes USB-Gerät basierend auf der Gerätenummer zurücksetzt. Die Gerätenummer erfahren Sie mit dem Befehl lsusb.

zum Beispiel:

$ lsusb

Bus 002 Device 004: ID 046d:c312 Logitech, Inc. DeLuxe 250 Keyboard

In dieser Zeichenfolge ist 004 die Gerätenummer

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()

Ich mag diese Lösung! Ich habe ein paar Änderungen am Skript vorgenommen, um meinen eigenen Vorlieben gerecht zu werden
Will S

2

Hier ist ein Skript, das nur eine übereinstimmende Produkt- / Lieferanten-ID zurücksetzt.

#!/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

1
Ich fand Ihr Skript nützlich. Aber was soll ich tun, wenn das $DIRverschwindet und das Gerät nicht sichtbar ist?
Eugen Konkov

1

Hat jemand einen Vorschlaghammer bestellt? Dies ist aus verschiedenen anderen Antworten hier zusammengesetzt.

#!/bin/bash

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

cd /sys/bus/pci/drivers

function reinit {(
        local d="$1"
        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

Markus, hast du festgestellt, dass das Entbinden wirklich notwendig ist oder ist es hier nur um auf der sicheren Seite zu sein?
Ndemou

Dies ist ein Vorschlaghammer, er macht wahrscheinlich eine Menge unnötiger Dinge
Mark K Cowan

@ MarkKCowan, wie benutzt du es? Welche Befehlsargumente werden benötigt / erwartet?
not2qubit

1
@ not2qubit: Keine Befehlszeilenargumente erforderlich. Der $@im sudo-Proxy enthaltene Code ist nur eine Gewohnheit des Habbits, da er Fehler verhindert, wenn ich später Argumente hinzufüge (und vergesse, den sudo-Proxy zu aktualisieren).
Mark K Cowan

1
@ MarkKCowan Doh! Entschuldigung Kumpel! Oh ja, Fluch! Ich sollte diese Seite nicht kommentieren, wenn ich schläfrig bin. Upvoted!
not2qubit

1

Manchmal möchte ich diesen Vorgang auf einem bestimmten Gerät ausführen, wie durch VID (Hersteller-ID) und PID (Produkt-ID) angegeben. Dies ist ein Skript, das ich für diesen Zweck nützlich gefunden habe und das die raffinierte libusb-Bibliothek verwendet.

Erster Lauf:

sudo apt-get install libusb-dev

Anschließend sollte resetDeviceConnection dieser c ++ - Datei diese Aufgabe ausführen, nämlich das Zurücksetzen einer durch vid und pid identifizierten Geräteverbindung.

#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;
}

(gestohlen aus meinem persönlichen TIL-Katalog: https://github.com/Marviel/TIL/blob/master/unix_tools/Reset_specific_USB_Device.md )


3
Bitte zeigen Sie, wie dieses Skript ausgeführt wird.
George Udosen

Klar, lass mich updaten.
Marviel

1
@ Marviel, wir warten immer noch auf ein Update ...
not2qubit

braucht downvote als nutzlos
Eugen

1

Ich habe ein einfaches Bash-Skript erstellt, um ein bestimmtes USB-Gerät zurückzusetzen.

#!/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

0

Vielleicht funktioniert das auch für eine Kamera:

Im Anschluss habe ich eine ausgehungerte USB 3.0Festplatte auf einem 3.4.42(kernel.org) Linux wiederbelebt . dmesghabe gesagt, dass es nach 360s ein Timeout von Befehlen gab (sorry, ich kann das Syslog hier nicht kopieren, keine verbundenen Netzwerke) und das Laufwerk komplett hängen geblieben ist. Prozesse, die auf das Gerät zugreifen, wurden im Kernel blockiert und konnten nicht beendet werden. NFShing, ZFShing, ddhing.

Danach hat alles wieder funktioniert. dmesgerzählte nur eine einzige Zeile über das USBgefundene Gerät.

Ich habe wirklich keine Ahnung, was das Folgende im Detail bewirkt. Aber es hat geklappt.

Die folgende Beispielausgabe stammt von Debian Squeeze mit 2.6.32-5-686Kernel, daher denke ich, dass sie für 2.6 und höher funktioniert:

$ 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

Wenn dies nicht funktioniert, kann möglicherweise jemand anderes herausfinden, wie ein echter Reset an ein Gerät gesendet werden kann.


0

Versuchen Sie dies, es ist ein Software-Unplug (Auswerfen).

Manchmal funktioniert es bei manchen Geräten nicht einfach, das Gerät zu lösen.

Beispiel:

Ich möchte meinen "Genius NetScroll 120" entfernen oder auswerfen.

Dann überprüfe ich zuerst mein angeschlossenes USB-Gerät

$ 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**

Ok, ich habe meine Maus gefunden, sie hat einen Bus 002, ein Gerät 009, einen IDVendor 0458 und ein IDProduct 003a. Dies ist also ein Referenzgerät für die Maus.

Dies ist wichtig. Die Busnummer ist der Pfad des Anfangsnamens zum Gerät. Ich überprüfe die Produkt-ID und den Hersteller, um sicherzustellen, dass das richtige Gerät entfernt wird.

$ 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/

Achten Sie auf die Ordner, überprüfen Sie den Anfang mit Ordnernummer 2, ich werde diese überprüfen, weil mein Bus 002 ist, und nacheinander überprüfe ich jeden Ordner, der den richtigen idVendor und das richtige idProduct über meine Mausinformationen enthält.

In diesem Fall werde ich die Informationen mit diesem Befehl abrufen:

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

Ok, der Pfad /sys/bus/usb/drivers/usb/2-1.3/ stimmt mit meiner Info-Maus überein! XDDD.

Es ist Zeit, das Gerät zu entfernen!

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

Stecken Sie das USB-Gerät wieder ein und es funktioniert wieder!


10
Was ist, wenn Sie es nicht wieder anschließen können? (Zum Beispiel ist es ein interner SD-Kartenleser)
Aleb

0

Wenn Sie Ihren Gerätenamen kennen, funktioniert dieses Python-Skript:

#!/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()
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.