Как перезагрузить USB-устройство из командной строки?

Можно ли сбросить подключение USB-устройства без физического отключения / подключения от ПК?

В частности, мое устройство представляет собой цифровую камеру. Я использую gphoto2, но в последнее время я получаю «ошибки чтения устройства», поэтому я хотел бы попытаться выполнить программный сброс соединения.

Насколько я могу судить, для камеры не загружаются модули ядра. Единственное, что выглядит связанным, это usbhid.

161
задан 17.10.2019, 04:27

15 ответов

Сохранить следующее как 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;
}

Выполнить следующие команды в терминале:

  1. Скомпилировать программу:

    $ cc usbreset.c -o usbreset
    
    [ 1110]
  2. Получите идентификатор шины и устройства USB-устройства, которое вы хотите сбросить:

    $ lsusb  
    Bus 002 Device 003: ID 0fe9:9010 DVICO  
    
  3. Сделайте нашу скомпилированную программу исполняемой:

    $ chmod +x usbreset
    
  4. Запустить программу с привилегией sudo; выполните необходимые замены для идентификаторов <Bus> и <Device>, найденных с помощью команды lsusb:

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

Источник вышеуказанной программы: http: //marc.info/?l=linux-usb&m=121459435621262&w=2

114
ответ дан 17.10.2019, 04:35
  • 1
    @ Водолей, я также получаю ту же ошибку "Ошибка в ioctl: каталог". Это решено? – Lightness Races in Orbit 17.10.2019, 04:36
  • 2
    Если кто-нибудь, читающий это, зависнет (usb) мыши после входа в Ubuntu 16.04 (с dmesg, заполненным «input irq status -75»), я могу подтвердить, что это единственное решение, которое работало для меня. Спасибо – Sebastian Mach 17.10.2019, 04:36
  • 3
    мой внешний диск, кажется, не обнаруживается (мне нужно повторно подключить USB-кабель); это usb2.0, подключенный к порту настольного ПК usb3.0; когда я запускаю usbreset /dev/bus/usb/011/001, который является одним из корневых концентраторов 2 usb 3.0 в lsusb, он выдает ошибку: «Ошибка в ioctl: каталог», какая-то идея? Я пробовал на обоих usb 3.0 хабах – ctor 17.10.2019, 04:36
  • 4
    Это работает с Ubuntu 13.10. Идентификатор устройства может отличаться. Чтобы получить его для мыши, я обернул код выше в несколько команд оболочки 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 – Jerry Coffin 17.10.2019, 04:37
  • 5
    Смотрите мой ответ здесь askubuntu.com/a/988297/558070 , который использует тот же метод сброса, что и этот ответ, но также позволяет упростить перечисление и поиск устройств. – emsr 17.10.2019, 04:37

Я раньше не сталкивался с вашими конкретными обстоятельствами, поэтому не уверен, что этого будет достаточно, но я нашел самый простой способ перезагрузить USB-устройство: (Нет необходимости во внешних приложениях). )

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"

Это именно то, что я использую для сброса моего Kinect, поскольку у libfreenect, похоже, нет API для возврата его в спящий режим. Он у меня в Gentoo, но ядро ​​должно быть достаточно новым, чтобы использовать ту же структуру пути для sysfs.

Ваш, очевидно, не будет 1-4.6, но вы можете либо извлечь этот путь устройства из журнала ядра (dmesg), либо использовать что-то вроде lsusb, чтобы получить идентификаторы поставщика и продукта, а затем использовать быстрый команда, подобная этой, чтобы показать, как пути связаны с различными парами поставщиков / идентификаторов продуктов:

for X in /sys/bus/usb/devices/*; do 
    echo "$X"
    cat "$X/idVendor" 2>/dev/null 
    cat "$X/idProduct" 2>/dev/null
    echo
done
57
ответ дан 17.10.2019, 04:27
  • 1
    Спасибо, отлично поработали! Возможно, вам также следует упомянуть выполнение echo 1 > /sys/bus/usb/devices/whatever/authorized внутри скрипта для повторного включения устройства, как только оно было отключено. Я сделал это и на моей мыши, и на клавиатуре USB, и у меня получилась совершенно глухая система :) – Cassio Neri 17.10.2019, 04:28
  • 2
    sh: 1: невозможно создать /sys/bus/usb/devices/1-3.1:1.0/authorized: каталог не существует – v.oddou 17.10.2019, 04:28
  • 3
    В заметке для тех, кто пытается перейти на подход | sudo tee ... к привилегированным /sys, написано: «Это плохо, если у вас еще нет кэшированных учетных данных sudo. sudo sh -c "..." работает, как и ожидалось, когда sudo нужно запросить пароль. – assylias 17.10.2019, 04:28
  • 4
    Чрезвычайно странно, если он автоматически сбрасывает значение 1, так как установка его в 0 говорит системе, что вы не хотите, чтобы устройство было «авторизовано» и поэтому недоступен. – assylias 17.10.2019, 04:29
  • 5
    Похоже, они изменили расположение файловой системы usbfs. Я постараюсь выяснить, что нового происходит в Ubuntu, когда я не буду таким сонным. – Sebastian Mach 17.10.2019, 04:30

Это сбросит все подключенные USB1 / 2/3 порты [1]:

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

Я думаю, это решит вашу проблему. Если вы не хотите сбрасывать все конечные точки USB, вы можете использовать соответствующий идентификатор устройства из /sys/bus/pci/drivers/ehci_hcd


Примечания: [1]: драйверы ядра *hci_hcd обычно управляют портами USB. ohci_hcd и uhci_hcd для портов USB1.1, ehci_hcd для портов USB2 и xhci_hcd для портов USB3. (см. https://en.wikipedia.org/wiki/Host_controller_interface_ (USB, _Firewire) )

49
ответ дан 17.10.2019, 04:28
  • 1
    @Otheus OHCI и UHCI - это стандарты хоста USB 1.1, EHCI - стандарт хоста USB 2.0, а XHCI - стандарт хоста USB 3.0. – user482745 17.10.2019, 04:28
  • 2
    Хотя я получил следующее сообщение: ls: cannot access /sys/bus/pci/drivers/ehci_hcd/: No such file or directory это решило проблему, мышь сразу же заработала. +1 – jacobhyphenated 17.10.2019, 04:29
  • 3
    Верите ли вы, что это может сработать , чтобы разбудить USB-накопитель ? – Andy Prowl 17.10.2019, 04:29
  • 4
    На Banana Pi, по-видимому, нет шины PCI, мне пришлось использовать следующее: for i in /sys/bus/usb/drivers/*/*:*; do – mvg 17.10.2019, 04:30
  • 5
    Это прекрасное решение. Однако в некоторых более поздних версиях Kernel и других * nix вы обнаружите, что вам необходимо заменить *hci_hcd на *hci-pci, поскольку драйвер hci_hcd уже скомпилирован в ядро. – Pavel 17.10.2019, 04:30

Мне нужно было автоматизировать это в скрипте Python, поэтому я адаптировал чрезвычайно полезный ответ LiLo к следующему:

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

В моем случае это был драйвер cp210x (о котором я мог сказать из lsmod | grep usbserial ), так что вы можете сохранить приведенный выше фрагмент как reset_usb.py и затем сделать это:

sudo python reset_usb.py cp210x

Это также может быть полезно, если у вас еще нет настройки компилятора ac в вашей системе, но у вас есть Python.

10
ответ дан 17.10.2019, 04:29
  • 1
    Еще несколько слов о вашем решении, пожалуйста. Например, кое-что о константе USBDEVFS_RESET. Это всегда одинаково для всех систем? – abagh0703 17.10.2019, 04:29
  • 2
    @ not2qubit USBDEVFS_RESET одинаково для всех систем. Для MIPS это 536892692. – Darren Bartrup-Cook 17.10.2019, 04:29
  • 3
    Более новые версии lsusb, похоже, нуждаются в аргументе -t (древовидный режим), чтобы показать информацию о драйвере, которую ожидает этот сценарий, но затем сценарию требуются некоторые обновления для анализа различных строк вывода, которые он генерирует. – Patch92 17.10.2019, 04:30
  • 4
    Смотрите мой ответ здесь askubuntu.com/a/988297/558070 , где приведена значительно улучшенная версия этого скрипта. – Amit Wagner 17.10.2019, 04:30
  • 5
    работал для меня на малине – saltthehash 17.10.2019, 04:30

Я использую кувалду, перезагружая модули. Это мой сценарий 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

А это мой файл службы systemd /usr/lib/systemd/system/usbreset.service, который запускает usb_reset.sh после запуска моего менеджера diplay:: 113 ]

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

[Service]
Type=oneshot
ExecStart=/path/to/usb_reset.sh
3
ответ дан 17.10.2019, 04:29
  • 1
    К сожалению, в моей системе эти модули ядра не являются отдельными от ядра, поэтому это не будет работать: rmmod: ERROR: Module xhci_pci is builtin. – Martin Ullrich 17.10.2019, 04:30
  • 2
    Использование опции listpci моего скрипта здесь: askubuntu.com/a/988297/558070 поможет определить, какой USB-модуль необходимо перезагрузить (например, xhci_pci, ehci_pci). – LP13 17.10.2019, 04:30

Поскольку частным случаем вопроса является проблема связи gphoto2 с камерой по USB, в gphoto2 есть возможность сбросить USB-соединение:

gphoto2 --reset

Возможно, этой опции не существовало в 2010 году, когда был задан вопрос.

4
ответ дан 17.10.2019, 04:30

Самый быстрый способ сброса - сброс самого контроллера USB. Это заставит udev отменить регистрацию устройства при отключении, и регистрация вернется после того, как вы его включите.

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

Это должно работать для большинства ПК. Однако, если вы используете какое-то нестандартное оборудование, вы можете просто перебирать имена устройств. С помощью этого метода вам не нужно узнавать имя устройства по lsusb. Вы также можете включить в автоматизированный скрипт.

3
ответ дан 17.10.2019, 04:31
  • 1
    Вам нужно запускать эти команды как root / sudo, и это не сработает во всех системах (в некоторых вам нужно заменить ehci_hcd на ehci-pci. Подробнее об этом решении (возможно, откуда оно?) : davidjb.com/blog/2012/06/… – Andy Prowl 17.10.2019, 04:31

Я сделал скрипт Python, который будет сбрасывать определенное USB-устройство на основе номера устройства. Вы можете узнать номер устройства из команды lsusb.

например:

$ lsusb

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

В этой строке 004 указан номер устройства

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()
3
ответ дан 17.10.2019, 04:32

Вот скрипт, который будет сбрасывать только соответствующий идентификатор продукта / поставщика.

#!/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
2
ответ дан 17.10.2019, 04:32
  • 1
    Я нашел ваш сценарий полезным. Но что мне делать, если $DIR исчезает, а устройство не видно? – Iqra. 17.10.2019, 04:33

Кто-нибудь заказывал кувалду? Это воедино из различных других ответов здесь.

#!/bin/bash

# Root required
if (( UID )); then
        exec sudo "[110]" "$@"
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
1
ответ дан 17.10.2019, 04:33

Иногда я хочу выполнить эту операцию на определенном устройстве, как указано VID (идентификатор поставщика) и PID (идентификатор продукта). Это скрипт, который я нашел полезным для этой цели, который использует изящную библиотеку libusb.

Первый запуск:

sudo apt-get install libusb-dev

Затем resetDeviceConnection этого файла c ++ должен выполнить эту задачу, сбросить подключение устройства, как указано в vid и 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;
}

(украдено из моего личного каталога TIL: https://github.com/Marviel/TIL/blob/master/unix_tools/Reset_specific_USB_Device.md )

1
ответ дан 17.10.2019, 04:33
  • 1
    нужно понизить как бесполезный – Constantino Tsarouhas 17.10.2019, 04:33
  • 2
    @Marviel, мы все еще ждем обновления ... – Freeman 17.10.2019, 04:34
  • 3
    Подскажите, пожалуйста, как работает этот скрипт . – jeffc666 17.10.2019, 04:34
  • 4
    Конечно, позвольте мне обновить. –  17.10.2019, 04:34

Возможно, это работает и для камеры:

После того, как я восстановил голодный USB 3.0 HDD на 3.4.42 (kernel.org) Linux на моей стороне. dmesg сказал, что это было время ожидания команд после 360 секунд (извините, я не могу скопировать системный журнал здесь, не подключенные сети), и диск завис полностью. Процессы доступа к устройству были заблокированы в ядре и не могут быть уничтожены. NFS повешен, ZFS повешен, dd повешен.

1112 После этого все снова заработало. dmesg рассказал только одну строчку об обнаруженном устройстве USB.

Я действительно понятия не имею, что следует делать в деталях. Но это сработало.

Следующий пример выходных данных взят из Debian Squeeze с ядром 2.6.32-5-686, поэтому я думаю, что он работает для 2.6 и выше:

$ 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

Если это не работает, возможно, кто-то еще может выяснить, как отправить реальный сброс на устройство.

0
ответ дан 17.10.2019, 04:34

Если вы знаете имя вашего устройства, этот скрипт Python будет работать:

#!/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()
0
ответ дан 17.10.2019, 04:34

я сделал простой bash-скрипт для сброса определенного 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
1
ответ дан 17.10.2019, 04:35

Я создал скрипт Python, который упрощает весь процесс на основе ответов здесь.

Сохраните приведенный ниже скрипт как reset_usb.py или клонируйте этого репо .

Использование:

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

Сценарий:

#!/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)
7
ответ дан 17.10.2019, 04:36
  • 1
    это лучший ответ на этот вопрос. – Jerry Coffin 17.10.2019, 04:36

Теги

Похожие вопросы