usbreset: rewrite to not rely on /proc/bus/usb anymore
SVN-Revision: 37893
This commit is contained in:
parent
07216b9f46
commit
e01fb70f1b
2 changed files with 53 additions and 71 deletions
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (C) 2011-2012 OpenWrt.org
|
# Copyright (C) 2011-2013 OpenWrt.org
|
||||||
#
|
#
|
||||||
# This is free software, licensed under the GNU General Public License v2.
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
# See /LICENSE for more information.
|
# See /LICENSE for more information.
|
||||||
|
@ -8,7 +8,7 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=usbreset
|
PKG_NAME:=usbreset
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=3
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,11 @@ Alan Stern
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <linux/usbdevice_fs.h>
|
#include <linux/usbdevice_fs.h>
|
||||||
|
|
||||||
|
@ -59,86 +63,70 @@ struct usbentry {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static bool find_usbfs(void)
|
static char *sysfs_attr(const char *dev, const char *attr)
|
||||||
{
|
{
|
||||||
FILE *mtab;
|
int fd, len;
|
||||||
|
char path[PATH_MAX];
|
||||||
|
static char buf[129];
|
||||||
|
|
||||||
char buf[1024], type[32];
|
memset(buf, 0, sizeof(buf));
|
||||||
static char path[1024];
|
snprintf(path, sizeof(path) - 1, "/sys/bus/usb/devices/%s/%s", dev, attr);
|
||||||
|
|
||||||
if ((mtab = fopen("/proc/mounts", "r")) != NULL)
|
if ((fd = open(path, O_RDONLY)) >= 0)
|
||||||
{
|
{
|
||||||
while (fgets(buf, sizeof(buf), mtab))
|
len = read(fd, buf, sizeof(buf) - 1);
|
||||||
{
|
close(fd);
|
||||||
if (sscanf(buf, "%*s %1023s %31s ", path, type) == 2 &&
|
|
||||||
!strncmp(type, "usbfs", 5))
|
|
||||||
{
|
|
||||||
usbfs = path;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(mtab);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return !!usbfs;
|
while (--len > 0 && isspace(buf[len]))
|
||||||
|
buf[len] = 0;
|
||||||
|
|
||||||
|
return (len >= 0) ? buf : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE * open_devlist(void)
|
static struct usbentry * parse_devlist(DIR *d)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char *attr;
|
||||||
snprintf(buf, sizeof(buf), "%s/devices", usbfs);
|
struct dirent *e;
|
||||||
return fopen(buf, "r");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void close_devlist(FILE *devs)
|
|
||||||
{
|
|
||||||
fclose(devs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct usbentry * parse_devlist(FILE *devs)
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
static struct usbentry dev;
|
static struct usbentry dev;
|
||||||
|
|
||||||
|
do {
|
||||||
|
e = readdir(d);
|
||||||
|
|
||||||
|
if (!e)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while(!isdigit(e->d_name[0]) || strchr(e->d_name, ':'));
|
||||||
|
|
||||||
memset(&dev, 0, sizeof(dev));
|
memset(&dev, 0, sizeof(dev));
|
||||||
|
|
||||||
while (fgets(buf, sizeof(buf), devs))
|
if ((attr = sysfs_attr(e->d_name, "busnum")) != NULL)
|
||||||
{
|
dev.bus_num = strtoul(attr, NULL, 10);
|
||||||
buf[strlen(buf)-1] = 0;
|
|
||||||
|
|
||||||
switch (buf[0])
|
if ((attr = sysfs_attr(e->d_name, "devnum")) != NULL)
|
||||||
{
|
dev.dev_num = strtoul(attr, NULL, 10);
|
||||||
case 'T':
|
|
||||||
sscanf(buf, "T: Bus=%d Lev=%*d Prnt=%*d Port=%*d Cnt=%*d Dev#=%d",
|
|
||||||
&dev.bus_num, &dev.dev_num);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'P':
|
if ((attr = sysfs_attr(e->d_name, "idVendor")) != NULL)
|
||||||
sscanf(buf, "P: Vendor=%x ProdID=%x",
|
dev.vendor_id = strtoul(attr, NULL, 16);
|
||||||
&dev.vendor_id, &dev.product_id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'S':
|
if ((attr = sysfs_attr(e->d_name, "idProduct")) != NULL)
|
||||||
if (!strncmp(buf, "S: Manufacturer=", 17))
|
dev.product_id = strtoul(attr, NULL, 16);
|
||||||
snprintf(dev.vendor_name, sizeof(dev.vendor_name),
|
|
||||||
"%s", buf+17);
|
|
||||||
else if (!strncmp(buf, "S: Product=", 12))
|
|
||||||
snprintf(dev.product_name, sizeof(dev.product_name),
|
|
||||||
"%s", buf+12);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dev.product_name[0])
|
if ((attr = sysfs_attr(e->d_name, "manufacturer")) != NULL)
|
||||||
return &dev;
|
strcpy(dev.vendor_name, attr);
|
||||||
}
|
|
||||||
|
if ((attr = sysfs_attr(e->d_name, "product")) != NULL)
|
||||||
|
strcpy(dev.product_name, attr);
|
||||||
|
|
||||||
|
if (dev.bus_num && dev.dev_num && dev.vendor_id && dev.product_id)
|
||||||
|
return &dev;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_devices(void)
|
static void list_devices(void)
|
||||||
{
|
{
|
||||||
FILE *devs = open_devlist();
|
DIR *devs = opendir("/sys/bus/usb/devices");
|
||||||
struct usbentry *dev;
|
struct usbentry *dev;
|
||||||
|
|
||||||
if (!devs)
|
if (!devs)
|
||||||
|
@ -152,14 +140,14 @@ static void list_devices(void)
|
||||||
dev->product_name);
|
dev->product_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
close_devlist(devs);
|
closedir(devs);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct usbentry * find_device(int *bus, int *dev,
|
struct usbentry * find_device(int *bus, int *dev,
|
||||||
int *vid, int *pid,
|
int *vid, int *pid,
|
||||||
const char *product)
|
const char *product)
|
||||||
{
|
{
|
||||||
FILE *devs = open_devlist();
|
DIR *devs = opendir("/sys/bus/usb/devices");
|
||||||
|
|
||||||
struct usbentry *e, *match = NULL;
|
struct usbentry *e, *match = NULL;
|
||||||
|
|
||||||
|
@ -177,7 +165,7 @@ struct usbentry * find_device(int *bus, int *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
close_devlist(devs);
|
closedir(devs);
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
@ -185,10 +173,10 @@ struct usbentry * find_device(int *bus, int *dev,
|
||||||
static void reset_device(struct usbentry *dev)
|
static void reset_device(struct usbentry *dev)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char path[1024];
|
char path[PATH_MAX];
|
||||||
|
|
||||||
snprintf(path, sizeof(path), "%s/%03d/%03d",
|
snprintf(path, sizeof(path) - 1, "/dev/bus/usb/%03d/%03d",
|
||||||
usbfs, dev->bus_num, dev->dev_num);
|
dev->bus_num, dev->dev_num);
|
||||||
|
|
||||||
printf("Resetting %s ... ", dev->product_name);
|
printf("Resetting %s ... ", dev->product_name);
|
||||||
|
|
||||||
|
@ -213,12 +201,6 @@ int main(int argc, char **argv)
|
||||||
int id1, id2;
|
int id1, id2;
|
||||||
struct usbentry *dev;
|
struct usbentry *dev;
|
||||||
|
|
||||||
if (!find_usbfs())
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Unable to find usbfs, is it mounted?\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2))
|
if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2))
|
||||||
{
|
{
|
||||||
dev = find_device(&id1, &id2, NULL, NULL, NULL);
|
dev = find_device(&id1, &id2, NULL, NULL, NULL);
|
||||||
|
|
Loading…
Reference in a new issue