Отключите и снова подключите USB-порт через Cli

17

У меня есть мышь, которая перестает работать случайно. Решение легко, отключите и снова подключите. Есть ли способ сделать это через командную строку? Работа через командную строку имеет несколько преимуществ.

  1. Не изнашивает разъем.
  2. Быстрее.
  3. Избавляет меня от необходимости ползти под моим столом.
  4. Самое главное: не дает мне случайно отключить что-то еще.

Плюс мне любопытно, как это сделать.

ОС Debian 8.

Благодарность!

кошачьи штаны
источник
1
Не совсем тот же вопрос, но ответы должны быть применимы: как восстановить логически отключенное USB-устройство?
Жиль "ТАК - перестань быть злым"
Может быть, unix.stackexchange.com/a/166601/117599 - это то, что вы ищете.
phk

Ответы:

13

Сохраните следующее 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;
}

Выполните следующие команды в терминале:

  1. Скомпилируйте программу:

    cc usbreset.c -o usbreset
    
  2. Получите идентификатор шины и устройства USB-устройства, которое вы хотите сбросить:

    lsusb -t 
    
    Bus#  4  
    -Dev#   1 Vendor 0x1d6b Product 0x0001    
    -Dev#   3 Vendor 0x046b Product 0xff10
    
  3. Сделайте нашу скомпилированную программу исполняемой:

    chmod +x usbreset
    
  4. Выполнить программу с sudoпривилегиями; сделать необходимые замены <Bus>и <Device>идентификаторы, найденные с помощью lsusbкоманды:

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

Источник вышеуказанной программы: http://marc.info/?l=linux-usb&m=121459435621262&w=2

Павел
источник
1
Эффективно ли сбрасывает питание устройства и, следовательно, полностью сбрасывает его, не отключая и не подключая его снова?
Джаррид
Это работает как шарм.
Клин Мартин
Если программа открыла последовательное USB-устройство (скажем, / dev / ttyUSB0 по символической ссылке из / dev / myserialdevice, как указано в /etc/udev/rules.d/mystuff.rules), и устройство по какой-то причине зависает, затем необходимо сбросить его с помощью ioctl (), как указано выше, или достаточно просто закрыть () и снова открыть ()?
Пер Линдберг
1
@Jarryd см. Объяснение Алана в ссылке выше :Note however, that reset followed by re-enumeration is _not_ the same thing as power-cycle followed by reconnect and re-enumeration.
ckujau
2

Я создал скрипт Python, который упрощает весь процесс на основе ответов здесь: /ubuntu/645/how-do-you-reset-a-usb-device-from-the-command-line ,

Сохраните приведенный ниже скрипт как reset_usb.py или клонируйте этот репозиторий: https://github.com/mcarans/resetusb/ .

Использование:

python reset_usb.py help: показать эту помощь

sudo python reset_usb.py list: список всех USB-устройств

sudo python reset_usb.py путь / dev / bus / usb / XXX / YYY: сброс устройства USB с использованием пути / dev / bus / usb / XXX / YYY

sudo python reset_usb.py search «условия поиска»: поиск устройства USB с использованием условий поиска в строке поиска, возвращаемой списком, и сброс соответствующего устройства

sudo python reset_usb.py listpci: список всех USB-устройств PCI

sudo питон XX.X

sudo python reset_usb.py searchpci "условия поиска": поиск устройства USB USB с использованием условий поиска в строке поиска, возвращенной listpci, и сброс соответствующего устройства

#!/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)
mcarans
источник
0

Вы всегда можете сбросить USB-стек с помощью программного обеспечения, а также перевести USB-устройства в режим ожидания ( энергосбережения ), но это не влияет на питание порта + 5В, которое всегда включено.

В зависимости от вашего USB-концентратора, вы можете или не можете реально отключить (включить) питание физического порта USB.

Только «умные» USB-концентраторы допускают циклическое включение питания для каждого порта. Вот небольшой проект, который позволяет вам контролировать это.

Birkensocks
источник