Como você redefine um dispositivo USB na linha de comando?


164

É possível redefinir a conexão de um dispositivo USB, sem desconectar / conectar fisicamente do PC?

Especificamente, meu dispositivo é uma câmera digital. Estou usando gphoto2, mas ultimamente recebo "erros de leitura do dispositivo", então gostaria de tentar fazer uma redefinição de software da conexão.

Pelo que sei, não há módulos de kernel sendo carregados para a câmera. O único que parece relacionado é usbhid.


Qual versão do Ubuntu você está usando?
Utilizador

Eu tentei ambas as soluções de Li Lo e ssokolow, tudo o que recebo é permissão negada, nomatter se eu usar o código usbreset ou a linha de comando "echo 0> ..." eu uso sudo, também meus dispositivos USB são de propriedade de raiz, mas eu pode usá-los sem administração de direitos (câmeras ..)

1
Se você estiver recebendo erros de leitura, poderá ter alguma corrupção de dados. Se sua câmera usa um cartão de memória externo (como o MicroSD), pode ser aconselhável conectá-lo ao computador e executar o fsck.
TSJNachos117

Respostas:


118

Salve o seguinte 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;
}

Execute os seguintes comandos no terminal:

  1. Compile o programa:

    $ cc usbreset.c -o usbreset
    
  2. Obtenha o ID do barramento e do dispositivo USB que você deseja redefinir:

    $ lsusb  
    Bus 002 Device 003: ID 0fe9:9010 DVICO  
    
  3. Torne nosso programa compilado executável:

    $ chmod +x usbreset
    
  4. Execute o programa com privilégio sudo; faça a substituição necessária <Bus>e os <Device>IDs conforme encontrado executando o lsusbcomando:

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

Fonte do programa acima: http://marc.info/?l=linux-usb&m=121459435621262&w=2


3
Isso funciona com o ubuntu 13.10. O ID do dispositivo pode variar. Para obtê-lo para o mouse eu ter embrulhado acima código em alguns comandos 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
minha unidade externa parece se tornar indetectável (eu tenho que reconectar com força o cabo usb); é um usb2.0 conectado a uma porta de PC desktop usb3.0; quando executo usbreset /dev/bus/usb/011/001esse é um dos 2 hubs raiz do usb 3.0 lsusb, ele erro: "Erro no ioctl: is a directory", alguma ideia? Eu tentei em ambos os hubs usb 3.0
Aquarius Power

1
Se alguém lendo isso tiver um mouse (usb) congelado após o login no Ubuntu 16.04 (com o dmesg preenchido por "input irq status -75"), posso confirmar que esta é a única solução que funcionou para mim. Obrigado
Agustin Baez

1
@ Aquarius, também recebo o mesmo erro "Erro no ioctl: é um diretório". Está resolvido?
ransh

1
Veja minha resposta aqui askubuntu.com/a/988297/558070 que usa o mesmo método de redefinição que esta resposta, mas também permite a listagem simplificada e a pesquisa de dispositivos.
precisa saber é o seguinte

58

Eu não me encontrei em suas circunstâncias específicas antes, então não tenho certeza se isso fará o suficiente, mas a maneira mais simples que encontrei para redefinir um dispositivo USB é este comando: (Nenhum aplicativo externo é necessário)

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"

Essa é a atual que eu uso para redefinir meu Kinect, pois a libfreenect parece não ter API para colocá-lo de volta no modo de suspensão. Está na minha caixa do Gentoo, mas o kernel deve ser novo o suficiente para usar a mesma estrutura de caminho para o sysfs.

O seu obviamente não seria, 1-4.6mas você pode extrair esse caminho do dispositivo do log do kernel ( dmesg) ou pode usar algo como lsusbpara obter o ID do fornecedor e do produto e, em seguida, usar um comando rápido como este para listar como os caminhos se relacionam com o fornecedor diferente / pares de ID do produto:

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: não é possível criar /sys/bus/usb/devices/1-3.1:1.0/autorizado: diretório inexistente
Nicolas Marchildon

Parece que eles mudaram o layout do sistema de arquivos usbfs. Vou tentar descobrir qual é a nova maneira de fazer as coisas no Ubuntu quando não estiver com tanto sono.
Ssokolow #

9
Obrigado trabalhou muito bem! Talvez você também deva mencionar a execução de um echo 1 > /sys/bus/usb/devices/whatever/authorizedscript interno para reativar o dispositivo assim que ele for desativado. Eu fiz isso em ambos meu mouse e teclado USB e acabei com um sistema completamente surdo :)
Avio

1
É extremamente estranho se redefinir automaticamente o valor para 1, pois defini-lo como 0 indica ao sistema que você não deseja que o dispositivo seja "autorizado" e, portanto, inacessível.
precisa

2
Uma observação para qualquer pessoa que tentar mudar para a | sudo tee ...abordagem de /sysgravações privilegiadas : Isso falha muito se você ainda não tiver suas credenciais de sudo em cache. sudo sh -c "..."funciona como esperado quando o sudo precisa solicitar uma senha.
precisa saber é o seguinte

51

Isso redefinirá todas as portas USB1 / 2/3 conectadas [1]:

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

Acredito que isso resolverá seu problema. Se você não deseja redefinir todos os pontos de extremidade USB, pode usar o ID do dispositivo apropriado em/sys/bus/pci/drivers/ehci_hcd


Notas: [1]: os *hci_hcddrivers do kernel normalmente controlam as portas USB. ohci_hcde uhci_hcdsão para portas USB1.1, ehci_hcdsão para portas USB2 e xhci_hcdsão para portas USB3. (consulte https://en.wikipedia.org/wiki/Host_controller_interface_(USB,_Firewire) )


você acredita que pode funcionar para ativar um armazenamento USB ?
Poder de Aquário

2
Embora tenha recebido a seguinte mensagem: ls: cannot access /sys/bus/pci/drivers/ehci_hcd/: No such file or directoryisso resolveu o problema, o mouse começou a funcionar imediatamente. +1
Attila Fulop 10/10

2
@Otheus OHCI e UHCI são os padrões de host USB 1.1, EHCI é o padrão de host USB 2.0 e XHCI é o padrão de host USB 3.0.
Ssokolow

2
Esta é uma solução bonita. No entanto, em alguns kernels, e outros * nix distribuições, você vai achar que você precisa para substituir *hci_hcdcom *hci-pci, como o motorista hci_hcd já está compilado no kernel.
not2qubit #

1
Em um Banana Pi, aparentemente não há um barramento PCI, eu tive que usar o seguinte:for i in /sys/bus/usb/drivers/*/*:*; do
Martin Hansen

10

Eu precisava automatizar isso em um script python, então adaptei a resposta extremamente útil do LiLo ao seguinte:

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

No meu caso, era o driver cp210x (do qual eu poderia dizer lsmod | grep usbserial), para que você pudesse salvar o trecho acima como reset_usb.py e faça o seguinte:

sudo python reset_usb.py cp210x

Isso também pode ser útil se você ainda não possui a configuração do compilador de corrente alternada no sistema, mas possui python.


trabalhou para mim em uma framboesa
webo80

1
Mais algumas palavras sobre sua solução, por favor. Por exemplo, algo sobre a constante USBDEVFS_RESET. É sempre o mesmo para todos os sistemas?
Not2qubit

@ not2qubit USBDEVFS_RESETé o mesmo para todos os sistemas. Para MIPS é 536892692.
yegorich

Versões mais recentes do lsusb parecem precisar o -t(modo de árvore) argumento para mostrar a informação driver que este script está esperando, mas o script, em seguida, precisa de algumas atualizações para analisar as diferentes linhas de saída deste gera
Cheetah

Veja minha resposta aqui, askubuntu.com/a/988297/558070, para obter uma versão muito melhorada desse script.
Mcarans

8

Eu criei um script Python que simplifica todo o processo com base nas respostas aqui.

Salve o script abaixo como reset_usb.py ou clone este repositório .

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

Roteiro:

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

esta é a melhor resposta para esta pergunta.
kapad 5/04

4

Como o caso especial da questão é um problema de comunicação do gphoto2 com uma câmera USB, existe uma opção no gphoto2 para redefinir sua conexão USB:

gphoto2 --reset

Talvez essa opção não existisse em 2010 quando a pergunta foi feita.


3

A maneira mais rápida de redefinir será redefinir o próprio controlador USB. Isso fará com que o udev cancele o registro do dispositivo na desconexão e o registro retornará assim que você o ativar.

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

Isso deve funcionar para a maioria dos ambientes de PC. No entanto, se você estiver usando algum hardware personalizado, pode simplesmente percorrer os nomes dos dispositivos. Com esse método, você não precisa descobrir o nome do dispositivo por lsusb. Você também pode incorporar um script automatizado.


1
Você precisa executar esses comandos como root / sudo, e ele não funcionará em todos os sistemas (em alguns, você precisará substituí-lo ehci_hcdpor ehci-pci. Mais informações sobre esta solução (talvez de onde veio?): Davidjb.com/blog /
2012/06

3

Estou usando uma espécie de marreta recarregando os módulos. Este é o meu 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 este é o meu arquivo de serviço systemd /usr/lib/systemd/system/usbreset.service que executa usb_reset.sh após o início do meu gerenciador de diplay:

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

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

Usando a opção listpci do meu script aqui: askubuntu.com/a/988297/558070 ajudará a identificar qual módulo USB recarregar (por exemplo, xhci_pci, ehci_pci).
precisa saber é

2
Infelizmente no meu sistema destes módulos do kernel não são separados formam o kernel, para que isso não vai funcionar:rmmod: ERROR: Module xhci_pci is builtin.
UNFA

3

Eu criei um script python que redefinirá um dispositivo USB específico com base no número do dispositivo. Você pode descobrir o número do dispositivo no comando lsusb.

por exemplo:

$ lsusb

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

Nesta cadeia, 004 é o número do 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()

Eu gosto desta solução! Eu fiz alguns ajustes no script para meu próprio gosto: gist.github.com/willstott101/7a455817ec6f4b8d89571ce72bdfd34a
Will S

2

Aqui está um script que redefinirá apenas um ID de produto / fornecedor correspondente.

#!/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
Achei que seu script é útil. Mas o que devo fazer se o $DIRdispositivo desaparecer e não estiver visível?
9788 Eugen Konkov #

1

Alguém pediu uma marreta? Isso é reunido a partir de várias outras respostas aqui.

#!/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, você achou que a desvinculação é realmente necessária ou está aqui apenas para estar do lado seguro?
Ndemou

Esta é uma marreta, ele provavelmente faz um monte de coisas desnecessárias
Mark K Cowan

@ MarkKCowan, como você o usa? Quais são os argumentos de comando necessários / esperados?
Not2qubit

1
@ not2qubit: Não são necessários argumentos de linha de comando. O $@proxy no sudo é apenas uma força do habbit, impedindo erros se eu decidir mais tarde adicionar argumentos (e esquecer de atualizar o proxy do sudo).
Mark K Cowan

1
@MarkKCowan Doh! Desculpe amigo! Oh sim de maldição! Não devo comentar neste site enquanto estiver com sono. Voto a favor!
not2qubit

1

Às vezes, quero executar esta operação em um dispositivo específico, conforme identificado pelo VID (ID do fornecedor) e PID (ID do produto). Este é um script que considero útil para esse fim, que usa a biblioteca lifaz bacana.

Primeira corrida:

sudo apt-get install libusb-dev

Em seguida, o resetDeviceConnection deste arquivo c ++ deve executar esta tarefa, de redefinir uma conexão de dispositivo conforme identificado por 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;
}

(roubado do meu catálogo pessoal de TIL: https://github.com/Marviel/TIL/blob/master/unix_tools/Reset_specific_USB_Device.md )


3
Você pode mostrar como esse script é executado.
George Udosen

Claro, deixe-me atualizar.
Marviel

1
@Marviel, ainda estamos à espera de uma atualização ...
not2qubit

necessidades downvote tão inútil
Eugen Konkov

1

Eu criei um script bash simples para redefinir um dispositivo USB específico.

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

Talvez isso funcione também para uma câmera:

A seguir, reviveu um USB 3.0HDD faminto em um 3.4.42Linux (kernel.org) do meu lado. dmesgdisse, que estava expirando comandos após 360s (desculpe, não posso copiar o syslog aqui, não redes conectadas) e a unidade travou completamente. Os processos que acessam o dispositivo foram bloqueados no kernel, inutilizáveis. NFSpendurado, ZFSpendurado, ddpendurado.

Depois de fazer isso, tudo funcionou novamente. dmesgcontou apenas uma única linha sobre o USBdispositivo encontrado.

Eu realmente não tenho idéia do que fazer a seguir em detalhes. Mas funcionou.

O exemplo de saída a seguir é do Debian Squeeze com 2.6.32-5-686kernel, então acho que funciona para o 2.6 e acima:

$ 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 isso não funcionar, talvez alguém possa descobrir como enviar uma redefinição real para um dispositivo.


0

Tente isso, é um software desconectado (Ejetar).

Às vezes, não funciona simplesmente para desvincular dispositivo de alguns dispositivos.

Exemplo:

Quero remover ou ejetar meu "Genius NetScroll 120".

Então eu primeiro Verifique meu 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, encontrei meu mouse, ele tem um barramento 002, dispositivo 009, idVendor 0458 e idProduct 003a, portanto, essa é uma informação de dispositivo de referência sobre o mouse.

Isso é importante, o número do barramento é o caminho do nome inicial do dispositivo e vou verificar o ID e o fornecedor do produto para garantir que o dispositivo correto seja removido.

$ 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 atenção nas pastas, verifique o início com a pasta número 2, eu irei verificar essa porque o meu Bus é 002, e uma a uma eu verifiquei cada pasta contendo o idVendor e o idProduct corretos sobre as informações do mouse.

Nesse caso, recuperarei as informações com 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, o caminho /sys/bus/usb/drivers/usb/2-1.3/ corresponde ao meu mouse de informações! XDDD.

É hora de remover o dispositivo!

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

Conecte novamente o dispositivo USB e ele funcionará novamente!


10
E se você não conseguir conectá-lo novamente? (por exemplo, é um leitor sdcard interno)
aleb

0

Se você souber o nome do seu dispositivo, este script 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()
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.