Changeset 32741


Ignore:
Timestamp:
2012-07-16T02:39:39+02:00 (6 years ago)
Author:
jow
Message:

[packages] usbreset: improve usability

  • add device list in usage screen
  • support resetting by bus/device number, by produc:vendor id or by device name
Location:
trunk/package/usbreset
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/package/usbreset/Makefile

    r29611 r32741  
    11# 
    2 # Copyright (C) 2011 OpenWrt.org 
     2# Copyright (C) 2011-2012 OpenWrt.org 
    33# 
    44# This is free software, licensed under the GNU General Public License v2. 
     
    99 
    1010PKG_NAME:=usbreset 
    11 PKG_RELEASE:=1 
     11PKG_RELEASE:=2 
    1212 
    1313include $(INCLUDE_DIR)/package.mk 
  • trunk/package/usbreset/src/usbreset.c

    r29611 r32741  
    99        sudo mount -t usbfs none /proc/bus/usb 
    1010 
    11 There is a way to suspend a USB device.  In order to use it,  
    12 you must have a kernel with CONFIG_PM_SYSFS_DEPRECATED turned on.  To  
     11There is a way to suspend a USB device.  In order to use it, 
     12you must have a kernel with CONFIG_PM_SYSFS_DEPRECATED turned on.  To 
    1313suspend a device, do (as root): 
    1414 
    1515        echo -n 2 >/sys/bus/usb/devices/.../power/state 
    1616 
    17 where the "..." is the ID for your device.  To unsuspend, do the same  
     17where the "..." is the ID for your device.  To unsuspend, do the same 
    1818thing but with a "0" instead of the "2" above. 
    1919 
    20 Note that this mechanism is slated to be removed from the kernel within  
     20Note that this mechanism is slated to be removed from the kernel within 
    2121the next year.  Hopefully some other mechanism will take its place. 
    2222 
     
    3838 
    3939#include <stdio.h> 
     40#include <stdbool.h> 
    4041#include <unistd.h> 
    4142#include <fcntl.h> 
    4243#include <errno.h> 
     44#include <string.h> 
    4345#include <sys/ioctl.h> 
    4446 
     
    4648 
    4749 
     50static char *usbfs = NULL; 
     51 
     52struct usbentry { 
     53        int bus_num; 
     54        int dev_num; 
     55        int vendor_id; 
     56        int product_id; 
     57        char vendor_name[128]; 
     58        char product_name[128]; 
     59}; 
     60 
     61 
     62static bool find_usbfs(void) 
     63{ 
     64        FILE *mtab; 
     65 
     66        char buf[1024], type[32]; 
     67        static char path[1024]; 
     68 
     69        if ((mtab = fopen("/proc/mounts", "r")) != NULL) 
     70        { 
     71                while (fgets(buf, sizeof(buf), mtab)) 
     72                { 
     73                        if (sscanf(buf, "%*s %1023s %31s ", path, type) == 2 && 
     74                                !strncmp(type, "usbfs", 5)) 
     75                        { 
     76                                usbfs = path; 
     77                                break; 
     78                        } 
     79                } 
     80 
     81                fclose(mtab); 
     82        } 
     83 
     84        return !!usbfs; 
     85} 
     86 
     87static FILE * open_devlist(void) 
     88{ 
     89        char buf[1024]; 
     90        snprintf(buf, sizeof(buf), "%s/devices", usbfs); 
     91        return fopen(buf, "r"); 
     92} 
     93 
     94static void close_devlist(FILE *devs) 
     95{ 
     96        fclose(devs); 
     97} 
     98 
     99static struct usbentry * parse_devlist(FILE *devs) 
     100{ 
     101        char buf[1024]; 
     102        static struct usbentry dev; 
     103 
     104        memset(&dev, 0, sizeof(dev)); 
     105 
     106        while (fgets(buf, sizeof(buf), devs)) 
     107        { 
     108                buf[strlen(buf)-1] = 0; 
     109 
     110                switch (buf[0]) 
     111                { 
     112                case 'T': 
     113                        sscanf(buf, "T: Bus=%d Lev=%*d Prnt=%*d Port=%*d Cnt=%*d Dev#=%d", 
     114                                   &dev.bus_num, &dev.dev_num); 
     115                        break; 
     116 
     117                case 'P': 
     118                        sscanf(buf, "P: Vendor=%x ProdID=%x", 
     119                                   &dev.vendor_id, &dev.product_id); 
     120                        break; 
     121 
     122                case 'S': 
     123                        if (!strncmp(buf, "S:  Manufacturer=", 17)) 
     124                                snprintf(dev.vendor_name, sizeof(dev.vendor_name), 
     125                                         "%s", buf+17); 
     126                        else if (!strncmp(buf, "S:  Product=", 12)) 
     127                                snprintf(dev.product_name, sizeof(dev.product_name), 
     128                                         "%s", buf+12); 
     129                        break; 
     130                } 
     131 
     132                if (dev.product_name[0]) 
     133                        return &dev; 
     134        } 
     135 
     136        return NULL; 
     137} 
     138 
     139static void list_devices(void) 
     140{ 
     141        FILE *devs = open_devlist(); 
     142        struct usbentry *dev; 
     143 
     144        if (!devs) 
     145                return; 
     146 
     147        while ((dev = parse_devlist(devs)) != NULL) 
     148        { 
     149                printf("  Number %03d/%03d  ID %04x:%04x  %s\n", 
     150                           dev->bus_num, dev->dev_num, 
     151                           dev->vendor_id, dev->product_id, 
     152                           dev->product_name); 
     153        } 
     154 
     155        close_devlist(devs); 
     156} 
     157 
     158struct usbentry * find_device(int *bus, int *dev, 
     159                              int *vid, int *pid, 
     160                              const char *product) 
     161{ 
     162        FILE *devs = open_devlist(); 
     163 
     164        struct usbentry *e, *match = NULL; 
     165 
     166        if (!devs) 
     167                return NULL; 
     168 
     169        while ((e = parse_devlist(devs)) != NULL) 
     170        { 
     171                if ((bus && (e->bus_num == *bus) && (e->dev_num == *dev)) || 
     172                        (vid && (e->vendor_id == *vid) && (e->product_id == *pid)) || 
     173                        (product && !strcasecmp(e->product_name, product))) 
     174                { 
     175                        match = e; 
     176                        break; 
     177                } 
     178        } 
     179 
     180        close_devlist(devs); 
     181 
     182        return match; 
     183} 
     184 
     185static void reset_device(struct usbentry *dev) 
     186{ 
     187        int fd; 
     188        char path[1024]; 
     189 
     190        snprintf(path, sizeof(path), "%s/%03d/%03d", 
     191                         usbfs, dev->bus_num, dev->dev_num); 
     192 
     193        printf("Resetting %s ... ", dev->product_name); 
     194 
     195        if ((fd = open(path, O_WRONLY)) > -1) 
     196        { 
     197                if (ioctl(fd, USBDEVFS_RESET, 0) < 0) 
     198                        printf("failed [%s]\n", strerror(errno)); 
     199                else 
     200                        printf("ok\n"); 
     201 
     202                close(fd); 
     203        } 
     204        else 
     205        { 
     206                printf("can't open [%s]\n", strerror(errno)); 
     207        } 
     208} 
     209 
     210 
    48211int main(int argc, char **argv) 
    49212{ 
    50         const char *filename; 
    51         int fd; 
    52         int rc; 
    53  
    54         if (argc != 2) { 
    55                 fprintf(stderr, "Usage: usbreset device-filename\n"); 
     213        int id1, id2; 
     214        struct usbentry *dev; 
     215 
     216        if (!find_usbfs()) 
     217        { 
     218                fprintf(stderr, "Unable to find usbfs, is it mounted?\n"); 
    56219                return 1; 
    57220        } 
    58         filename = argv[1]; 
    59  
    60         fd = open(filename, O_WRONLY); 
    61         if (fd < 0) { 
    62                 perror("Error opening output file"); 
     221 
     222        if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2)) 
     223        { 
     224                dev = find_device(&id1, &id2, NULL, NULL, NULL); 
     225        } 
     226        else if ((argc == 2) && (sscanf(argv[1], "%4x:%4x", &id1, &id2) == 2)) 
     227        { 
     228                dev = find_device(NULL, NULL, &id1, &id2, NULL); 
     229        } 
     230        else if ((argc == 2) && strlen(argv[1]) < 128) 
     231        { 
     232                dev = find_device(NULL, NULL, NULL, NULL, argv[1]); 
     233        } 
     234        else 
     235        { 
     236                printf("Usage:\n" 
     237                       "  usbreset PPPP:VVVV - reset by product and vendor id\n" 
     238                       "  usbreset BBB/DDD   - reset by bus and device number\n" 
     239                       "  usbreset \"Product\" - reset by product name\n\n" 
     240                       "Devices:\n"); 
     241                list_devices(); 
    63242                return 1; 
    64243        } 
    65244 
    66         printf("Resetting USB device %s\n", filename); 
    67         rc = ioctl(fd, USBDEVFS_RESET, 0); 
    68         if (rc < 0) { 
    69                 perror("Error in ioctl"); 
     245        if (!dev) 
     246        { 
     247                fprintf(stderr, "No such device found\n"); 
    70248                return 1; 
    71249        } 
    72         printf("Reset successful\n"); 
    73  
    74         close(fd); 
     250 
     251        reset_device(dev); 
    75252        return 0; 
    76253} 
Note: See TracChangeset for help on using the changeset viewer.