usbip: tools: Start using VUDC backend in usbip tools
authorIgor Kotrasinski <i.kotrasinsk@samsung.com>
Tue, 8 Mar 2016 20:49:06 +0000 (21:49 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 26 Apr 2016 22:19:50 +0000 (15:19 -0700)
Modify userspace tools to allow exporting and connecting to vudc.

This commit is a result of cooperation between Samsung R&D Institute
Poland and Open Operating Systems Student Society at University
of Warsaw (O2S3@UW) consisting of:

   Igor Kotrasinski <ikotrasinsk@gmail.com>
   Karol Kosik <karo9@interia.eu>
   Ewelina Kosmider <3w3lfin@gmail.com>
   Dawid Lazarczyk <lazarczyk.dawid@gmail.com>
   Piotr Szulc <ps347277@students.mimuw.edu.pl>

Tutor and project owner:
   Krzysztof Opasiak <k.opasiak@samsung.com>

Signed-off-by: Igor Kotrasinski <i.kotrasinsk@samsung.com>
Signed-off-by: Ewelina Kosmider <3w3lfin@gmail.com>
[Various bug fixes and improvements]
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
tools/usb/usbip/src/usbip_attach.c
tools/usb/usbip/src/usbip_list.c
tools/usb/usbip/src/usbipd.c

index d58a14d..70a6b50 100644 (file)
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,7 +39,8 @@
 static const char usbip_attach_usage_string[] =
        "usbip attach <args>\n"
        "    -r, --remote=<host>      The machine with exported USB devices\n"
-       "    -b, --busid=<busid>    Busid of the device on <host>\n";
+       "    -b, --busid=<busid>    Busid of the device on <host>\n"
+       "    -d, --device=<devid>    Id of the virtual UDC on <host>\n";
 
 void usbip_attach_usage(void)
 {
@@ -203,6 +207,7 @@ int usbip_attach(int argc, char *argv[])
        static const struct option opts[] = {
                { "remote", required_argument, NULL, 'r' },
                { "busid",  required_argument, NULL, 'b' },
+               { "device",  required_argument, NULL, 'd' },
                { NULL, 0,  NULL, 0 }
        };
        char *host = NULL;
@@ -211,7 +216,7 @@ int usbip_attach(int argc, char *argv[])
        int ret = -1;
 
        for (;;) {
-               opt = getopt_long(argc, argv, "r:b:", opts, NULL);
+               opt = getopt_long(argc, argv, "d:r:b:", opts, NULL);
 
                if (opt == -1)
                        break;
@@ -220,6 +225,7 @@ int usbip_attach(int argc, char *argv[])
                case 'r':
                        host = optarg;
                        break;
+               case 'd':
                case 'b':
                        busid = optarg;
                        break;
index d5ce34a..f1b38e8 100644 (file)
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasinsk@samsung.com>
+ *               Krzysztof Opasiak <k.opasiak@samsung.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 #include <netdb.h>
 #include <unistd.h>
 
+#include <dirent.h>
+
+#include <linux/usb/ch9.h>
+
 #include "usbip_common.h"
 #include "usbip_network.h"
 #include "usbip.h"
@@ -205,8 +212,10 @@ static int list_devices(bool parsable)
                /* Get device information. */
                idVendor = udev_device_get_sysattr_value(dev, "idVendor");
                idProduct = udev_device_get_sysattr_value(dev, "idProduct");
-               bConfValue = udev_device_get_sysattr_value(dev, "bConfigurationValue");
-               bNumIntfs = udev_device_get_sysattr_value(dev, "bNumInterfaces");
+               bConfValue = udev_device_get_sysattr_value(dev,
+                               "bConfigurationValue");
+               bNumIntfs = udev_device_get_sysattr_value(dev,
+                               "bNumInterfaces");
                busid = udev_device_get_sysname(dev);
                if (!idVendor || !idProduct || !bConfValue || !bNumIntfs) {
                        err("problem getting device attributes: %s",
@@ -237,12 +246,90 @@ err_out:
        return ret;
 }
 
+static int list_gadget_devices(bool parsable)
+{
+       int ret = -1;
+       struct udev *udev;
+       struct udev_enumerate *enumerate;
+       struct udev_list_entry *devices, *dev_list_entry;
+       struct udev_device *dev;
+       const char *path;
+       const char *driver;
+
+       const struct usb_device_descriptor *d_desc;
+       const char *descriptors;
+       char product_name[128];
+
+       uint16_t idVendor;
+       char idVendor_buf[8];
+       uint16_t idProduct;
+       char idProduct_buf[8];
+       const char *busid;
+
+       udev = udev_new();
+       enumerate = udev_enumerate_new(udev);
+
+       udev_enumerate_add_match_subsystem(enumerate, "platform");
+
+       udev_enumerate_scan_devices(enumerate);
+       devices = udev_enumerate_get_list_entry(enumerate);
+
+       udev_list_entry_foreach(dev_list_entry, devices) {
+               path = udev_list_entry_get_name(dev_list_entry);
+               dev = udev_device_new_from_syspath(udev, path);
+
+               driver = udev_device_get_driver(dev);
+               /* We only have mechanism to enumerate gadgets bound to vudc */
+               if (driver == NULL || strcmp(driver, USBIP_DEVICE_DRV_NAME))
+                       continue;
+
+               /* Get device information. */
+               descriptors = udev_device_get_sysattr_value(dev,
+                               VUDC_DEVICE_DESCR_FILE);
+
+               if (!descriptors) {
+                       err("problem getting device attributes: %s",
+                           strerror(errno));
+                       goto err_out;
+               }
+
+               d_desc = (const struct usb_device_descriptor *) descriptors;
+
+               idVendor = le16toh(d_desc->idVendor);
+               sprintf(idVendor_buf, "0x%4x", idVendor);
+               idProduct = le16toh(d_desc->idProduct);
+               sprintf(idProduct_buf, "0x%4x", idVendor);
+               busid = udev_device_get_sysname(dev);
+
+               /* Get product name. */
+               usbip_names_get_product(product_name, sizeof(product_name),
+                                       le16toh(idVendor),
+                                       le16toh(idProduct));
+
+               /* Print information. */
+               print_device(busid, idVendor_buf, idProduct_buf, parsable);
+               print_product_name(product_name, parsable);
+
+               printf("\n");
+
+               udev_device_unref(dev);
+       }
+       ret = 0;
+
+err_out:
+       udev_enumerate_unref(enumerate);
+       udev_unref(udev);
+
+       return ret;
+}
+
 int usbip_list(int argc, char *argv[])
 {
        static const struct option opts[] = {
                { "parsable", no_argument,       NULL, 'p' },
                { "remote",   required_argument, NULL, 'r' },
                { "local",    no_argument,       NULL, 'l' },
+               { "device",    no_argument,       NULL, 'd' },
                { NULL,       0,                 NULL,  0  }
        };
 
@@ -254,7 +341,7 @@ int usbip_list(int argc, char *argv[])
                err("failed to open %s", USBIDS_FILE);
 
        for (;;) {
-               opt = getopt_long(argc, argv, "pr:l", opts, NULL);
+               opt = getopt_long(argc, argv, "pr:ld", opts, NULL);
 
                if (opt == -1)
                        break;
@@ -269,6 +356,9 @@ int usbip_list(int argc, char *argv[])
                case 'l':
                        ret = list_devices(parsable);
                        goto out;
+               case 'd':
+                       ret = list_gadget_devices(parsable);
+                       goto out;
                default:
                        goto err_out;
                }
index 8a2ec4d..a0972de 100644 (file)
@@ -45,6 +45,7 @@
 
 #include "usbip_host_driver.h"
 #include "usbip_host_common.h"
+#include "usbip_device_driver.h"
 #include "usbip_common.h"
 #include "usbip_network.h"
 #include "list.h"
@@ -68,6 +69,11 @@ static const char usbipd_help_string[] =
        "       -6, --ipv6\n"
        "               Bind to IPv6. Default is both.\n"
        "\n"
+       "       -e, --device\n"
+       "               Run in device mode.\n"
+       "               Rather than drive an attached device, create\n"
+       "               a virtual UDC to bind gadgets to.\n"
+       "\n"
        "       -D, --daemon\n"
        "               Run as a daemon process.\n"
        "\n"
@@ -590,6 +596,7 @@ int main(int argc, char *argv[])
                { "daemon",   no_argument,       NULL, 'D' },
                { "daemon",   no_argument,       NULL, 'D' },
                { "debug",    no_argument,       NULL, 'd' },
+               { "device",   no_argument,       NULL, 'e' },
                { "pid",      optional_argument, NULL, 'P' },
                { "tcp-port", required_argument, NULL, 't' },
                { "help",     no_argument,       NULL, 'h' },
@@ -618,7 +625,7 @@ int main(int argc, char *argv[])
        cmd = cmd_standalone_mode;
        driver = &host_driver;
        for (;;) {
-               opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL);
+               opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL);
 
                if (opt == -1)
                        break;
@@ -648,6 +655,9 @@ int main(int argc, char *argv[])
                case 'v':
                        cmd = cmd_version;
                        break;
+               case 'e':
+                       driver = &device_driver;
+                       break;
                case '?':
                        usbipd_help();
                default: