View | Details | Raw Unified | Return to bug 241950
Collapse All | Expand All

(-)usb-linux.c (-88 / +95 lines)
Lines 26-33 Link Here
26
#if defined(__linux__)
26
#if defined(__linux__)
27
#include <dirent.h>
27
#include <dirent.h>
28
#include <sys/ioctl.h>
28
#include <sys/ioctl.h>
29
#include <linux/usbdevice_fs.h>
29
struct usbdevfs_bulktransfer {
30
#include <linux/version.h>
30
        unsigned int ep;
31
        unsigned int len;
32
        unsigned int timeout; /* in milliseconds */
33
        void *data;
34
};
35
struct usbdevfs_connectinfo {
36
        unsigned int devnum;
37
        unsigned char slow;
38
};
31
39
32
/* We redefine it to avoid version problems */
40
/* We redefine it to avoid version problems */
33
struct usb_ctrltransfer {
41
struct usb_ctrltransfer {
Lines 49-55 Link Here
49
57
50
//#define DEBUG
58
//#define DEBUG
51
59
52
#define USBDEVFS_PATH "/proc/bus/usb"
60
#define USBDEVFS_PATH "/dev/bus/usb"
53
#define PRODUCT_NAME_SZ 32
61
#define PRODUCT_NAME_SZ 32
54
62
55
typedef struct USBHostDevice {
63
typedef struct USBHostDevice {
Lines 99-105 Link Here
99
        ct.wLength = length;
107
        ct.wLength = length;
100
        ct.timeout = 50;
108
        ct.timeout = 50;
101
        ct.data = data;
109
        ct.data = data;
102
        ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
110
        //ret = ioctl(s->fd, USBDEVFS_CONTROL, &ct);
111
        ret = ioctl(s->fd, _IOWR('U', 0, struct usb_ctrltransfer), &ct);
103
        if (ret < 0) {
112
        if (ret < 0) {
104
            switch(errno) {
113
            switch(errno) {
105
            case ETIMEDOUT:
114
            case ETIMEDOUT:
Lines 128-134 Link Here
128
    bt.len = p->len;
137
    bt.len = p->len;
129
    bt.timeout = 50;
138
    bt.timeout = 50;
130
    bt.data = p->data;
139
    bt.data = p->data;
131
    ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
140
    //ret = ioctl(s->fd, USBDEVFS_BULK, &bt);
141
    ret = ioctl(s->fd, _IOWR('U', 2, struct usbdevfs_bulktransfer), &bt);
132
    if (ret < 0) {
142
    if (ret < 0) {
133
        switch(errno) {
143
        switch(errno) {
134
        case ETIMEDOUT:
144
        case ETIMEDOUT:
Lines 208-214 Link Here
208
218
209
    /* XXX: only grab if all interfaces are free */
219
    /* XXX: only grab if all interfaces are free */
210
    interface = 0;
220
    interface = 0;
211
    ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
221
    //ret = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &interface);
222
    ret = ioctl(fd, _IOR('U', 15, unsigned int), &interface);
212
    if (ret < 0) {
223
    if (ret < 0) {
213
        if (errno == EBUSY) {
224
        if (errno == EBUSY) {
214
            fprintf(stderr, "usb_host: device already grabbed\n");
225
            fprintf(stderr, "usb_host: device already grabbed\n");
Lines 220-226 Link Here
220
        return NULL;
231
        return NULL;
221
    }
232
    }
222
233
223
    ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
234
    //ret = ioctl(fd, USBDEVFS_CONNECTINFO, &ci);
235
    ret = ioctl(fd, _IOW('U', 17, struct usbdevfs_connectinfo), &ci);
224
    if (ret < 0) {
236
    if (ret < 0) {
225
        perror("USBDEVFS_CONNECTINFO");
237
        perror("USBDEVFS_CONNECTINFO");
226
        goto fail;
238
        goto fail;
Lines 255-356 Link Here
255
    return (USBDevice *)dev;
267
    return (USBDevice *)dev;
256
}
268
}
257
269
258
static int get_tag_value(char *buf, int buf_size,
259
                         const char *str, const char *tag, 
260
                         const char *stopchars)
261
{
262
    const char *p;
263
    char *q;
264
    p = strstr(str, tag);
265
    if (!p)
266
        return -1;
267
    p += strlen(tag);
268
    while (isspace(*p))
269
        p++;
270
    q = buf;
271
    while (*p != '\0' && !strchr(stopchars, *p)) {
272
        if ((q - buf) < (buf_size - 1))
273
            *q++ = *p;
274
        p++;
275
    }
276
    *q = '\0';
277
    return q - buf;
278
}
279
280
static int usb_host_scan(void *opaque, USBScanFunc *func)
270
static int usb_host_scan(void *opaque, USBScanFunc *func)
281
{
271
{
282
    FILE *f;
272
    FILE *f;
283
    char line[1024];
273
    char line[1024];
284
    char buf[1024];
274
    int bus_num, addr, speed, class_id, product_id, vendor_id;
285
    int bus_num, addr, speed, device_count, class_id, product_id, vendor_id;
286
    int ret;
275
    int ret;
287
    char product_name[512];
276
    char product_name[512];
277
    DIR* d;
278
    struct dirent* de;
288
    
279
    
289
    f = fopen(USBDEVFS_PATH "/devices", "r");
280
    d = opendir("/sys/bus/usb/devices");
290
    if (!f) {
281
    if (!d) {
291
        term_printf("Could not open %s\n", USBDEVFS_PATH "/devices");
282
        term_printf("Could not open /sys/bus/usb/devices\n");
292
        return 0;
283
        return 0;
293
    }
284
    }
294
    device_count = 0;
285
    while ((de = readdir(d))) {
295
    bus_num = addr = speed = class_id = product_id = vendor_id = 0;
286
	if (de->d_name[0] != '.' && ! strchr(de->d_name, ':')) {
296
    ret = 0;
287
	    char filename[PATH_MAX];
297
    for(;;) {
288
	    char* tmpstr = de->d_name;
298
        if (fgets(line, sizeof(line), f) == NULL)
289
	    if (!strncmp(de->d_name, "usb", 3))
299
            break;
290
		tmpstr += 3;
300
        if (strlen(line) > 0)
291
	    bus_num = atoi(tmpstr);
301
            line[strlen(line) - 1] = '\0';
292
	    snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/devnum", de->d_name);
302
        if (line[0] == 'T' && line[1] == ':') {
293
	    f = fopen(filename, "r");
303
            if (device_count && (vendor_id || product_id)) {
294
	    if (!f) {
304
                /* New device.  Add the previously discovered device.  */
295
	        term_printf("Could not open %s\n", filename);
305
                ret = func(opaque, bus_num, addr, class_id, vendor_id, 
296
	        return 0;
306
                           product_id, product_name, speed);
297
	    }
307
                if (ret)
298
            fgets(line, sizeof(line), f);
308
                    goto the_end;
299
	    fclose(f);
309
            }
300
	    addr = atoi(line);
310
            if (get_tag_value(buf, sizeof(buf), line, "Bus=", " ") < 0)
301
	    snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/bDeviceClass", de->d_name);
311
                goto fail;
302
	    f = fopen(filename, "r");
312
            bus_num = atoi(buf);
303
	    if (!f) {
313
            if (get_tag_value(buf, sizeof(buf), line, "Dev#=", " ") < 0)
304
	        term_printf("Could not open %s\n", filename);
314
                goto fail;
305
	        return 0;
315
            addr = atoi(buf);
306
	    }
316
            if (get_tag_value(buf, sizeof(buf), line, "Spd=", " ") < 0)
307
            fgets(line, sizeof(line), f);
317
                goto fail;
308
	    fclose(f);
318
            if (!strcmp(buf, "480"))
309
	    class_id = strtoul(line, NULL, 16);
310
	    snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/idVendor", de->d_name);
311
	    f = fopen(filename, "r");
312
	    if (!f) {
313
	        term_printf("Could not open %s\n", filename);
314
	        return 0;
315
	    }
316
            fgets(line, sizeof(line), f);
317
	    fclose(f);
318
	    vendor_id = strtoul(line, NULL, 16);
319
	    snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/idProduct", de->d_name);
320
	    f = fopen(filename, "r");
321
	    if (!f) {
322
	        term_printf("Could not open %s\n", filename);
323
	        return 0;
324
	    }
325
            fgets(line, sizeof(line), f);
326
	    fclose(f);
327
	    product_id = strtoul(line, NULL, 16);
328
	    snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/product", de->d_name);
329
	    f = fopen(filename, "r");
330
	    if (!f) {
331
	        term_printf("Could not open %s\n", filename);
332
	        return 0;
333
	    }
334
            fgets(line, sizeof(line), f);
335
	    fclose(f);
336
            if (strlen(line) > 0)
337
            	line[strlen(line) - 1] = '\0';
338
            pstrcpy(product_name, sizeof(product_name), line);
339
	    snprintf(filename, PATH_MAX, "/sys/bus/usb/devices/%s/speed", de->d_name);
340
	    f = fopen(filename, "r");
341
	    if (!f) {
342
	        term_printf("Could not open %s\n", filename);
343
	        return 0;
344
	    }
345
            fgets(line, sizeof(line), f);
346
	    fclose(f);
347
            if (!strcmp(line, "480\n"))
319
                speed = USB_SPEED_HIGH;
348
                speed = USB_SPEED_HIGH;
320
            else if (!strcmp(buf, "1.5"))
349
            else if (!strcmp(line, "1.5\n"))
321
                speed = USB_SPEED_LOW;
350
                speed = USB_SPEED_LOW;
322
            else
351
            else
323
                speed = USB_SPEED_FULL;
352
                speed = USB_SPEED_FULL;
324
            product_name[0] = '\0';
353
	    ret = func(opaque, bus_num, addr, class_id, vendor_id,
325
            class_id = 0xff;
354
                       product_id, product_name, speed);
326
            device_count++;
355
            if (ret)
327
            product_id = 0;
356
                goto the_end;
328
            vendor_id = 0;
357
	}
329
        } else if (line[0] == 'P' && line[1] == ':') {
330
            if (get_tag_value(buf, sizeof(buf), line, "Vendor=", " ") < 0)
331
                goto fail;
332
            vendor_id = strtoul(buf, NULL, 16);
333
            if (get_tag_value(buf, sizeof(buf), line, "ProdID=", " ") < 0)
334
                goto fail;
335
            product_id = strtoul(buf, NULL, 16);
336
        } else if (line[0] == 'S' && line[1] == ':') {
337
            if (get_tag_value(buf, sizeof(buf), line, "Product=", "") < 0)
338
                goto fail;
339
            pstrcpy(product_name, sizeof(product_name), buf);
340
        } else if (line[0] == 'D' && line[1] == ':') {
341
            if (get_tag_value(buf, sizeof(buf), line, "Cls=", " (") < 0)
342
                goto fail;
343
            class_id = strtoul(buf, NULL, 16);
344
        }
345
    fail: ;
346
    }
347
    if (device_count && (vendor_id || product_id)) {
348
        /* Add the last device.  */
349
        ret = func(opaque, bus_num, addr, class_id, vendor_id, 
350
                   product_id, product_name, speed);
351
    }
358
    }
352
 the_end:
359
 the_end:
353
    fclose(f);
360
    closedir(d);
354
    return ret;
361
    return ret;
355
}
362
}
356
363

Return to bug 241950