Déconnectez et reconnectez le port USB via cli

17

J'ai une souris qui cessera de fonctionner au hasard. La solution est simple, débranchez et rebranchez. Existe-t-il un moyen de le faire via la ligne de commande? Faire via la ligne de commande présente quelques avantages.

  1. N'use pas le connecteur.
  2. Plus rapide.
  3. Cela m'évite d'avoir à ramper sous mon bureau.
  4. Le plus important: m'empêche de débrancher accidentellement autre chose.

De plus, je suis curieux de savoir comment procéder.

Le système d'exploitation est Debian 8.

Merci!

pantalon de chat
la source
1
Pas exactement la même question, mais les réponses devraient être applicables: comment reconnecter un périphérique USB déconnecté logiquement?
Gilles 'SO- arrête d'être méchant'
Peut-être que unix.stackexchange.com/a/166601/117599 est ce que vous cherchez.
phk

Réponses:

13

Enregistrez les éléments suivants dans 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;
}

Exécutez les commandes suivantes dans le terminal:

  1. Compilez le programme:

    cc usbreset.c -o usbreset
    
  2. Obtenez l'ID de bus et de périphérique du périphérique USB que vous souhaitez réinitialiser:

    lsusb -t 
    
    Bus#  4  
    -Dev#   1 Vendor 0x1d6b Product 0x0001    
    -Dev#   3 Vendor 0x046b Product 0xff10
    
  3. Rendez notre programme compilé exécutable:

    chmod +x usbreset
    
  4. Exécutez le programme avec sudoprivilège; faire la substitution nécessaire pour <Bus>et <Device>id comme trouvé en exécutant la lsusbcommande:

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

Source du programme ci-dessus: http://marc.info/?l=linux-usb&m=121459435621262&w=2

Paul
la source
1
Cela réinitialise-t-il efficacement l'alimentation de l'appareil et le réinitialiserait-il donc sans avoir à le débrancher et à le rebrancher?
Jarryd
Cela a fonctionné comme un charme.
Wedge Martin
Si un programme a ouvert un périphérique USB série (par exemple, / dev / ttyUSB0 avec un lien symbolique depuis / dev / myserialdevice comme spécifié dans /etc/udev/rules.d/mystuff.rules), et que le périphérique se bloque pour une raison quelconque, est-ce alors nécessaire de le réinitialiser avec un ioctl () comme ci-dessus, ou est-ce suffisant de simplement le fermer () et de l'ouvrir () à nouveau?
Per Lindberg
1
@ Jarryd voir l'explication d'Alan dans le lien ci-dessus :Note however, that reset followed by re-enumeration is _not_ the same thing as power-cycle followed by reconnect and re-enumeration.
ckujau
2

J'ai créé un script Python qui simplifie l'ensemble du processus en fonction des réponses ici: /ubuntu/645/how-do-you-reset-a-usb-device-from-the-command-line .

Enregistrez le script ci-dessous sous reset_usb.py ou clonez ce dépôt: https://github.com/mcarans/resetusb/ .

Usage:

python reset_usb.py help: Afficher cette aide

sudo python reset_usb.py list: liste tous les périphériques USB

sudo python reset_usb.py path / dev / bus / usb / XXX / YYY: réinitialiser le périphérique USB en utilisant path / dev / bus / usb / XXX / YYY

sudo python reset_usb.py recherche "termes de recherche": recherchez un périphérique USB en utilisant les termes de recherche dans la chaîne de recherche renvoyée par liste et réinitialisez le périphérique correspondant

sudo python reset_usb.py listpci: liste tous les périphériques USB PCI

sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X: réinitialiser le périphérique USB PCI à l'aide du chemin /sys/bus/pci/drivers/.../XXXX:XX: XX.X

sudo python reset_usb.py searchpci "termes de recherche": recherchez un périphérique USB PCI en utilisant les termes de recherche dans la chaîne de recherche renvoyée par listpci et réinitialisez le périphérique correspondant

#!/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
la source
0

Vous pouvez toujours réinitialiser la pile USB via un logiciel, et également mettre les périphériques USB en mode veille ( économie d'énergie ), mais cela n'affecte pas l'alimentation du port + 5V, qui est toujours allumé.

En fonction de votre concentrateur USB, vous pouvez ou non être en mesure de couper (redémarrer) l'alimentation d'un port USB physique.

Seuls les concentrateurs USB «intelligents» permettent un cycle d'alimentation par port. Voici un petit projet qui vous permet de les contrôler.

Birkensocks
la source