250 lines
8.1 KiB
Diff
250 lines
8.1 KiB
Diff
|
--- usb-linux.c 2006-07-22 19:23:34.000000000 +0200
|
||
|
+++ usb-linux.c 2007-02-03 09:26:48.000000000 +0100
|
||
|
@@ -26,9 +26,16 @@
|
||
|
#if defined(__linux__)
|
||
|
#include <dirent.h>
|
||
|
#include <sys/ioctl.h>
|
||
|
-#include <linux/compiler.h>
|
||
|
-#include <linux/usbdevice_fs.h>
|
||
|
-#include <linux/version.h>
|
||
|
+struct usbdevfs_bulktransfer {
|
||
|
+ unsigned int ep;
|
||
|
+ unsigned int len;
|
||
|
+ unsigned int timeout; /* in milliseconds */
|
||
|
+ void *data;
|
||
|
+};
|
||
|
+struct usbdevfs_connectinfo {
|
||
|
+ unsigned int devnum;
|
||
|
+ unsigned char slow;
|
||
|
+};
|
||
|
|
||
|
/* We redefine it to avoid version problems */
|
||
|
struct usb_ctrltransfer {
|
||
|
@@ -50,7 +57,7 @@
|
||
|
|
||
|
//#define DEBUG
|
||
|
|
||
|
-#define USBDEVFS_PATH "/proc/bus/usb"
|
||
|
+#define USBDEVFS_PATH "/dev/bus/usb"
|
||
|
#define PRODUCT_NAME_SZ 32
|
||
|
|
||
|
typedef struct USBHostDevice {
|
||
|
@@ -100,7 +107,8 @@
|
||
|
ct.wLength = length;
|
||
|
ct.timeout = 50;
|
||
|
ct.data = data;
|
||
|
- ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
|
||
|
+ //ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
|
||
|
+ ret = ioctl(s->fd, _IOWR('U', 0, struct usb_ctrltransfer), &ct);
|
||
|
if (ret < 0) {
|
||
|
switch(errno) {
|
||
|
case ETIMEDOUT:
|
||
|
@@ -130,7 +138,8 @@
|
||
|
bt.len = len;
|
||
|
bt.timeout = 50;
|
||
|
bt.data = data;
|
||
|
- ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
|
||
|
+ //ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
|
||
|
+ ret = ioctl(s->fd, _IOWR('U', 2, struct usbdevfs_bulktransfer), &bt);
|
||
|
if (ret < 0) {
|
||
|
switch(errno) {
|
||
|
case ETIMEDOUT:
|
||
|
@@ -210,7 +219,8 @@
|
||
|
|
||
|
/* XXX: only grab if all interfaces are free */
|
||
|
interface = 0;
|
||
|
- ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
|
||
|
+ //ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
|
||
|
+ ret = ioctl(fd, _IOR('U', 15, unsigned int), &interface);
|
||
|
if (ret < 0) {
|
||
|
if (errno == EBUSY) {
|
||
|
fprintf(stderr, "usb_host: device already grabbed\n");
|
||
|
@@ -222,7 +232,8 @@
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
- ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
|
||
|
+ //ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
|
||
|
+ ret = ioctl(fd, _IOW('U', 17, struct usbdevfs_connectinfo), &ci);
|
||
|
if (ret < 0) {
|
||
|
perror("USBDEVFS_CONNECTINFO");
|
||
|
goto fail;
|
||
|
@@ -257,102 +268,96 @@
|
||
|
return (USBDevice *)dev;
|
||
|
}
|
||
|
|
||
|
-static int get_tag_value(char *buf, int buf_size,
|
||
|
- const char *str, const char *tag,
|
||
|
- const char *stopchars)
|
||
|
-{
|
||
|
- const char *p;
|
||
|
- char *q;
|
||
|
- p = strstr(str, tag);
|
||
|
- if (!p)
|
||
|
- return -1;
|
||
|
- p += strlen(tag);
|
||
|
- while (isspace(*p))
|
||
|
- p++;
|
||
|
- q = buf;
|
||
|
- while (*p != '\0' && !strchr(stopchars, *p)) {
|
||
|
- if ((q - buf) < (buf_size - 1))
|
||
|
- *q++ = *p;
|
||
|
- p++;
|
||
|
- }
|
||
|
- *q = '\0';
|
||
|
- return q - buf;
|
||
|
-}
|
||
|
-
|
||
|
static int usb_host_scan(void *opaque, USBScanFunc *func)
|
||
|
{
|
||
|
FILE *f;
|
||
|
char line[1024];
|
||
|
- char buf[1024];
|
||
|
- int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
|
||
|
+ int bus_num, addr, speed, class_id, product_id, vendor_id;
|
||
|
int ret;
|
||
|
char product_name[512];
|
||
|
+ DIR* d;
|
||
|
+ struct dirent* de;
|
||
|
|
||
|
- f = fopen(USBDEVFS_PATH "/devices", "r");
|
||
|
- if (!f) {
|
||
|
- term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
|
||
|
+ d = opendir("/sys/bus/usb/devices");
|
||
|
+ if (!d) {
|
||
|
+ term_printf("Could not open /sys/bus/usb/devices\n");
|
||
|
return 0;
|
||
|
}
|
||
|
- device_count = 0;
|
||
|
- bus_num = addr = speed = class_id = product_id = vendor_id = 0;
|
||
|
- ret = 0;
|
||
|
- for(;;) {
|
||
|
- if (fgets(line, sizeof(line), f) == NULL)
|
||
|
- break;
|
||
|
- if (strlen(line) > 0)
|
||
|
- line[strlen(line) - 1] = '\0';
|
||
|
- if (line[0] == 'T' && line[1] == ':') {
|
||
|
- if (device_count && (vendor_id || product_id)) {
|
||
|
- /* New device. Add the previously discovered device. */
|
||
|
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
|
||
|
- product_id, product_name, speed);
|
||
|
- if (ret)
|
||
|
- goto the_end;
|
||
|
- }
|
||
|
- if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
|
||
|
- goto fail;
|
||
|
- bus_num = atoi(buf);
|
||
|
- if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
|
||
|
- goto fail;
|
||
|
- addr = atoi(buf);
|
||
|
- if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
|
||
|
- goto fail;
|
||
|
- if (!strcmp(buf, "480"))
|
||
|
+ while ((de = readdir(d))) {
|
||
|
+ if (de->d_name[0] != '.' && ! strchr(de->d_name, ':')) {
|
||
|
+ char filename[PATH_MAX];
|
||
|
+ char* tmpstr = de->d_name;
|
||
|
+ if (!strncmp(de->d_name, "usb", 3))
|
||
|
+ tmpstr += 3;
|
||
|
+ bus_num = atoi(tmpstr);
|
||
|
+ snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/devnum", de->d_name);
|
||
|
+ f = fopen(filename, "r");
|
||
|
+ if (!f) {
|
||
|
+ term_printf("Could not open %s\n", filename);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ fgets(line, sizeof(line), f);
|
||
|
+ fclose(f);
|
||
|
+ addr = atoi(line);
|
||
|
+ snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/bDeviceClass", de->d_name);
|
||
|
+ f = fopen(filename, "r");
|
||
|
+ if (!f) {
|
||
|
+ term_printf("Could not open %s\n", filename);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ fgets(line, sizeof(line), f);
|
||
|
+ fclose(f);
|
||
|
+ class_id = strtoul(line, NULL, 16);
|
||
|
+ snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/idVendor", de->d_name);
|
||
|
+ f = fopen(filename, "r");
|
||
|
+ if (!f) {
|
||
|
+ term_printf("Could not open %s\n", filename);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ fgets(line, sizeof(line), f);
|
||
|
+ fclose(f);
|
||
|
+ vendor_id = strtoul(line, NULL, 16);
|
||
|
+ snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/idProduct", de->d_name);
|
||
|
+ f = fopen(filename, "r");
|
||
|
+ if (!f) {
|
||
|
+ term_printf("Could not open %s\n", filename);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ fgets(line, sizeof(line), f);
|
||
|
+ fclose(f);
|
||
|
+ product_id = strtoul(line, NULL, 16);
|
||
|
+ snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/product", de->d_name);
|
||
|
+ f = fopen(filename, "r");
|
||
|
+ if (f) {
|
||
|
+ fgets(line, sizeof(line), f);
|
||
|
+ fclose(f);
|
||
|
+ if (strlen(line) > 0)
|
||
|
+ line[strlen(line) - 1] = '\0';
|
||
|
+ pstrcpy(product_name, sizeof(product_name), line);
|
||
|
+ } else
|
||
|
+ *product_name = 0;
|
||
|
+ snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/speed", de->d_name);
|
||
|
+ f = fopen(filename, "r");
|
||
|
+ if (!f) {
|
||
|
+ term_printf("Could not open %s\n", filename);
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ fgets(line, sizeof(line), f);
|
||
|
+ fclose(f);
|
||
|
+ if (!strcmp(line, "480\n"))
|
||
|
speed = USB_SPEED_HIGH;
|
||
|
- else if (!strcmp(buf, "1.5"))
|
||
|
+ else if (!strcmp(line, "1.5\n"))
|
||
|
speed = USB_SPEED_LOW;
|
||
|
else
|
||
|
speed = USB_SPEED_FULL;
|
||
|
- product_name[0] = '\0';
|
||
|
- class_id = 0xff;
|
||
|
- device_count++;
|
||
|
- product_id = 0;
|
||
|
- vendor_id = 0;
|
||
|
- } else if (line[0] == 'P' && line[1] == ':') {
|
||
|
- if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
|
||
|
- goto fail;
|
||
|
- vendor_id = strtoul(buf, NULL, 16);
|
||
|
- if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
|
||
|
- goto fail;
|
||
|
- product_id = strtoul(buf, NULL, 16);
|
||
|
- } else if (line[0] == 'S' && line[1] == ':') {
|
||
|
- if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
|
||
|
- goto fail;
|
||
|
- pstrcpy(product_name, sizeof(product_name), buf);
|
||
|
- } else if (line[0] == 'D' && line[1] == ':') {
|
||
|
- if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
|
||
|
- goto fail;
|
||
|
- class_id = strtoul(buf, NULL, 16);
|
||
|
- }
|
||
|
- fail: ;
|
||
|
- }
|
||
|
- if (device_count && (vendor_id || product_id)) {
|
||
|
- /* Add the last device. */
|
||
|
- ret = func(opaque, bus_num, addr, class_id, vendor_id,
|
||
|
- product_id, product_name, speed);
|
||
|
+ ret = func(opaque, bus_num, addr, class_id, vendor_id,
|
||
|
+ product_id, product_name, speed);
|
||
|
+ if (ret)
|
||
|
+ goto the_end;
|
||
|
+ }
|
||
|
}
|
||
|
the_end:
|
||
|
- fclose(f);
|
||
|
+ closedir(d);
|
||
|
return ret;
|
||
|
}
|
||
|
|