Odłącz i ponownie podłącz port USB przez cli


18

Mam mysz, która przestanie działać losowo. Rozwiązanie jest łatwe, odłącz i podłącz ponownie. Czy jest jednak sposób, aby to zrobić za pomocą wiersza polecenia? Robienie za pomocą wiersza poleceń ma kilka zalet.

  1. Nie zużywa złącza.
  2. Szybciej.
  3. Oszczędza mi kłopotów pełzania pod biurkiem.
  4. Najważniejsze: chroni mnie przed przypadkowym odłączeniem wtyczki.

Dodatkowo jestem ciekawy, jak to zrobić.

System operacyjny to Debian 8.

Dzięki!


1
Nie do końca to samo pytanie, ale odpowiedzi powinny być odpowiednie: Jak ponownie podłączyć logicznie odłączone urządzenie USB?
Gilles „SO- przestań być zły”

Może unix.stackexchange.com/a/166601/117599 jest tym, czego szukasz.
phk

Odpowiedzi:


13

Zapisz następujące elementy w 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;
}

Uruchom następujące polecenia w terminalu:

  1. Skompiluj program:

    cc usbreset.c -o usbreset
    
  2. Uzyskaj identyfikator magistrali i urządzenia urządzenia USB, które chcesz zresetować:

    lsusb -t 
    
    Bus#  4  
    -Dev#   1 Vendor 0x1d6b Product 0x0001    
    -Dev#   3 Vendor 0x046b Product 0xff10
    
  3. Spraw, aby nasz skompilowany program był wykonywalny:

    chmod +x usbreset
    
  4. Uruchom program z sudouprawnieniami; dokonaj niezbędnych podstawień <Bus>i <Device>identyfikatorów zgodnie z lsusbpoleceniem:

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

Źródło powyższego programu: http://marc.info/?l=linux-usb&m=121459435621262&w=2


1
Czy to skutecznie resetuje zasilanie urządzenia i dlatego całkowicie je zresetuje bez konieczności odłączania i ponownego podłączania?
Jarryd

To działało jak urok.
Wedge Martin

Jeśli program otworzył szeregowe urządzenie USB (powiedzmy, / dev / ttyUSB0 dowiązanie symboliczne z / dev / myserialdevice, jak określono w /etc/udev/rules.d/mystuff.rules), a urządzenie zawiesi się z jakiegoś powodu, czy to następnie konieczne jest zresetowanie go za pomocą ioctl () jak wyżej, czy wystarczy wystarczy zamknąć () i ponownie () ponownie?
Per Lindberg,

1
@Jarryd patrz wyjaśnienie Alana w powyższym linku :Note however, that reset followed by re-enumeration is _not_ the same thing as power-cycle followed by reconnect and re-enumeration.
ckujau,

2

Stworzyłem skrypt w języku Python, który upraszcza cały proces na podstawie odpowiedzi tutaj: /ubuntu/645/how-do-you-reset-a-usb-device-from-the-command-line .

Zapisz poniższy skrypt jako reset_usb.py lub sklonuj to repozytorium: https://github.com/mcarans/resetusb/ .

Stosowanie:

python reset_usb.py help: Pokaż tę pomoc

sudo python reset_usb.py list: Wyświetla listę wszystkich urządzeń USB

sudo python reset_usb.py ścieżka / dev / bus / usb / XXX / YYY: Zresetuj urządzenie USB za pomocą path / dev / bus / usb / XXX / YYY

sudo python reset_usb.py wyszukaj „wyszukiwane hasła”: Wyszukaj urządzenie USB za pomocą wyszukiwanych terminów w ciągu wyszukiwania zwróconym przez listę i zresetuj pasujące urządzenie

sudo python reset_usb.py listpci: Wyświetla listę wszystkich urządzeń PCI USB

sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X: Zresetuj urządzenie PCI USB za pomocą ścieżki /sys/bus/pci/drivers/.../XXXX:XX: XX.X

sudo python reset_usb.py searchpci "wyszukiwane hasła": Wyszukaj urządzenie PCI USB za pomocą wyszukiwanych terminów w ciągu wyszukiwania zwróconym przez listpci i zresetuj pasujące urządzenie

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

Zawsze możesz zresetować stos USB za pomocą oprogramowania, a także przełączyć urządzenia USB w tryb uśpienia ( oszczędzania energii ), ale nie wpływa to na zasilanie portu + 5 V, które jest zawsze włączone.

W zależności od koncentratora USB, możesz faktycznie nie być w stanie wyłączyć (przełączyć) zasilania fizycznego portu USB.

Tylko „inteligentne” koncentratory USB pozwalają na cykliczne przełączanie zasilania na port. Oto mały projekt, który pozwala ci je kontrolować.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.