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

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

Return to bug 241950