ถอดและเชื่อมต่อพอร์ต USB อีกครั้งผ่านทาง cli


18

ฉันมีเมาส์ที่จะหยุดทำงานแบบสุ่ม การแก้ปัญหาเป็นเรื่องง่ายถอดและถอดออก มีวิธีที่ฉันสามารถทำได้ผ่านทางบรรทัดคำสั่งว่า? การทำผ่านบรรทัดคำสั่งมีข้อดีเล็กน้อย

  1. ไม่ทำให้ขั้วต่อหลุดออก
  2. ได้เร็วขึ้น
  3. ช่วยให้ฉันมีปัญหาในการคลานใต้โต๊ะ
  4. สิ่งสำคัญที่สุด: ป้องกันไม่ให้ฉันถอดปลั๊กอย่างอื่นโดยไม่ได้ตั้งใจ

รวมทั้งฉันอยากรู้วิธีการทำเช่นนี้

ระบบปฏิบัติการคือ Debian 8

ขอบคุณ!



บางทีunix.stackexchange.com/a/166601/117599คือสิ่งที่คุณกำลังมองหา
phk

คำตอบ:


13

บันทึกสิ่งต่อไปนี้เป็น 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
    
  2. รับ Bus และ ID อุปกรณ์ของอุปกรณ์ USB ที่คุณต้องการรีเซ็ต:

    lsusb -t 
    
    Bus#  4  
    -Dev#   1 Vendor 0x1d6b Product 0x0001    
    -Dev#   3 Vendor 0x046b Product 0xff10
    
  3. ทำให้โปรแกรมที่คอมไพล์แล้วของเราสามารถทำงานได้:

    chmod +x usbreset
    
  4. ดำเนินการโปรแกรมด้วยsudoสิทธิ์ ทำการทดแทนที่จำเป็นสำหรับ <Bus>และ<Device>รหัสที่พบโดยการเรียกใช้lsusbคำสั่ง:

    sudo ./usbreset /dev/bus/usb/004/003
    
    Resetting USB device /dev/bus/usb/004/003
    
    Reset successful
    

แหล่งที่มาของโปรแกรมข้างต้น: http://marc.info/?l=linux-usb&m=121459435621262&w=2


1
สิ่งนี้เป็นการรีเซ็ตพลังงานบนอุปกรณ์ได้อย่างมีประสิทธิภาพหรือไม่และจะรีเซ็ตอย่างสมบูรณ์โดยไม่ต้องถอดปลั๊กแล้วเสียบใหม่
Jarryd

สิ่งนี้ได้ผลเหมือนมนต์เสน่ห์
Wedge Martin

หากโปรแกรมได้เปิดอุปกรณ์ USB แบบอนุกรม (พูด / dev / ttyUSB0 เชื่อมโยงจาก / dev / myserialdevice ตามที่ระบุใน /etc/udev/rules.d/mystuff.rules) และอุปกรณ์หยุดทำงานด้วยเหตุผลบางประการ จำเป็นต้องรีเซ็ตด้วย ioctl () ตามที่กล่าวไว้ข้างต้นหรือเพียงพอหรือไม่ที่จะปิด () และเปิด () อีกครั้ง
ต่อ Lindberg

1
@Jarryd เห็นคำอธิบายของอลันในลิงก์ด้านบน :Note however, that reset followed by re-enumeration is _not_ the same thing as power-cycle followed by reconnect and re-enumeration.
ckujau

2

ฉันสร้างสคริปต์ Python ที่ทำให้กระบวนการทั้งหมดง่ายขึ้นโดยขึ้นอยู่กับคำตอบที่นี่: /ubuntu/645/how-do-you-reset-a-usb-device-from-the-command .

บันทึกสคริปต์ด้านล่างเป็นโคลน reset_usb.py หรือ repo นี้: https://github.com/mcarans/resetusb/

การใช้งาน:

python reset_usb.py help: แสดงความช่วยเหลือนี้

sudo python list_usb.py รายการ: แสดงรายการอุปกรณ์ USB ทั้งหมด

sudo python reset_usb.py path / dev / bus / usb / XXX / YYY: รีเซ็ตอุปกรณ์ USB โดยใช้ path / dev / bus / usb / XXX / YYY

sudo python reset_usb.py ค้นหา "คำค้นหา": ค้นหาอุปกรณ์ USB โดยใช้คำค้นหาภายในสตริงการค้นหาที่ส่งคืนโดยรายการและรีเซ็ตอุปกรณ์ที่ตรงกัน

sudo python reset_usb.py listpci: แสดงรายการอุปกรณ์ PCI USB ทั้งหมด

sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X: รีเซ็ตอุปกรณ์ USB PCI โดยใช้พา ธ /sys/bus/pci/drivers/.../XXXX::XX: XX.X

sudo python reset_usb.py searchpci "คำค้นหา": ค้นหาอุปกรณ์ PCI USB โดยใช้คำค้นหาภายในสตริงการค้นหาที่ส่งคืนโดย listpci และรีเซ็ตอุปกรณ์ที่ตรงกัน

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

0

คุณสามารถรีเซ็ตสแต็ก USB ผ่านซอฟต์แวร์ได้ตลอดเวลาและทำให้อุปกรณ์ USB เข้าสู่โหมดสลีป ( ประหยัดพลังงาน ) แต่สิ่งนี้จะไม่ส่งผลต่อกำลังไฟ + 5V พอร์ตซึ่งเปิดอยู่เสมอ

ทั้งนี้ขึ้นอยู่กับฮับ USB ของคุณคุณอาจจะหรืออาจไม่สามารถปิด (รอบ) พลังงานไปยังพอร์ต USB จริง

ฮับ ​​USB "อัจฉริยะ" เท่านั้นที่อนุญาตการหมุนเวียนพลังงานต่อพอร์ต นี่เป็นโครงการขนาดเล็กที่ให้คุณควบคุมสิ่งเหล่านี้ได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.