From: Igor Kotrasinski <i.kotrasi...@samsung.com>

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 <ikotrasi...@gmail.com>
   Karol Kosik <ka...@interia.eu>
   Ewelina Kosmider <3w3l...@gmail.com>
   Dawid Lazarczyk <lazarczyk.da...@gmail.com>
   Piotr Szulc <ps347...@students.mimuw.edu.pl>

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

Signed-off-by: Igor Kotrasinski <i.kotrasi...@samsung.com>
Signed-off-by: Ewelina Kosmider <3w3l...@gmail.com>
[Various bug fixes and improvements]
Signed-off-by: Krzysztof Opasiak <k.opas...@samsung.com>
---
 tools/usb/usbip/src/usbip_attach.c |   10 +++-
 tools/usb/usbip/src/usbip_list.c   |   96 ++++++++++++++++++++++++++++++++++--
 tools/usb/usbip/src/usbipd.c       |   12 ++++-
 3 files changed, 112 insertions(+), 6 deletions(-)

diff --git a/tools/usb/usbip/src/usbip_attach.c 
b/tools/usb/usbip/src/usbip_attach.c
index d58a14d..70a6b50 100644
--- a/tools/usb/usbip/src/usbip_attach.c
+++ b/tools/usb/usbip/src/usbip_attach.c
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <m...@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasi...@samsung.com>
+ *               Krzysztof Opasiak <k.opas...@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;
diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c
index d5ce34a..f1b38e8 100644
--- a/tools/usb/usbip/src/usbip_list.c
+++ b/tools/usb/usbip/src/usbip_list.c
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2011 matt mooney <m...@muteddisk.com>
  *               2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2015-2016 Samsung Electronics
+ *               Igor Kotrasinski <i.kotrasi...@samsung.com>
+ *               Krzysztof Opasiak <k.opas...@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
@@ -30,6 +33,10 @@
 #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;
                }
diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c
index 8a2ec4d..a0972de 100644
--- a/tools/usb/usbip/src/usbipd.c
+++ b/tools/usb/usbip/src/usbipd.c
@@ -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:
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to