2011-05-26 13:17:24

by matt mooney

[permalink] [raw]
Subject: [PATCH 0/6] usbip: userspace improvements

Hi Greg,

Here is a series to go in your queue until you have time to look at
them and open up your tree for patches. The major patch in the series
is userspace tools v1.0.0. There is a _lot_ of work left to improve
the userspace stuff, but this is what I think is a big step in the
right direction, which will lead into major work in the kernel code.

I would also like to let you guys know (Arjan!) that I am working on
a draft of a protocol for usbip. This will attempt to provide a
well-defined and unified userspace and kernel protocol, along with
providing some documentation of what usbip is doing, which seems to be
in high demand. The goal is to have interoperability between different
systems without the need to have the same implementation. I will post
a draft soon so that everyone interested can help me refine it.
Unfortunately, I am going out of town for the next few days, so I am
not exactly sure when that will be.

Thanks,
matt


matt mooney (6):
staging: usbip: userspace: set kernel module names in one place
staging: usbip: userspace: change struct class_device to
usbip_class_device
staging: usbip: userspace: vhci_driver: parameterize path names
staging: usbip: userspace tools v1.0.0
staging: usbip: userspace: usbipd.c: add header into source file
staging: usbip: userspace: usbip_network: rename and cleanup function

drivers/staging/usbip/userspace/configure.ac | 4 +-
.../staging/usbip/userspace/libsrc/stub_driver.c | 12 +-
.../staging/usbip/userspace/libsrc/usbip_common.h | 6 +-
.../staging/usbip/userspace/libsrc/vhci_driver.c | 76 ++-
.../staging/usbip/userspace/libsrc/vhci_driver.h | 19 +-
drivers/staging/usbip/userspace/src/Makefile.am | 11 +-
drivers/staging/usbip/userspace/src/bind-driver.c | 643 ----------------
drivers/staging/usbip/userspace/src/usbip.c | 813 ++++----------------
drivers/staging/usbip/userspace/src/usbip.h | 39 +
drivers/staging/usbip/userspace/src/usbip_attach.c | 228 ++++++
drivers/staging/usbip/userspace/src/usbip_bind.c | 261 +++++++
drivers/staging/usbip/userspace/src/usbip_detach.c | 103 +++
drivers/staging/usbip/userspace/src/usbip_list.c | 306 ++++++++
.../staging/usbip/userspace/src/usbip_network.c | 73 +-
.../staging/usbip/userspace/src/usbip_network.h | 37 +-
drivers/staging/usbip/userspace/src/usbip_unbind.c | 95 +++
drivers/staging/usbip/userspace/src/usbipd.c | 8 +-
drivers/staging/usbip/userspace/src/utils.c | 60 ++-
drivers/staging/usbip/userspace/src/utils.h | 1 +
19 files changed, 1347 insertions(+), 1448 deletions(-)
delete mode 100644 drivers/staging/usbip/userspace/src/bind-driver.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip.h
create mode 100644 drivers/staging/usbip/userspace/src/usbip_attach.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_bind.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_detach.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_list.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_unbind.c

--
1.7.5.1


2011-05-26 13:17:34

by matt mooney

[permalink] [raw]
Subject: [PATCH 1/6] staging: usbip: userspace: set kernel module names in one place

Move kernel module name setting to usbip_common.h so that macros can
be used instead of hard coding the names in multiple places.

Signed-off-by: matt mooney <[email protected]>
---
.../staging/usbip/userspace/libsrc/stub_driver.c | 12 ++++------
.../staging/usbip/userspace/libsrc/usbip_common.h | 6 ++++-
.../staging/usbip/userspace/libsrc/vhci_driver.c | 8 ++----
drivers/staging/usbip/userspace/src/bind-driver.c | 23 +++++++++++++------
4 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/usbip/userspace/libsrc/stub_driver.c b/drivers/staging/usbip/userspace/libsrc/stub_driver.c
index cc33643..0355604 100644
--- a/drivers/staging/usbip/userspace/libsrc/stub_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/stub_driver.c
@@ -8,10 +8,6 @@

#include "usbip.h"

-/* kernel module name */
-static const char *usbip_stub_driver_name = "usbip-host";
-
-
struct usbip_stub_driver *stub_driver;

static struct sysfs_driver *open_sysfs_stub_driver(void)
@@ -31,11 +27,12 @@ static struct sysfs_driver *open_sysfs_stub_driver(void)

snprintf(stub_driver_path, SYSFS_PATH_MAX, "%s/%s/usb/%s/%s",
sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME,
- usbip_stub_driver_name);
+ USBIP_HOST_DRV_NAME);

stub_driver = sysfs_open_driver_path(stub_driver_path);
if (!stub_driver) {
- err("usbip-core.ko and usbip-host.ko must be loaded");
+ err(USBIP_CORE_MOD_NAME ".ko and " USBIP_HOST_DRV_NAME
+ ".ko must be loaded");
return NULL;
}

@@ -200,7 +197,8 @@ static int refresh_exported_devices(void)

suinf_list = sysfs_get_driver_devices(stub_driver->sysfs_driver);
if (!suinf_list) {
- printf("Bind usbip-host.ko to a usb device to be exportable!\n");
+ info("bind " USBIP_HOST_DRV_NAME ".ko to a usb device to be "
+ "exportable!\n");
goto bye;
}

diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/drivers/staging/usbip/userspace/libsrc/usbip_common.h
index c254b54..2c58af5 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.h
@@ -26,7 +26,11 @@
#define VHCI_STATE_PATH "/var/run/vhci_hcd"
#endif

-//#include <linux/usb_ch9.h>
+/* kernel module names */
+#define USBIP_CORE_MOD_NAME "usbip-core"
+#define USBIP_HOST_DRV_NAME "usbip-host"
+#define USBIP_VHCI_DRV_NAME "vhci_hcd"
+
enum usb_device_speed {
USB_SPEED_UNKNOWN = 0, /* enumerating */
USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
index db43f8d..aa439c6 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
@@ -5,9 +5,6 @@

#include "usbip.h"

-
-static const char vhci_driver_name[] = "vhci_hcd";
-
struct usbip_vhci_driver *vhci_driver;

static struct usbip_imported_device *imported_device_init(struct usbip_imported_device *idev, char *busid)
@@ -277,12 +274,13 @@ static int get_hc_busid(char *sysfs_mntpath, char *hc_busid)

snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/platform/%s/%s",
sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME,
- vhci_driver_name);
+ USBIP_VHCI_DRV_NAME);

sdriver = sysfs_open_driver_path(sdriver_path);
if (!sdriver) {
info("%s is not found", sdriver_path);
- info("load usbip-core.ko and vhci-hcd.ko !");
+ info("please load " USBIP_CORE_MOD_NAME ".ko and "
+ USBIP_VHCI_DRV_NAME ".ko!");
return -1;
}

diff --git a/drivers/staging/usbip/userspace/src/bind-driver.c b/drivers/staging/usbip/userspace/src/bind-driver.c
index dcc540a..1396ff9 100644
--- a/drivers/staging/usbip/userspace/src/bind-driver.c
+++ b/drivers/staging/usbip/userspace/src/bind-driver.c
@@ -3,13 +3,12 @@
* Copyright (C) 2005-2007 Takahiro Hirofuchi
*/

-#include "utils.h"
-
#define _GNU_SOURCE
#include <getopt.h>
#include <glib.h>

-
+#include "usbip.h"
+#include "utils.h"

static const struct option longopts[] = {
{"usbip", required_argument, NULL, 'u'},
@@ -27,9 +26,6 @@ static const struct option longopts[] = {
{NULL, 0, NULL, 0}
};

-static const char match_busid_path[] = "/sys/bus/usb/drivers/usbip-host/match_busid";
-
-
static void show_help(void)
{
printf("Usage: usbip_bind_driver [OPTION]\n");
@@ -51,6 +47,18 @@ static int modify_match_busid(char *busid, int add)
int fd;
int ret;
char buff[BUS_ID_SIZE + 4];
+ char sysfs_mntpath[SYSFS_PATH_MAX];
+ char match_busid_path[SYSFS_PATH_MAX];
+
+ ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
+ if (ret < 0) {
+ err("sysfs must be mounted");
+ return -1;
+ }
+
+ snprintf(match_busid_path, sizeof(match_busid_path),
+ "%s/%s/usb/%s/%s/match_busid", sysfs_mntpath, SYSFS_BUS_NAME,
+ SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME);

/* BUS_IS_SIZE includes NULL termination? */
if (strnlen(busid, BUS_ID_SIZE) > BUS_ID_SIZE - 1) {
@@ -228,7 +236,8 @@ static int bind_to_usbip(char *busid)
for (i = 0; i < ninterface; i++) {
int ret;

- ret = bind_interface(busid, configvalue, i, "usbip-host");
+ ret = bind_interface(busid, configvalue, i,
+ USBIP_HOST_DRV_NAME);
if (ret < 0) {
g_warning("bind usbip at %s:%d.%d, failed",
busid, configvalue, i);
--
1.7.5.1

2011-05-26 13:18:45

by matt mooney

[permalink] [raw]
Subject: [PATCH 2/6] staging: usbip: userspace: change struct class_device to usbip_class_device

Rename class_device struct to avoid confusion and change member names.

Signed-off-by: matt mooney <[email protected]>
---
.../staging/usbip/userspace/libsrc/vhci_driver.c | 48 ++++++++++---------
.../staging/usbip/userspace/libsrc/vhci_driver.h | 17 ++++---
drivers/staging/usbip/userspace/src/usbip.c | 9 ++--
3 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
index aa439c6..9296f96 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
@@ -20,10 +20,12 @@ static struct usbip_imported_device *imported_device_init(struct usbip_imported_
sysfs_close_device(sudev);

/* add class devices of this imported device */
- struct class_device *cdev;
- dlist_for_each_data(vhci_driver->cdev_list, cdev, struct class_device) {
- if (!strncmp(cdev->devpath, idev->udev.path, strlen(idev->udev.path))) {
- struct class_device *new_cdev;
+ struct usbip_class_device *cdev;
+ dlist_for_each_data(vhci_driver->cdev_list, cdev,
+ struct usbip_class_device) {
+ if (!strncmp(cdev->dev_path, idev->udev.path,
+ strlen(idev->udev.path))) {
+ struct usbip_class_device *new_cdev;

/* alloc and copy because dlist is linked from only one list */
new_cdev = calloc(1, sizeof(*new_cdev));
@@ -87,7 +89,7 @@ static int parse_status(char *value)
idev->busnum = (devid >> 16);
idev->devnum = (devid & 0x0000ffff);

- idev->cdev_list = dlist_new(sizeof(struct class_device));
+ idev->cdev_list = dlist_new(sizeof(struct usbip_class_device));
if (!idev->cdev_list) {
err("init new device");
return -1;
@@ -115,29 +117,29 @@ static int parse_status(char *value)

static int check_usbip_device(struct sysfs_class_device *cdev)
{
- char clspath[SYSFS_PATH_MAX]; /* /sys/class/video4linux/video0/device */
- char devpath[SYSFS_PATH_MAX]; /* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1 */
-
+ char class_path[SYSFS_PATH_MAX]; /* /sys/class/video4linux/video0/device */
+ char dev_path[SYSFS_PATH_MAX]; /* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1 */
int ret;
+ struct usbip_class_device *usbip_cdev;

- snprintf(clspath, sizeof(clspath), "%s/device", cdev->path);
+ snprintf(class_path, sizeof(class_path), "%s/device", cdev->path);

- ret = sysfs_get_link(clspath, devpath, SYSFS_PATH_MAX);
- if (!ret) {
- if (!strncmp(devpath, vhci_driver->hc_device->path,
- strlen(vhci_driver->hc_device->path))) {
+ ret = sysfs_get_link(class_path, dev_path, sizeof(dev_path));
+ if (ret == 0) {
+ if (!strncmp(dev_path, vhci_driver->hc_device->path,
+ strlen(vhci_driver->hc_device->path))) {
/* found usbip device */
- struct class_device *cdev;
-
- cdev = calloc(1, sizeof(*cdev));
+ usbip_cdev = calloc(1, sizeof(*usbip_cdev));
if (!cdev) {
- err("calloc cdev");
+ err("calloc usbip_cdev");
return -1;
}
- dlist_unshift(vhci_driver->cdev_list, (void*) cdev);
- strncpy(cdev->clspath, clspath, sizeof(cdev->clspath));
- strncpy(cdev->devpath, devpath, sizeof(cdev->clspath));
- dbg(" found %s %s", clspath, devpath);
+ dlist_unshift(vhci_driver->cdev_list, usbip_cdev);
+ strncpy(usbip_cdev->class_path, class_path,
+ sizeof(usbip_cdev->class_path));
+ strncpy(usbip_cdev->dev_path, dev_path,
+ sizeof(usbip_cdev->dev_path));
+ dbg(" found %s %s", class_path, dev_path);
}
}

@@ -341,7 +343,7 @@ int usbip_vhci_driver_open(void)

info("%d ports available\n", vhci_driver->nports);

- vhci_driver->cdev_list = dlist_new(sizeof(struct class_device));
+ vhci_driver->cdev_list = dlist_new(sizeof(struct usbip_class_device));
if (!vhci_driver->cdev_list)
goto err;

@@ -400,7 +402,7 @@ int usbip_vhci_refresh_device_list(void)
dlist_destroy(vhci_driver->idev[i].cdev_list);
}

- vhci_driver->cdev_list = dlist_new(sizeof(struct class_device));
+ vhci_driver->cdev_list = dlist_new(sizeof(struct usbip_class_device));
if (!vhci_driver->cdev_list)
goto err;

diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
index cad8ad7..3af41c5 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
@@ -11,9 +11,9 @@

#define MAXNPORT 128

-struct class_device {
- char clspath[SYSFS_PATH_MAX];
- char devpath[SYSFS_PATH_MAX];
+struct usbip_class_device {
+ char class_path[SYSFS_PATH_MAX];
+ char dev_path[SYSFS_PATH_MAX];
};

struct usbip_imported_device {
@@ -25,16 +25,19 @@ struct usbip_imported_device {
uint8_t busnum;
uint8_t devnum;

-
- struct dlist *cdev_list; /* list of class device */
+ /* usbip_class_device list */
+ struct dlist *cdev_list;
struct usb_device udev;
};

struct usbip_vhci_driver {
char sysfs_mntpath[SYSFS_PATH_MAX];
- struct sysfs_device *hc_device; /* /sys/devices/platform/vhci_hcd */

- struct dlist *cdev_list; /* list of class device */
+ /* /sys/devices/platform/vhci_hcd */
+ struct sysfs_device *hc_device;
+
+ /* usbip_class_device list */
+ struct dlist *cdev_list;

int nports;
struct usbip_imported_device idev[MAXNPORT];
diff --git a/drivers/staging/usbip/userspace/src/usbip.c b/drivers/staging/usbip/userspace/src/usbip.c
index 01a5628..c73b355 100644
--- a/drivers/staging/usbip/userspace/src/usbip.c
+++ b/drivers/staging/usbip/userspace/src/usbip.c
@@ -174,12 +174,13 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev)
sysfs_close_device(suinf);

/* show class device information */
- struct class_device *cdev;
+ struct usbip_class_device *cdev;

- dlist_for_each_data(idev->cdev_list, cdev, struct class_device) {
- int ifnum = get_interface_number(cdev->devpath);
+ dlist_for_each_data(idev->cdev_list, cdev,
+ struct usbip_class_device) {
+ int ifnum = get_interface_number(cdev->dev_path);
if (ifnum == i) {
- info(" %s", cdev->clspath);
+ info(" %s", cdev->class_path);
}
}
}
--
1.7.5.1

2011-05-26 13:17:45

by matt mooney

[permalink] [raw]
Subject: [PATCH 3/6] staging: usbip: userspace: vhci_driver: parameterize path names

Define a macro for the bus type and use libsysfs for class path.

Signed-off-by: matt mooney <[email protected]>
---
.../staging/usbip/userspace/libsrc/vhci_driver.c | 22 +++++++++++++++----
.../staging/usbip/userspace/libsrc/vhci_driver.h | 2 +-
2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
index 9296f96..f2030b1 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
@@ -186,9 +186,20 @@ static int refresh_class_device_list(void)
int ret;
struct dlist *cname_list;
char *cname;
+ char sysfs_mntpath[SYSFS_PATH_MAX];
+ char class_path[SYSFS_PATH_MAX];
+
+ ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
+ if (ret < 0) {
+ err("sysfs must be mounted");
+ return -1;
+ }
+
+ snprintf(class_path, sizeof(class_path), "%s/%s", sysfs_mntpath,
+ SYSFS_CLASS_NAME);

/* search under /sys/class */
- cname_list = sysfs_open_directory_list("/sys/class");
+ cname_list = sysfs_open_directory_list(class_path);
if (!cname_list) {
err("open class directory");
return -1;
@@ -274,9 +285,9 @@ static int get_hc_busid(char *sysfs_mntpath, char *hc_busid)

int found = 0;

- snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/platform/%s/%s",
- sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME,
- USBIP_VHCI_DRV_NAME);
+ snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/%s/%s/%s", sysfs_mntpath,
+ SYSFS_BUS_NAME, USBIP_VHCI_BUS_TYPE, SYSFS_DRIVERS_NAME,
+ USBIP_VHCI_DRV_NAME);

sdriver = sysfs_open_driver_path(sdriver_path);
if (!sdriver) {
@@ -333,7 +344,8 @@ int usbip_vhci_driver_open(void)
goto err;

/* will be freed in usbip_driver_close() */
- vhci_driver->hc_device = sysfs_open_device("platform", hc_busid);
+ vhci_driver->hc_device = sysfs_open_device(USBIP_VHCI_BUS_TYPE,
+ hc_busid);
if (!vhci_driver->hc_device) {
err("get sysfs vhci_driver");
goto err;
diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
index 3af41c5..3395586 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
@@ -7,7 +7,7 @@

#include "usbip.h"

-
+#define USBIP_VHCI_BUS_TYPE "platform"

#define MAXNPORT 128

--
1.7.5.1

2011-05-26 13:17:43

by matt mooney

[permalink] [raw]
Subject: [PATCH 4/6] staging: usbip: userspace tools v1.0.0

The new and improved (well somewhat, with a ways to go) userspace utility.

mfm:pts/8[~/tmp/userspace]
May26 05:18:31 % ./src/usbip help
usage: usbip [--debug] [version]
[help] <command> <args>

attach Attach a remote USB device
detach Detach a remote USB device
list List exported or local USB devices
bind Bind device to usbip-host.ko
unbind Unbind device from usbip-host.ko

This first commit of the userspace `usbip' utility uses to same
implementation as the old tools, `usbip' and `usbip_bind_driver'.
Nothing significant has changed so compatibility with windows has
_not_ been broken. However, the tools remain broken in many ways
due to the old implementation.

Signed-off-by: matt mooney <[email protected]>
---
drivers/staging/usbip/userspace/configure.ac | 4 +-
drivers/staging/usbip/userspace/src/Makefile.am | 11 +-
drivers/staging/usbip/userspace/src/bind-driver.c | 652 ----------------
drivers/staging/usbip/userspace/src/usbip.c | 814 ++++----------------
drivers/staging/usbip/userspace/src/usbip.h | 39 +
drivers/staging/usbip/userspace/src/usbip_attach.c | 228 ++++++
drivers/staging/usbip/userspace/src/usbip_bind.c | 261 +++++++
drivers/staging/usbip/userspace/src/usbip_detach.c | 103 +++
drivers/staging/usbip/userspace/src/usbip_list.c | 306 ++++++++
drivers/staging/usbip/userspace/src/usbip_unbind.c | 95 +++
drivers/staging/usbip/userspace/src/utils.c | 60 ++-
drivers/staging/usbip/userspace/src/utils.h | 1 +
12 files changed, 1233 insertions(+), 1341 deletions(-)
delete mode 100644 drivers/staging/usbip/userspace/src/bind-driver.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip.h
create mode 100644 drivers/staging/usbip/userspace/src/usbip_attach.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_bind.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_detach.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_list.c
create mode 100644 drivers/staging/usbip/userspace/src/usbip_unbind.c

diff --git a/drivers/staging/usbip/userspace/configure.ac b/drivers/staging/usbip/userspace/configure.ac
index e3afa15..e7d801b 100644
--- a/drivers/staging/usbip/userspace/configure.ac
+++ b/drivers/staging/usbip/userspace/configure.ac
@@ -1,8 +1,8 @@
dnl Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)
-AC_INIT([usbip], [0.1.8], [[email protected]])
-AC_DEFINE([USBIP_VERSION], [0x000106], [numeric version number])
+AC_INIT([usbip], [1.0.0], [[email protected]])
+AC_DEFINE([USBIP_VERSION], [0x00000100], [binary-coded decimal version number])

CURRENT=0
REVISION=1
diff --git a/drivers/staging/usbip/userspace/src/Makefile.am b/drivers/staging/usbip/userspace/src/Makefile.am
index 05a7aa5..52741c8 100644
--- a/drivers/staging/usbip/userspace/src/Makefile.am
+++ b/drivers/staging/usbip/userspace/src/Makefile.am
@@ -2,9 +2,10 @@ AM_CPPFLAGS := -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"'
AM_CFLAGS := @EXTRA_CFLAGS@ @PACKAGE_CFLAGS@
LDADD := $(top_srcdir)/libsrc/libusbip.la @PACKAGE_LIBS@

-sbin_PROGRAMS := usbip usbipd usbip_bind_driver
+sbin_PROGRAMS := usbip usbipd

-usbip_SOURCES := usbip.c usbip_network.c usbip_network.h
-usbipd_SOURCES := usbipd.c usbip_network.c usbip_network.h
-usbip_bind_driver_SOURCES := bind-driver.c utils.c utils.h \
- usbip_network.h usbip_network.c
+usbip_SOURCES := usbip.c utils.c usbip_network.c \
+ usbip_attach.c usbip_detach.c usbip_list.c \
+ usbip_bind.c usbip_unbind.c
+
+usbipd_SOURCES := usbipd.c usbip_network.c
diff --git a/drivers/staging/usbip/userspace/src/bind-driver.c b/drivers/staging/usbip/userspace/src/bind-driver.c
deleted file mode 100644
index 1396ff9..0000000
--- a/drivers/staging/usbip/userspace/src/bind-driver.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- *
- * Copyright (C) 2005-2007 Takahiro Hirofuchi
- */
-
-#define _GNU_SOURCE
-#include <getopt.h>
-#include <glib.h>
-
-#include "usbip.h"
-#include "utils.h"
-
-static const struct option longopts[] = {
- {"usbip", required_argument, NULL, 'u'},
- {"other", required_argument, NULL, 'o'},
- {"list", no_argument, NULL, 'l'},
- {"list2", no_argument, NULL, 'L'},
- {"help", no_argument, NULL, 'h'},
-#if 0
- {"allusbip", no_argument, NULL, 'a'},
- {"export-to", required_argument, NULL, 'e'},
- {"unexport", required_argument, NULL, 'x'},
- {"busid", required_argument, NULL, 'b'},
-#endif
-
- {NULL, 0, NULL, 0}
-};
-
-static void show_help(void)
-{
- printf("Usage: usbip_bind_driver [OPTION]\n");
- printf("Change driver binding for USB/IP.\n");
- printf(" --usbip busid make a device exportable\n");
- printf(" --other busid use a device by a local driver\n");
- printf(" --list print usb devices and their drivers\n");
- printf(" --list2 print usb devices and their drivers in parseable mode\n");
-#if 0
- printf(" --allusbip make all devices exportable\n");
- printf(" --export-to host export the device to 'host'\n");
- printf(" --unexport host unexport a device previously exported to 'host'\n");
- printf(" --busid busid the busid used for --export-to\n");
-#endif
-}
-
-static int modify_match_busid(char *busid, int add)
-{
- int fd;
- int ret;
- char buff[BUS_ID_SIZE + 4];
- char sysfs_mntpath[SYSFS_PATH_MAX];
- char match_busid_path[SYSFS_PATH_MAX];
-
- ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
- if (ret < 0) {
- err("sysfs must be mounted");
- return -1;
- }
-
- snprintf(match_busid_path, sizeof(match_busid_path),
- "%s/%s/usb/%s/%s/match_busid", sysfs_mntpath, SYSFS_BUS_NAME,
- SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME);
-
- /* BUS_IS_SIZE includes NULL termination? */
- if (strnlen(busid, BUS_ID_SIZE) > BUS_ID_SIZE - 1) {
- g_warning("too long busid");
- return -1;
- }
-
- fd = open(match_busid_path, O_WRONLY);
- if (fd < 0)
- return -1;
-
- if (add)
- snprintf(buff, BUS_ID_SIZE + 4, "add %s", busid);
- else
- snprintf(buff, BUS_ID_SIZE + 4, "del %s", busid);
-
- g_debug("write \"%s\" to %s", buff, match_busid_path);
-
- ret = write(fd, buff, sizeof(buff));
- if (ret < 0) {
- close(fd);
- return -1;
- }
-
- close(fd);
-
- return 0;
-}
-
-static const char unbind_path_format[] = "/sys/bus/usb/devices/%s/driver/unbind";
-
-/* buggy driver may cause dead lock */
-static int unbind_interface_busid(char *busid)
-{
- char unbind_path[PATH_MAX];
- int fd;
- int ret;
-
- snprintf(unbind_path, sizeof(unbind_path), unbind_path_format, busid);
-
- fd = open(unbind_path, O_WRONLY);
- if (fd < 0) {
- g_warning("opening unbind_path failed: %d", fd);
- return -1;
- }
-
- ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
- if (ret < 0) {
- g_warning("write to unbind_path failed: %d", ret);
- close(fd);
- return -1;
- }
-
- close(fd);
-
- return 0;
-}
-
-static int unbind_interface(char *busid, int configvalue, int interface)
-{
- char inf_busid[BUS_ID_SIZE];
- g_debug("unbinding interface");
-
- snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface);
-
- return unbind_interface_busid(inf_busid);
-}
-
-
-static const char bind_path_format[] = "/sys/bus/usb/drivers/%s/bind";
-
-static int bind_interface_busid(char *busid, char *driver)
-{
- char bind_path[PATH_MAX];
- int fd;
- int ret;
-
- snprintf(bind_path, sizeof(bind_path), bind_path_format, driver);
-
- fd = open(bind_path, O_WRONLY);
- if (fd < 0)
- return -1;
-
- ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
- if (ret < 0) {
- close(fd);
- return -1;
- }
-
- close(fd);
-
- return 0;
-}
-
-static int bind_interface(char *busid, int configvalue, int interface, char *driver)
-{
- char inf_busid[BUS_ID_SIZE];
-
- snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface);
-
- return bind_interface_busid(inf_busid, driver);
-}
-
-static int unbind(char *busid)
-{
- int configvalue = 0;
- int ninterface = 0;
- int devclass = 0;
- int i;
- int failed = 0;
-
- configvalue = read_bConfigurationValue(busid);
- ninterface = read_bNumInterfaces(busid);
- devclass = read_bDeviceClass(busid);
-
- if (configvalue < 0 || ninterface < 0 || devclass < 0) {
- g_warning("read config and ninf value, removed?");
- return -1;
- }
-
- if (devclass == 0x09) {
- g_message("skip unbinding of hub");
- return -1;
- }
-
- for (i = 0; i < ninterface; i++) {
- char driver[PATH_MAX];
- int ret;
-
- bzero(&driver, sizeof(driver));
-
- getdriver(busid, configvalue, i, driver, PATH_MAX-1);
-
- g_debug(" %s:%d.%d -> %s ", busid, configvalue, i, driver);
-
- if (!strncmp("none", driver, PATH_MAX))
- continue; /* unbound interface */
-
-#if 0
- if (!strncmp("usbip", driver, PATH_MAX))
- continue; /* already bound to usbip */
-#endif
-
- /* unbinding */
- ret = unbind_interface(busid, configvalue, i);
- if (ret < 0) {
- g_warning("unbind driver at %s:%d.%d failed",
- busid, configvalue, i);
- failed = 1;
- }
- }
-
- if (failed)
- return -1;
- else
- return 0;
-}
-
-/* call at unbound state */
-static int bind_to_usbip(char *busid)
-{
- int configvalue = 0;
- int ninterface = 0;
- int i;
- int failed = 0;
-
- configvalue = read_bConfigurationValue(busid);
- ninterface = read_bNumInterfaces(busid);
-
- if (configvalue < 0 || ninterface < 0) {
- g_warning("read config and ninf value, removed?");
- return -1;
- }
-
- for (i = 0; i < ninterface; i++) {
- int ret;
-
- ret = bind_interface(busid, configvalue, i,
- USBIP_HOST_DRV_NAME);
- if (ret < 0) {
- g_warning("bind usbip at %s:%d.%d, failed",
- busid, configvalue, i);
- failed = 1;
- /* need to contine binding at other interfaces */
- }
- }
-
- if (failed)
- return -1;
- else
- return 0;
-}
-
-
-static int use_device_by_usbip(char *busid)
-{
- int ret;
-
- ret = unbind(busid);
- if (ret < 0) {
- g_warning("unbind drivers of %s, failed", busid);
- return -1;
- }
-
- ret = modify_match_busid(busid, 1);
- if (ret < 0) {
- g_warning("add %s to match_busid, failed", busid);
- return -1;
- }
-
- ret = bind_to_usbip(busid);
- if (ret < 0) {
- g_warning("bind usbip to %s, failed", busid);
- modify_match_busid(busid, 0);
- return -1;
- }
-
- g_message("bind %s to usbip, complete!", busid);
-
- return 0;
-}
-
-
-
-static int use_device_by_other(char *busid)
-{
- int ret;
- int config;
-
- /* read and write the same config value to kick probing */
- config = read_bConfigurationValue(busid);
- if (config < 0) {
- g_warning("read bConfigurationValue of %s, failed", busid);
- return -1;
- }
-
- ret = modify_match_busid(busid, 0);
- if (ret < 0) {
- g_warning("del %s to match_busid, failed", busid);
- return -1;
- }
-
- ret = write_bConfigurationValue(busid, config);
- if (ret < 0) {
- g_warning("read bConfigurationValue of %s, failed", busid);
- return -1;
- }
-
- g_message("bind %s to other drivers than usbip, complete!", busid);
-
- return 0;
-}
-
-
-#include <sys/types.h>
-#include <regex.h>
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-
-
-
-static int is_usb_device(char *busid)
-{
- int ret;
-
- regex_t regex;
- regmatch_t pmatch[1];
-
- ret = regcomp(&regex, "^[0-9]+-[0-9]+(\\.[0-9]+)*$", REG_NOSUB|REG_EXTENDED);
- if (ret < 0)
- g_error("regcomp: %s\n", strerror(errno));
-
- ret = regexec(&regex, busid, 0, pmatch, 0);
- if (ret)
- return 0; /* not matched */
-
- return 1;
-}
-
-
-#include <dirent.h>
-static int show_devices(void)
-{
- DIR *dir;
-
- dir = opendir("/sys/bus/usb/devices/");
- if (!dir)
- g_error("opendir: %s", strerror(errno));
-
- printf("List USB devices\n");
- for (;;) {
- struct dirent *dirent;
- char *busid;
-
- dirent = readdir(dir);
- if (!dirent)
- break;
-
- busid = dirent->d_name;
-
- if (is_usb_device(busid)) {
- char name[100] = {'\0'};
- char driver[100] = {'\0'};
- int conf, ninf = 0;
- int i;
-
- conf = read_bConfigurationValue(busid);
- ninf = read_bNumInterfaces(busid);
-
- getdevicename(busid, name, sizeof(name));
-
- printf(" - busid %s (%s)\n", busid, name);
-
- for (i = 0; i < ninf; i++) {
- getdriver(busid, conf, i, driver, sizeof(driver));
- printf(" %s:%d.%d -> %s\n", busid, conf, i, driver);
- }
- printf("\n");
- }
- }
-
- closedir(dir);
-
- return 0;
-}
-
-static int show_devices2(void)
-{
- DIR *dir;
-
- dir = opendir("/sys/bus/usb/devices/");
- if (!dir)
- g_error("opendir: %s", strerror(errno));
-
- for (;;) {
- struct dirent *dirent;
- char *busid;
-
- dirent = readdir(dir);
- if (!dirent)
- break;
-
- busid = dirent->d_name;
-
- if (is_usb_device(busid)) {
- char name[100] = {'\0'};
- char driver[100] = {'\0'};
- int conf, ninf = 0;
- int i;
-
- conf = read_bConfigurationValue(busid);
- ninf = read_bNumInterfaces(busid);
-
- getdevicename(busid, name, sizeof(name));
-
- printf("busid=%s#usbid=%s#", busid, name);
-
- for (i = 0; i < ninf; i++) {
- getdriver(busid, conf, i, driver, sizeof(driver));
- printf("%s:%d.%d=%s#", busid, conf, i, driver);
- }
- printf("\n");
- }
- }
-
- closedir(dir);
-
- return 0;
-}
-
-
-#if 0
-static int export_to(char *host, char *busid) {
-
- int ret;
-
- if( host == NULL ) {
- printf( "no host given\n\n");
- show_help();
- return -1;
- }
- if( busid == NULL ) {
- /* XXX print device list and ask for busnumber, if none is
- * given */
- printf( "no busid given, use --busid switch\n\n");
- show_help();
- return -1;
- }
-
-
- ret = use_device_by_usbip(busid);
- if( ret != 0 ) {
- printf( "could not bind driver to usbip\n");
- return -1;
- }
-
- printf( "DEBUG: exporting device '%s' to '%s'\n", busid, host );
- ret = export_busid_to_host(host, busid); /* usbip_export.[ch] */
- if( ret != 0 ) {
- printf( "could not export device to host\n" );
- printf( " host: %s, device: %s\n", host, busid );
- use_device_by_other(busid);
- return -1;
- }
-
- return 0;
-}
-
-static int unexport_from(char *host, char *busid) {
-
- int ret;
-
- if (!host || !busid)
- g_error("no host or no busid\n");
-
- g_message("unexport_from: host: '%s', busid: '%s'", host, busid);
-
- ret = unexport_busid_from_host(host, busid); /* usbip_export.[ch] */
- if( ret != 0 ) {
- err( "could not unexport device from host\n" );
- err( " host: %s, device: %s\n", host, busid );
- }
-
- ret = use_device_by_other(busid);
- if (ret < 0)
- g_error("could not unbind device from usbip\n");
-
- return 0;
-}
-
-
-static int allusbip(void)
-{
- DIR *dir;
-
- dir = opendir("/sys/bus/usb/devices/");
- if (!dir)
- g_error("opendir: %s", strerror(errno));
-
- for (;;) {
- struct dirent *dirent;
- char *busid;
-
- dirent = readdir(dir);
- if (!dirent)
- break;
-
- busid = dirent->d_name;
-
- if (!is_usb_device(busid))
- continue;
-
- {
- char name[PATH_MAX];
- int conf, ninf = 0;
- int i;
- int be_local = 0;
-
- conf = read_bConfigurationValue(busid);
- ninf = read_bNumInterfaces(busid);
-
- getdevicename(busid, name, sizeof(name));
-
- for (i = 0; i < ninf; i++) {
- char driver[PATH_MAX];
-
- getdriver(busid, conf, i, driver, sizeof(driver));
-#if 0
- if (strncmp(driver, "usbhid", 6) == 0 || strncmp(driver, "usb-storage", 11) == 0) {
- be_local = 1;
- break;
- }
-#endif
- }
-
- if (be_local == 0)
- use_device_by_usbip(busid);
- }
- }
-
- closedir(dir);
-
- return 0;
-}
-#endif
-
-int main(int argc, char **argv)
-{
- char *busid = NULL;
- char *remote_host __attribute__((unused)) = NULL;
-
- enum {
- cmd_unknown = 0,
- cmd_use_by_usbip,
- cmd_use_by_other,
- cmd_list,
- cmd_list2,
- cmd_allusbip,
- cmd_export_to,
- cmd_unexport,
- cmd_help,
- } cmd = cmd_unknown;
-
- if (geteuid() != 0)
- g_warning("running non-root?");
-
- for (;;) {
- int c;
- int index = 0;
-
- c = getopt_long(argc, argv, "u:o:hlLae:x:b:", longopts, &index);
- if (c == -1)
- break;
-
- switch (c) {
- case 'u':
- cmd = cmd_use_by_usbip;
- busid = optarg;
- break;
- case 'o' :
- cmd = cmd_use_by_other;
- busid = optarg;
- break;
- case 'l' :
- cmd = cmd_list;
- break;
- case 'L' :
- cmd = cmd_list2;
- break;
- case 'a' :
- cmd = cmd_allusbip;
- break;
- case 'b':
- busid = optarg;
- break;
- case 'e':
- cmd = cmd_export_to;
- remote_host = optarg;
- break;
- case 'x':
- cmd = cmd_unexport;
- remote_host = optarg;
- break;
- case 'h': /* fallthrough */
- case '?':
- cmd = cmd_help;
- break;
- default:
- g_error("getopt");
- }
-
- //if (cmd)
- // break;
- }
-
- switch (cmd) {
- case cmd_use_by_usbip:
- use_device_by_usbip(busid);
- break;
- case cmd_use_by_other:
- use_device_by_other(busid);
- break;
- case cmd_list:
- show_devices();
- break;
- case cmd_list2:
- show_devices2();
- break;
-#if 0
- case cmd_allusbip:
- allusbip();
- break;
- case cmd_export_to:
- export_to(remote_host, busid);
- break;
- case cmd_unexport:
- unexport_from(remote_host, busid);
- break;
-#endif
- case cmd_help: /* fallthrough */
- case cmd_unknown:
- show_help();
- break;
- default:
- g_error("NOT REACHED");
- }
-
- return 0;
-}
diff --git a/drivers/staging/usbip/userspace/src/usbip.c b/drivers/staging/usbip/userspace/src/usbip.c
index c73b355..8940cd0 100644
--- a/drivers/staging/usbip/userspace/src/usbip.c
+++ b/drivers/staging/usbip/userspace/src/usbip.c
@@ -1,724 +1,180 @@
/*
+ * command structure borrowed from udev
+ * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git)
*
- * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ * Copyright (C) 2011 matt mooney <[email protected]>
+ * 2005-2007 Takahiro Hirofuchi
+ *
+ * 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
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

-#ifdef HAVE_CONFIG_H
-#include "../config.h"
-#endif
-
-#include "usbip.h"
-#include "usbip_network.h"
-#include <ctype.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
-#include <glib.h>
-
-static const char version[] = PACKAGE_STRING;
-
-
-/* /sys/devices/platform/vhci_hcd/usb6/6-1/6-1:1.1 -> 1 */
-static int get_interface_number(char *path)
-{
- char *c;
-
- c = strstr(path, vhci_driver->hc_device->bus_id);
- if (!c)
- return -1; /* hc exist? */
- c++;
- /* -> usb6/6-1/6-1:1.1 */
-
- c = strchr(c, '/');
- if (!c)
- return -1; /* hc exist? */
- c++;
- /* -> 6-1/6-1:1.1 */
-
- c = strchr(c, '/');
- if (!c)
- return -1; /* no interface path */
- c++;
- /* -> 6-1:1.1 */
-
- c = strchr(c, ':');
- if (!c)
- return -1; /* no configuration? */
- c++;
- /* -> 1.1 */
-
- c = strchr(c, '.');
- if (!c)
- return -1; /* no interface? */
- c++;
- /* -> 1 */
-
-
- return atoi(c);
-}
-
-
-static struct sysfs_device *open_usb_interface(struct usb_device *udev, int i)
-{
- struct sysfs_device *suinf;
- char busid[SYSFS_BUS_ID_SIZE];
-
- snprintf(busid, SYSFS_BUS_ID_SIZE, "%s:%d.%d",
- udev->busid, udev->bConfigurationValue, i);
-
- suinf = sysfs_open_device("usb", busid);
- if (!suinf)
- err("sysfs_open_device %s", busid);
-
- return suinf;
-}
-
-
-#define MAX_BUFF 100
-static int record_connection(char *host, char *port, char *busid, int rhport)
-{
- int fd;
- char path[PATH_MAX+1];
- char buff[MAX_BUFF+1];
- int ret;
-
- mkdir(VHCI_STATE_PATH, 0700);

- snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
-
- fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
- if (fd < 0)
- return -1;
-
- snprintf(buff, MAX_BUFF, "%s %s %s\n",
- host, port, busid);
-
- ret = write(fd, buff, strlen(buff));
- if (ret != (ssize_t) strlen(buff)) {
- close(fd);
- return -1;
- }
-
- close(fd);
-
- return 0;
-}
-
-static int read_record(int rhport, char *host, char *port, char *busid)
-{
- FILE *file;
- char path[PATH_MAX+1];
-
- snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
-
- file = fopen(path, "r");
- if (!file) {
- err("fopen");
- return -1;
- }
+#include <getopt.h>

- if (fscanf(file, "%s %s %s\n", host, port, busid) != 3) {
- err("fscanf");
- fclose(file);
- return -1;
- }
+#include "usbip_common.h"
+#include "usbip.h"

- fclose(file);
+static int usbip_help(int argc, char *argv[]);
+static int usbip_version(int argc, char *argv[]);

- return 0;
-}
+static const char usbip_version_string[] = PACKAGE_STRING;

+static const char usbip_usage_string[] =
+ "usbip [--debug] [version]\n"
+ " [help] <command> <args>\n";

-int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev)
+static void usbip_usage(void)
{
- char product_name[100];
- char host[NI_MAXHOST] = "unknown host";
- char serv[NI_MAXSERV] = "unknown port";
- char remote_busid[SYSFS_BUS_ID_SIZE];
- int ret;
-
- if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) {
- info("Port %02d: <%s>", idev->port, usbip_status_string(idev->status));
- return 0;
- }
-
- ret = read_record(idev->port, host, serv, remote_busid);
- if (ret) {
- err("read_record");
- return -1;
- }
-
- info("Port %02d: <%s> at %s", idev->port,
- usbip_status_string(idev->status), usbip_speed_string(idev->udev.speed));
-
- usbip_names_get_product(product_name, sizeof(product_name),
- idev->udev.idVendor, idev->udev.idProduct);
-
- info(" %s", product_name);
-
- info("%10s -> usbip://%s:%s/%s (remote devid %08x (bus/dev %03d/%03d))",
- idev->udev.busid, host, serv, remote_busid,
- idev->devid,
- idev->busnum, idev->devnum);
-
- for (int i=0; i < idev->udev.bNumInterfaces; i++) {
- /* show interface information */
- struct sysfs_device *suinf;
-
- suinf = open_usb_interface(&idev->udev, i);
- if (!suinf)
- continue;
-
- info(" %6s used by %-17s", suinf->bus_id, suinf->driver_name);
- sysfs_close_device(suinf);
-
- /* show class device information */
- struct usbip_class_device *cdev;
-
- dlist_for_each_data(idev->cdev_list, cdev,
- struct usbip_class_device) {
- int ifnum = get_interface_number(cdev->dev_path);
- if (ifnum == i) {
- info(" %s", cdev->class_path);
- }
- }
- }
-
- return 0;
+ printf("usage: %s", usbip_usage_string);
}

+struct command {
+ const char *name;
+ int (*fn)(int argc, char *argv[]);
+ const char *help;
+ void (*usage)(void);
+};

+static const struct command cmds[] = {
+ {
+ .name = "help",
+ .fn = usbip_help,
+ .help = NULL,
+ .usage = NULL
+ },
+ {
+ .name = "version",
+ .fn = usbip_version,
+ .help = NULL,
+ .usage = NULL
+ },
+ {
+ .name = "attach",
+ .fn = usbip_attach,
+ .help = "Attach a remote USB device",
+ .usage = usbip_attach_usage
+ },
+ {
+ .name = "detach",
+ .fn = usbip_detach,
+ .help = "Detach a remote USB device",
+ .usage = usbip_detach_usage
+ },
+ {
+ .name = "list",
+ .fn = usbip_list,
+ .help = "List exported or local USB devices",
+ .usage = usbip_list_usage
+ },
+ {
+ .name = "bind",
+ .fn = usbip_bind,
+ .help = "Bind device to " USBIP_HOST_DRV_NAME ".ko",
+ .usage = usbip_bind_usage
+ },
+ {
+ .name = "unbind",
+ .fn = usbip_unbind,
+ .help = "Unbind device from " USBIP_HOST_DRV_NAME ".ko",
+ .usage = usbip_unbind_usage
+ },
+ { NULL, NULL, NULL, NULL }
+};

-
-static int query_exported_devices(int sockfd)
+static int usbip_help(int argc, char *argv[])
{
- int ret;
- struct op_devlist_reply rep;
- uint16_t code = OP_REP_DEVLIST;
-
- bzero(&rep, sizeof(rep));
-
- ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
- if (ret < 0) {
- err("send op_common");
- return -1;
- }
-
- ret = usbip_recv_op_common(sockfd, &code);
- if (ret < 0) {
- err("recv op_common");
- return -1;
- }
-
- ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep));
- if (ret < 0) {
- err("recv op_devlist");
- return -1;
- }
-
- PACK_OP_DEVLIST_REPLY(0, &rep);
- dbg("exportable %d devices", rep.ndev);
-
- for (unsigned int i=0; i < rep.ndev; i++) {
- char product_name[100];
- char class_name[100];
- struct usb_device udev;
+ const struct command *cmd;
+ int i;
+ int ret = 0;

- bzero(&udev, sizeof(udev));
-
- ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev));
- if (ret < 0) {
- err("recv usb_device[%d]", i);
- return -1;
- }
- pack_usb_device(0, &udev);
-
- usbip_names_get_product(product_name, sizeof(product_name),
- udev.idVendor, udev.idProduct);
- usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass,
- udev.bDeviceSubClass, udev.bDeviceProtocol);
-
- info("%8s: %s", udev.busid, product_name);
- info("%8s: %s", " ", udev.path);
- info("%8s: %s", " ", class_name);
-
- for (int j=0; j < udev.bNumInterfaces; j++) {
- struct usb_interface uinf;
-
- ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf));
- if (ret < 0) {
- err("recv usb_interface[%d]", j);
- return -1;
+ if (argc > 1 && argv++) {
+ for (i = 0; cmds[i].name != NULL; i++)
+ if (!strcmp(cmds[i].name, argv[0]) && cmds[i].usage) {
+ cmds[i].usage();
+ goto done;
}
-
- pack_usb_interface(0, &uinf);
- usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass,
- uinf.bInterfaceSubClass, uinf.bInterfaceProtocol);
-
- info("%8s: %2d - %s", " ", j, class_name);
- }
-
- info(" ");
- }
-
- return rep.ndev;
-}
-
-static int import_device(int sockfd, struct usb_device *udev)
-{
- int ret;
- int port;
-
- ret = usbip_vhci_driver_open();
- if (ret < 0) {
- err("open vhci_driver");
- return -1;
- }
-
- port = usbip_vhci_get_free_port();
- if (port < 0) {
- err("no free port");
- usbip_vhci_driver_close();
- return -1;
- }
-
- ret = usbip_vhci_attach_device(port, sockfd, udev->busnum,
- udev->devnum, udev->speed);
- if (ret < 0) {
- err("import device");
- usbip_vhci_driver_close();
- return -1;
- }
-
- usbip_vhci_driver_close();
-
- return port;
-}
-
-
-static int query_import_device(int sockfd, char *busid)
-{
- int ret;
- struct op_import_request request;
- struct op_import_reply reply;
- uint16_t code = OP_REP_IMPORT;
-
- bzero(&request, sizeof(request));
- bzero(&reply, sizeof(reply));
-
-
- /* send a request */
- ret = usbip_send_op_common(sockfd, OP_REQ_IMPORT, 0);
- if (ret < 0) {
- err("send op_common");
- return -1;
- }
-
- strncpy(request.busid, busid, SYSFS_BUS_ID_SIZE-1);
-
- PACK_OP_IMPORT_REQUEST(0, &request);
-
- ret = usbip_send(sockfd, (void *) &request, sizeof(request));
- if (ret < 0) {
- err("send op_import_request");
- return -1;
+ ret = -1;
}

-
- /* recieve a reply */
- ret = usbip_recv_op_common(sockfd, &code);
- if (ret < 0) {
- err("recv op_common");
- return -1;
- }
-
- ret = usbip_recv(sockfd, (void *) &reply, sizeof(reply));
- if (ret < 0) {
- err("recv op_import_reply");
- return -1;
- }
-
- PACK_OP_IMPORT_REPLY(0, &reply);
-
-
- /* check the reply */
- if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) {
- err("recv different busid %s", reply.udev.busid);
- return -1;
- }
-
-
- /* import a device */
- return import_device(sockfd, &reply.udev);
-}
-
-static int attach_device(char *host, char *busid)
-{
- int sockfd;
- int ret;
- int rhport;
-
- sockfd = tcp_connect(host, USBIP_PORT_STRING);
- if (sockfd < 0) {
- err("tcp connect");
- return -1;
- }
-
- rhport = query_import_device(sockfd, busid);
- if (rhport < 0) {
- err("query");
- return -1;
- }
-
- close(sockfd);
-
- ret = record_connection(host, USBIP_PORT_STRING,
- busid, rhport);
- if (ret < 0) {
- err("record connection");
- return -1;
- }
-
- return 0;
-}
-
-static int detach_port(char *port)
-{
- int ret;
- uint8_t portnum;
-
- for (unsigned int i=0; i < strlen(port); i++)
- if (!isdigit(port[i])) {
- err("invalid port %s", port);
- return -1;
- }
-
- /* check max port */
-
- portnum = atoi(port);
-
- ret = usbip_vhci_driver_open();
- if (ret < 0) {
- err("open vhci_driver");
- return -1;
- }
-
- ret = usbip_vhci_detach_device(portnum);
- if (ret < 0)
- return -1;
-
- usbip_vhci_driver_close();
-
+ usbip_usage();
+ printf("\n");
+ for (cmd = cmds; cmd->name != NULL; cmd++)
+ if (cmd->help != NULL)
+ printf(" %-10s %s\n", cmd->name, cmd->help);
+ printf("\n");
+done:
return ret;
}

-static int show_exported_devices(char *host)
+static int usbip_version(int argc, char *argv[])
{
- int ret;
- int sockfd;
-
- sockfd = tcp_connect(host, USBIP_PORT_STRING);
- if (sockfd < 0) {
- err("- %s failed", host);
- return -1;
- }
-
- info("- %s", host);
-
- ret = query_exported_devices(sockfd);
- if (ret < 0) {
- err("query");
- return -1;
- }
+ (void) argc;
+ (void) argv;

- close(sockfd);
+ printf("%s\n", usbip_version_string);
return 0;
}

-static int attach_exported_devices(char *host, int sockfd)
+static int run_command(const struct command *cmd, int argc, char *argv[])
{
- int ret;
- struct op_devlist_reply rep;
- uint16_t code = OP_REP_DEVLIST;
-
- bzero(&rep, sizeof(rep));
-
- ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
- if(ret < 0) {
- err("send op_common");
- return -1;
- }
-
- ret = usbip_recv_op_common(sockfd, &code);
- if(ret < 0) {
- err("recv op_common");
- return -1;
- }
-
- ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep));
- if(ret < 0) {
- err("recv op_devlist");
- return -1;
- }
-
- PACK_OP_DEVLIST_REPLY(0, &rep);
- dbg("exportable %d devices", rep.ndev);
-
- for(unsigned int i=0; i < rep.ndev; i++) {
- char product_name[100];
- char class_name[100];
- struct usb_device udev;
-
- bzero(&udev, sizeof(udev));
-
- ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev));
- if(ret < 0) {
- err("recv usb_device[%d]", i);
- return -1;
- }
- pack_usb_device(0, &udev);
-
- usbip_names_get_product(product_name, sizeof(product_name),
- udev.idVendor, udev.idProduct);
- usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass,
- udev.bDeviceSubClass, udev.bDeviceProtocol);
-
- dbg("Attaching usb port %s from host %s on usbip, with deviceid: %s", udev.busid, host, product_name);
-
- for (int j=0; j < udev.bNumInterfaces; j++) {
- struct usb_interface uinf;
-
- ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf));
- if (ret < 0) {
- err("recv usb_interface[%d]", j);
- return -1;
- }
-
- pack_usb_interface(0, &uinf);
- usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass,
- uinf.bInterfaceSubClass, uinf.bInterfaceProtocol);
-
- dbg("interface %2d - %s", j, class_name);
- }
-
- attach_device(host, udev.busid);
- }
-
- return rep.ndev;
-}
-
-static int attach_devices_all(char *host)
-{
- int ret;
- int sockfd;
-
- sockfd = tcp_connect(host, USBIP_PORT_STRING);
- if(sockfd < 0) {
- err("- %s failed", host);
- return -1;
- }
-
- info("- %s", host);
-
- ret = attach_exported_devices(host, sockfd);
- if(ret < 0) {
- err("query");
- return -1;
- }
-
- close(sockfd);
- return 0;
-}
-
-
-const char help_message[] = "\
-Usage: usbip [options] \n\
- -a, --attach [host] [bus_id] \n\
- Attach a remote USB device. \n\
- \n\
- -x, --attachall [host] \n\
- Attach all remote USB devices on the specific host. \n\
- \n\
- -d, --detach [ports] \n\
- Detach an imported USB device. \n\
- \n\
- -l, --list [hosts] \n\
- List exported USB devices. \n\
- \n\
- -p, --port \n\
- List virtual USB port status. \n\
- \n\
- -D, --debug \n\
- Print debugging information. \n\
- \n\
- -v, --version \n\
- Show version. \n\
- \n\
- -h, --help \n\
- Print this help. \n";
-
-static void show_help(void)
-{
- printf("%s", help_message);
-}
-
-static int show_port_status(void)
-{
- int ret;
- struct usbip_imported_device *idev;
-
- ret = usbip_vhci_driver_open();
- if (ret < 0)
- return ret;
-
- for (int i = 0; i < vhci_driver->nports; i++) {
- idev = &vhci_driver->idev[i];
-
- if (usbip_vhci_imported_device_dump(idev) < 0)
- ret = -1;
- }
-
- usbip_vhci_driver_close();
-
- return ret;
+ dbg("running command: `%s'\n", cmd->name);
+ return cmd->fn(argc, argv);
}

-#define _GNU_SOURCE
-#include <getopt.h>
-static const struct option longopts[] = {
- {"attach", no_argument, NULL, 'a'},
- {"attachall", no_argument, NULL, 'x'},
- {"detach", no_argument, NULL, 'd'},
- {"port", no_argument, NULL, 'p'},
- {"list", no_argument, NULL, 'l'},
- {"version", no_argument, NULL, 'v'},
- {"help", no_argument, NULL, 'h'},
- {"debug", no_argument, NULL, 'D'},
- {"syslog", no_argument, NULL, 'S'},
- {NULL, 0, NULL, 0}
-};
-
int main(int argc, char *argv[])
{
- int ret;
-
- enum {
- cmd_attach = 1,
- cmd_attachall,
- cmd_detach,
- cmd_port,
- cmd_list,
- cmd_help,
- cmd_version
- } cmd = 0;
-
- usbip_use_stderr = 1;
-
- if (geteuid() != 0)
- g_warning("running non-root?");
-
- ret = usbip_names_init(USBIDS_FILE);
- if (ret)
- notice("failed to open %s", USBIDS_FILE);
+ static const struct option opts[] = {
+ { "debug", no_argument, NULL, 'd' },
+ { NULL, 0, NULL, 0 }
+ };
+ char *cmd;
+ int opt;
+ int i, rc = -1;

+ opterr = 0;
for (;;) {
- int c;
- int index = 0;
-
- c = getopt_long(argc, argv, "adplvhDSx", longopts, &index);
+ opt = getopt_long(argc, argv, "+d", opts, NULL);

- if (c == -1)
+ if (opt == -1)
break;

- switch(c) {
- case 'a':
- if (!cmd)
- cmd = cmd_attach;
- else
- cmd = cmd_help;
- break;
- case 'd':
- if (!cmd)
- cmd = cmd_detach;
- else
- cmd = cmd_help;
- break;
- case 'p':
- if (!cmd)
- cmd = cmd_port;
- else cmd = cmd_help;
- break;
- case 'l':
- if (!cmd)
- cmd = cmd_list;
- else
- cmd = cmd_help;
- break;
- case 'v':
- if (!cmd)
- cmd = cmd_version;
- else
- cmd = cmd_help;
- break;
- case 'x':
- if(!cmd)
- cmd = cmd_attachall;
- else
- cmd = cmd_help;
- break;
- case 'h':
- cmd = cmd_help;
- break;
- case 'D':
- usbip_use_debug = 1;
- break;
- case 'S':
- usbip_use_syslog = 1;
- break;
- case '?':
- break;
-
- default:
- err("getopt");
- }
- }
-
- ret = 0;
- switch(cmd) {
- case cmd_attach:
- if (optind == argc - 2)
- ret = attach_device(argv[optind], argv[optind+1]);
- else
- show_help();
- break;
- case cmd_detach:
- while (optind < argc)
- ret = detach_port(argv[optind++]);
- break;
- case cmd_port:
- ret = show_port_status();
- break;
- case cmd_list:
- while (optind < argc)
- ret = show_exported_devices(argv[optind++]);
- break;
- case cmd_attachall:
- while(optind < argc)
- ret = attach_devices_all(argv[optind++]);
- break;
- case cmd_version:
- printf("%s\n", version);
- break;
- case cmd_help:
- show_help();
+ switch (opt) {
+ case 'd':
+ usbip_use_debug = 1;
+ usbip_use_stderr = 1;
break;
default:
- show_help();
+ goto err_out;
+ }
}

+ cmd = argv[optind];
+ if (cmd) {
+ for (i = 0; cmds[i].name != NULL; i++)
+ if (!strcmp(cmds[i].name, cmd)) {
+ argc -= optind;
+ argv += optind;
+ optind = 0;
+ rc = run_command(&cmds[i], argc, argv);
+ goto out;
+ }
+ }

- usbip_names_free();
-
- exit((ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
+err_out:
+ usbip_usage();
+out:
+ return (rc > -1 ? EXIT_SUCCESS : EXIT_FAILURE);
}
diff --git a/drivers/staging/usbip/userspace/src/usbip.h b/drivers/staging/usbip/userspace/src/usbip.h
new file mode 100644
index 0000000..14d4a47
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 matt mooney <[email protected]>
+ * 2005-2007 Takahiro Hirofuchi
+ *
+ * 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
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __USBIP_H
+#define __USBIP_H
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+/* usbip commands */
+int usbip_attach(int argc, char *argv[]);
+int usbip_detach(int argc, char *argv[]);
+int usbip_list(int argc, char *argv[]);
+int usbip_bind(int argc, char *argv[]);
+int usbip_unbind(int argc, char *argv[]);
+
+void usbip_attach_usage(void);
+void usbip_detach_usage(void);
+void usbip_list_usage(void);
+void usbip_bind_usage(void);
+void usbip_unbind_usage(void);
+
+#endif /* __USBIP_H */
diff --git a/drivers/staging/usbip/userspace/src/usbip_attach.c b/drivers/staging/usbip/userspace/src/usbip_attach.c
new file mode 100644
index 0000000..671d23c
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_attach.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2011 matt mooney <[email protected]>
+ * 2005-2007 Takahiro Hirofuchi
+ *
+ * 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
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/stat.h>
+#include <sysfs/libsysfs.h>
+
+#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <getopt.h>
+#include <unistd.h>
+
+#include "vhci_driver.h"
+#include "usbip_common.h"
+#include "usbip_network.h"
+#include "usbip.h"
+
+static const char usbip_attach_usage_string[] =
+ "usbip attach <args>\n"
+ " -h, --host=<host> The machine with exported USB devices\n"
+ " -b, --busid=<busid> Busid of the device on <host>\n";
+
+void usbip_attach_usage(void)
+{
+ printf("usage: %s", usbip_attach_usage_string);
+}
+
+#define MAX_BUFF 100
+static int record_connection(char *host, char *port, char *busid, int rhport)
+{
+ int fd;
+ char path[PATH_MAX+1];
+ char buff[MAX_BUFF+1];
+ int ret;
+
+ mkdir(VHCI_STATE_PATH, 0700);
+
+ snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
+
+ fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
+ if (fd < 0)
+ return -1;
+
+ snprintf(buff, MAX_BUFF, "%s %s %s\n",
+ host, port, busid);
+
+ ret = write(fd, buff, strlen(buff));
+ if (ret != (ssize_t) strlen(buff)) {
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
+static int import_device(int sockfd, struct usb_device *udev)
+{
+ int rc;
+ int port;
+
+ rc = usbip_vhci_driver_open();
+ if (rc < 0) {
+ err("open vhci_driver");
+ return -1;
+ }
+
+ port = usbip_vhci_get_free_port();
+ if (port < 0) {
+ err("no free port");
+ usbip_vhci_driver_close();
+ return -1;
+ }
+
+ rc = usbip_vhci_attach_device(port, sockfd, udev->busnum,
+ udev->devnum, udev->speed);
+ if (rc < 0) {
+ err("import device");
+ usbip_vhci_driver_close();
+ return -1;
+ }
+
+ usbip_vhci_driver_close();
+
+ return port;
+}
+
+static int query_import_device(int sockfd, char *busid)
+{
+ int rc;
+ struct op_import_request request;
+ struct op_import_reply reply;
+ uint16_t code = OP_REP_IMPORT;
+
+ memset(&request, 0, sizeof(request));
+ memset(&reply, 0, sizeof(reply));
+
+ /* send a request */
+ rc = usbip_send_op_common(sockfd, OP_REQ_IMPORT, 0);
+ if (rc < 0) {
+ err("send op_common");
+ return -1;
+ }
+
+ strncpy(request.busid, busid, SYSFS_BUS_ID_SIZE-1);
+
+ PACK_OP_IMPORT_REQUEST(0, &request);
+
+ rc = usbip_send(sockfd, (void *) &request, sizeof(request));
+ if (rc < 0) {
+ err("send op_import_request");
+ return -1;
+ }
+
+ /* recieve a reply */
+ rc = usbip_recv_op_common(sockfd, &code);
+ if (rc < 0) {
+ err("recv op_common");
+ return -1;
+ }
+
+ rc = usbip_recv(sockfd, (void *) &reply, sizeof(reply));
+ if (rc < 0) {
+ err("recv op_import_reply");
+ return -1;
+ }
+
+ PACK_OP_IMPORT_REPLY(0, &reply);
+
+ /* check the reply */
+ if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) {
+ err("recv different busid %s", reply.udev.busid);
+ return -1;
+ }
+
+ /* import a device */
+ return import_device(sockfd, &reply.udev);
+}
+
+static int attach_device(char *host, char *busid)
+{
+ int sockfd;
+ int rc;
+ int rhport;
+
+ sockfd = usbip_net_tcp_connect(host, USBIP_PORT_STRING);
+ if (sockfd < 0) {
+ err("tcp connect");
+ return -1;
+ }
+
+ rhport = query_import_device(sockfd, busid);
+ if (rhport < 0) {
+ err("query");
+ return -1;
+ }
+
+ close(sockfd);
+
+ rc = record_connection(host, USBIP_PORT_STRING, busid, rhport);
+ if (rc < 0) {
+ err("record connection");
+ return -1;
+ }
+
+ return 0;
+}
+
+int usbip_attach(int argc, char *argv[])
+{
+ static const struct option opts[] = {
+ { "host", required_argument, NULL, 'h' },
+ { "busid", required_argument, NULL, 'b' },
+ { NULL, 0, NULL, 0 }
+ };
+ char *host = NULL;
+ char *busid = NULL;
+ int opt;
+ int ret = -1;
+
+ for (;;) {
+ opt = getopt_long(argc, argv, "h:b:", opts, NULL);
+
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'h':
+ host = optarg;
+ break;
+ case 'b':
+ busid = optarg;
+ break;
+ default:
+ goto err_out;
+ }
+ }
+
+ if (!host || !busid)
+ goto err_out;
+
+ ret = attach_device(host, busid);
+ goto out;
+
+err_out:
+ usbip_attach_usage();
+out:
+ return ret;
+}
diff --git a/drivers/staging/usbip/userspace/src/usbip_bind.c b/drivers/staging/usbip/userspace/src/usbip_bind.c
new file mode 100644
index 0000000..26cfbad
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_bind.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2011 matt mooney <[email protected]>
+ * 2005-2007 Takahiro Hirofuchi
+ *
+ * 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
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sysfs/libsysfs.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <getopt.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "usbip_common.h"
+#include "utils.h"
+#include "usbip.h"
+
+static const char usbip_bind_usage_string[] =
+ "usbip bind <args>\n"
+ " -b, --busid=<busid> Bind " USBIP_HOST_DRV_NAME ".ko to device "
+ "on <busid>\n";
+
+void usbip_bind_usage(void)
+{
+ printf("usage: %s", usbip_bind_usage_string);
+}
+
+static const char unbind_path_format[] = "/sys/bus/usb/devices/%s/driver/unbind";
+
+/* buggy driver may cause dead lock */
+static int unbind_interface_busid(char *busid)
+{
+ char unbind_path[SYSFS_PATH_MAX];
+ int fd;
+ int ret;
+
+ snprintf(unbind_path, sizeof(unbind_path), unbind_path_format, busid);
+
+ fd = open(unbind_path, O_WRONLY);
+ if (fd < 0) {
+ dbg("opening unbind_path failed: %d", fd);
+ return -1;
+ }
+
+ ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
+ if (ret < 0) {
+ dbg("write to unbind_path failed: %d", ret);
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
+static int unbind_interface(char *busid, int configvalue, int interface)
+{
+ char inf_busid[BUS_ID_SIZE];
+ dbg("unbinding interface");
+
+ snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface);
+
+ return unbind_interface_busid(inf_busid);
+}
+
+static int unbind(char *busid)
+{
+ int configvalue = 0;
+ int ninterface = 0;
+ int devclass = 0;
+ int i;
+ int failed = 0;
+
+ configvalue = read_bConfigurationValue(busid);
+ ninterface = read_bNumInterfaces(busid);
+ devclass = read_bDeviceClass(busid);
+
+ if (configvalue < 0 || ninterface < 0 || devclass < 0) {
+ dbg("read config and ninf value, removed?");
+ return -1;
+ }
+
+ if (devclass == 0x09) {
+ dbg("skip unbinding of hub");
+ return -1;
+ }
+
+ for (i = 0; i < ninterface; i++) {
+ char driver[PATH_MAX];
+ int ret;
+
+ memset(&driver, 0, sizeof(driver));
+
+ getdriver(busid, configvalue, i, driver, PATH_MAX-1);
+
+ dbg(" %s:%d.%d -> %s ", busid, configvalue, i, driver);
+
+ if (!strncmp("none", driver, PATH_MAX))
+ continue; /* unbound interface */
+
+#if 0
+ if (!strncmp("usbip", driver, PATH_MAX))
+ continue; /* already bound to usbip */
+#endif
+
+ /* unbinding */
+ ret = unbind_interface(busid, configvalue, i);
+ if (ret < 0) {
+ dbg("unbind driver at %s:%d.%d failed",
+ busid, configvalue, i);
+ failed = 1;
+ }
+ }
+
+ if (failed)
+ return -1;
+ else
+ return 0;
+}
+
+static const char bind_path_format[] = "/sys/bus/usb/drivers/%s/bind";
+
+static int bind_interface_busid(char *busid, char *driver)
+{
+ char bind_path[PATH_MAX];
+ int fd;
+ int ret;
+
+ snprintf(bind_path, sizeof(bind_path), bind_path_format, driver);
+
+ fd = open(bind_path, O_WRONLY);
+ if (fd < 0)
+ return -1;
+
+ ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
+static int bind_interface(char *busid, int configvalue, int interface, char *driver)
+{
+ char inf_busid[BUS_ID_SIZE];
+
+ snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface);
+
+ return bind_interface_busid(inf_busid, driver);
+}
+
+/* call at unbound state */
+static int bind_to_usbip(char *busid)
+{
+ int configvalue = 0;
+ int ninterface = 0;
+ int i;
+ int failed = 0;
+
+ configvalue = read_bConfigurationValue(busid);
+ ninterface = read_bNumInterfaces(busid);
+
+ if (configvalue < 0 || ninterface < 0) {
+ dbg("read config and ninf value, removed?");
+ return -1;
+ }
+
+ for (i = 0; i < ninterface; i++) {
+ int ret;
+
+ ret = bind_interface(busid, configvalue, i,
+ USBIP_HOST_DRV_NAME);
+ if (ret < 0) {
+ dbg("bind usbip at %s:%d.%d, failed",
+ busid, configvalue, i);
+ failed = 1;
+ /* need to contine binding at other interfaces */
+ }
+ }
+
+ if (failed)
+ return -1;
+ else
+ return 0;
+}
+
+static int use_device_by_usbip(char *busid)
+{
+ int ret;
+
+ ret = unbind(busid);
+ if (ret < 0) {
+ dbg("unbind drivers of %s, failed", busid);
+ return -1;
+ }
+
+ ret = modify_match_busid(busid, 1);
+ if (ret < 0) {
+ dbg("add %s to match_busid, failed", busid);
+ return -1;
+ }
+
+ ret = bind_to_usbip(busid);
+ if (ret < 0) {
+ dbg("bind usbip to %s, failed", busid);
+ modify_match_busid(busid, 0);
+ return -1;
+ }
+
+ dbg("bind %s complete!", busid);
+
+ return 0;
+}
+
+int usbip_bind(int argc, char *argv[])
+{
+ static const struct option opts[] = {
+ { "busid", required_argument, NULL, 'b' },
+ { NULL, 0, NULL, 0 }
+ };
+ int opt;
+ int ret = -1;
+
+ for (;;) {
+ opt = getopt_long(argc, argv, "b:", opts, NULL);
+
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'b':
+ ret = use_device_by_usbip(optarg);
+ goto out;
+ default:
+ goto err_out;
+ }
+ }
+
+err_out:
+ usbip_bind_usage();
+out:
+ return ret;
+}
diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/drivers/staging/usbip/userspace/src/usbip_detach.c
new file mode 100644
index 0000000..89bf3c1
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_detach.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 matt mooney <[email protected]>
+ * 2005-2007 Takahiro Hirofuchi
+ *
+ * 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
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sysfs/libsysfs.h>
+
+#include <ctype.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include "vhci_driver.h"
+#include "usbip_common.h"
+#include "usbip_network.h"
+#include "usbip.h"
+
+static const char usbip_detach_usage_string[] =
+ "usbip detach <args>\n"
+ " -p, --port=<port> " USBIP_VHCI_DRV_NAME
+ " port the device is on\n";
+
+void usbip_detach_usage(void)
+{
+ printf("usage: %s", usbip_detach_usage_string);
+}
+
+static int detach_port(char *port)
+{
+ int ret;
+ uint8_t portnum;
+
+ for (unsigned int i=0; i < strlen(port); i++)
+ if (!isdigit(port[i])) {
+ err("invalid port %s", port);
+ return -1;
+ }
+
+ /* check max port */
+
+ portnum = atoi(port);
+
+ ret = usbip_vhci_driver_open();
+ if (ret < 0) {
+ err("open vhci_driver");
+ return -1;
+ }
+
+ ret = usbip_vhci_detach_device(portnum);
+ if (ret < 0)
+ return -1;
+
+ usbip_vhci_driver_close();
+
+ return ret;
+}
+
+int usbip_detach(int argc, char *argv[])
+{
+ static const struct option opts[] = {
+ { "port", required_argument, NULL, 'p' },
+ { NULL, 0, NULL, 0 }
+ };
+ int opt;
+ int ret = -1;
+
+ for (;;) {
+ opt = getopt_long(argc, argv, "p:", opts, NULL);
+
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'p':
+ ret = detach_port(optarg);
+ goto out;
+ default:
+ goto err_out;
+ }
+ }
+
+err_out:
+ usbip_detach_usage();
+out:
+ return ret;
+}
diff --git a/drivers/staging/usbip/userspace/src/usbip_list.c b/drivers/staging/usbip/userspace/src/usbip_list.c
new file mode 100644
index 0000000..72236ae
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_list.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2011 matt mooney <[email protected]>
+ * 2005-2007 Takahiro Hirofuchi
+ *
+ * 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
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <sysfs/libsysfs.h>
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <dirent.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <regex.h>
+#include <unistd.h>
+
+#include "usbip_common.h"
+#include "usbip_network.h"
+#include "utils.h"
+#include "usbip.h"
+
+static const char usbip_list_usage_string[] =
+ "usbip list [-p|--parsable] <args>\n"
+ " -p, --parsable Parsable list format\n"
+ " -r, --remote=<host> List the exported USB devices on <host>\n"
+ " -l, --local List the local USB devices\n";
+
+void usbip_list_usage(void)
+{
+ printf("usage: %s", usbip_list_usage_string);
+}
+
+static int query_exported_devices(int sockfd)
+{
+ int ret;
+ struct op_devlist_reply rep;
+ uint16_t code = OP_REP_DEVLIST;
+
+ memset(&rep, 0, sizeof(rep));
+
+ ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
+ if (ret < 0) {
+ err("send op_common");
+ return -1;
+ }
+
+ ret = usbip_recv_op_common(sockfd, &code);
+ if (ret < 0) {
+ err("recv op_common");
+ return -1;
+ }
+
+ ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep));
+ if (ret < 0) {
+ err("recv op_devlist");
+ return -1;
+ }
+
+ PACK_OP_DEVLIST_REPLY(0, &rep);
+ dbg("exportable %d devices", rep.ndev);
+
+ for (unsigned int i=0; i < rep.ndev; i++) {
+ char product_name[100];
+ char class_name[100];
+ struct usb_device udev;
+
+ memset(&udev, 0, sizeof(udev));
+
+ ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev));
+ if (ret < 0) {
+ err("recv usb_device[%d]", i);
+ return -1;
+ }
+ pack_usb_device(0, &udev);
+
+ usbip_names_get_product(product_name, sizeof(product_name),
+ udev.idVendor, udev.idProduct);
+ usbip_names_get_class(class_name, sizeof(class_name),
+ udev.bDeviceClass, udev.bDeviceSubClass,
+ udev.bDeviceProtocol);
+
+ printf("%8s: %s\n", udev.busid, product_name);
+ printf("%8s: %s\n", " ", udev.path);
+ printf("%8s: %s\n", " ", class_name);
+
+ for (int j=0; j < udev.bNumInterfaces; j++) {
+ struct usb_interface uinf;
+
+ ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf));
+ if (ret < 0) {
+ err("recv usb_interface[%d]", j);
+ return -1;
+ }
+
+ pack_usb_interface(0, &uinf);
+ usbip_names_get_class(class_name, sizeof(class_name),
+ uinf.bInterfaceClass,
+ uinf.bInterfaceSubClass,
+ uinf.bInterfaceProtocol);
+
+ printf("%8s: %2d - %s\n", " ", j, class_name);
+ }
+
+ printf("\n");
+ }
+
+ return rep.ndev;
+}
+
+static int show_exported_devices(char *host)
+{
+ int ret;
+ int sockfd;
+
+ sockfd = usbip_net_tcp_connect(host, USBIP_PORT_STRING);
+ if (sockfd < 0) {
+ err("unable to connect to %s port %s: %s\n", host,
+ USBIP_PORT_STRING, gai_strerror(sockfd));
+ return -1;
+ }
+ dbg("connected to %s port %s\n", host, USBIP_PORT_STRING);
+
+ printf("- %s\n", host);
+
+ ret = query_exported_devices(sockfd);
+ if (ret < 0) {
+ err("query");
+ return -1;
+ }
+
+ close(sockfd);
+ return 0;
+}
+
+static int is_usb_device(char *busid)
+{
+ int ret;
+
+ regex_t regex;
+ regmatch_t pmatch[1];
+
+ ret = regcomp(&regex, "^[0-9]+-[0-9]+(\\.[0-9]+)*$", REG_NOSUB|REG_EXTENDED);
+ if (ret < 0)
+ err("regcomp: %s\n", strerror(errno));
+
+ ret = regexec(&regex, busid, 0, pmatch, 0);
+ if (ret)
+ return 0; /* not matched */
+
+ return 1;
+}
+
+static int show_devices(void)
+{
+ DIR *dir;
+
+ dir = opendir("/sys/bus/usb/devices/");
+ if (!dir)
+ err("opendir: %s", strerror(errno));
+
+ printf("List USB devices\n");
+ for (;;) {
+ struct dirent *dirent;
+ char *busid;
+
+ dirent = readdir(dir);
+ if (!dirent)
+ break;
+
+ busid = dirent->d_name;
+
+ if (is_usb_device(busid)) {
+ char name[100] = {'\0'};
+ char driver[100] = {'\0'};
+ int conf, ninf = 0;
+ int i;
+
+ conf = read_bConfigurationValue(busid);
+ ninf = read_bNumInterfaces(busid);
+
+ getdevicename(busid, name, sizeof(name));
+
+ printf(" - busid %s (%s)\n", busid, name);
+
+ for (i = 0; i < ninf; i++) {
+ getdriver(busid, conf, i, driver,
+ sizeof(driver));
+ printf(" %s:%d.%d -> %s\n", busid, conf,
+ i, driver);
+ }
+ printf("\n");
+ }
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
+static int show_devices2(void)
+{
+ DIR *dir;
+
+ dir = opendir("/sys/bus/usb/devices/");
+ if (!dir)
+ err("opendir: %s", strerror(errno));
+
+ for (;;) {
+ struct dirent *dirent;
+ char *busid;
+
+ dirent = readdir(dir);
+ if (!dirent)
+ break;
+
+ busid = dirent->d_name;
+
+ if (is_usb_device(busid)) {
+ char name[100] = {'\0'};
+ char driver[100] = {'\0'};
+ int conf, ninf = 0;
+ int i;
+
+ conf = read_bConfigurationValue(busid);
+ ninf = read_bNumInterfaces(busid);
+
+ getdevicename(busid, name, sizeof(name));
+
+ printf("busid=%s#usbid=%s#", busid, name);
+
+ for (i = 0; i < ninf; i++) {
+ getdriver(busid, conf, i, driver, sizeof(driver));
+ printf("%s:%d.%d=%s#", busid, conf, i, driver);
+ }
+ printf("\n");
+ }
+ }
+
+ closedir(dir);
+
+ return 0;
+}
+
+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' },
+ { NULL, 0, NULL, 0 }
+ };
+ bool is_parsable = false;
+ int opt;
+ int ret = -1;
+
+ if (usbip_names_init(USBIDS_FILE))
+ err("failed to open %s\n", USBIDS_FILE);
+
+ for (;;) {
+ opt = getopt_long(argc, argv, "pr:l", opts, NULL);
+
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'p':
+ is_parsable = true;
+ break;
+ case 'r':
+ ret = show_exported_devices(optarg);
+ goto out;
+ case 'l':
+ if (is_parsable)
+ ret = show_devices2();
+ else
+ ret = show_devices();
+ goto out;
+ default:
+ goto err_out;
+ }
+ }
+
+err_out:
+ usbip_list_usage();
+out:
+ usbip_names_free();
+
+ return ret;
+}
diff --git a/drivers/staging/usbip/userspace/src/usbip_unbind.c b/drivers/staging/usbip/userspace/src/usbip_unbind.c
new file mode 100644
index 0000000..9978d38
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_unbind.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 matt mooney <[email protected]>
+ * 2005-2007 Takahiro Hirofuchi
+ *
+ * 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
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+
+#include <getopt.h>
+#include <unistd.h>
+
+#include "usbip_common.h"
+#include "utils.h"
+#include "usbip.h"
+
+static const char usbip_unbind_usage_string[] =
+ "usbip unbind <args>\n"
+ " -b, --busid=<busid> Unbind " USBIP_HOST_DRV_NAME ".ko from "
+ "device on <busid>\n";
+
+void usbip_unbind_usage(void)
+{
+ printf("usage: %s", usbip_unbind_usage_string);
+}
+
+static int use_device_by_other(char *busid)
+{
+ int rc;
+ int config;
+
+ /* read and write the same config value to kick probing */
+ config = read_bConfigurationValue(busid);
+ if (config < 0) {
+ dbg("read bConfigurationValue of %s, failed", busid);
+ return -1;
+ }
+
+ rc = modify_match_busid(busid, 0);
+ if (rc < 0) {
+ dbg("del %s to match_busid, failed", busid);
+ return -1;
+ }
+
+ rc = write_bConfigurationValue(busid, config);
+ if (rc < 0) {
+ dbg("read bConfigurationValue of %s, failed", busid);
+ return -1;
+ }
+
+ info("bind %s to other drivers than usbip, complete!", busid);
+
+ return 0;
+}
+
+int usbip_unbind(int argc, char *argv[])
+{
+ static const struct option opts[] = {
+ { "busid", required_argument, NULL, 'b' },
+ { NULL, 0, NULL, 0 }
+ };
+ int opt;
+ int ret = -1;
+
+ for (;;) {
+ opt = getopt_long(argc, argv, "b:", opts, NULL);
+
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'b':
+ ret = use_device_by_other(optarg);
+ goto out;
+ default:
+ goto err_out;
+ }
+ }
+
+err_out:
+ usbip_unbind_usage();
+out:
+ return ret;
+}
diff --git a/drivers/staging/usbip/userspace/src/utils.c b/drivers/staging/usbip/userspace/src/utils.c
index 8f44108..6f91557 100644
--- a/drivers/staging/usbip/userspace/src/utils.c
+++ b/drivers/staging/usbip/userspace/src/utils.c
@@ -3,8 +3,61 @@
* Copyright (C) 2005-2007 Takahiro Hirofuchi
*/

+#include <sysfs/libsysfs.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "usbip_common.h"
#include "utils.h"

+int modify_match_busid(char *busid, int add)
+{
+ int fd;
+ int ret;
+ char buff[BUS_ID_SIZE + 4];
+ char sysfs_mntpath[SYSFS_PATH_MAX];
+ char match_busid_path[SYSFS_PATH_MAX];
+
+ ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
+ if (ret < 0) {
+ err("sysfs must be mounted");
+ return -1;
+ }
+
+ snprintf(match_busid_path, sizeof(match_busid_path),
+ "%s/%s/usb/%s/%s/match_busid", sysfs_mntpath, SYSFS_BUS_NAME,
+ SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME);
+
+ /* BUS_IS_SIZE includes NULL termination? */
+ if (strnlen(busid, BUS_ID_SIZE) > BUS_ID_SIZE - 1) {
+ dbg("busid is too long");
+ return -1;
+ }
+
+ fd = open(match_busid_path, O_WRONLY);
+ if (fd < 0)
+ return -1;
+
+ if (add)
+ snprintf(buff, BUS_ID_SIZE + 4, "add %s", busid);
+ else
+ snprintf(buff, BUS_ID_SIZE + 4, "del %s", busid);
+
+ dbg("write \"%s\" to %s", buff, match_busid_path);
+
+ ret = write(fd, buff, sizeof(buff));
+ if (ret < 0) {
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
int read_integer(char *path)
{
char buff[100];
@@ -36,7 +89,7 @@ int read_string(char *path, char *string, size_t len)
int ret = 0;
char *p;

- bzero(string, len);
+ memset(string, 0, len);

fd = open(path, O_RDONLY);
if (fd < 0) {
@@ -122,15 +175,16 @@ int getdriver(char *busid, int conf, int infnum, char *driver, size_t len)
{
char path[PATH_MAX];
char linkto[PATH_MAX];
+ const char none[] = "none";
int ret;

snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s:%d.%d/driver", busid, conf, infnum);

/* readlink does not add NULL */
- bzero(linkto, sizeof(linkto));
+ memset(linkto, 0, sizeof(linkto));
ret = readlink(path, linkto, sizeof(linkto)-1);
if (ret < 0) {
- strncpy(driver, "none", len);
+ strncpy(driver, none, len);
return -1;
} else {
strncpy(driver, basename(linkto), len);
diff --git a/drivers/staging/usbip/userspace/src/utils.h b/drivers/staging/usbip/userspace/src/utils.h
index 6c29ae9..423716d 100644
--- a/drivers/staging/usbip/userspace/src/utils.h
+++ b/drivers/staging/usbip/userspace/src/utils.h
@@ -25,6 +25,7 @@
/* Be sync to kernel header */
#define BUS_ID_SIZE 20

+int modify_match_busid(char *busid, int add);
int read_string(char *path, char *, size_t len);
int read_integer(char *path);
int getdevicename(char *busid, char *name, size_t len);
--
1.7.5.1

2011-05-26 13:18:21

by matt mooney

[permalink] [raw]
Subject: [PATCH 5/6] staging: usbip: userspace: usbipd.c: add header into source file

The old usbip.h header that was only used to masked what each source
file needed has been changed. So some headers this file needed had to
be added.

Signed-off-by: matt mooney <[email protected]>
---
drivers/staging/usbip/userspace/src/usbipd.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/usbip/userspace/src/usbipd.c b/drivers/staging/usbip/userspace/src/usbipd.c
index ec9faac..ccc7dfd 100644
--- a/drivers/staging/usbip/userspace/src/usbipd.c
+++ b/drivers/staging/usbip/userspace/src/usbipd.c
@@ -7,6 +7,7 @@
#include "../config.h"
#endif

+#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <strings.h>
@@ -23,16 +24,15 @@

#define _GNU_SOURCE
#include <getopt.h>
+#include <glib.h>
#include <signal.h>

-#include "usbip.h"
+#include "stub_driver.h"
+#include "usbip_common.h"
#include "usbip_network.h"

-#include <glib.h>
-
static const char version[] = PACKAGE_STRING;

-
static int send_reply_devlist(int sockfd)
{
int ret;
--
1.7.5.1

2011-05-26 13:18:04

by matt mooney

[permalink] [raw]
Subject: [PATCH 6/6] staging: usbip: userspace: usbip_network: rename and cleanup function

Rename tcp_connection to usbip_net_tcp_connection, which alludes to a
usbip network library that will eventually follow. The implementation
of this function has also been cleaned up.

Headers had to be adjusted due to the elimination of the old usbip.h.

Signed-off-by: matt mooney <[email protected]>
---
.../staging/usbip/userspace/src/usbip_network.c | 73 +++++++++-----------
.../staging/usbip/userspace/src/usbip_network.h | 37 +++-------
2 files changed, 45 insertions(+), 65 deletions(-)

diff --git a/drivers/staging/usbip/userspace/src/usbip_network.c b/drivers/staging/usbip/userspace/src/usbip_network.c
index 01be3c7..ef93b02 100644
--- a/drivers/staging/usbip/userspace/src/usbip_network.c
+++ b/drivers/staging/usbip/userspace/src/usbip_network.c
@@ -3,6 +3,16 @@
* Copyright (C) 2005-2007 Takahiro Hirofuchi
*/

+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+#include <string.h>
+
+#include <netdb.h>
+#include <netinet/tcp.h>
+#include <unistd.h>
+
+#include "usbip_common.h"
#include "usbip_network.h"

void pack_uint32_t(int pack, uint32_t *num)
@@ -186,66 +196,49 @@ int usbip_set_keepalive(int sockfd)
return ret;
}

-/* IPv6 Ready */
/*
- * moved here from vhci_attach.c
+ * IPv6 Ready
*/
-int tcp_connect(char *hostname, char *service)
+int usbip_net_tcp_connect(char *hostname, char *port)
{
- struct addrinfo hints, *res, *res0;
+ struct addrinfo hints, *res, *rp;
int sockfd;
- int err;
-
+ int ret;

memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;

/* get all possible addresses */
- err = getaddrinfo(hostname, service, &hints, &res0);
- if (err) {
- err("%s %s: %s", hostname, service, gai_strerror(err));
- return -1;
+ ret = getaddrinfo(hostname, port, &hints, &res);
+ if (ret < 0) {
+ dbg("getaddrinfo: %s port %s: %s", hostname, port,
+ gai_strerror(ret));
+ return ret;
}

- /* try all the addresses */
- for (res = res0; res; res = res->ai_next) {
- char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
-
- err = getnameinfo(res->ai_addr, res->ai_addrlen,
- hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
- if (err) {
- err("%s %s: %s", hostname, service, gai_strerror(err));
- continue;
- }
-
- dbg("trying %s port %s\n", hbuf, sbuf);
-
- sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (sockfd < 0) {
- err("socket");
+ /* try the addresses */
+ for (rp = res; rp; rp = rp->ai_next) {
+ sockfd = socket(rp->ai_family, rp->ai_socktype,
+ rp->ai_protocol);
+ if (sockfd < 0)
continue;
- }

/* should set TCP_NODELAY for usbip */
usbip_set_nodelay(sockfd);
- /* TODO: write code for heatbeat */
+ /* TODO: write code for heartbeat */
usbip_set_keepalive(sockfd);

- err = connect(sockfd, res->ai_addr, res->ai_addrlen);
- if (err < 0) {
- close(sockfd);
- continue;
- }
+ if (connect(sockfd, rp->ai_addr, rp->ai_addrlen) == 0)
+ break;

- /* connected */
- dbg("connected to %s:%s", hbuf, sbuf);
- freeaddrinfo(res0);
- return sockfd;
+ close(sockfd);
}

+ if (!rp)
+ return EAI_SYSTEM;

- dbg("%s:%s, %s", hostname, service, "no destination to connect to");
- freeaddrinfo(res0);
+ freeaddrinfo(res);

- return -1;
+ return sockfd;
}
diff --git a/drivers/staging/usbip/userspace/src/usbip_network.h b/drivers/staging/usbip/userspace/src/usbip_network.h
index 1225466..82b0811 100644
--- a/drivers/staging/usbip/userspace/src/usbip_network.h
+++ b/drivers/staging/usbip/userspace/src/usbip_network.h
@@ -2,19 +2,20 @@
* Copyright (C) 2005-2007 Takahiro Hirofuchi
*/

-#ifndef _USBIP_NETWORK_H
-#define _USBIP_NETWORK_H
+#ifndef __USBIP_NETWORK_H
+#define __USBIP_NETWORK_H

-#include "usbip.h"
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/tcp.h>
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif

+#include <sys/types.h>
+#include <sysfs/libsysfs.h>

-/* -------------------------------------------------- */
-/* Define Protocol Format */
-/* -------------------------------------------------- */
+#include <stdint.h>

+#define USBIP_PORT 3240
+#define USBIP_PORT_STRING "3240"

/* ---------------------------------------------------------------------- */
/* Common header for all the kinds of PDUs. */
@@ -38,7 +39,6 @@ struct op_common {
pack_uint32_t(pack, &(op_common)->status );\
} while (0)

-
/* ---------------------------------------------------------------------- */
/* Dummy Code */
#define OP_UNSPEC 0x00
@@ -60,7 +60,6 @@ struct op_devinfo_reply {
struct usb_interface uinf[];
} __attribute__((packed));

-
/* ---------------------------------------------------------------------- */
/* Import a remote USB device. */
#define OP_IMPORT 0x03
@@ -83,8 +82,6 @@ struct op_import_reply {
pack_usb_device(pack, &(reply)->udev);\
} while (0)

-
-
/* ---------------------------------------------------------------------- */
/* Export a USB device to a remote host. */
#define OP_EXPORT 0x06
@@ -128,8 +125,6 @@ struct op_unexport_reply {
#define PACK_OP_UNEXPORT_REPLY(pack, reply) do {\
} while (0)

-
-
/* ---------------------------------------------------------------------- */
/* Negotiate IPSec encryption key. (still not used) */
#define OP_CRYPKEY 0x04
@@ -172,11 +167,6 @@ struct op_devlist_reply_extra {
pack_uint32_t(pack, &(reply)->ndev);\
} while (0)

-
-/* -------------------------------------------------- */
-/* Declare Prototype Function */
-/* -------------------------------------------------- */
-
void pack_uint32_t(int pack, uint32_t *num);
void pack_uint16_t(int pack, uint16_t *num);
void pack_usb_device(int pack, struct usb_device *udev);
@@ -190,9 +180,6 @@ int usbip_set_reuseaddr(int sockfd);
int usbip_set_nodelay(int sockfd);
int usbip_set_keepalive(int sockfd);

-int tcp_connect(char *hostname, char *service);
+int usbip_net_tcp_connect(char *hostname, char *port);

-#define USBIP_PORT 3240
-#define USBIP_PORT_STRING "3240"
-
-#endif
+#endif /* __USBIP_NETWORK_H */
--
1.7.5.1