Come si reimposta un dispositivo USB dalla riga di comando?


164

È possibile ripristinare la connessione di un dispositivo USB, senza disconnettersi / collegarsi fisicamente dal PC?

In particolare, il mio dispositivo è una fotocamera digitale. Sto usando gphoto2, ma ultimamente ricevo "errori di lettura del dispositivo", quindi vorrei provare a ripristinare il software della connessione.

Da quello che posso dire, non ci sono moduli del kernel caricati per la videocamera. L'unico che sembra correlato è usbhid.


Quale versione di Ubuntu stai usando?
Utente

ho provato entrambe le soluzioni di Li Lo e ssokolow, tutto quello che ottengo è l'autorizzazione negata, nomatter se uso il codice usbreset o la riga di comando "echo 0> ..." uso sudo, anche i miei dispositivi USB sono di proprietà di root ma io possono usarli senza i diritti di amministratore (telecamere ..)

1
Se ricevi errori di lettura, potresti avere del danneggiamento dei dati. Se la fotocamera utilizza una scheda di memoria esterna (come MicroSD), potrebbe essere saggio collegarla al computer ed eseguire fsck.
TSJNachos117,

Risposte:


118

Salva quanto segue come 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;
}

Eseguono i seguenti comandi nel terminale:

  1. Compila il programma:

    $ cc usbreset.c -o usbreset
    
  2. Ottieni l'ID bus e dispositivo del dispositivo USB che desideri ripristinare:

    $ lsusb  
    Bus 002 Device 003: ID 0fe9:9010 DVICO  
    
  3. Rendi eseguibile il nostro programma compilato:

    $ chmod +x usbreset
    
  4. Eseguire il programma con privilegio sudo; effettuare la sostituzione necessaria per <Bus>e <Device>id come trovato eseguendo il lsusbcomando:

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

Fonte del programma precedente: http://marc.info/?l=linux-usb&m=121459435621262&w=2


3
Funziona con Ubuntu 13.10. L'ID dispositivo può variare. Per ottenerlo per il mouse ho racchiuso il codice sopra in alcuni comandi della shellecho $(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
knb

1
il mio disco esterno sembra non essere rilevabile (devo ricollegare il cavo USB); è un usb2.0 collegato su una porta PC desktop usb3.0; quando eseguo usbreset /dev/bus/usb/011/001che è uno dei 2 hub root USB 3.0 su lsusb, si verifica un errore: "Errore in ioctl: è una directory", qualche ideia? Ho provato su entrambi gli hub USB 3.0
Aquarius Power il

1
Se qualcuno che legge questo ha un blocco del mouse (usb) dopo aver effettuato l'accesso su Ubuntu 16.04 (con dmesg riempito da "input irq status -75"), posso confermare che questa è l'unica soluzione che ha funzionato per me. Grazie
Agustin Baez,

1
@Acquario, ottengo anche lo stesso errore "Errore in ioctl: è una directory". È stato risolto?
riscatto

1
Vedi la mia risposta qui askubuntu.com/a/988297/558070 che utilizza lo stesso metodo di ripristino di questa risposta ma consente anche un elenco semplificato e la ricerca di dispositivi.
mcarans,

58

Non mi sono mai trovato nelle tue circostanze specifiche prima, quindi non sono sicuro che farà abbastanza, ma il modo più semplice che ho trovato per ripristinare un dispositivo USB è questo comando: (Non sono necessarie app esterne)

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"

È quello vero che uso per ripristinare il mio Kinect poiché libfreenect sembra non avere API per rimetterlo in sospensione. È sulla mia scatola di Gentoo, ma il kernel dovrebbe essere abbastanza nuovo da usare la stessa struttura di percorso per sysfs.

Ovviamente il tuo non lo sarebbe, 1-4.6ma puoi estrarre quel percorso del dispositivo dal log del kernel ( dmesg) oppure puoi usare qualcosa di simile lsusbper ottenere il fornitore e gli ID del prodotto e quindi utilizzare un comando rapido come questo per elencare come i percorsi si collegano a un fornitore diverso / coppie ID prodotto:

for X in /sys/bus/usb/devices/*; do 
    echo "$X"
    cat "$X/idVendor" 2>/dev/null 
    cat "$X/idProduct" 2>/dev/null
    echo
done

sh: 1: impossibile creare /sys/bus/usb/devices/1-3.1:1.0/authorized: Directory inesistente
Nicolas Marchildon

Sembra che abbiano cambiato il layout del filesystem usbfs. Proverò a capire quale sia il nuovo modo di fare le cose su Ubuntu una volta che non ho sonno.
ssokolow,

9
Grazie hai funzionato alla grande! Forse dovresti anche menzionare di eseguire uno echo 1 > /sys/bus/usb/devices/whatever/authorizedscript all'interno per riattivare il dispositivo non appena è stato disabilitato. L'ho fatto sia con il mouse che con la tastiera USB e ho finito con un sistema completamente sordo :)
Avio,

1
È estremamente strano se reimposta automaticamente il valore su 1 poiché impostarlo su 0 indica al sistema che non si desidera che il dispositivo sia "autorizzato" e quindi inaccessibile.
Tim Tisdall,

2
Una nota per chiunque tenti di passare | sudo tee ...all'approccio alle /sysscritture privilegiate : ciò si interrompe gravemente se non si dispone già delle credenziali sudo memorizzate nella cache. sudo sh -c "..."funziona come previsto quando sudo deve richiedere una password.
ssokolow,

51

Ciò ripristinerà tutte le porte USB1 / 2/3 collegate [1]:

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

Credo che questo risolverà il tuo problema. Se non si desidera ripristinare tutti gli endpoint USB, è possibile utilizzare l'ID dispositivo appropriato da/sys/bus/pci/drivers/ehci_hcd


Note: [1]: i *hci_hcddriver del kernel in genere controllano le porte USB. ohci_hcde uhci_hcdsono per le porte USB 1.1, ehci_hcdper le porte USB2 e xhci_hcdper le porte USB3. (vedi https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire) )


credi che possa funzionare per riattivare una memoria USB ?
Aquarius Power il

2
Anche se ho ricevuto il seguente messaggio: ls: cannot access /sys/bus/pci/drivers/ehci_hcd/: No such file or directoryquesto ha risolto il problema, il mouse ha iniziato a funzionare immediatamente. +1
Attila Fulop,

2
@Otheus OHCI e UHCI sono gli standard host USB 1.1, EHCI è lo standard host USB 2.0 e XHCI è lo standard host USB 3.0.
ssokolow,

2
Questa è una bella soluzione. Tuttavia, su alcuni kernel più recenti e le altre distribuzioni * nix, troverete che è necessario sostituire *hci_hcdcon *hci-pci, come il conducente hci_hcd è già compilato nel kernel.
not2qubit

1
Su un Banana Pi, a quanto pare non esiste un bus PCI, ho dovuto usare quanto segue:for i in /sys/bus/usb/drivers/*/*:*; do
Martin Hansen,

10

Avevo bisogno di automatizzare questo in uno script Python, quindi ho adattato la risposta estremamente utile di LiLo a quanto segue:

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

Nel mio caso era il driver cp210x (che potrei dire da lsmod | grep usbserial), quindi è possibile salvare lo snippet sopra come reset_usb.py e quindi fare questo:

sudo python reset_usb.py cp210x

Questo potrebbe essere utile anche se non hai già configurato il compilatore ac sul tuo sistema, ma hai Python.


ha funzionato per me su un Raspberry
webo80 il

1
Ancora qualche parola sulla tua soluzione, per favore. Ad esempio, qualcosa sulla costante USBDEVFS_RESET. È sempre lo stesso per tutti i sistemi?
not2qubit,

@ not2qubit USBDEVFS_RESETè lo stesso per tutti i sistemi. Per MIPS è 536892692.
yegorich,

Le versioni più recenti di lsusb sembrano aver bisogno -tdell'argomento (modalità albero) per mostrare le informazioni sul driver che questo script si aspetta, ma lo script ha bisogno di alcuni aggiornamenti per analizzare le diverse linee di output che genera
Ghepardo

Vedi la mia risposta qui askubuntu.com/a/988297/558070 per una versione molto migliorata di questo script.
mcarans,

8

Ho creato uno script Python che semplifica l'intero processo in base alle risposte qui.

Salvare lo script seguente come reset_usb.py o clonare questo repository .

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

script:

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

questa è la migliore risposta a questa domanda.
Kapad,

4

Poiché il caso speciale della domanda è un problema di comunicazione di gphoto2 con una fotocamera su USB, in gphoto2 è disponibile un'opzione per ripristinare la connessione USB:

gphoto2 --reset

Forse questa opzione non esisteva nel 2010 quando è stata posta la domanda.


3

Il modo più rapido per ripristinare sarà ripristinare il controller USB stesso. In questo modo imponerai a udev di annullare la registrazione del dispositivo al momento della disconnessione e il registro tornerà dopo averlo abilitato.

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

Questo dovrebbe funzionare per la maggior parte dell'ambiente PC. Tuttavia, se stai utilizzando hardware personalizzato, puoi semplicemente scorrere i nomi dei dispositivi. Con questo metodo non è necessario scoprire il nome del dispositivo tramite lsusb. Puoi anche incorporare in uno script automatizzato.


1
È necessario eseguire questi comandi come root / sudo e non funzionerà su tutti i sistemi (su alcuni, è necessario sostituirli ehci_hcdcon ehci-pci. Ulteriori informazioni su questa soluzione (forse da dove proviene?): Davidjb.com/blog / 2012/06 /…
Lambart,

3

Sto usando una specie di mazza ricaricando i moduli. Questo è il mio 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

E questo è il mio file di servizio systemd /usr/lib/systemd/system/usbreset.service che esegue usb_reset.sh dopo l'avvio del mio gestore di visualizzazione:

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

[Service]
Type=oneshot
ExecStart=/path/to/usb_reset.sh

Utilizzando l'opzione listpci del mio script qui: askubuntu.com/a/988297/558070 aiuterà a identificare quale modulo USB ricaricare (es. Xhci_pci, ehci_pci).
mcarans,

2
Sfortunatamente sul mio sistema questi moduli del kernel non sono separati dal kernel, quindi non funzionerà:rmmod: ERROR: Module xhci_pci is builtin.
unfa,

3

Ho creato uno script Python che ripristinerà un particolare dispositivo USB in base al numero del dispositivo. Puoi trovare il numero del dispositivo dal comando lsusb.

per esempio:

$ lsusb

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

In questa stringa 004 è il numero del 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()

Mi piace questa soluzione! Ho apportato alcune modifiche alla sceneggiatura per i miei gusti: gist.github.com/willstott101/7a455817ec6f4b8d89571ce72bdfd34a
Will S

2

Ecco uno script che reimposterà solo un ID prodotto / fornitore corrispondente.

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

1
Ho trovato utile la tua sceneggiatura. Cosa devo fare se il $DIRdispositivo scompare e il dispositivo non è visibile?
Eugen Konkov,

1

Qualcuno ha ordinato un martello? Questo è messo insieme da varie altre risposte qui.

#!/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, hai scoperto che la non separazione è davvero necessaria o è qui solo per essere al sicuro?
ndemou,

Questo è un martello, probabilmente fa molte cose inutili
Mark K Cowan,

@MarkKCowan, come lo usi? Quali sono gli argomenti di comando necessari / previsti?
not2qubit,

1
@ not2qubit: nessun argomento della riga di comando richiesto. Il $@proxy in sudo è solo una forza di habbit, avendo previene i bug se in seguito decido di aggiungere argomenti (e dimentico di aggiornare il proxy sudo).
Mark K Cowan,

1
@MarkKCowan Doh! Scusa amico! Oh si della maledizione! Non dovrei commentare questo sito mentre ho sonno. Upvoted!
not2qubit,

1

A volte voglio eseguire questa operazione su un particolare dispositivo, come identificato da VID (ID fornitore) e PID (ID prodotto). Questo è uno script che ho trovato utile a questo scopo, che utilizza la libreria nifty libusb.

Prima corsa:

sudo apt-get install libusb-dev

Quindi, resetDeviceConnection di questo file c ++ dovrebbe eseguire questa attività, di ripristinare una connessione del dispositivo identificata da vid e 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;
}

(rubato dal mio catalogo TIL personale: https://github.com/Marviel/TIL/blob/master/unix_tools/Reset_specific_USB_Device.md )


3
Per favore, puoi mostrare come viene eseguito questo script .
George Udosen,

Certo, fammi aggiornare.
Marviel,

1
@Marviel, stiamo ancora aspettando un aggiornamento ...
not2qubit,

ha bisogno di essere votato come inutile
Eugen Konkov il

1

ho realizzato un semplice script bash per ripristinare particolari dispositivi USB.

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

0

Forse funziona anche per una macchina fotografica:

In seguito ho rianimato un USB 3.0HDD affamato su un 3.4.42(kernel.org) Linux dalla mia parte. dmesgdetto che stava scadendo i comandi dopo 360 secondi (scusate, non riesco a copiare il syslog qui, non le reti connesse) e l'unità si è bloccata completamente. I processi di accesso al dispositivo sono stati bloccati nel kernel, non verificabili. NFSappeso, ZFSappeso, ddappeso.

Dopo aver fatto questo, tutto ha funzionato di nuovo. dmesgdetto solo una riga sul USBdispositivo trovato.

Non ho davvero idea di cosa segue in dettaglio. Ma ha funzionato.

Il seguente esempio di output proviene da Debian Squeeze con 2.6.32-5-686kernel, quindi penso che funzioni per 2.6 e versioni successive:

$ 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

Se questo non funziona, forse qualcun altro può capire come inviare un ripristino reale a un dispositivo.


0

Prova questo, è un software unplug (Espelli).

A volte non funziona semplicemente sbloccare il dispositivo per alcuni dispositivi.

Esempio:

Voglio rimuovere o espellere il mio "Genius NetScroll 120".

Quindi prima controllo il mio dispositivo USB collegato

$ 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, ho trovato il mio mouse, ha un bus 002, dispositivo 009, idVendor 0458 e idProduct 003a, quindi queste sono le informazioni di un dispositivo di riferimento sul mouse.

Questo è importante, il numero del bus è il percorso del nome iniziale per il dispositivo e controllerò l'ID del prodotto e il fornitore per garantire che il dispositivo corretto da rimuovere.

$ 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/

Prestare attenzione alle cartelle, controllare all'inizio con la cartella numero 2, verificherò questa perché il mio bus è 002 e uno per uno ho controllato ogni cartella contenente l'idVendor e l'idProduct corretti sulle informazioni del mio mouse.

In questo caso, recupererò le informazioni con questo comando:

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

Ok, il percorso /sys/bus/usb/drivers/usb/2-1.3/ corrisponde al mio mouse informativo! XDDD.

È tempo di rimuovere il dispositivo!

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

Ricollega il dispositivo USB ed è di nuovo funzionante!


10
Cosa succede se non riesci a ricollegarlo? (ad esempio è un lettore sdcard interno)
aleb,

0

Se conosci il nome del tuo dispositivo, questo script Python funzionerà:

#!/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()
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.