CLI를 통해 USB 포트를 분리했다가 다시 연결

CLI를 통해 USB 포트를 분리했다가 다시 연결

마우스가 갑자기 작동을 멈춥니다. 해결책은 간단합니다. 플러그를 뽑았다가 다시 연결하면 됩니다. 명령줄을 통해 이를 수행할 수 있는 방법이 있습니까? 명령줄을 통해 이 작업을 수행하면 몇 가지 이점이 있습니다.

  1. 커넥터가 마모되지 않습니다.
  2. 서둘러요.
  3. 테이블 밑으로 기어가는 수고를 덜었습니다.
  4. 가장 중요한 것은 실수로 다른 장치의 플러그를 뽑는 일이 없도록 방지하는 것입니다.

또한 이를 어떻게 하는지 궁금합니다.

운영체제는 데비안 8이다.

감사해요!

답변1

다음을 저장하세요.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. 재설정할 USB 장치의 버스 및 장치 ID를 가져옵니다.

    lsusb -t 
    
    Bus#  4  
    -Dev#   1 Vendor 0x1d6b Product 0x0001    
    -Dev#   3 Vendor 0x046b Product 0xff10
    
  3. 컴파일된 프로그램을 실행 가능하게 만듭니다.

    chmod +x usbreset
    
  4. sudo다음 명령을 실행하여 찾은 권한과 ID를 <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

답변2

여기에 대한 답변을 기반으로 전체 프로세스를 단순화하는 Python 스크립트를 만들었습니다.https://askubuntu.com/questions/645/how-do-you-reset-a-usb-device-from-the-command-line.

아래 스크립트를 Reset_usb.py로 저장하거나 이 저장소를 복제하세요.https://github.com/mcarans/resetusb/.

용법:

python Reset_usb.py help: 이 도움말을 표시합니다.

sudo python Reset_usb.py list : 모든 USB 장치 나열

sudo python Reset_usb.py 경로 /dev/bus/usb/XXX/YYY: USB 장치를 재설정하려면 /dev/bus/usb/XXX/YYY 경로를 사용하세요.

sudo python Reset_usb.py search "search terms" : 목록에서 반환된 검색 문자열의 검색어를 사용하여 USB 장치를 검색하고 일치하는 장치를 재설정합니다.

sudo python Reset_usb.py listpci: 모든 PCI USB 장치 나열

sudo python Reset_usb.py pathpci /sys/bus/pci/drivers/.../XXXX:XX:XX.X: /sys/bus/pci/drivers/.../XXXX:XX 경로를 사용하여 PCI를 재설정합니다. USB 장치 :XX.X

sudo python Reset_usb.py searchpci "검색어": listpci에서 반환된 검색 문자열의 검색어를 사용하여 PCI USB 장치를 검색하고 일치하는 장치를 재설정합니다.

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

답변3

언제든지 소프트웨어를 통해 USB 스택을 재설정하거나 USB 장치를 절전 모드로 전환할 수 있습니다(절전) 모드이지만 항상 켜져 있는 +5V 포트 전원 공급 장치에는 영향을 미치지 않습니다.

USB 허브에 따라 실제 USB 포트의 전원을 실제로 끄지(순환)하지 못할 수도 있습니다.

"스마트" USB 허브만 포트별 전원 순환을 허용합니다.여기는 이를 제어할 수 있는 작은 프로젝트입니다.

답변4

USB 저장 장치의 경우 훨씬 간단합니다. 방금 알아낸 내용이고 다른 사람도 이 스레드에 있고 유용하다고 생각하는 경우를 대비해 여기에 남겨 두겠습니다.

  1. 버스, 포트, 장치 찾기:

    $ sudo dmesg --ctime | grep usb-storage
    [Mon Feb 27 10:27:05 2023] usb-storage 3-1:1.0: USB Mass Storage device detected
    [Mon Feb 27 10:27:05 2023] scsi host4: usb-storage 3-1:1.0
    [Mon Feb 27 10:27:05 2023] usbcore: registered new interface driver usb-storage
    

    이 예에서 우리는 찾을 것입니다.분명히 3-1:1.0하나 이상의 USB 저장 장치가 연결되어 있으면 여러 항목이 표시됩니다. 타임스탬프는 찾고 있는 장치를 파악하는 데 도움이 됩니다. 그렇지 않으면 lsusb -t도움이 될 수도 있습니다.

  2. 바인딩 해제 및 다시 바인딩:

    $ usb=3-1:1.0
    $ printf %s\\n "$usb" | sudo tee /sys/bus/usb/drivers/usb-storage/unbind
    3-1:1.0
    $ printf %s\\n "$usb" | sudo tee /sys/bus/usb/drivers/usb-storage/bind
    3-1:1.0
    

관련 정보