Відключіть і підключіть USB-порт через cli


18

У мене є миша, яка перестане працювати випадковим чином. Рішення легко, від'єднайтесь від мережі та підключіть. Чи є спосіб я це зробити через командний рядок? У командному рядку є кілька переваг.

  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
Це ефективно скидає живлення на пристрої і тому повністю скине його, не відключаючи та відключаючи живлення?
Jarryd

Це спрацювало як шарм.
Клін Мартін

Якщо програма відкрила послідовний 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 список: Список усіх USB-пристроїв

sudo python reset_usb.py шлях / dev / автобус / usb / XXX / YYY: скидання USB-пристрою за допомогою шляху / dev / bus / usb / XXX / YYY

sudo python reset_usb.py пошук "пошукові терміни": пошук USB-пристрою за допомогою пошукових термінів у рядку пошуку, поверненому за списком та скидання відповідного пристрою

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

sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X: Скинути USB-пристрій PCI, використовуючи шлях /sys/bus/pci/drivers/…/XXXX:XX: XX.X

sudo python reset_usb.py searchpci "пошукові терміни": пошук USB-пристрою PCI за допомогою пошукових термінів у рядку пошуку, поверненому 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)

0

Ви завжди можете скинути USB-стек за допомогою програмного забезпечення, а також перевести USB-пристрої у режим сну ( економія енергії ) режим, але це не впливає на потужність порту + 5 В, яке завжди увімкнено.

Залежно від вашого концентратора USB, ви можете або не зможете фактично вимкнути (переключити) живлення на фізичний порт USB.

Лише "розумні" концентратори USB дозволяють їздити на велосипеді по порту. Ось невеликий проект, який дозволяє контролювати їх.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.