¿Cómo se restablece un dispositivo USB desde la línea de comandos?

164

¿Es posible restablecer la conexión de un dispositivo USB, sin desconectar / conectar físicamente desde la PC?

Específicamente, mi dispositivo es una cámara digital. Estoy usando gphoto2, pero últimamente recibo "errores de lectura del dispositivo", así que me gustaría intentar restablecer el software de la conexión.

Por lo que puedo decir, no se están cargando módulos del núcleo para la cámara. El único que parece relacionado es usbhid.

cmcginty
fuente
¿Qué versión de Ubuntu estás usando?
Usuario
Probé ambas soluciones de Li Lo y ssokolow, todo lo que obtengo es permiso denegado, nomatter si uso el código usbreset o la línea de comando "echo 0> ..." uso sudo, también mis dispositivos usb son propiedad de root pero yo puede usarlos sin derechos de administrador (cámaras ...)
1
Si recibe errores de lectura, es posible que tenga algunos daños en los datos. Si su cámara usa una tarjeta de memoria externa (como MicroSD), puede ser conveniente conectarla a la computadora y ejecutar fsck.
TSJNachos117

Respuestas:

118

Guarde lo siguiente como 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;
}

El ejecutar los siguientes comandos en la terminal:

  1. Compila el programa:

    $ cc usbreset.c -o usbreset
    
  2. Obtenga la identificación de bus y dispositivo del dispositivo USB que desea restablecer:

    $ lsusb  
    Bus 002 Device 003: ID 0fe9:9010 DVICO  
    
  3. Haga que nuestro programa compilado sea ejecutable:

    $ chmod +x usbreset
    
  4. Ejecute el programa con privilegio sudo; realice la sustitución necesaria para <Bus>y los <Device>identificadores que se encuentran al ejecutar el lsusbcomando:

    $ sudo ./usbreset /dev/bus/usb/002/003  
    

Fuente del programa anterior: http://marc.info/?l=linux-usb&m=121459435621262&w=2

Li Lo
fuente
3
Esto funciona con ubuntu 13.10. La identificación del dispositivo puede variar. Para obtenerlo para el mouse, he echo $(lsusb | grep Mouse) mouse=$( lsusb | grep Mouse | perl -nE "/\D+(\d+)\D+(\d+).+/; print qq(\$1/\$2)") sudo /path/to/c-program/usbreset /dev/bus/usb/$mouse
incluido el
1
mi unidad externa parece volverse indetectable (tengo que volver a conectar el cable usb); es un usb2.0 conectado en un puerto de PC de escritorio usb3.0; cuando ejecuto usbreset /dev/bus/usb/011/001que es uno de los 2 concentradores raíz usb 3.0 en lsusb, errores: "Error en ioctl: ¿Es un directorio", alguna idea? Probé en ambos hubs usb 3.0
Aquarius Power
1
Si alguien que lee esto tiene un mouse (usb) congelado después de iniciar sesión en Ubuntu 16.04 (con dmesg lleno por "input irq status -75"), puedo confirmar que esta es la única solución que funcionó para mí. Gracias
Agustin Baez
1
@ Acuario, también recibo el mismo error "Error en ioctl: es un directorio". ¿Está resuelto?
ransh
1
Vea mi respuesta aquí askubuntu.com/a/988297/558070 que usa el mismo método de reinicio que esta respuesta pero también permite una lista simplificada y la búsqueda de dispositivos.
mcarans
58

No me he encontrado en sus circunstancias específicas antes, por lo que no estoy seguro de si hará lo suficiente, pero la forma más simple que he encontrado para restablecer un dispositivo USB es este comando: (No se necesitan aplicaciones externas)

sudo sh -c "echo 0 > /sys/bus/usb/devices/1-4.6/authorized"
sudo sh -c "echo 1 > /sys/bus/usb/devices/1-4.6/authorized"

Ese es el que uso para restablecer mi Kinect, ya que libfreenect parece no tener API para volverlo a dormir. Está en mi cuadro Gentoo, pero el núcleo debería ser lo suficientemente nuevo como para usar la misma estructura de ruta para sysfs.

Obviamente, el suyo no lo sería, 1-4.6pero puede extraer esa ruta del dispositivo del registro del kernel ( dmesg) o puede usar algo como lsusbobtener las ID del proveedor y del producto y luego usar un comando rápido como este para enumerar cómo las rutas se relacionan con diferentes proveedores / pares de ID de producto:

for X in /sys/bus/usb/devices/*; do 
    echo "$X"
    cat "$X/idVendor" 2>/dev/null 
    cat "$X/idProduct" 2>/dev/null
    echo
done
ssokolow
fuente
sh: 1: no se puede crear /sys/bus/usb/devices/1-3.1:1.0/authorized: Directory inexistente
Nicolas Marchildon
Parece que han cambiado el diseño del sistema de archivos usbfs. Intentaré descubrir cuál es la nueva forma de hacer las cosas en Ubuntu una vez que no tenga tanto sueño.
ssokolow
99
Gracias trabajado genial! Tal vez también debería mencionar realizar un echo 1 > /sys/bus/usb/devices/whatever/authorizedscript interno para volver a habilitar el dispositivo tan pronto como se haya deshabilitado. Lo hice tanto en mi mouse como en mi teclado usb y terminé con un sistema completamente sordo :)
Avio
1
Es extremadamente extraño si restablece automáticamente el valor a 1, ya que establecerlo en 0 le indica al sistema que no desea que el dispositivo esté "autorizado" y, por lo tanto, inaccesible.
Tim Tisdall
2
Una nota para cualquiera que intente cambiar al | sudo tee ...enfoque de las /sysescrituras privilegiadas : eso se rompe mal si aún no tiene sus credenciales de sudo almacenadas en caché. sudo sh -c "..."funciona como se esperaba cuando sudo necesita solicitar una contraseña.
ssokolow 05 de
51

Esto restablecerá todos los puertos USB1 / 2/3 conectados [1]:

for i in /sys/bus/pci/drivers/[uoex]hci_hcd/*:*; do
  [ -e "$i" ] || continue
  echo "${i##*/}" > "${i%/*}/unbind"
  echo "${i##*/}" > "${i%/*}/bind"
done

Creo que esto resolverá tu problema. Si no desea restablecer todos los puntos finales USB, puede usar la ID de dispositivo adecuada desde/sys/bus/pci/drivers/ehci_hcd


Notas: [1]: los *hci_hcdcontroladores del kernel generalmente controlan los puertos USB. ohci_hcdy uhci_hcdson para puertos USB1.1, ehci_hcdson para puertos USB2 y xhci_hcdson para puertos USB3. (ver https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire) )

Tamás Tapsonyi
fuente
¿crees que puede funcionar para activar un almacenamiento usb ?
Aquarius Power
2
Aunque recibí el siguiente mensaje: ls: cannot access /sys/bus/pci/drivers/ehci_hcd/: No such file or directoryesto resolvió el problema, el mouse comenzó a funcionar de inmediato. +1
Atila Fulop
2
@Otheus OHCI y UHCI son los estándares de host USB 1.1, EHCI es el estándar de host USB 2.0 y XHCI es el estándar de host USB 3.0.
ssokolow
2
Esta es una hermosa solución. Sin embargo, en algunos núcleos posteriores y otros * nix distribuciones, se encuentra que es necesario sustituir *hci_hcdcon *hci-pci, ya que el conductor hci_hcd ya está compilado en el núcleo.
not2qubit
1
En un Banana Pi, aparentemente no hay bus PCI, tuve que usar lo siguiente:for i in /sys/bus/usb/drivers/*/*:*; do
Martin Hansen
10

Necesitaba automatizar esto en un script de Python, así que adapté la respuesta extremadamente útil de LiLo a lo siguiente:

#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE
import fcntl
driver = sys.argv[-1]
print "resetting driver:", driver
USBDEVFS_RESET= 21780

try:
    lsusb_out = Popen("lsusb | grep -i %s"%driver, shell=True, bufsize=64, stdin=PIPE, stdout=PIPE, close_fds=True).stdout.read().strip().split()
    bus = lsusb_out[1]
    device = lsusb_out[3][:-1]
    f = open("/dev/bus/usb/%s/%s"%(bus, device), 'w', os.O_WRONLY)
    fcntl.ioctl(f, USBDEVFS_RESET, 0)
except Exception, msg:
    print "failed to reset device:", msg

En mi caso, era el controlador cp210x (que podía ver lsmod | grep usbserial), por lo que podría guardar el fragmento anterior como reset_usb.py y luego hacer esto:

sudo python reset_usb.py cp210x

Esto también podría ser útil si aún no tiene la configuración del compilador de CA en su sistema, pero sí tiene Python.

Peter
fuente
funcionó para mí en una frambuesa
webo80
1
Algunas palabras más sobre su solución, por favor. Por ejemplo, algo sobre la constante USBDEVFS_RESET. ¿Es siempre lo mismo para todos los sistemas?
not2qubit
@ not2qubit USBDEVFS_RESETes igual para todos los sistemas. Para MIPS es 536892692.
yegorich
Las versiones más nuevas de lsusb parecen necesitar el -targumento (modo de árbol) para mostrar la información del controlador que este script espera, pero el script luego necesita algunas actualizaciones para analizar las diferentes líneas de salida que esto genera
Cheetah
Vea mi respuesta aquí askubuntu.com/a/988297/558070 para obtener una versión mucho mejor de este script.
mcarans
8

He creado un script de Python que simplifica todo el proceso basado en las respuestas aquí.

Guarde el script a continuación como reset_usb.py o clone este repositorio .

Uso:

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 /sys/bus/pci/drivers/.../XXXX:XX:XX.X
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

Guión:

#!/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
fuente
Esta es la mejor respuesta a esta pregunta.
kapad
4

Como el caso especial de la pregunta es un problema de comunicación de gphoto2 con una cámara en USB, hay una opción en gphoto2 para restablecer su conexión USB:

gphoto2 --reset

Quizás esta opción no existía en 2010 cuando se hizo la pregunta.

mviereck
fuente
3

La forma más rápida de restablecer será restablecer el controlador USB en sí. Hacerlo obligará a udev a cancelar el registro del dispositivo en la desconexión, y el registro volverá una vez que lo habilite.

echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci_hcd/unbind
echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci_hcd/unbind
echo -n "0000:00:1a.0" | tee /sys/bus/pci/drivers/ehci_hcd/bind
echo -n "0000:00:1d.0" | tee /sys/bus/pci/drivers/ehci_hcd/bind

Esto debería funcionar para la mayoría de los entornos de PC. Sin embargo, si está utilizando un hardware personalizado, simplemente puede recorrer los nombres de los dispositivos. Con este método no necesita encontrar el nombre del dispositivo por lsusb. También puede incorporar en un script automatizado.

chandank
fuente
1
Tiene que ejecutar estos comandos como root / sudo, y no va a funcionar en todos los sistemas (en algunos, tendrá que sustituir ehci_hcdcon ehci-pcimás información sobre esta solución (tal vez de donde vino.):? Davidjb.com/blog / 2012/06 /…
Lambart el
3

Estoy usando una especie de mazo al recargar los módulos. Este es mi script usb_reset.sh:

#!/bin/bash

# USB drivers
rmmod xhci_pci
rmmod ehci_pci

# uncomment if you have firewire
#rmmod ohci_pci

modprobe xhci_pci
modprobe ehci_pci

# uncomment if you have firewire
#modprobe ohci_pci

Y este es mi archivo de servicio systemd /usr/lib/systemd/system/usbreset.service que ejecuta usb_reset.sh después de que mi administrador de diplay ha comenzado:

[Unit]
Description=usbreset Service
After=gdm.service
Wants=gdm.service

[Service]
Type=oneshot
ExecStart=/path/to/usb_reset.sh
Ulrich-Lorenz Schlüter
fuente
Usar la opción listpci de mi script aquí: askubuntu.com/a/988297/558070 ayudará a identificar qué módulo USB recargar (por ejemplo, xhci_pci, ehci_pci).
mcarans
2
Desafortunadamente en mi sistema, estos módulos del kernel no están separados del kernel, por lo que esto no funcionará:rmmod: ERROR: Module xhci_pci is builtin.
hasta el
3

Hice un script de Python que restablecerá un dispositivo USB en particular en función del número de dispositivo. Puede encontrar el número de dispositivo desde el comando lsusb.

por ejemplo:

$ lsusb

Bus 002 Device 004: ID 046d:c312 Logitech, Inc. DeLuxe 250 Keyboard

En esta cadena 004 es el número de dispositivo

import os
import argparse
import subprocess

path='/sys/bus/usb/devices/'

def runbash(cmd):
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
    out = p.stdout.read().strip()
    return out

def reset_device(dev_num):
    sub_dirs = []
    for root, dirs, files in os.walk(path):
            for name in dirs:
                    sub_dirs.append(os.path.join(root, name))

    dev_found = 0
    for sub_dir in sub_dirs:
            if True == os.path.isfile(sub_dir+'/devnum'):
                    fd = open(sub_dir+'/devnum','r')
                    line = fd.readline()
                    if int(dev_num) == int(line):
                            print ('Your device is at: '+sub_dir)
                            dev_found = 1
                            break

                    fd.close()

    if dev_found == 1:
            reset_file = sub_dir+'/authorized'
            runbash('echo 0 > '+reset_file) 
            runbash('echo 1 > '+reset_file) 
            print ('Device reset successful')

    else:
            print ("No such device")

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--devnum', dest='devnum')
    args = parser.parse_args()

    if args.devnum is None:
            print('Usage:usb_reset.py -d <device_number> \nThe device    number can be obtained from lsusb command result')
            return

    reset_device(args.devnum)

if __name__=='__main__':
    main()
Raghu
fuente
¡Me gusta esta solución! He hecho algunos ajustes al script para mis propios gustos: gist.github.com/willstott101/7a455817ec6f4b8d89571ce72bdfd34a
Será
2

Aquí hay un script que solo restablecerá una identificación de producto / proveedor coincidente.

#!/bin/bash

set -euo pipefail
IFS=$'\n\t'

VENDOR="045e"
PRODUCT="0719"

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 0 > $DIR/authorized
    sleep 0.5
    echo 1 > $DIR/authorized
  fi
done
cmcginty
fuente
1
Encontré que tu guión es útil. Pero, ¿qué debo hacer si el $DIRdispositivo desaparece y el dispositivo no es visible?
Eugen Konkov
1

¿Alguien ordenó un mazo? Esto se reconstruye a partir de varias otras respuestas aquí.

#!/bin/bash

# Root required
if (( UID )); then
        exec sudo "$0" "$@"
fi

cd /sys/bus/pci/drivers

function reinit {(
        local d="$1"
        test -e "$d" || return

        rmmod "$d"

        cd "$d"

        for i in $(ls | grep :); do
                echo "$i" > unbind
        done

        sleep 1

        for i in $(ls | grep :); do
                echo "$i" > bind
        done

        modprobe "$d"

)}

for d in ?hci_???; do
        echo " - $d"
        reinit "$d"
done
Mark K Cowan
fuente
Mark, ¿descubriste que la desvinculación es realmente necesaria o es solo para estar seguros?
ndemou
Este es un mazo, probablemente hace muchas cosas innecesarias
Mark K Cowan
@ MarkKCowan, ¿Cómo lo usas? ¿Cuáles son los argumentos del comando necesarios / esperados?
not2qubit
1
@ not2qubit: no se requieren argumentos de línea de comandos. El $@en el sudo proxy es solo una fuerza de habbit, ya que evita errores si luego decido agregar argumentos (y me olvido de actualizar el sudo proxy).
Mark K Cowan
1
@MarkKCowan Doh! ¡Lo siento compañero! Oh si de maldición! No debería comentar en este sitio mientras tengo sueño. ¡Votado!
not2qubit
1

A veces quiero realizar esta operación en un dispositivo en particular, según lo identificado por VID (identificación del proveedor) y PID (identificación del producto). Este es un script que he encontrado útil para este propósito, que utiliza la ingeniosa biblioteca libusb.

Primer intento:

sudo apt-get install libusb-dev

Luego, resetDeviceConnection de este archivo c ++ debería realizar esta tarea, de restablecer una conexión de dispositivo como se identifica por vid y pid.

#include <libusb-1.0/libusb.h>

int resetDeviceConnection(UINT_16 vid, UINT_16 pid){
    /*Open libusb*/
    int resetStatus = 0;
    libusb_context * context;
    libusb_init(&context);

    libusb_device_handle * dev_handle = libusb_open_device_with_vid_pid(context,vid,pid);
    if (dev_handle == NULL){
      printf("usb resetting unsuccessful! No matching device found, or error encountered!\n");
      resetStatus = 1;
    }
    else{
      /*reset the device, if one was found*/
      resetStatus = libusb_reset_device(dev_handle);
    }
    /*exit libusb*/
    libusb_exit(context);
    return resetStatus;
}

(robado de mi catálogo personal de TIL: https://github.com/Marviel/TIL/blob/master/unix_tools/Reset_specific_USB_Device.md )

Marviel
fuente
3
¿Puede mostrar cómo se ejecuta este script ?
George Udosen
Claro, déjame actualizar.
Marviel
1
@ Marviel, todavía estamos esperando una actualización ...
not2qubit
necesita un voto negativo como inútil
Eugen Konkov
1

Hice un script bash simple para restablecer un dispositivo USB en particular.

#!/bin/bash
#type lsusb to find "vendor" and "product" ID in terminal
set -euo pipefail
IFS=$'\n\t'

#edit the below two lines of vendor and product values using lsusb result
dev=$(lsusb -t | grep usbdevicename | grep 'If 1' | cut -d' ' -f13|cut -d"," -f1)
#VENDOR=05a3
#PRODUCT=9230
VENDOR=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f1)
PRODUCT=$(lsusb -s $dev | cut -d' ' -f6 | cut -d: -f2)

for DIR in $(find /sys/bus/usb/devices/ -maxdepth 1 -type l); do
  if [[ -f $DIR/idVendor && -f $DIR/idProduct &&
        $(cat $DIR/idVendor) == $VENDOR && $(cat $DIR/idProduct) == $PRODUCT ]]; then
    echo 0 > $DIR/authorized
    sleep 0.5
    echo 1 > $DIR/authorized
  fi
done
Thoht
fuente
0

Quizás esto también funcione para una cámara:

Después revivió un USB 3.0HDD muerto de hambre en un 3.4.42(kernel.org) Linux de mi lado. dmesgle dije que estaba agotando los comandos después de 360s (lo siento, no puedo copiar el syslog aquí, no las redes conectadas) y la unidad se bloqueó por completo. Los procesos que acceden al dispositivo fueron bloqueados en el núcleo, imposibles de matar. NFScolgado, ZFScolgado, ddcolgado.

Después de hacer esto, todo volvió a funcionar. dmesgcontó solo una línea sobre el USBdispositivo encontrado.

Realmente no tengo idea de lo que sigue en detalle. Pero funcionó.

El siguiente resultado de ejemplo es de Debian Squeeze con 2.6.32-5-686kernel, por lo que creo que funciona para 2.6 y superiores:

$ ls -al /dev/sdb
brw-rw---T 1 root floppy 8, 16 Jun  3 20:24 /dev/sdb

$ ls -al /sys/dev/block/8:16/device/rescan
--w------- 1 root root 4096 Jun  6 01:46 /sys/dev/block/8:16/device/rescan

$ echo 1 > /sys/dev/block/8:16/device/rescan

Si esto no funciona, quizás alguien más pueda descubrir cómo enviar un reinicio real a un dispositivo.

Tino
fuente
0

Intente esto, es un desenchufe de software (Expulsar).

A veces no funciona simplemente desconectar el dispositivo para algunos dispositivos.

Ejemplo:

Quiero eliminar o expulsar mi "Genius NetScroll 120".

Luego, primero verifico mi dispositivo usb conectado

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 002 Device 002: ID 8087:0020 Intel Corp. Integrated Rate Matching Hub
Bus 001 Device 003: ID 03f0:231d Hewlett-Packard 
Bus 001 Device 004: ID 138a:0007 Validity Sensors, Inc. VFS451 Fingerprint Reader
Bus 001 Device 005: ID 04f2:b163 Chicony Electronics Co., Ltd 
Bus 002 Device 009: ID 0458:003a KYE Systems Corp. (Mouse Systems) NetScroll+ Mini Traveler / Genius NetScroll 120  **<----This my Mouse! XDDD**

Ok, encontré mi mouse, tiene un Bus 002, Dispositivo 009, idVendor 0458 e idProduct 003a, así que esta es una información del dispositivo de referencia sobre el mouse.

Esto es importante, el número de Bus es la ruta de inicio del nombre del dispositivo y comprobaré el Id. Del producto y el Proveedor para asegurar que se elimine el dispositivo correcto.

$ ls /sys/bus/usb/drivers/usb/
1-1/    1-1.1/  1-1.3/  1-1.5/  2-1/    2-1.3/  bind    uevent  unbind  usb1/   usb2/

Preste atención a las carpetas, verifique el comienzo con la carpeta número 2, comprobaré esta porque mi Bus es 002, y una por una compruebo cada carpeta que contiene el idVendor y idProduct correctos sobre la información de mi mouse.

En este caso, recuperaré la información con este comando:

cat /sys/bus/usb/drivers/usb/2-1.3/idVendor
0458
cat /sys/bus/usb/drivers/usb/2-1.3/idProduct
003a

Ok, la ruta /sys/bus/usb/drivers/usb/2-1.3/ coincide con mi mouse de información. XDDD.

¡Es hora de quitar el dispositivo!

su -c "echo 1 > /sys/bus/usb/drivers/usb/2-1.3/remove"

¡Vuelva a enchufar el dispositivo usb y vuelve a funcionar!

user242078
fuente
10
¿Qué pasa si no puedes volver a enchufarlo? (por ejemplo, es un lector de tarjetas SD interno)
aleb
0

Si conoce el nombre de su dispositivo, este script de Python funcionará:

#!/usr/bin/python
"""
USB Reset

Call as "usbreset.py <device_file_path>"

With device_file_path like "/dev/bus/usb/bus_number/device_number"
"""
import fcntl, sys, os

USBDEVFS_RESET = ord('U') << (4*2) | 20

def main():
    fd = os.open(sys.argv[1], os.O_WRONLY)
    if fd < 0: sys.exit(1)
    fcntl.ioctl(fd, USBDEVFS_RESET, 0)
    os.close(fd)
    sys.exit(0)
# end main

if __name__ == '__main__':
    main()
Arcilla
fuente