Trennen Sie den USB-Anschluss über das CLI und schließen Sie ihn wieder an


16

Ich habe eine Maus, die zufällig nicht mehr funktioniert. Die Lösung ist einfach: Ziehen Sie den Stecker heraus und stecken Sie ihn wieder ein. Gibt es eine Möglichkeit, dies über die Befehlszeile zu tun? Das Ausführen über die Befehlszeile hat einige Vorteile.

  1. Verschleißt den Stecker nicht.
  2. Schneller.
  3. Spart mir die Mühe, unter meinen Schreibtisch zu kriechen.
  4. Das Wichtigste: Verhindert, dass ich versehentlich etwas anderes aus der Steckdose ziehe.

Außerdem bin ich gespannt, wie das geht.

Betriebssystem ist Debian 8.

Vielen Dank!


1
Nicht genau dieselbe Frage, aber die Antworten sollten zutreffen: Wie verbinde
Gilles 'SO- hör auf böse zu sein'

Vielleicht ist unix.stackexchange.com/a/166601/117599 das, wonach Sie suchen.
Phk

Antworten:


13

Speichern Sie das Folgende in 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 -t 
    
    Bus#  4  
    -Dev#   1 Vendor 0x1d6b Product 0x0001    
    -Dev#   3 Vendor 0x046b Product 0xff10
    
  3. Machen Sie unser kompiliertes Programm ausführbar:

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

    sudo ./usbreset /dev/bus/usb/004/003
    
    Resetting USB device /dev/bus/usb/004/003
    
    Reset successful
    

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


1
Wird dadurch die Stromversorgung des Geräts effektiv zurückgesetzt und es würde daher vollständig zurückgesetzt, ohne dass das Gerät ausgesteckt und wieder eingesteckt werden muss?
Jarryd

Das hat wie ein Zauber gewirkt.
Wedge Martin

Wenn ein Programm ein serielles USB-Gerät geöffnet hat (z. B. / dev / ttyUSB0, das mit / dev / myserialdevice wie in /etc/udev/rules.d/mystuff.rules angegeben verknüpft ist) und das Gerät aus irgendeinem Grund hängen bleibt, ist dies der Fall dann muss man es mit einem ioctl () wie oben zurücksetzen, oder reicht es aus, es einfach zu schließen () und wieder zu öffnen ()?
Per Lindberg

1
@ Jarryd siehe Alans Erklärung im obigen Link :Note however, that reset followed by re-enumeration is _not_ the same thing as power-cycle followed by reconnect and re-enumeration.
ckujau

2

Ich habe ein Python-Skript erstellt, das den gesamten Vorgang basierend auf den Antworten hier vereinfacht: /ubuntu/645/how-do-you-reset-a-usb-device-from-the-command-line .

Speichern Sie das folgende Skript als reset_usb.py oder klonen Sie dieses Repo: https://github.com/mcarans/resetusb/ .

Verwendung:

Hilfe zu python reset_usb.py: Zeigen Sie diese Hilfe an

sudo python reset_usb.py list: Listet alle USB-Geräte auf

sudo python reset_usb.py pfad / dev / bus / usb / XXX / YYY: USB-Gerät mit pfad / dev / bus / usb / XXX / YYY zurücksetzen

sudo python reset_usb.py search "search terms": Suche nach USB-Gerät unter Verwendung der Suchbegriffe in der von der Liste zurückgegebenen Suchzeichenfolge und Zurücksetzen des übereinstimmenden Geräts

sudo python reset_usb.py listpci: Listet alle PCI-USB-Geräte auf

sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X: Setzt das PCI-USB-Gerät über den Pfad /sys/bus/pci/drivers/.../XXXX:XX zurück: XX.X

sudo python reset_usb.py searchpci "search terms": Suche nach PCI-USB-Gerät unter Verwendung der Suchbegriffe in der von listpci zurückgegebenen Suchzeichenfolge und Zurücksetzen des übereinstimmenden Geräts

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

0

Sie können den USB-Stack jederzeit über die Software zurücksetzen und USB-Geräte auch in den Energiesparmodus versetzen. Dies hat jedoch keine Auswirkungen auf die Stromversorgung des + 5-V-Anschlusses, der immer eingeschaltet ist.

Abhängig von Ihrem USB-Hub können Sie möglicherweise die Stromversorgung eines physischen USB-Anschlusses tatsächlich ausschalten (aus- und wieder einschalten) oder nicht.

Nur "intelligente" USB-Hubs ermöglichen das Aus- und Einschalten pro Port. Hier ist ein kleines Projekt, mit dem Sie diese steuern können.

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.