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.
45 #include <sys/ioctl.h>
47 #include <linux/usbdevice_fs.h>
50 static char *usbfs = NULL;
57 char vendor_name[128];
58 char product_name[128];
62 static bool find_usbfs(void)
66 char buf[1024], type[32];
67 static char path[1024];
69 if ((mtab = fopen("/proc/mounts", "r")) != NULL)
71 while (fgets(buf, sizeof(buf), mtab))
73 if (sscanf(buf, "%*s %1023s %31s ", path, type) == 2 &&
74 !strncmp(type, "usbfs", 5))
87 static FILE * open_devlist(void)
90 snprintf(buf, sizeof(buf), "%s/devices", usbfs);
91 return fopen(buf, "r");
94 static void close_devlist(FILE *devs)
99 static struct usbentry * parse_devlist(FILE *devs)
102 static struct usbentry dev;
104 memset(&dev, 0, sizeof(dev));
106 while (fgets(buf, sizeof(buf), devs))
108 buf[strlen(buf)-1] = 0;
113 sscanf(buf, "T: Bus=%d Lev=%*d Prnt=%*d Port=%*d Cnt=%*d Dev#=%d",
114 &dev.bus_num, &dev.dev_num);
118 sscanf(buf, "P: Vendor=%x ProdID=%x",
119 &dev.vendor_id, &dev.product_id);
123 if (!strncmp(buf, "S: Manufacturer=", 17))
124 snprintf(dev.vendor_name, sizeof(dev.vendor_name),
126 else if (!strncmp(buf, "S: Product=", 12))
127 snprintf(dev.product_name, sizeof(dev.product_name),
132 if (dev.product_name[0])
139 static void list_devices(void)
141 FILE *devs = open_devlist();
142 struct usbentry *dev;
147 while ((dev = parse_devlist(devs)) != NULL)
149 printf(" Number %03d/%03d ID %04x:%04x %s\n",
150 dev->bus_num, dev->dev_num,
151 dev->vendor_id, dev->product_id,
158 struct usbentry * find_device(int *bus, int *dev,
162 FILE *devs = open_devlist();
164 struct usbentry *e, *match = NULL;
169 while ((e = parse_devlist(devs)) != NULL)
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)))
185 static void reset_device(struct usbentry *dev)
190 snprintf(path, sizeof(path), "%s/%03d/%03d",
191 usbfs, dev->bus_num, dev->dev_num);
193 printf("Resetting %s ... ", dev->product_name);
195 if ((fd = open(path, O_WRONLY)) > -1)
197 if (ioctl(fd, USBDEVFS_RESET, 0) < 0)
198 printf("failed [%s]\n", strerror(errno));
206 printf("can't open [%s]\n", strerror(errno));
211 int main(int argc, char **argv)
214 struct usbentry *dev;
218 fprintf(stderr, "Unable to find usbfs, is it mounted?\n");
222 if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2))
224 dev = find_device(&id1, &id2, NULL, NULL, NULL);
226 else if ((argc == 2) && (sscanf(argv[1], "%4x:%4x", &id1, &id2) == 2))
228 dev = find_device(NULL, NULL, &id1, &id2, NULL);
230 else if ((argc == 2) && strlen(argv[1]) < 128)
232 dev = find_device(NULL, NULL, NULL, NULL, argv[1]);
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"
247 fprintf(stderr, "No such device found\n");