Ngắt kết nối và kết nối lại cổng USB qua cli


16

Tôi có một con chuột sẽ ngừng hoạt động ngẫu nhiên. Giải pháp rất dễ dàng, rút ​​phích cắm và cắm lại. Có cách nào tôi có thể làm điều này thông qua dòng lệnh không? Làm thông qua dòng lệnh có một vài lợi thế.

  1. Không làm hao mòn đầu nối.
  2. Nhanh hơn.
  3. Cứu tôi những rắc rối khi bò dưới bàn của tôi.
  4. Quan trọng nhất: ngăn tôi vô tình rút phích cắm thứ khác.

Thêm vào đó tôi tò mò làm thế nào để làm điều này.

HĐH là Debian 8.

Cảm ơn!


1
Không chính xác cùng một câu hỏi, nhưng câu trả lời nên được áp dụng: Làm cách nào để kết nối lại thiết bị USB bị ngắt kết nối logic?
Gilles 'SO- ngừng trở nên xấu xa'

Có lẽ unix.stackexchange.com/a/166601/117599 là những gì bạn đang tìm kiếm.
phk

Câu trả lời:


13

Lưu những điều sau đây vào 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;
}

Việc chạy các lệnh sau trong terminal:

  1. Biên dịch chương trình:

    cc usbreset.c -o usbreset
    
  2. Nhận Bus và ID thiết bị của thiết bị USB bạn muốn đặt lại:

    lsusb -t 
    
    Bus#  4  
    -Dev#   1 Vendor 0x1d6b Product 0x0001    
    -Dev#   3 Vendor 0x046b Product 0xff10
    
  3. Làm cho chương trình biên dịch của chúng tôi thực thi:

    chmod +x usbreset
    
  4. Thực hiện chương trình với sudođặc quyền; thực hiện thay thế cần thiết cho <Bus><Device>id như được tìm thấy bằng cách chạy lsusblệnh:

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

Nguồn của chương trình trên: http://marc.info/?l=linux-usb&m=121459435621262&w=2


1
Điều này có hiệu quả thiết lập lại nguồn điện trên thiết bị và do đó sẽ thiết lập lại hoàn toàn mà không cần phải rút và cắm lại?
Jarryd

Điều này làm việc như một nét duyên dáng.
Wedge Martin

Nếu một chương trình đã mở một thiết bị USB nối tiếp (giả sử / dev / ttyUSB0 được liên kết từ / dev / myserialdevice như được chỉ định trong /etc/udev/rules.d/mystuff.rules) và vì lý do nào đó, thiết bị bị treo sau đó cần thiết để thiết lập lại nó với một ioctl () như trên, hoặc nó có đủ để chỉ cần đóng () và mở () lại không?
Per Lindberg

1
@Jarryd xem lời giải thích của Alan trong liên kết trên :Note however, that reset followed by re-enumeration is _not_ the same thing as power-cycle followed by reconnect and re-enumeration.
ckujau

2

Tôi đã tạo một tập lệnh Python đơn giản hóa toàn bộ quá trình dựa trên các câu trả lời tại đây: https://askubfox.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line .

Lưu tập lệnh bên dưới dưới dạng reset_usb.py hoặc sao chép repo này: https://github.com/mcarans/resetusb/ .

Sử dụng:

python reset_usb.py trợ giúp: Hiển thị trợ giúp này

sudo python reset_usb.py list: Liệt kê tất cả các thiết bị USB

sudo python reset_usb.py path / dev / bus / usb / XXX / YYY: Đặt lại thiết bị USB bằng đường dẫn / dev / bus / usb / XXX / YYY

sudo python reset_usb.py tìm kiếm "thuật ngữ tìm kiếm": Tìm kiếm thiết bị USB bằng cụm từ tìm kiếm trong chuỗi tìm kiếm được trả về bởi danh sách và đặt lại thiết bị phù hợp

sudo python reset_usb.py listpci: Liệt kê tất cả các thiết bị USB PCI

sudo python reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X: Đặt lại thiết bị USB PCI bằng đường dẫn /sys/bus/pci/drivers/.../XXXX:XX: XX.X

sudo python reset_usb.py searchpci "cụm từ tìm kiếm": Tìm kiếm thiết bị USB PCI bằng cách sử dụng cụm từ tìm kiếm trong chuỗi tìm kiếm được listpci trả về và đặt lại thiết bị phù hợp

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

Bạn luôn có thể đặt lại ngăn xếp USB thông qua phần mềm và cũng có thể đặt các thiết bị USB ở chế độ ngủ ( tiết kiệm năng lượng ), nhưng điều này không ảnh hưởng đến nguồn cổng + 5V, luôn luôn bật.

Tùy thuộc vào trung tâm USB của bạn, bạn có thể thực sự không thể tắt (chu kỳ) nguồn điện sang cổng USB vật lý.

Chỉ các hub USB "thông minh" mới cho phép đạp xe trên mỗi cổng. Đây là một dự án nhỏ cho phép bạn kiểm soát những điều này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.