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.
49 #include <sys/ioctl.h>
50 #include <sys/types.h>
52 #include <linux/usbdevice_fs.h>
55 static char *usbfs
= NULL
;
62 char vendor_name
[128];
63 char product_name
[128];
67 static char *sysfs_attr(const char *dev
, const char *attr
)
73 memset(buf
, 0, sizeof(buf
));
74 snprintf(path
, sizeof(path
) - 1, "/sys/bus/usb/devices/%s/%s", dev
, attr
);
76 if ((fd
= open(path
, O_RDONLY
)) >= 0)
78 len
= read(fd
, buf
, sizeof(buf
) - 1);
82 while (--len
> 0 && isspace(buf
[len
]))
85 return (len
>= 0) ? buf
: NULL
;
88 static struct usbentry
* parse_devlist(DIR *d
)
92 static struct usbentry dev
;
100 while(!isdigit(e
->d_name
[0]) || strchr(e
->d_name
, ':'));
102 memset(&dev
, 0, sizeof(dev
));
104 if ((attr
= sysfs_attr(e
->d_name
, "busnum")) != NULL
)
105 dev
.bus_num
= strtoul(attr
, NULL
, 10);
107 if ((attr
= sysfs_attr(e
->d_name
, "devnum")) != NULL
)
108 dev
.dev_num
= strtoul(attr
, NULL
, 10);
110 if ((attr
= sysfs_attr(e
->d_name
, "idVendor")) != NULL
)
111 dev
.vendor_id
= strtoul(attr
, NULL
, 16);
113 if ((attr
= sysfs_attr(e
->d_name
, "idProduct")) != NULL
)
114 dev
.product_id
= strtoul(attr
, NULL
, 16);
116 if ((attr
= sysfs_attr(e
->d_name
, "manufacturer")) != NULL
)
117 strcpy(dev
.vendor_name
, attr
);
119 if ((attr
= sysfs_attr(e
->d_name
, "product")) != NULL
)
120 strcpy(dev
.product_name
, attr
);
122 if (dev
.bus_num
&& dev
.dev_num
&& dev
.vendor_id
&& dev
.product_id
)
128 static void list_devices(void)
130 DIR *devs
= opendir("/sys/bus/usb/devices");
131 struct usbentry
*dev
;
136 while ((dev
= parse_devlist(devs
)) != NULL
)
138 printf(" Number %03d/%03d ID %04x:%04x %s\n",
139 dev
->bus_num
, dev
->dev_num
,
140 dev
->vendor_id
, dev
->product_id
,
147 struct usbentry
* find_device(int *bus
, int *dev
,
151 DIR *devs
= opendir("/sys/bus/usb/devices");
153 struct usbentry
*e
, *match
= NULL
;
158 while ((e
= parse_devlist(devs
)) != NULL
)
160 if ((bus
&& (e
->bus_num
== *bus
) && (e
->dev_num
== *dev
)) ||
161 (vid
&& (e
->vendor_id
== *vid
) && (e
->product_id
== *pid
)) ||
162 (product
&& !strcasecmp(e
->product_name
, product
)))
174 static void reset_device(struct usbentry
*dev
)
179 snprintf(path
, sizeof(path
) - 1, "/dev/bus/usb/%03d/%03d",
180 dev
->bus_num
, dev
->dev_num
);
182 printf("Resetting %s ... ", dev
->product_name
);
184 if ((fd
= open(path
, O_WRONLY
)) > -1)
186 if (ioctl(fd
, USBDEVFS_RESET
, 0) < 0)
187 printf("failed [%s]\n", strerror(errno
));
195 printf("can't open [%s]\n", strerror(errno
));
200 int main(int argc
, char **argv
)
203 struct usbentry
*dev
;
205 if ((argc
== 2) && (sscanf(argv
[1], "%3d/%3d", &id1
, &id2
) == 2))
207 dev
= find_device(&id1
, &id2
, NULL
, NULL
, NULL
);
209 else if ((argc
== 2) && (sscanf(argv
[1], "%4x:%4x", &id1
, &id2
) == 2))
211 dev
= find_device(NULL
, NULL
, &id1
, &id2
, NULL
);
213 else if ((argc
== 2) && strlen(argv
[1]) < 128)
215 dev
= find_device(NULL
, NULL
, NULL
, NULL
, argv
[1]);
220 " usbreset PPPP:VVVV - reset by product and vendor id\n"
221 " usbreset BBB/DDD - reset by bus and device number\n"
222 " usbreset \"Product\" - reset by product name\n\n"
230 fprintf(stderr
, "No such device found\n");