[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v5)
From: |
Rick Vernam |
Subject: |
Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v5) |
Date: |
Mon, 22 Sep 2008 14:47:51 -0500 |
User-agent: |
KMail/1.9.9 |
So is anything going to come of this?
I tried to apply this patch to my local svn checkout - but apparently I'm too
bone-headed to apply the patch correctly.
I'd love to test it, so I inquire - are there any plans to commit this? Or
can anyone suggest how I might apply this patch?
Thanks.
On Wednesday 17 September 2008 05:47:27 pm TJ wrote:
[snip}
> --------------------------------------
> This patch adds support for host USB devices discovered via:
>
> /sys/bus/usb/devices/* and opened from /dev/bus/usb/*/*
> /dev/bus/usb/devices and opened from /dev/bus/usb/*/*
>
> in addition to the existing discovery via:
>
> /proc/bus/usb/devices and opened from /proc/bus/usb/*/*
>
> Signed-off-by: TJ <address@hidden>
> ---
> --- a/usb-linux.c 2008-09-17 22:39:38.000000000 +0100
> +++ b/usb-linux.c 2008-09-17 23:42:32.000000000 +0100
> @@ -7,6 +7,10 @@
> * Support for host device auto connect & disconnect
> * Major rewrite to support fully async operation
> *
> + * Copyright 2008 TJ <address@hidden>
> + * Added flexible support for /dev/bus/usb /sys/bus/usb/devices in
> addition + * to the legacy /proc/bus/usb USB device discovery and
> handling + *
> * Permission is hereby granted, free of charge, to any person obtaining a
> copy * of this software and associated documentation files (the
> "Software"), to deal * in the Software without restriction, including
> without limitation the rights @@ -72,9 +76,20 @@
> #define dprintf(...)
> #endif
>
> -#define USBDEVFS_PATH "/proc/bus/usb"
> +#define USBPROCBUS_PATH "/proc/bus/usb"
> #define PRODUCT_NAME_SZ 32
> #define MAX_ENDPOINTS 16
> +#define USBDEVBUS_PATH "/dev/bus/usb"
> +#define USBSYSBUS_PATH "/sys/bus/usb"
> +
> +static char *usb_host_device_path;
> +
> +#define USB_FS_NONE 0
> +#define USB_FS_PROC 1
> +#define USB_FS_DEV 2
> +#define USB_FS_SYS 3
> +
> +static int usb_fs_type = 0;
>
> /* endpoint association data */
> struct endp_data {
> @@ -890,13 +905,18 @@
>
> printf("husb: open device %d.%d\n", bus_num, addr);
>
> - snprintf(buf, sizeof(buf), USBDEVFS_PATH "/%03d/%03d",
> + if (!usb_host_device_path) {
> + perror("husb: USB Host Device Path not set");
> + goto fail;
> + }
> + snprintf(buf, sizeof(buf), "%s/%03d/%03d", usb_host_device_path,
> bus_num, addr);
> fd = open(buf, O_RDWR | O_NONBLOCK);
> if (fd < 0) {
> perror(buf);
> goto fail;
> }
> + dprintf("husb: opened %s\n", buf);
>
> /* read the device description */
> dev->descr_len = read(fd, dev->descr, sizeof(dev->descr));
> @@ -1038,80 +1058,275 @@
> return q - buf;
> }
>
> -static int usb_host_scan(void *opaque, USBScanFunc *func)
> +/*
> + Use /proc/bus/usb/devices or /dev/bus/usb/devices file to determine
> + host's USB devices. This is legacy support since many distributions
> + are moving to /sys/bus/usb
> +*/
> +static int usb_host_scan_dev(void *opaque, USBScanFunc *func)
> {
> - FILE *f;
> + FILE *f = 0;
> char line[1024];
> char buf[1024];
> int bus_num, addr, speed, device_count, class_id, product_id,
> vendor_id; - int ret;
> char product_name[512];
> + int ret = 0;
>
> - f = fopen(USBDEVFS_PATH "/devices", "r");
> + snprintf(line, sizeof(line), "%s/devices", usb_host_device_path);
> + f = fopen(line, "r");
> if (!f) {
> - term_printf("husb: could not open %s\n", USBDEVFS_PATH
> "/devices"); - return 0;
> + perror("husb: cannot open devices file");
> + goto the_end;
> }
> +
> 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"))
> - speed = USB_SPEED_HIGH;
> - else if (!strcmp(buf, "1.5"))
> - 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 (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"))
> + speed = USB_SPEED_HIGH;
> + else if (!strcmp(buf, "1.5"))
> + 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);
> + /* Add the last device. */
> + ret = func(opaque, bus_num, addr, class_id, vendor_id,
> + product_id, product_name, speed);
> + }
> + the_end:
> + if (f) fclose(f);
> + return ret;
> +}
> +
> +/*
> + Use /sys/bus/usb/devices/ directory to determine host's USB devices.
> +
> + This code is taken from Robert Schiele's original patches posted to the
> + Novell bug-tracker https://bugzilla.novell.com/show_bug.cgi?id=241950
> +*/
> +static int usb_host_scan_sys(void *opaque, USBScanFunc *func)
> +{
> + FILE *f;
> + DIR *dir = 0;
> + char line[1024];
> + int bus_num, addr, speed, class_id, product_id, vendor_id;
> + int ret = 0;
> + char product_name[512];
> + struct dirent* de;
> +
> + dir = opendir(USBSYSBUS_PATH "/devices");
> + if (!dir) {
> + perror("husb: cannot open devices directory");
> + goto the_end;
> + }
> +
> + while ((de = readdir(dir))) {
> + 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, USBSYSBUS_PATH
> "/devices/%s/devnum", de->d_name); + f = fopen(filename, "r");
> + if (!f) {
> + term_printf("Could not open %s\n", filename);
> + goto the_end;
> + }
> + fgets(line, sizeof(line), f);
> + fclose(f);
> + addr = atoi(line);
> + snprintf(filename, PATH_MAX, USBSYSBUS_PATH
> "/devices/%s/bDeviceClass", de->d_name); + f = fopen(filename,
> "r");
> + if (!f) {
> + term_printf("Could not open %s\n", filename);
> + goto the_end;
> + }
> + fgets(line, sizeof(line), f);
> + fclose(f);
> + class_id = strtoul(line, NULL, 16);
> + snprintf(filename, PATH_MAX, USBSYSBUS_PATH
> "/devices/%s/idVendor", de->d_name); + f = fopen(filename, "r");
> + if (!f) {
> + term_printf("Could not open %s\n", filename);
> + goto the_end;
> + }
> + fgets(line, sizeof(line), f);
> + fclose(f);
> + vendor_id = strtoul(line, NULL, 16);
> + snprintf(filename, PATH_MAX, USBSYSBUS_PATH
> "/devices/%s/idProduct", de->d_name); + f = fopen(filename,
> "r");
> + if (!f) {
> + term_printf("Could not open %s\n", filename);
> + goto the_end;
> + }
> + fgets(line, sizeof(line), f);
> + fclose(f);
> + product_id = strtoul(line, NULL, 16);
> + snprintf(filename, PATH_MAX, USBSYSBUS_PATH
> "/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, USBSYSBUS_PATH
> "/devices/%s/speed", de->d_name); + f = fopen(filename, "r");
> + if (!f) {
> + term_printf("Could not open %s\n", filename);
> + goto the_end;
> + }
> + fgets(line, sizeof(line), f);
> + fclose(f);
> + if (!strcmp(line, "480\n"))
> + speed = USB_SPEED_HIGH;
> + else if (!strcmp(line, "1.5\n"))
> + speed = USB_SPEED_LOW;
> + else
> + speed = USB_SPEED_FULL;
> +
> + ret = func(opaque, bus_num, addr, class_id, vendor_id,
> + product_id, product_name, speed);
> + if (ret)
> + goto the_end;
> + }
> + }
> + the_end:
> + if (dir) closedir(dir);
> + return ret;
> +}
> +
> +/*
> + Determine how to access the host's USB devices and call the specific
> + support function.
> + */
> +static int usb_host_scan(void *opaque, USBScanFunc *func)
> +{
> + FILE *f = 0;
> + DIR *dir = 0;
> + int ret = 0;
> + const char *devices = "/devices";
> + const char *trying = "husb: trying to open %s%s\n";
> + const char *failed = "husb: could not open %s%s\n";
> + char devpath[PATH_MAX];
> +
> + // only check the host once
> + if (!usb_fs_type) {
> + // test for dev file-system access in /proc/
> + dprintf(trying, USBPROCBUS_PATH, devices);
> + f = fopen(USBPROCBUS_PATH "/devices", "r");
> + if (!f) {
> + dprintf(failed, USBPROCBUS_PATH, devices);
> + // maybe it has been moved to the /dev/ base
> + dprintf(trying, USBDEVBUS_PATH, devices);
> + f = fopen(USBDEVBUS_PATH "/devices", "r");
> + if (!f) {
> + dprintf(failed, USBDEVBUS_PATH, devices);
> + // test for newer sys file-system access
> + dprintf(trying, USBSYSBUS_PATH, devices);
> + dir = opendir(USBSYSBUS_PATH "/devices");
> + if (!dir) {
> + dprintf(failed, USBSYSBUS_PATH, devices);
> + goto the_end;
> + }
> + else { // devices found in /dev/bus/usb/ (yes - not a
> mistake!) + strcpy(devpath, USBDEVBUS_PATH);
> + usb_fs_type = USB_FS_SYS;
> + }
> + if (dir) closedir(dir);
> + }
> + else { // devices found in /dev/bus/usb/
> + strcpy(devpath, USBDEVBUS_PATH);
> + usb_fs_type = USB_FS_DEV;
> + }
> + }
> + else { // devices found in /proc/bus/usb/
> + strcpy(devpath, USBPROCBUS_PATH);
> + usb_fs_type = USB_FS_PROC;
> + }
> + if (f) fclose(f);
> +
> + // the module setting (used later for opening devices)
> + usb_host_device_path = qemu_mallocz(strlen(devpath)+1);
> + if (usb_host_device_path) {
> + strcpy(usb_host_device_path, devpath);
> + term_printf("husb: using %s\n", usb_host_device_path);
> + }
> + else { // out of memory?
> + perror("husb: unable to allocate memory for device path");
> + goto the_end;
> + }
> + }
> +
> + switch (usb_fs_type) {
> + case USB_FS_PROC:
> + case USB_FS_DEV:
> + ret = usb_host_scan_dev(opaque, func);
> + break;
> + case USB_FS_SYS:
> + ret = usb_host_scan_sys(opaque, func);
> + break;
> }
> the_end:
> - fclose(f);
> return ret;
> }
- Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v2), (continued)
- Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v2), Jason Wessel, 2008/09/05
- [Qemu-devel] [PATCH] Add USB sys file-system support (v3), TJ, 2008/09/05
- [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v3), Jason Wessel, 2008/09/08
- [Qemu-devel] [PATCH] Add USB sys file-system support (v4), TJ, 2008/09/17
- [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v4), Anthony Liguori, 2008/09/17
- [Qemu-devel] [PATCH] Add USB sys file-system support (v5), TJ, 2008/09/17
- Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v5),
Rick Vernam <=
- Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v5), Anthony Liguori, 2008/09/22
- Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v5), Rick Vernam, 2008/09/25
- Re: [Qemu-devel] [PATCH] Add USB sys file-system support (v5), Anthony Liguori, 2008/09/25
- [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v5), Anthony Liguori, 2008/09/22
- Re: [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v5), TJ, 2008/09/22
- [Qemu-devel] [PATCH] Add USB sys file-system support (v6), TJ, 2008/09/22
- [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v6), Anthony Liguori, 2008/09/25
- Re: [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v6), Jason Wessel, 2008/09/26
- Re: [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v6), Anthony Liguori, 2008/09/26
- Re: [Qemu-devel] Re: [PATCH] Add USB sys file-system support (v6), Robert Riebisch, 2008/09/26