Como reiniciar o USB sem tirar o cabo

Publicado por Fábio Berbert de Paula em 15/08/2013

[ Hits: 16.799 ]

Blog: https://fabio.automatizando.dev

 


Como reiniciar o USB sem tirar o cabo



Nesta dica veremos como reiniciar um dispositivo USB sem a necessidade de desconectar/conectar o cabo do PC. Isso pode ser bem útil em casos onde o dispositivo plugado apresenta instabilidade. Li relatos de que isso ocorre em algumas câmeras digitais.

No meu caso, estou desenvolvendo scripts para teste de UI em dispositivos Android e após algumas horas conectado ao PC, meu celular começava a apresentar comunicação instável com o adb (Android Debugger Bridge). Antes desta solução, minha única saída era desconectar/conectar o cabo, o que inviabilizava a execução do script de forma automática.

Solução 1 - Resetando todos os dispositivos USB

O programa abaixo reinicia todos os dispositivos USB conectados ao PC.

#include <stdio.h>
#include <usb.h>

int main(void)
{
      struct usb_bus *busses;
      usb_init();
      usb_find_busses();
      usb_find_devices();
      busses = usb_get_busses();
      struct usb_bus *bus;
      int c, i, a;
 ;     /* ... */
      for (bus = busses; bus; bus = bus->next) {
        struct usb_device *dev;
        int val;
        usb_dev_handle *junk;
        for (dev = bus->devices; dev; dev = dev->next) {
          char buf[1024];
          junk = usb_open ( dev );
          usb_get_string_simple(junk,2,buf,1023);
          if ( junk == NULL ){
            printf("Can't open %p (%s)\n", dev, buf );
          } else {
            val = usb_reset(junk);
            printf( "reset %p %d (%s)\n", dev, val, buf );
          }
          usb_close(junk);
        }
      }
}

Salve o código acima num arquivo e compile-o. Salvei como usb_reset_all.c:

gcc -o usb_reset_all usb_reset_all.c

Agora basta executar e conferir o resultado nos logs:

./usb_reset_all

$ sudo tail -f /var/log/syslog


Fonte: Resetting the USB Bus under linux - ClearChain

Solução 2 - Resetando apenas um dispositivo

Se você deseja escolher o dispositivo a ser reiniciado, utilize o código a seguir.

#include <stdio.h> #include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>

void main(int argc, char **argv)

{

   const char *filename;

   int fd;

   filename = argv[1];

   fd = open(filename, O_WRONLY);

   ioctl(fd, USBDEVFS_RESET, 0);

   close(fd);

   return;

}

Salve o código acima num arquivo e compile-o. Salvei como usb_reset_one.c:

gcc -o usb_reset_one usb_reset_one.c

Antes de executá-lo devemos identificar o dispositivo a ser reiniciado. No meu caso um celular da Samsung:

lsusb
Bus 001 Device 002: ID 046d:c408 Logitech, Inc. Marble Mouse (4-button)
Bus 001 Device 003: ID 045e:009d Microsoft Corp. Wireless Optical Desktop 3.0
Bus 004 Device 110: ID 04e8:6866 Samsung Electronics Co., Ltd
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Ou seja, dispositivo 110 do barramento 004.

Sendo assim:

./usb_reset_one /dev/bus/usb/004/110

Fonte: How to reset a USB device without unplugging Linux from the command line | Linux world

Fico por aqui. Sei que trata-se de uma necessidade pouco comum, mas espero que ajude quem por ventura venha a precisar.

Outras dicas deste autor

ctorrent - Cliente torrent modo texto

Expressão Regular para Endereço IP

O comando man

Skype Call Recorder - Como gravar áudio de chamadas do Skype

Como desabilitar o protocolo SSL3 no Nginx

Leitura recomendada

Migrando aplicativos C++ do Windows para Linux

Nemiver - Depurador gráfico (GDB) de C/C++

movfuscator - Compilador de uma única instrução Assembly

Compilando em um Cluster Linux

Interface gráfica com C

  

Comentários
[1] Comentário enviado por rahremix em 15/08/2013 - 14:24h

Obrigado!

Vou testar no meu computador, apesar da situação ser um pouco diferente pode ser que me ajude!

[2] Comentário enviado por julio_hoffimann em 15/08/2013 - 17:58h

Ótima dica Fábio.

Abs.

[3] Comentário enviado por danniel-lara em 15/08/2013 - 22:38h

Parabens pela dica

[4] Comentário enviado por kito.eag em 02/09/2017 - 20:47h

Não estava conseguindo compilar o primeiro código.
Só consegui deste jeito:
#include <stdio.h>
#include <usb.h>

int main(void)
{
struct usb_bus *busses;
usb_init();
usb_find_busses();
usb_find_devices();
busses = usb_get_busses();
struct usb_bus *bus;
int c, i, a;
/* ... */
for (bus = busses; bus; bus = bus->next) {
struct usb_device *dev;
int val;
usb_dev_handle *junk;
for (dev = bus->devices; dev; dev = dev->next) {
char buf[1024];
junk = usb_open ( dev );
usb_get_string_simple(junk,2,buf,1023);
if ( junk == NULL ){
printf("Can't open %p (%s)\n", dev, buf );
} else {
val = usb_reset(junk);
printf( "reset %p %d (%s)\n", dev, val, buf );
}
usb_close(junk);
}
}
}


E pra compilar usei o comando:
gcc -o reset_all_usb reset_all_usb.c -lusb




[5] Comentário enviado por jbtozetti em 22/07/2020 - 10:59h

Bom dia

Eu precisaria reiniciar a USB pelo vendor e o ID do dispositivo, tem como?

[6] Comentário enviado por fabio em 22/07/2020 - 11:36h


[5] Comentário enviado por jbtozetti em 22/07/2020 - 10:59h

Bom dia

Eu precisaria reiniciar a USB pelo vendor e o ID do dispositivo, tem como?



Dê um confere nessa dica aqui amigo:

https://www.vivaolinux.com.br/dica/Como-reiniciar-um-dispositivo-USB-sem-desconectar-o-cabo/

[7] Comentário enviado por jbtozetti em 22/07/2020 - 13:34h



oPA!

Eu tinha visto esta dica, porém preciso colocar num script q faça isso em várias maquinas diferentes e à medida q o dispositivo é espetado numa porta USB diferente as informações se alteram e o script não funcioaria

Já o vendor e o product são fixos em todas as máquinas independente de qual porta estão espetados

[ ]'s



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts