summaryrefslogtreecommitdiffstats
path: root/drivers/staging/usbip
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-06-09 13:49:02 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-06-09 13:49:02 -0700
commitdc5a18941b4226846f0c5994e4f45bc685f7bcfe (patch)
tree8189cc7586fb875484bce2a7122f2152343904bb /drivers/staging/usbip
parent461df4ded3a143f09f9d0e870e7b16b787dc0591 (diff)
parentc773298788598a26e325bc2639877c76818943e3 (diff)
downloadlinux-0-day-dc5a18941b4226846f0c5994e4f45bc685f7bcfe.tar.gz
linux-0-day-dc5a18941b4226846f0c5994e4f45bc685f7bcfe.tar.xz
Merge Linus's tree into staging-next
This was done to resolve the conflicts that were in a number of files due to changes done upstream with others done in the staging-next branch. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/usbip')
-rw-r--r--drivers/staging/usbip/README1
-rw-r--r--drivers/staging/usbip/stub.h4
-rw-r--r--drivers/staging/usbip/stub_dev.c68
-rw-r--r--drivers/staging/usbip/stub_main.c193
-rw-r--r--drivers/staging/usbip/stub_rx.c6
-rw-r--r--drivers/staging/usbip/stub_tx.c13
-rw-r--r--drivers/staging/usbip/usbip_common.c35
-rw-r--r--drivers/staging/usbip/usbip_common.h238
-rw-r--r--drivers/staging/usbip/userspace/configure.ac8
-rw-r--r--drivers/staging/usbip/userspace/libsrc/stub_driver.c17
-rw-r--r--drivers/staging/usbip/userspace/libsrc/stub_driver.h4
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_common.c9
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_common.h20
-rw-r--r--drivers/staging/usbip/userspace/libsrc/vhci_driver.c78
-rw-r--r--drivers/staging/usbip/userspace/libsrc/vhci_driver.h21
-rw-r--r--drivers/staging/usbip/userspace/src/Makefile.am11
-rw-r--r--drivers/staging/usbip/userspace/src/bind-driver.c643
-rw-r--r--drivers/staging/usbip/userspace/src/usbip.c813
-rw-r--r--drivers/staging/usbip/userspace/src/usbip.h39
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_attach.c228
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_bind.c264
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_detach.c103
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_list.c286
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_network.c91
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_network.h57
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_unbind.c95
-rw-r--r--drivers/staging/usbip/userspace/src/usbipd.c28
-rw-r--r--drivers/staging/usbip/userspace/src/utils.c66
-rw-r--r--drivers/staging/usbip/userspace/src/utils.h29
-rw-r--r--drivers/staging/usbip/vhci.h11
-rw-r--r--drivers/staging/usbip/vhci_hcd.c17
-rw-r--r--drivers/staging/usbip/vhci_rx.c2
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c6
33 files changed, 1657 insertions, 1847 deletions
diff --git a/drivers/staging/usbip/README b/drivers/staging/usbip/README
index c11be57354851..41a2cf2e77a60 100644
--- a/drivers/staging/usbip/README
+++ b/drivers/staging/usbip/README
@@ -2,5 +2,6 @@ TODO:
- more discussion about the protocol
- testing
- review of the userspace interface
+ - document the protocol
Please send patches for this code to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h
index 6592aa2ad15ca..132adc57ebc1a 100644
--- a/drivers/staging/usbip/stub.h
+++ b/drivers/staging/usbip/stub.h
@@ -76,7 +76,9 @@ struct stub_unlink {
__u32 status;
};
-#define BUSID_SIZE 20
+/* same as SYSFS_BUS_ID_SIZE */
+#define BUSID_SIZE 32
+
struct bus_id_priv {
char name[BUSID_SIZE];
char status;
diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c
index 8cbea42b69bc7..e26b2eede507f 100644
--- a/drivers/staging/usbip/stub_dev.c
+++ b/drivers/staging/usbip/stub_dev.c
@@ -23,16 +23,10 @@
#include "usbip_common.h"
#include "stub.h"
-static int stub_probe(struct usb_interface *interface,
- const struct usb_device_id *id);
-static void stub_disconnect(struct usb_interface *interface);
-static int stub_pre_reset(struct usb_interface *interface);
-static int stub_post_reset(struct usb_interface *interface);
-
/*
* Define device IDs here if you want to explicitly limit exportable devices.
- * In the most cases, wild card matching will be ok because driver binding can
- * be changed dynamically by a userland program.
+ * In most cases, wildcard matching will be okay because driver binding can be
+ * changed dynamically by a userland program.
*/
static struct usb_device_id stub_table[] = {
#if 0
@@ -56,18 +50,9 @@ static struct usb_device_id stub_table[] = {
};
MODULE_DEVICE_TABLE(usb, stub_table);
-struct usb_driver stub_driver = {
- .name = "usbip",
- .probe = stub_probe,
- .disconnect = stub_disconnect,
- .id_table = stub_table,
- .pre_reset = stub_pre_reset,
- .post_reset = stub_post_reset,
-};
-
/*
- * usbip_status shows status of usbip as long as this driver is bound to the
- * target device.
+ * usbip_status shows the status of usbip-host as long as this driver is bound
+ * to the target device.
*/
static ssize_t show_status(struct device *dev, struct device_attribute *attr,
char *buf)
@@ -211,10 +196,11 @@ static void stub_shutdown_connection(struct usbip_device *ud)
if (ud->tcp_tx && !task_is_dead(ud->tcp_tx))
kthread_stop(ud->tcp_tx);
- /* 2. close the socket */
/*
- * tcp_socket is freed after threads are killed.
- * So usbip_xmit do not touch NULL socket.
+ * 2. close the socket
+ *
+ * tcp_socket is freed after threads are killed so that usbip_xmit does
+ * not touch NULL socket.
*/
if (ud->tcp_socket) {
sock_release(ud->tcp_socket);
@@ -234,8 +220,8 @@ static void stub_shutdown_connection(struct usbip_device *ud)
list_del(&unlink->list);
kfree(unlink);
}
- list_for_each_entry_safe(unlink, tmp,
- &sdev->unlink_free, list) {
+ list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free,
+ list) {
list_del(&unlink->list);
kfree(unlink);
}
@@ -262,22 +248,17 @@ static void stub_device_reset(struct usbip_device *ud)
/* try to reset the device */
ret = usb_reset_device(udev);
-
usb_unlock_device(udev);
spin_lock(&ud->lock);
if (ret) {
dev_err(&udev->dev, "device reset\n");
ud->status = SDEV_ST_ERROR;
-
} else {
dev_info(&udev->dev, "device reset\n");
ud->status = SDEV_ST_AVAILABLE;
-
}
spin_unlock(&ud->lock);
-
- return;
}
static void stub_device_unusable(struct usbip_device *ud)
@@ -379,7 +360,7 @@ static int stub_probe(struct usb_interface *interface,
/* check we should claim or not by busid_table */
busid_priv = get_busid_priv(udev_busid);
- if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
+ if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
(busid_priv->status == STUB_BUSID_OTHER)) {
dev_info(&interface->dev, "%s is not in match_busid table... "
"skip!\n", udev_busid);
@@ -424,7 +405,6 @@ static int stub_probe(struct usb_interface *interface,
udev_busid);
usb_set_intfdata(interface, NULL);
busid_priv->interf_count--;
-
return err;
}
@@ -432,7 +412,7 @@ static int stub_probe(struct usb_interface *interface,
return 0;
}
- /* ok. this is my device. */
+ /* ok, this is my device */
sdev = stub_device_alloc(udev, interface);
if (!sdev)
return -ENOMEM;
@@ -447,7 +427,6 @@ static int stub_probe(struct usb_interface *interface,
/* set private data to usb_interface */
usb_set_intfdata(interface, sdev);
busid_priv->interf_count++;
-
busid_priv->sdev = sdev;
err = stub_add_files(&interface->dev);
@@ -457,7 +436,6 @@ static int stub_probe(struct usb_interface *interface,
usb_put_intf(interface);
busid_priv->interf_count = 0;
-
busid_priv->sdev = NULL;
stub_device_free(sdev);
return err;
@@ -546,19 +524,9 @@ static void stub_disconnect(struct usb_interface *interface)
}
}
-/*
- * Presence of pre_reset and post_reset prevents the driver from being unbound
- * when the device is being reset
- */
-
-int stub_pre_reset(struct usb_interface *interface)
-{
- dev_dbg(&interface->dev, "pre_reset\n");
- return 0;
-}
-
-int stub_post_reset(struct usb_interface *interface)
-{
- dev_dbg(&interface->dev, "post_reset\n");
- return 0;
-}
+struct usb_driver stub_driver = {
+ .name = "usbip-host",
+ .probe = stub_probe,
+ .disconnect = stub_disconnect,
+ .id_table = stub_table,
+};
diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c
index e9085d6639450..a34249a9cb6e1 100644
--- a/drivers/staging/usbip/stub_main.c
+++ b/drivers/staging/usbip/stub_main.c
@@ -25,9 +25,7 @@
#define DRIVER_AUTHOR "Takahiro Hirofuchi"
#define DRIVER_DESC "USB/IP Host Driver"
-/* stub_priv is allocated from stub_priv_cache */
struct kmem_cache *stub_priv_cache;
-
/*
* busid_tables defines matching busids that usbip can grab. A user can change
* dynamically what device is locally used and what device is exported to a
@@ -37,70 +35,60 @@ struct kmem_cache *stub_priv_cache;
static struct bus_id_priv busid_table[MAX_BUSID];
static spinlock_t busid_table_lock;
-int match_busid(const char *busid)
+static void init_busid_table(void)
{
int i;
- spin_lock(&busid_table_lock);
-
+ memset(busid_table, 0, sizeof(busid_table));
for (i = 0; i < MAX_BUSID; i++)
- if (busid_table[i].name[0])
- if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
- /* already registerd */
- spin_unlock(&busid_table_lock);
- return 0;
- }
-
- spin_unlock(&busid_table_lock);
+ busid_table[i].status = STUB_BUSID_OTHER;
- return 1;
+ spin_lock_init(&busid_table_lock);
}
-struct bus_id_priv *get_busid_priv(const char *busid)
+/*
+ * Find the index of the busid by name.
+ * Must be called with busid_table_lock held.
+ */
+static int get_busid_idx(const char *busid)
{
int i;
-
- spin_lock(&busid_table_lock);
+ int idx = -1;
for (i = 0; i < MAX_BUSID; i++)
if (busid_table[i].name[0])
if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
- /* already registerd */
- spin_unlock(&busid_table_lock);
- return &(busid_table[i]);
+ idx = i;
+ break;
}
-
- spin_unlock(&busid_table_lock);
-
- return NULL;
+ return idx;
}
-static ssize_t show_match_busid(struct device_driver *drv, char *buf)
+struct bus_id_priv *get_busid_priv(const char *busid)
{
- int i;
- char *out = buf;
+ int idx;
+ struct bus_id_priv *bid = NULL;
spin_lock(&busid_table_lock);
-
- for (i = 0; i < MAX_BUSID; i++)
- if (busid_table[i].name[0])
- out += sprintf(out, "%s ", busid_table[i].name);
-
+ idx = get_busid_idx(busid);
+ if (idx >= 0)
+ bid = &(busid_table[idx]);
spin_unlock(&busid_table_lock);
- out += sprintf(out, "\n");
-
- return out - buf;
+ return bid;
}
static int add_match_busid(char *busid)
{
int i;
-
- if (!match_busid(busid))
- return 0;
+ int ret = -1;
spin_lock(&busid_table_lock);
+ /* already registered? */
+ if (get_busid_idx(busid) >= 0) {
+ ret = 0;
+ goto out;
+ }
for (i = 0; i < MAX_BUSID; i++)
if (!busid_table[i].name[0]) {
@@ -108,52 +96,55 @@ static int add_match_busid(char *busid)
if ((busid_table[i].status != STUB_BUSID_ALLOC) &&
(busid_table[i].status != STUB_BUSID_REMOV))
busid_table[i].status = STUB_BUSID_ADDED;
- spin_unlock(&busid_table_lock);
- return 0;
+ ret = 0;
+ break;
}
+out:
spin_unlock(&busid_table_lock);
- return -1;
+ return ret;
}
int del_match_busid(char *busid)
{
- int i;
+ int idx;
+ int ret = -1;
spin_lock(&busid_table_lock);
+ idx = get_busid_idx(busid);
+ if (idx < 0)
+ goto out;
- for (i = 0; i < MAX_BUSID; i++)
- if (!strncmp(busid_table[i].name, busid, BUSID_SIZE)) {
- /* found */
- if (busid_table[i].status == STUB_BUSID_OTHER)
- memset(busid_table[i].name, 0, BUSID_SIZE);
- if ((busid_table[i].status != STUB_BUSID_OTHER) &&
- (busid_table[i].status != STUB_BUSID_ADDED)) {
- busid_table[i].status = STUB_BUSID_REMOV;
- }
- spin_unlock(&busid_table_lock);
- return 0;
- }
+ /* found */
+ ret = 0;
+
+ if (busid_table[idx].status == STUB_BUSID_OTHER)
+ memset(busid_table[idx].name, 0, BUSID_SIZE);
+
+ if ((busid_table[idx].status != STUB_BUSID_OTHER) &&
+ (busid_table[idx].status != STUB_BUSID_ADDED))
+ busid_table[idx].status = STUB_BUSID_REMOV;
+out:
spin_unlock(&busid_table_lock);
- return -1;
+ return ret;
}
-static void init_busid_table(void)
+static ssize_t show_match_busid(struct device_driver *drv, char *buf)
{
int i;
+ char *out = buf;
- for (i = 0; i < MAX_BUSID; i++) {
- memset(busid_table[i].name, 0, BUSID_SIZE);
- busid_table[i].status = STUB_BUSID_OTHER;
- busid_table[i].interf_count = 0;
- busid_table[i].sdev = NULL;
- busid_table[i].shutdown_busid = 0;
- }
+ spin_lock(&busid_table_lock);
+ for (i = 0; i < MAX_BUSID; i++)
+ if (busid_table[i].name[0])
+ out += sprintf(out, "%s ", busid_table[i].name);
+ spin_unlock(&busid_table_lock);
+ out += sprintf(out, "\n");
- spin_lock_init(&busid_table_lock);
+ return out - buf;
}
static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
@@ -175,23 +166,24 @@ static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
strncpy(busid, buf + 4, BUSID_SIZE);
if (!strncmp(buf, "add ", 4)) {
- if (add_match_busid(busid) < 0)
+ if (add_match_busid(busid) < 0) {
return -ENOMEM;
- else {
+ } else {
pr_debug("add busid %s\n", busid);
return count;
}
} else if (!strncmp(buf, "del ", 4)) {
- if (del_match_busid(busid) < 0)
+ if (del_match_busid(busid) < 0) {
return -ENODEV;
- else {
+ } else {
pr_debug("del busid %s\n", busid);
return count;
}
- } else
+ } else {
return -EINVAL;
+ }
}
-static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid,
+static DRIVER_ATTR(match_busid, S_IRUSR | S_IWUSR, show_match_busid,
store_match_busid);
static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
@@ -214,36 +206,30 @@ static struct stub_priv *stub_priv_pop(struct stub_device *sdev)
spin_lock_irqsave(&sdev->priv_lock, flags);
priv = stub_priv_pop_from_listhead(&sdev->priv_init);
- if (priv) {
- spin_unlock_irqrestore(&sdev->priv_lock, flags);
- return priv;
- }
+ if (priv)
+ goto done;
priv = stub_priv_pop_from_listhead(&sdev->priv_tx);
- if (priv) {
- spin_unlock_irqrestore(&sdev->priv_lock, flags);
- return priv;
- }
+ if (priv)
+ goto done;
priv = stub_priv_pop_from_listhead(&sdev->priv_free);
- if (priv) {
- spin_unlock_irqrestore(&sdev->priv_lock, flags);
- return priv;
- }
+done:
spin_unlock_irqrestore(&sdev->priv_lock, flags);
- return NULL;
+
+ return priv;
}
void stub_device_cleanup_urbs(struct stub_device *sdev)
{
struct stub_priv *priv;
+ struct urb *urb;
dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev);
while ((priv = stub_priv_pop(sdev))) {
- struct urb *urb = priv->urb;
-
+ urb = priv->urb;
dev_dbg(&sdev->udev->dev, "free urb %p\n", urb);
usb_kill_urb(urb);
@@ -251,51 +237,46 @@ void stub_device_cleanup_urbs(struct stub_device *sdev)
kfree(urb->transfer_buffer);
kfree(urb->setup_packet);
-
usb_free_urb(urb);
}
}
-static int __init usb_stub_init(void)
+static int __init usbip_host_init(void)
{
int ret;
- stub_priv_cache = kmem_cache_create("stub_priv",
- sizeof(struct stub_priv), 0,
- SLAB_HWCACHE_ALIGN, NULL);
+ stub_priv_cache = KMEM_CACHE(stub_priv, SLAB_HWCACHE_ALIGN);
if (!stub_priv_cache) {
- pr_err("create stub_priv_cache error\n");
+ pr_err("kmem_cache_create failed\n");
return -ENOMEM;
}
ret = usb_register(&stub_driver);
- if (ret) {
+ if (ret < 0) {
pr_err("usb_register failed %d\n", ret);
- goto error_usb_register;
+ goto err_usb_register;
}
- pr_info(DRIVER_DESC " " USBIP_VERSION "\n");
-
- init_busid_table();
-
ret = driver_create_file(&stub_driver.drvwrap.driver,
&driver_attr_match_busid);
-
- if (ret) {
- pr_err("create driver sysfs\n");
- goto error_create_file;
+ if (ret < 0) {
+ pr_err("driver_create_file failed\n");
+ goto err_create_file;
}
+ init_busid_table();
+ pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
return ret;
-error_create_file:
+
+err_create_file:
usb_deregister(&stub_driver);
-error_usb_register:
+err_usb_register:
kmem_cache_destroy(stub_priv_cache);
return ret;
}
-static void __exit usb_stub_exit(void)
+static void __exit usbip_host_exit(void)
{
driver_remove_file(&stub_driver.drvwrap.driver,
&driver_attr_match_busid);
@@ -309,8 +290,8 @@ static void __exit usb_stub_exit(void)
kmem_cache_destroy(stub_priv_cache);
}
-module_init(usb_stub_init);
-module_exit(usb_stub_exit);
+module_init(usbip_host_init);
+module_exit(usbip_host_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index bc57844600b96..538fb9ee341a6 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -306,18 +306,18 @@ static int stub_recv_cmd_unlink(struct stub_device *sdev,
static int valid_request(struct stub_device *sdev, struct usbip_header *pdu)
{
struct usbip_device *ud = &sdev->ud;
+ int valid = 0;
if (pdu->base.devid == sdev->devid) {
spin_lock(&ud->lock);
if (ud->status == SDEV_ST_USED) {
/* A request is valid. */
- spin_unlock(&ud->lock);
- return 1;
+ valid = 1;
}
spin_unlock(&ud->lock);
}
- return 0;
+ return valid;
}
static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
diff --git a/drivers/staging/usbip/stub_tx.c b/drivers/staging/usbip/stub_tx.c
index fda2bc95e8598..1cbae44ba0dcf 100644
--- a/drivers/staging/usbip/stub_tx.c
+++ b/drivers/staging/usbip/stub_tx.c
@@ -97,13 +97,12 @@ void stub_complete(struct urb *urb)
/* link a urb to the queue of tx. */
spin_lock_irqsave(&sdev->priv_lock, flags);
-
if (priv->unlinking) {
stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status);
stub_free_priv_and_urb(priv);
- } else
+ } else {
list_move_tail(&priv->list, &sdev->priv_tx);
-
+ }
spin_unlock_irqrestore(&sdev->priv_lock, flags);
/* wake up tx_thread */
@@ -113,10 +112,10 @@ void stub_complete(struct urb *urb)
static inline void setup_base_pdu(struct usbip_header_basic *base,
__u32 command, __u32 seqnum)
{
- base->command = command;
- base->seqnum = seqnum;
- base->devid = 0;
- base->ep = 0;
+ base->command = command;
+ base->seqnum = seqnum;
+ base->devid = 0;
+ base->ep = 0;
base->direction = 0;
}
diff --git a/drivers/staging/usbip/usbip_common.c b/drivers/staging/usbip/usbip_common.c
index 433a3b6207d65..f4b53d103c54e 100644
--- a/drivers/staging/usbip/usbip_common.c
+++ b/drivers/staging/usbip/usbip_common.c
@@ -63,9 +63,9 @@ static void usbip_dump_buffer(char *buff, int bufflen)
static void usbip_dump_pipe(unsigned int p)
{
unsigned char type = usb_pipetype(p);
- unsigned char ep = usb_pipeendpoint(p);
- unsigned char dev = usb_pipedevice(p);
- unsigned char dir = usb_pipein(p);
+ unsigned char ep = usb_pipeendpoint(p);
+ unsigned char dev = usb_pipedevice(p);
+ unsigned char dir = usb_pipein(p);
pr_debug("dev(%d) ep(%d) [%s] ", dev, ep, dir ? "IN" : "OUT");
@@ -204,7 +204,7 @@ static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
pr_debug("CLEAR_FEAT\n");
break;
case USB_REQ_SET_FEATURE:
- pr_debug("SET_FEAT \n");
+ pr_debug("SET_FEAT\n");
break;
case USB_REQ_SET_ADDRESS:
pr_debug("SET_ADDRRS\n");
@@ -231,14 +231,14 @@ static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
pr_debug("SYNC_FRAME\n");
break;
default:
- pr_debug("REQ(%02X) \n", cmd->bRequest);
+ pr_debug("REQ(%02X)\n", cmd->bRequest);
break;
}
usbip_dump_request_type(cmd->bRequestType);
} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) {
- pr_debug("CLASS \n");
+ pr_debug("CLASS\n");
} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) {
- pr_debug("VENDOR \n");
+ pr_debug("VENDOR\n");
} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED) {
pr_debug("RESERVED\n");
}
@@ -334,8 +334,8 @@ void usbip_dump_header(struct usbip_header *pdu)
EXPORT_SYMBOL_GPL(usbip_dump_header);
/* Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
-int usbip_xmit(int send, struct socket *sock, char *buf,
- int size, int msg_flags)
+int usbip_xmit(int send, struct socket *sock, char *buf, int size,
+ int msg_flags)
{
int result;
struct msghdr msg;
@@ -627,9 +627,8 @@ void usbip_header_correct_endian(struct usbip_header *pdu, int send)
}
EXPORT_SYMBOL_GPL(usbip_header_correct_endian);
-static void usbip_iso_pakcet_correct_endian(
- struct usbip_iso_packet_descriptor *iso,
- int send)
+static void usbip_iso_packet_correct_endian(
+ struct usbip_iso_packet_descriptor *iso, int send)
{
/* does not need all members. but copy all simply. */
if (send) {
@@ -678,7 +677,7 @@ void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
iso = buff + (i * sizeof(*iso));
usbip_pack_iso(iso, &urb->iso_frame_desc[i], 1);
- usbip_iso_pakcet_correct_endian(iso, 1);
+ usbip_iso_packet_correct_endian(iso, 1);
}
*bufflen = size;
@@ -729,7 +728,7 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb)
for (i = 0; i < np; i++) {
iso = buff + (i * sizeof(*iso));
- usbip_iso_pakcet_correct_endian(iso, 0);
+ usbip_iso_packet_correct_endian(iso, 0);
usbip_pack_iso(iso, &urb->iso_frame_desc[i], 0);
total_length += urb->iso_frame_desc[i].actual_length;
}
@@ -839,19 +838,19 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
}
EXPORT_SYMBOL_GPL(usbip_recv_xbuff);
-static int __init usbip_common_init(void)
+static int __init usbip_core_init(void)
{
pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
return 0;
}
-static void __exit usbip_common_exit(void)
+static void __exit usbip_core_exit(void)
{
return;
}
-module_init(usbip_common_init);
-module_exit(usbip_common_exit);
+module_init(usbip_core_init);
+module_exit(usbip_core_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/staging/usbip/usbip_common.h b/drivers/staging/usbip/usbip_common.h
index 4a641c552b78c..074ac4267d3b5 100644
--- a/drivers/staging/usbip/usbip_common.h
+++ b/drivers/staging/usbip/usbip_common.h
@@ -65,7 +65,7 @@ enum {
#define usbip_dbg_flag_vhci_tx (usbip_debug_flag & usbip_debug_vhci_tx)
#define usbip_dbg_flag_stub_rx (usbip_debug_flag & usbip_debug_stub_rx)
#define usbip_dbg_flag_stub_tx (usbip_debug_flag & usbip_debug_stub_tx)
-#define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs)
+#define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs)
extern unsigned long usbip_debug_flag;
extern struct device_attribute dev_attr_usbip_debug;
@@ -104,111 +104,110 @@ extern struct device_attribute dev_attr_usbip_debug;
usbip_dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
/*
- * USB/IP request headers.
- * Currently, we define 4 request types:
+ * USB/IP request headers
*
- * - CMD_SUBMIT transfers a USB request, corresponding to usb_submit_urb().
- * (client to server)
- * - RET_RETURN transfers the result of CMD_SUBMIT.
- * (server to client)
- * - CMD_UNLINK transfers an unlink request of a pending USB request.
+ * Each request is transferred across the network to its counterpart, which
+ * facilitates the normal USB communication. The values contained in the headers
+ * are basically the same as in a URB. Currently, four request types are
+ * defined:
+ *
+ * - USBIP_CMD_SUBMIT: a USB request block, corresponds to usb_submit_urb()
* (client to server)
- * - RET_UNLINK transfers the result of CMD_UNLINK.
+ *
+ * - USBIP_RET_SUBMIT: the result of USBIP_CMD_SUBMIT
* (server to client)
*
- * Note: The below request formats are based on the USB subsystem of Linux. Its
- * details will be defined when other implementations come.
+ * - USBIP_CMD_UNLINK: an unlink request of a pending USBIP_CMD_SUBMIT,
+ * corresponds to usb_unlink_urb()
+ * (client to server)
*
+ * - USBIP_RET_UNLINK: the result of USBIP_CMD_UNLINK
+ * (server to client)
*
*/
+#define USBIP_CMD_SUBMIT 0x0001
+#define USBIP_RET_SUBMIT 0x0002
+#define USBIP_CMD_UNLINK 0x0003
+#define USBIP_RET_UNLINK 0x0004
-/*
- * A basic header followed by other additional headers.
+#define USBIP_DIR_IN 0x00
+#define USBIP_DIR_OUT 0x01
+
+/**
+ * struct usbip_header_basic - data pertinent to every request
+ * @command: the usbip request type
+ * @seqnum: sequential number that identifies requests; incremented per
+ * connection
+ * @devid: specifies a remote USB device uniquely instead of busnum and devnum;
+ * in the stub driver, this value is ((busnum << 16) | devnum)
+ * @direction: direction of the transfer
+ * @ep: endpoint number
*/
struct usbip_header_basic {
-#define USBIP_CMD_SUBMIT 0x0001
-#define USBIP_CMD_UNLINK 0x0002
-#define USBIP_RET_SUBMIT 0x0003
-#define USBIP_RET_UNLINK 0x0004
__u32 command;
-
- /* sequential number which identifies requests.
- * incremented per connections */
__u32 seqnum;
-
- /* devid is used to specify a remote USB device uniquely instead
- * of busnum and devnum in Linux. In the case of Linux stub_driver,
- * this value is ((busnum << 16) | devnum) */
__u32 devid;
-
-#define USBIP_DIR_OUT 0
-#define USBIP_DIR_IN 1
__u32 direction;
- __u32 ep; /* endpoint number */
+ __u32 ep;
} __packed;
-/*
- * An additional header for a CMD_SUBMIT packet.
+/**
+ * struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header
+ * @transfer_flags: URB flags
+ * @transfer_buffer_length: the data size for (in) or (out) transfer
+ * @start_frame: initial frame for isochronous or interrupt transfers
+ * @number_of_packets: number of isochronous packets
+ * @interval: maximum time for the request on the server-side host controller
+ * @setup: setup data for a control request
*/
struct usbip_header_cmd_submit {
- /* these values are basically the same as in a URB. */
-
- /* the same in a URB. */
__u32 transfer_flags;
-
- /* set the following data size (out),
- * or expected reading data size (in) */
__s32 transfer_buffer_length;
/* it is difficult for usbip to sync frames (reserved only?) */
__s32 start_frame;
-
- /* the number of iso descriptors that follows this header */
__s32 number_of_packets;
-
- /* the maximum time within which this request works in a host
- * controller of a server side */
__s32 interval;
- /* set setup packet data for a CTRL request */
unsigned char setup[8];
} __packed;
-/*
- * An additional header for a RET_SUBMIT packet.
+/**
+ * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header
+ * @status: return status of a non-iso request
+ * @actual_length: number of bytes transferred
+ * @start_frame: initial frame for isochronous or interrupt transfers
+ * @number_of_packets: number of isochronous packets
+ * @error_count: number of errors for isochronous transfers
*/
struct usbip_header_ret_submit {
__s32 status;
- __s32 actual_length; /* returned data length */
- __s32 start_frame; /* ISO and INT */
- __s32 number_of_packets; /* ISO only */
- __s32 error_count; /* ISO only */
+ __s32 actual_length;
+ __s32 start_frame;
+ __s32 number_of_packets;
+ __s32 error_count;
} __packed;
-/*
- * An additional header for a CMD_UNLINK packet.
+/**
+ * struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header
+ * @seqnum: the URB seqnum to unlink
*/
struct usbip_header_cmd_unlink {
- __u32 seqnum; /* URB's seqnum that will be unlinked */
+ __u32 seqnum;
} __packed;
-/*
- * An additional header for a RET_UNLINK packet.
+/**
+ * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header
+ * @status: return status of the request
*/
struct usbip_header_ret_unlink {
__s32 status;
} __packed;
-/* the same as usb_iso_packet_descriptor but packed for pdu */
-struct usbip_iso_packet_descriptor {
- __u32 offset;
- __u32 length; /* expected length */
- __u32 actual_length;
- __u32 status;
-} __packed;
-
-/*
- * All usbip packets use a common header to keep code simple.
+/**
+ * struct usbip_header - common header for all usbip packets
+ * @base: the basic header
+ * @u: packet type dependent header
*/
struct usbip_header {
struct usbip_header_basic base;
@@ -221,40 +220,15 @@ struct usbip_header {
} u;
} __packed;
-int usbip_xmit(int, struct socket *, char *, int, int);
-int usbip_sendmsg(struct socket *, struct msghdr *, int);
-
-static inline int interface_to_busnum(struct usb_interface *interface)
-{
- struct usb_device *udev = interface_to_usbdev(interface);
- return udev->bus->busnum;
-}
-
-static inline int interface_to_devnum(struct usb_interface *interface)
-{
- struct usb_device *udev = interface_to_usbdev(interface);
- return udev->devnum;
-}
-
-static inline int interface_to_infnum(struct usb_interface *interface)
-{
- return interface->cur_altsetting->desc.bInterfaceNumber;
-}
-
-#if 0
-int setnodelay(struct socket *);
-int setquickack(struct socket *);
-int setkeepalive(struct socket *socket);
-void setreuse(struct socket *);
-#endif
-
-struct socket *sockfd_to_socket(unsigned int);
-int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
-
-void usbip_dump_urb(struct urb *purb);
-void usbip_dump_header(struct usbip_header *pdu);
-
-struct usbip_device;
+/*
+ * This is the same as usb_iso_packet_descriptor but packed for pdu.
+ */
+struct usbip_iso_packet_descriptor {
+ __u32 offset;
+ __u32 length; /* expected length */
+ __u32 actual_length;
+ __u32 status;
+} __packed;
enum usbip_side {
USBIP_VHCI,
@@ -277,20 +251,7 @@ enum usbip_status {
VDEV_ST_ERROR
};
-/* a common structure for stub_device and vhci_device */
-struct usbip_device {
- enum usbip_side side;
- enum usbip_status status;
-
- /* lock for status */
- spinlock_t lock;
-
- struct socket *tcp_socket;
-
- struct task_struct *tcp_rx;
- struct task_struct *tcp_tx;
-
- /* event handler */
+/* event handler */
#define USBIP_EH_SHUTDOWN (1 << 0)
#define USBIP_EH_BYE (1 << 1)
#define USBIP_EH_RESET (1 << 2)
@@ -307,6 +268,19 @@ struct usbip_device {
#define VDEV_EVENT_ERROR_TCP (USBIP_EH_SHUTDOWN | USBIP_EH_RESET)
#define VDEV_EVENT_ERROR_MALLOC (USBIP_EH_SHUTDOWN | USBIP_EH_UNUSABLE)
+/* a common structure for stub_device and vhci_device */
+struct usbip_device {
+ enum usbip_side side;
+ enum usbip_status status;
+
+ /* lock for status */
+ spinlock_t lock;
+
+ struct socket *tcp_socket;
+
+ struct task_struct *tcp_rx;
+ struct task_struct *tcp_tx;
+
unsigned long event;
struct task_struct *eh;
wait_queue_head_t eh_waitq;
@@ -318,17 +292,32 @@ struct usbip_device {
} eh_ops;
};
+#if 0
+int usbip_sendmsg(struct socket *, struct msghdr *, int);
+int set_sockaddr(struct socket *socket, struct sockaddr_storage *ss);
+int setnodelay(struct socket *);
+int setquickack(struct socket *);
+int setkeepalive(struct socket *socket);
+void setreuse(struct socket *);
+#endif
+
+/* usbip_common.c */
+void usbip_dump_urb(struct urb *purb);
+void usbip_dump_header(struct usbip_header *pdu);
+
+int usbip_xmit(int send, struct socket *sock, char *buf, int size,
+ int msg_flags);
+struct socket *sockfd_to_socket(unsigned int sockfd);
+
void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
int pack);
-
void usbip_header_correct_endian(struct usbip_header *pdu, int send);
-/* some members of urb must be substituted before. */
-int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
+
+void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
/* some members of urb must be substituted before. */
int usbip_recv_iso(struct usbip_device *ud, struct urb *urb);
-/* some members of urb must be substituted before. */
int usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
-void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
+int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb);
/* usbip_event.c */
int usbip_start_eh(struct usbip_device *ud);
@@ -336,4 +325,21 @@ void usbip_stop_eh(struct usbip_device *ud);
void usbip_event_add(struct usbip_device *ud, unsigned long event);
int usbip_event_happened(struct usbip_device *ud);
+static inline int interface_to_busnum(struct usb_interface *interface)
+{
+ struct usb_device *udev = interface_to_usbdev(interface);
+ return udev->bus->busnum;
+}
+
+static inline int interface_to_devnum(struct usb_interface *interface)
+{
+ struct usb_device *udev = interface_to_usbdev(interface);
+ return udev->devnum;
+}
+
+static inline int interface_to_infnum(struct usb_interface *interface)
+{
+ return interface->cur_altsetting->desc.bInterfaceNumber;
+}
+
#endif /* __USBIP_COMMON_H */
diff --git a/drivers/staging/usbip/userspace/configure.ac b/drivers/staging/usbip/userspace/configure.ac
index e3afa159116a6..06fb95d083cf6 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], [usbip-devel@lists.sourceforge.net])
-AC_DEFINE([USBIP_VERSION], [0x000106], [numeric version number])
+AC_INIT([usbip], [1.0.0], [usbip-devel@lists.sourceforge.net])
+AC_DEFINE([USBIP_VERSION], [0x00000100], [binary-coded decimal version number])
CURRENT=0
REVISION=1
@@ -29,7 +29,7 @@ AC_PROG_MAKE_SET
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h dnl
- string.h strings.h sys/socket.h syslog.h unistd.h])
+ string.h sys/socket.h syslog.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_INT32_T
@@ -41,7 +41,7 @@ AC_TYPE_UINT8_T
# Checks for library functions.
AC_FUNC_REALLOC
-AC_CHECK_FUNCS([bzero memset mkdir regcomp socket strchr strerror strstr dnl
+AC_CHECK_FUNCS([memset mkdir regcomp socket strchr strerror strstr dnl
strtoul])
AC_CHECK_HEADER([sysfs/libsysfs.h],
diff --git a/drivers/staging/usbip/userspace/libsrc/stub_driver.c b/drivers/staging/usbip/userspace/libsrc/stub_driver.c
index cc3364345f5fb..4d4d17122ce95 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;
}
@@ -46,7 +43,7 @@ static struct sysfs_driver *open_sysfs_stub_driver(void)
#define SYSFS_OPEN_RETRIES 100
/* only the first interface value is true! */
-static int32_t read_attr_usbip_status(struct usb_device *udev)
+static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
{
char attrpath[SYSFS_PATH_MAX];
struct sysfs_attribute *attr;
@@ -148,7 +145,8 @@ static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath)
goto err;
/* reallocate buffer to include usb interface data */
- size_t size = sizeof(*edev) + edev->udev.bNumInterfaces * sizeof(struct usb_interface);
+ size_t size = sizeof(*edev) + edev->udev.bNumInterfaces *
+ sizeof(struct usbip_usb_interface);
edev = (struct usbip_exported_device *) realloc(edev, size);
if (!edev) {
err("alloc device");
@@ -200,7 +198,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/stub_driver.h b/drivers/staging/usbip/userspace/libsrc/stub_driver.h
index 3107d18de65af..332ebc5b3da35 100644
--- a/drivers/staging/usbip/userspace/libsrc/stub_driver.h
+++ b/drivers/staging/usbip/userspace/libsrc/stub_driver.h
@@ -19,8 +19,8 @@ struct usbip_exported_device {
struct sysfs_device *sudev;
int32_t status;
- struct usb_device udev;
- struct usb_interface uinf[];
+ struct usbip_usb_device udev;
+ struct usbip_usb_interface uinf[];
};
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/drivers/staging/usbip/userspace/libsrc/usbip_common.c
index a128a924b27e0..e9d06143141c5 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.c
@@ -64,7 +64,7 @@ const char *usbip_speed_string(int num)
#define DBG_UINF_INTEGER(name)\
dbg("%-20s = %x", to_string(name), (int) uinf->name)
-void dump_usb_interface(struct usb_interface *uinf)
+void dump_usb_interface(struct usbip_usb_interface *uinf)
{
char buff[100];
usbip_names_get_class(buff, sizeof(buff),
@@ -74,7 +74,7 @@ void dump_usb_interface(struct usb_interface *uinf)
dbg("%-20s = %s", "Interface(C/SC/P)", buff);
}
-void dump_usb_device(struct usb_device *udev)
+void dump_usb_device(struct usbip_usb_device *udev)
{
char buff[100];
@@ -181,7 +181,7 @@ err:
do { (object)->name = (type) read_attr_value(dev, to_string(name), format); } while (0)
-int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev)
+int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev)
{
uint32_t busnum, devnum;
@@ -209,7 +209,8 @@ int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev)
return 0;
}
-int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf)
+int read_usb_interface(struct usbip_usb_device *udev, int i,
+ struct usbip_usb_interface *uinf)
{
char busid[SYSFS_BUS_ID_SIZE];
struct sysfs_device *sif;
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/drivers/staging/usbip/userspace/libsrc/usbip_common.h
index c254b5481f7cf..32b27ed1c8b89 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.h
@@ -12,7 +12,6 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include <strings.h>
#include <sysfs/libsysfs.h>
#include <netdb.h>
@@ -26,7 +25,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 */
@@ -101,7 +104,7 @@ extern int usbip_use_debug ;
#define BUG() do { err("sorry, it's a bug"); abort(); } while (0)
-struct usb_interface {
+struct usbip_usb_interface {
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
@@ -110,7 +113,7 @@ struct usb_interface {
-struct usb_device {
+struct usbip_usb_device {
char path[SYSFS_PATH_MAX];
char busid[SYSFS_BUS_ID_SIZE];
@@ -132,11 +135,12 @@ struct usb_device {
#define to_string(s) #s
-void dump_usb_interface(struct usb_interface *);
-void dump_usb_device(struct usb_device *);
-int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev);
+void dump_usb_interface(struct usbip_usb_interface *);
+void dump_usb_device(struct usbip_usb_device *);
+int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev);
int read_attr_value(struct sysfs_device *dev, const char *name, const char *format);
-int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf);
+int read_usb_interface(struct usbip_usb_device *udev, int i,
+ struct usbip_usb_interface *uinf);
const char *usbip_speed_string(int num);
const char *usbip_status_string(int32_t status);
diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
index db43f8d2eb804..386f63b456f5a 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)
@@ -23,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));
@@ -53,7 +52,7 @@ static int parse_status(char *value)
for (int i = 0; i < vhci_driver->nports; i++)
- bzero(&vhci_driver->idev[i], sizeof(struct usbip_imported_device));
+ memset(&vhci_driver->idev[i], 0, sizeof(vhci_driver->idev[i]));
/* skip a header line */
@@ -90,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;
@@ -118,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);
}
}
@@ -187,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;
@@ -275,14 +285,15 @@ 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,
- vhci_driver_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) {
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;
}
@@ -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;
@@ -343,7 +355,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;
@@ -402,7 +414,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 cad8ad7586d93..a2f7db19cbc61 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
@@ -7,13 +7,13 @@
#include "usbip.h"
-
+#define USBIP_VHCI_BUS_TYPE "platform"
#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 */
- struct usb_device udev;
+ /* usbip_class_device list */
+ struct dlist *cdev_list;
+ struct usbip_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/Makefile.am b/drivers/staging/usbip/userspace/src/Makefile.am
index 05a7aa50d42f8..52741c8d60d80 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 201ffbbee5476..0000000000000
--- a/drivers/staging/usbip/userspace/src/bind-driver.c
+++ /dev/null
@@ -1,643 +0,0 @@
-/*
- *
- * Copyright (C) 2005-2007 Takahiro Hirofuchi
- */
-
-#include "utils.h"
-
-#define _GNU_SOURCE
-#include <getopt.h>
-#include <glib.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 const char match_busid_path[] = "/sys/bus/usb/drivers/usbip/match_busid";
-
-
-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];
-
- /* 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");
- 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 01a562866b5d5..8940cd0ae6b74 100644
--- a/drivers/staging/usbip/userspace/src/usbip.c
+++ b/drivers/staging/usbip/userspace/src/usbip.c
@@ -1,723 +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 <mfm@muteddisk.com>
+ * 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 class_device *cdev;
-
- dlist_for_each_data(idev->cdev_list, cdev, struct class_device) {
- int ifnum = get_interface_number(cdev->devpath);
- if (ifnum == i) {
- info(" %s", cdev->clspath);
- }
- }
- }
-
- 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 0000000000000..14d4a475b683f
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ * 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 0000000000000..189238b791b3f
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_attach.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ * 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 usbip_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 0000000000000..978b7aa018528
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_bind.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ * 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 <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <getopt.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, SYSFS_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[SYSFS_BUS_ID_SIZE];
+ dbg("unbinding interface");
+
+ snprintf(inf_busid, SYSFS_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, SYSFS_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[SYSFS_BUS_ID_SIZE];
+
+ snprintf(inf_busid, SYSFS_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 0000000000000..89bf3c195c284
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_detach.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ * 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 0000000000000..03f621046ec6a
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_list.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <getopt.h>
+#include <netdb.h>
+#include <unistd.h>
+
+#include "usbip_common.h"
+#include "usbip_network.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 get_exported_devices(int sockfd)
+{
+ char product_name[100];
+ char class_name[100];
+ struct op_devlist_reply rep;
+ uint16_t code = OP_REP_DEVLIST;
+ struct usbip_usb_device udev;
+ struct usbip_usb_interface uintf;
+ unsigned int i;
+ int j, rc;
+
+ rc = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
+ if (rc < 0) {
+ dbg("usbip_send_op_common");
+ return -1;
+ }
+
+ rc = usbip_recv_op_common(sockfd, &code);
+ if (rc < 0) {
+ dbg("usbip_recv_op_common");
+ return -1;
+ }
+
+ memset(&rep, 0, sizeof(rep));
+ rc = usbip_recv(sockfd, &rep, sizeof(rep));
+ if (rc < 0) {
+ dbg("usbip_recv_op_devlist");
+ return -1;
+ }
+ PACK_OP_DEVLIST_REPLY(0, &rep);
+ dbg("exportable devices: %d", rep.ndev);
+
+ for (i = 0; i < rep.ndev; i++) {
+ memset(&udev, 0, sizeof(udev));
+ rc = usbip_recv(sockfd, &udev, sizeof(udev));
+ if (rc < 0) {
+ dbg("usbip_recv: usbip_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 (j = 0; j < udev.bNumInterfaces; j++) {
+ rc = usbip_recv(sockfd, &uintf, sizeof(uintf));
+ if (rc < 0) {
+ dbg("usbip_recv: usbip_usb_interface[%d]", j);
+ return -1;
+ }
+ pack_usb_interface(0, &uintf);
+
+ usbip_names_get_class(class_name, sizeof(class_name),
+ uintf.bInterfaceClass,
+ uintf.bInterfaceSubClass,
+ uintf.bInterfaceProtocol);
+ printf("%8s: %2d - %s\n", "", j, class_name);
+
+ }
+ printf("\n");
+ }
+
+ return 0;
+}
+
+static int list_exported_devices(char *host)
+{
+ int rc;
+ 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);
+
+ rc = get_exported_devices(sockfd);
+ if (rc < 0) {
+ dbg("get_exported_devices failed");
+ return -1;
+ }
+
+ close(sockfd);
+
+ return 0;
+}
+
+static void print_device(char *busid, char *vendor, char *product,
+ bool parsable)
+{
+ if (parsable)
+ printf("busid=%s#usbid=%.4s:%.4s#", busid, vendor, product);
+ else
+ printf(" - busid %s (%.4s:%.4s)\n", busid, vendor, product);
+}
+
+static void print_interface(char *busid, char *driver, bool parsable)
+{
+ if (parsable)
+ printf("%s=%s#", busid, driver);
+ else
+ printf("%9s%s -> %s\n", "", busid, driver);
+}
+
+static int is_device(void *x)
+{
+ struct sysfs_attribute *devpath;
+ struct sysfs_device *dev = x;
+ int ret = 0;
+
+ devpath = sysfs_get_device_attr(dev, "devpath");
+ if (devpath && *devpath->value != '0')
+ ret = 1;
+
+ return ret;
+}
+
+static int devcmp(void *a, void *b)
+{
+ return strcmp(a, b);
+}
+
+static int list_devices(bool parsable)
+{
+ char bus_type[] = "usb";
+ char busid[SYSFS_BUS_ID_SIZE];
+ struct sysfs_bus *ubus;
+ struct sysfs_device *dev;
+ struct sysfs_device *intf;
+ struct sysfs_attribute *idVendor;
+ struct sysfs_attribute *idProduct;
+ struct sysfs_attribute *bConfValue;
+ struct sysfs_attribute *bNumIntfs;
+ struct dlist *devlist;
+ int i;
+ int ret = -1;
+
+ ubus = sysfs_open_bus(bus_type);
+ if (!ubus) {
+ err("sysfs_open_bus: %s", strerror(errno));
+ return -1;
+ }
+
+ devlist = sysfs_get_bus_devices(ubus);
+ if (!devlist) {
+ err("sysfs_get_bus_devices: %s", strerror(errno));
+ goto err_out;
+ }
+
+ /* remove interfaces and root hubs from device list */
+ dlist_filter_sort(devlist, is_device, devcmp);
+
+ if (!parsable) {
+ printf("Local USB devices\n");
+ printf("=================\n");
+ }
+ dlist_for_each_data(devlist, dev, struct sysfs_device) {
+ idVendor = sysfs_get_device_attr(dev, "idVendor");
+ idProduct = sysfs_get_device_attr(dev, "idProduct");
+ bConfValue = sysfs_get_device_attr(dev, "bConfigurationValue");
+ bNumIntfs = sysfs_get_device_attr(dev, "bNumInterfaces");
+ if (!idVendor || !idProduct || !bConfValue || !bNumIntfs)
+ goto err_out;
+
+ print_device(dev->bus_id, idVendor->value, idProduct->value,
+ parsable);
+
+ for (i = 0; i < atoi(bNumIntfs->value); i++) {
+ snprintf(busid, sizeof(busid), "%s:%.1s.%d",
+ dev->bus_id, bConfValue->value, i);
+ intf = sysfs_open_device(bus_type, busid);
+ if (!intf)
+ goto err_out;
+ print_interface(busid, intf->driver_name, parsable);
+ sysfs_close_device(intf);
+ }
+ printf("\n");
+ }
+
+ ret = 0;
+
+err_out:
+ sysfs_close_bus(ubus);
+
+ 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' },
+ { NULL, 0, NULL, 0 }
+ };
+ bool parsable = false;
+ int opt;
+ int ret = -1;
+
+ if (usbip_names_init(USBIDS_FILE))
+ err("failed to open %s", USBIDS_FILE);
+
+ for (;;) {
+ opt = getopt_long(argc, argv, "pr:l", opts, NULL);
+
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'p':
+ parsable = true;
+ break;
+ case 'r':
+ ret = list_exported_devices(optarg);
+ goto out;
+ case 'l':
+ ret = list_devices(parsable);
+ 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_network.c b/drivers/staging/usbip/userspace/src/usbip_network.c
index 01be3c7211d5c..26e95bd745320 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 <string.h>
+
+#include <arpa/inet.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)
@@ -29,7 +39,7 @@ void pack_uint16_t(int pack, uint16_t *num)
*num = i;
}
-void pack_usb_device(int pack, struct usb_device *udev)
+void pack_usb_device(int pack, struct usbip_usb_device *udev)
{
pack_uint32_t(pack, &udev->busnum);
pack_uint32_t(pack, &udev->devnum);
@@ -41,7 +51,7 @@ void pack_usb_device(int pack, struct usb_device *udev)
}
void pack_usb_interface(int pack __attribute__((unused)),
- struct usb_interface *udev __attribute__((unused)))
+ struct usbip_usb_interface *udev __attribute__((unused)))
{
/* uint8_t members need nothing */
}
@@ -90,17 +100,17 @@ int usbip_send_op_common(int sockfd, uint32_t code, uint32_t status)
int ret;
struct op_common op_common;
- bzero(&op_common, sizeof(op_common));
+ memset(&op_common, 0, sizeof(op_common));
- op_common.version = USBIP_VERSION;
- op_common.code = code;
- op_common.status = status;
+ op_common.version = USBIP_VERSION;
+ op_common.code = code;
+ op_common.status = status;
PACK_OP_COMMON(1, &op_common);
ret = usbip_send(sockfd, (void *) &op_common, sizeof(op_common));
if (ret < 0) {
- err("send op_common");
+ err("usbip_send has failed");
return -1;
}
@@ -112,11 +122,11 @@ int usbip_recv_op_common(int sockfd, uint16_t *code)
int ret;
struct op_common op_common;
- bzero(&op_common, sizeof(op_common));
+ memset(&op_common, 0, sizeof(op_common));
ret = usbip_recv(sockfd, (void *) &op_common, sizeof(op_common));
if (ret < 0) {
- err("recv op_common, %d", ret);
+ err("usbip_recv has failed ret=%d", ret);
goto err;
}
@@ -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 1225466e1c592..07274df7db153 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
@@ -56,11 +56,10 @@ struct op_devinfo_request {
} __attribute__((packed));
struct op_devinfo_reply {
- struct usb_device udev;
- struct usb_interface uinf[];
+ struct usbip_usb_device udev;
+ struct usbip_usb_interface uinf[];
} __attribute__((packed));
-
/* ---------------------------------------------------------------------- */
/* Import a remote USB device. */
#define OP_IMPORT 0x03
@@ -72,8 +71,8 @@ struct op_import_request {
} __attribute__((packed));
struct op_import_reply {
- struct usb_device udev;
-// struct usb_interface uinf[];
+ struct usbip_usb_device udev;
+// struct usbip_usb_interface uinf[];
} __attribute__((packed));
#define PACK_OP_IMPORT_REQUEST(pack, request) do {\
@@ -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
@@ -92,7 +89,7 @@ struct op_import_reply {
#define OP_REP_EXPORT (OP_REPLY | OP_EXPORT)
struct op_export_request {
- struct usb_device udev;
+ struct usbip_usb_device udev;
} __attribute__((packed));
struct op_export_reply {
@@ -114,7 +111,7 @@ struct op_export_reply {
#define OP_REP_UNEXPORT (OP_REPLY | OP_UNEXPORT)
struct op_unexport_request {
- struct usb_device udev;
+ struct usbip_usb_device udev;
} __attribute__((packed));
struct op_unexport_reply {
@@ -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
@@ -161,8 +156,8 @@ struct op_devlist_reply {
} __attribute__((packed));
struct op_devlist_reply_extra {
- struct usb_device udev;
- struct usb_interface uinf[];
+ struct usbip_usb_device udev;
+ struct usbip_usb_interface uinf[];
} __attribute__((packed));
#define PACK_OP_DEVLIST_REQUEST(pack, request) do {\
@@ -172,15 +167,10 @@ 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);
-void pack_usb_interface(int pack, struct usb_interface *uinf);
+void pack_usb_device(int pack, struct usbip_usb_device *udev);
+void pack_usb_interface(int pack, struct usbip_usb_interface *uinf);
ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen);
ssize_t usbip_send(int sockfd, void *buff, size_t bufflen);
@@ -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 */
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 0000000000000..9978d383cbea4
--- /dev/null
+++ b/drivers/staging/usbip/userspace/src/usbip_unbind.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
+ * 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/usbipd.c b/drivers/staging/usbip/userspace/src/usbipd.c
index ec9faac5ff8f2..332f9e631fd57 100644
--- a/drivers/staging/usbip/userspace/src/usbipd.c
+++ b/drivers/staging/usbip/userspace/src/usbipd.c
@@ -7,9 +7,10 @@
#include "../config.h"
#endif
+#include <errno.h>
#include <unistd.h>
#include <netdb.h>
-#include <strings.h>
+#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.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;
@@ -64,7 +64,7 @@ static int send_reply_devlist(int sockfd)
}
dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
- struct usb_device pdu_udev;
+ struct usbip_usb_device pdu_udev;
dump_usb_device(&edev->udev);
memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
@@ -77,7 +77,7 @@ static int send_reply_devlist(int sockfd)
}
for (int i=0; i < edev->udev.bNumInterfaces; i++) {
- struct usb_interface pdu_uinf;
+ struct usbip_usb_interface pdu_uinf;
dump_usb_interface(&edev->uinf[i]);
memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf));
@@ -100,7 +100,7 @@ static int recv_request_devlist(int sockfd)
int ret;
struct op_devlist_request req;
- bzero(&req, sizeof(req));
+ memset(&req, 0, sizeof(req));
ret = usbip_recv(sockfd, (void *) &req, sizeof(req));
if (ret < 0) {
@@ -127,8 +127,8 @@ static int recv_request_import(int sockfd)
int found = 0;
int error = 0;
- bzero(&req, sizeof(req));
- bzero(&reply, sizeof(reply));
+ memset(&req, 0, sizeof(req));
+ memset(&reply, 0, sizeof(reply));
ret = usbip_recv(sockfd, (void *) &req, sizeof(req));
if (ret < 0) {
@@ -167,7 +167,7 @@ static int recv_request_import(int sockfd)
}
if (!error) {
- struct usb_device pdu_udev;
+ struct usbip_usb_device pdu_udev;
memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
pack_usb_device(1, &pdu_udev);
@@ -244,7 +244,7 @@ static struct addrinfo *my_getaddrinfo(char *host, int ai_family)
int ret;
struct addrinfo hints, *ai_head;
- bzero(&hints, sizeof(hints));
+ memset(&hints, 0, sizeof(hints));
hints.ai_family = ai_family;
hints.ai_socktype = SOCK_STREAM;
@@ -337,7 +337,7 @@ static int my_accept(int lsock)
char host[NI_MAXHOST], port[NI_MAXSERV];
int ret;
- bzero(&ss, sizeof(ss));
+ memset(&ss, 0, sizeof(ss));
csock = accept(lsock, (struct sockaddr *) &ss, &len);
if (csock < 0) {
@@ -380,7 +380,7 @@ static void set_signal(void)
{
struct sigaction act;
- bzero(&act, sizeof(act));
+ memset(&act, 0, sizeof(act));
act.sa_handler = signal_handler;
sigemptyset(&act.sa_mask);
sigaction(SIGTERM, &act, NULL);
diff --git a/drivers/staging/usbip/userspace/src/utils.c b/drivers/staging/usbip/userspace/src/utils.c
index 8f441089b6450..1da1109d11d39 100644
--- a/drivers/staging/usbip/userspace/src/utils.c
+++ b/drivers/staging/usbip/userspace/src/utils.c
@@ -3,15 +3,72 @@
* Copyright (C) 2005-2007 Takahiro Hirofuchi
*/
+#include <sysfs/libsysfs.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <libgen.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[SYSFS_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, SYSFS_BUS_ID_SIZE) > SYSFS_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, SYSFS_BUS_ID_SIZE + 4, "add %s", busid);
+ else
+ snprintf(buff, SYSFS_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];
int fd;
int ret = 0;
- bzero(buff, sizeof(buff));
+ memset(buff, 0, sizeof(buff));
fd = open(path, O_RDONLY);
if (fd < 0)
@@ -36,7 +93,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 +179,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 6c29ae9452129..b50e95a0a515d 100644
--- a/drivers/staging/usbip/userspace/src/utils.h
+++ b/drivers/staging/usbip/userspace/src/utils.h
@@ -1,30 +1,9 @@
+#ifndef __UTILS_H
+#define __UTILS_H
-#ifdef HAVE_CONFIG_H
-#include "../config.h"
-#endif
-
-#define _GNU_SOURCE
-#include <string.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <sysfs/libsysfs.h>
-#include <glib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-
-
-
-/* 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);
@@ -36,3 +15,5 @@ int write_bConfigurationValue(char *busid, int config);
int read_bDeviceClass(char *busid);
int readline(int sockfd, char *str, int strlen);
int writeline(int sockfd, char *buff, int bufflen);
+
+#endif /* __UTILS_H */
diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h
index d5bc8e7e3d79d..71a586e00fd7a 100644
--- a/drivers/staging/usbip/vhci.h
+++ b/drivers/staging/usbip/vhci.h
@@ -6,15 +6,6 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * This 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
- * USA.
*/
#include <linux/device.h>
@@ -105,7 +96,7 @@ struct vhci_hcd {
};
extern struct vhci_hcd *the_controller;
-extern struct attribute_group dev_attr_group;
+extern const struct attribute_group dev_attr_group;
#define hardware (&the_controller->pdev.dev)
/* vhci_hcd.c */
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c
index a76e8fa69b6e3..359b4647b6017 100644
--- a/drivers/staging/usbip/vhci_hcd.c
+++ b/drivers/staging/usbip/vhci_hcd.c
@@ -344,9 +344,9 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
* */
if (dum->resuming && time_after(jiffies, dum->re_timeout)) {
dum->port_status[rhport] |=
- (1 << USB_PORT_FEAT_C_SUSPEND);
+ (1 << USB_PORT_FEAT_C_SUSPEND);
dum->port_status[rhport] &=
- ~(1 << USB_PORT_FEAT_SUSPEND);
+ ~(1 << USB_PORT_FEAT_SUSPEND);
dum->resuming = 0;
dum->re_timeout = 0;
/* if (dum->driver && dum->driver->resume) {
@@ -639,9 +639,7 @@ no_need_xmit:
usb_hcd_unlink_urb_from_ep(hcd, urb);
no_need_unlink:
spin_unlock_irqrestore(&the_controller->lock, flags);
-
usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
-
return ret;
}
@@ -1033,9 +1031,8 @@ static int vhci_bus_resume(struct usb_hcd *hcd)
hcd->state = HC_STATE_RUNNING;
}
spin_unlock_irq(&vhci->lock);
- return rc;
- return 0;
+ return rc;
}
#else
@@ -1212,7 +1209,7 @@ static struct platform_device the_pdev = {
},
};
-static int __init vhci_init(void)
+static int __init vhci_hcd_init(void)
{
int ret;
@@ -1236,14 +1233,14 @@ err_driver_register:
return ret;
}
-static void __exit vhci_cleanup(void)
+static void __exit vhci_hcd_exit(void)
{
platform_device_unregister(&the_pdev);
platform_driver_unregister(&vhci_driver);
}
-module_init(vhci_init);
-module_exit(vhci_cleanup);
+module_init(vhci_hcd_init);
+module_exit(vhci_hcd_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/staging/usbip/vhci_rx.c b/drivers/staging/usbip/vhci_rx.c
index e42ce9dab7ac5..09c44abb89e82 100644
--- a/drivers/staging/usbip/vhci_rx.c
+++ b/drivers/staging/usbip/vhci_rx.c
@@ -179,8 +179,6 @@ static void vhci_recv_ret_unlink(struct vhci_device *vdev,
}
kfree(unlink);
-
- return;
}
static int vhci_priv_tx_empty(struct vhci_device *vdev)
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index d9736f9c4028b..0cd039bb5fd65 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -135,7 +135,7 @@ static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
static int valid_args(__u32 rhport, enum usb_device_speed speed)
{
/* check rhport */
- if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
+ if (rhport >= VHCI_NPORTS) {
pr_err("port %u\n", rhport);
return -EINVAL;
}
@@ -192,7 +192,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
/* check sockfd */
socket = sockfd_to_socket(sockfd);
if (!socket)
- return -EINVAL;
+ return -EINVAL;
/* now need lock until setting vdev status as used */
@@ -239,6 +239,6 @@ static struct attribute *dev_attrs[] = {
NULL,
};
-struct attribute_group dev_attr_group = {
+const struct attribute_group dev_attr_group = {
.attrs = dev_attrs,
};