1 /* usbreset -- send a USB port reset to a USB device */
5 http://marc.info/?l=linux-usb-users&m=116827193506484&w=2
7 and needs mounted usbfs filesystem
9 sudo mount -t usbfs none /proc/bus/usb
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
13 suspend a device, do (as root):
15 echo -n 2 >/sys/bus/usb/devices/.../power/state
17 where the "..." is the ID for your device. To unsuspend, do the same
18 thing but with a "0" instead of the "2" above.
20 Note that this mechanism is slated to be removed from the kernel within
21 the next year. Hopefully some other mechanism will take its place.
26 Here's a program to do it. You invoke it as either
28 usbreset /proc/bus/usb/BBB/DDD
32 depending on how your system is set up, where BBB and DDD are the bus and
33 device address numbers.
48 #include <sys/ioctl.h>
49 #include <sys/types.h>
51 #include <linux/usbdevice_fs.h>
54 static char *usbfs = NULL;
61 char vendor_name[128];
62 char product_name[128];
66 static char *sysfs_attr(const char *dev, const char *attr)
72 memset(buf, 0, sizeof(buf));
73 snprintf(path, sizeof(path) - 1, "/sys/bus/usb/devices/%s/%s", dev, attr);
75 if ((fd = open(path, O_RDONLY)) >= 0)
77 len = read(fd, buf, sizeof(buf) - 1);
81 while (--len > 0 && isspace(buf[len]))
84 return (len >= 0) ? buf : NULL;
87 static struct usbentry * parse_devlist(DIR *d)
91 static struct usbentry dev;
99 while(!isdigit(e->d_name[0]) || strchr(e->d_name, ':'));
101 memset(&dev, 0, sizeof(dev));
103 if ((attr = sysfs_attr(e->d_name, "busnum")) != NULL)
104 dev.bus_num = strtoul(attr, NULL, 10);
106 if ((attr = sysfs_attr(e->d_name, "devnum")) != NULL)
107 dev.dev_num = strtoul(attr, NULL, 10);
109 if ((attr = sysfs_attr(e->d_name, "idVendor")) != NULL)
110 dev.vendor_id = strtoul(attr, NULL, 16);
112 if ((attr = sysfs_attr(e->d_name, "idProduct")) != NULL)
113 dev.product_id = strtoul(attr, NULL, 16);
115 if ((attr = sysfs_attr(e->d_name, "manufacturer")) != NULL)
116 strcpy(dev.vendor_name, attr);
118 if ((attr = sysfs_attr(e->d_name, "product")) != NULL)
119 strcpy(dev.product_name, attr);
121 if (dev.bus_num && dev.dev_num && dev.vendor_id && dev.product_id)
127 static void list_devices(void)
129 DIR *devs = opendir("/sys/bus/usb/devices");
130 struct usbentry *dev;
135 while ((dev = parse_devlist(devs)) != NULL)
137 printf(" Number %03d/%03d ID %04x:%04x %s\n",
138 dev->bus_num, dev->dev_num,
139 dev->vendor_id, dev->product_id,
146 struct usbentry * find_device(int *bus, int *dev,
150 DIR *devs = opendir("/sys/bus/usb/devices");
152 struct usbentry *e, *match = NULL;
157 while ((e = parse_devlist(devs)) != NULL)
159 if ((bus && (e->bus_num == *bus) && (e->dev_num == *dev)) ||
160 (vid && (e->vendor_id == *vid) && (e->product_id == *pid)) ||
161 (product && !strcasecmp(e->product_name, product)))
173 static void reset_device(struct usbentry *dev)
178 snprintf(path, sizeof(path) - 1, "/dev/bus/usb/%03d/%03d",
179 dev->bus_num, dev->dev_num);
181 printf("Resetting %s ... ", dev->product_name);
183 if ((fd = open(path, O_WRONLY)) > -1)
185 if (ioctl(fd, USBDEVFS_RESET, 0) < 0)
186 printf("failed [%s]\n", strerror(errno));
194 printf("can't open [%s]\n", strerror(errno));
199 int main(int argc, char **argv)
202 struct usbentry *dev;
204 if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2))
206 dev = find_device(&id1, &id2, NULL, NULL, NULL);
208 else if ((argc == 2) && (sscanf(argv[1], "%4x:%4x", &id1, &id2) == 2))
210 dev = find_device(NULL, NULL, &id1, &id2, NULL);
212 else if ((argc == 2) && strlen(argv[1]) < 128)
214 dev = find_device(NULL, NULL, NULL, NULL, argv[1]);
219 " usbreset PPPP:VVVV - reset by product and vendor id\n"
220 " usbreset BBB/DDD - reset by bus and device number\n"
221 " usbreset \"Product\" - reset by product name\n\n"
229 fprintf(stderr, "No such device found\n");