[PATCH v3 1/1] usbip: auto retry for concurrent attach
This patch adds recovery from false busy state on concurrent attach operation. The procedure of attach operation is as below. 1) Find an unused port in /sys/devices/platform/vhci_hcd/status. (userspace) 2) Request attach found port to driver through /sys/devices/platform/vhci_hcd/attach. (userspace) 3) Lock table, reserve requested port and unlock table. (vhci driver) Attaching more than one remote devices concurrently, same unused port number will be found in step-1. Then one request will succeed and others will fail even though there are some unused ports. With this patch, driver returns EBUSY when requested port has already been used. In this case, attach command retries from step-1: finding another unused port. If there's no unused port, the attach operation will fail in step-1. Otherwise it retries automatically using another unused port. vhci-hcd's interface (only errno) is changed as following. Current errno New errno Condition EINVAL same as leftspecified port number is in invalid range EAGAIN same as leftplatform_get_drvdata() failed EINVAL same as leftspecified socket fd is not valid EINVAL EBUSY specified port status is not free The errno EBUSY was not used in userspace src/usbip_attach.c:import_device(). It is needed to distinguish the condition to be able to retry from other unrecoverable errors. It is possible to avoid this failure by introducing userspace exclusive control. But it's exaggerated for this special condition. The locking itself has done in driver. As an alternate solution, userspace doesn't specify port number, driver searches unused port and it returns port number to the userspace. With this solution, the interface is much different than this patch. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Version information v3) Updated based on linux-next 2017-08-28. Removed unnecessary modification to store_detach(). Added description about difference from alternate solution in change log. Corrected spelling in change log. Moved the position of version info in change log. v2) Gathered usbip_vhci_driver_close() for errors under an exit label. --- drivers/usb/usbip/vhci_sysfs.c | 6 - tools/usb/usbip/src/usbip_attach.c | 35 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index 5778b64..1b9f60a 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -366,7 +366,11 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, sockfd_put(socket); dev_err(dev, "port %d already used\n", rhport); - return -EINVAL; + /* +* Will be retried from userspace +* if there's another free port. +*/ + return -EBUSY; } dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 6e89768..7f07b2d 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -99,29 +99,34 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) rc = usbip_vhci_driver_open(); if (rc < 0) { err("open vhci_driver"); - return -1; + goto err_out; } - port = usbip_vhci_get_free_port(speed); - if (port < 0) { - err("no free port"); - usbip_vhci_driver_close(); - return -1; - } + do { + port = usbip_vhci_get_free_port(speed); + if (port < 0) { + err("no free port"); + goto err_driver_close; + } - dbg("got free port %d", port); + dbg("got free port %d", port); - 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; - } + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, + udev->devnum, udev->speed); + if (rc < 0 && errno != EBUSY) { + err("import device"); + goto err_driver_close; + } + } while (rc < 0); usbip_vhci_driver_close(); return port; + +err_driver_close: + usbip_vhci_driver_close(); +err_out: + return -1; } static int query_import_device(int sockfd, char *busid) -- 2.1.0 -- To unsubscr
[PATCH v2 1/1] usbip: auto retry for concurrent attach
This patch adds recovery from false busy state on concurrent attach operation. The procedure of attach operation is as below. 1) Find an unused port in /sys/devices/platform/vhci_hcd/status. (userspace) 2) Request attach found port to driver through /sys/devices/platform/vhci_hcd/attach. (userspace) 3) Lock table, reserve requested port and unlock table. (vhci driver) Attaching more than one remote devices concurrently, same unused port number will be found in step-1. Then one request will succeed and others will fail even though there are some unused ports. It is possible to avoid this fail by introdocing userspace exclusive control. But it's exaggerated for this special condition. The locking itself is done in driver. With this patch, driver returns EBUSY when requested port has already been used. In this case, attach command retries from step-1: finding another unused port. If there's no unused port, the attach operation will fail. Othrwise it retries automatically using new free port. Currunt userspace src/usbip_attach.c:import_device() doesn't use the errno. vhci-hcd's interface (only errno) is changed as following. Current errno New errno Condition EINVAL same as leftspecified port numbre is in invalid range EAGAIN same as leftplatform_get_drvdata() failed EINVAL same as leftspecified socket fd is not valid EINVAL EBUSY specified port status is not free --- Version information v2) Gathered usbip_vhci_driver_close() for errors under an exit label. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/vhci_sysfs.c | 8 ++-- tools/usb/usbip/src/usbip_attach.c | 33 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index b96e5b1..5d4be4b 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -214,7 +214,7 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr, ret = vhci_port_disconnect(hcd_to_vhci(hcd), rhport); if (ret < 0) - return -EINVAL; + return ret; usbip_dbg_vhci_sysfs("Leave\n"); @@ -314,7 +314,11 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, sockfd_put(socket); dev_err(dev, "port %d already used\n", rhport); - return -EINVAL; + /* +* Will be retried from userspace +* if there's another free port. +*/ + return -EBUSY; } dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..f1e7ddd 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -98,27 +98,32 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) rc = usbip_vhci_driver_open(); if (rc < 0) { err("open vhci_driver"); - return -1; + goto err_out; } - port = usbip_vhci_get_free_port(); - if (port < 0) { - err("no free port"); - usbip_vhci_driver_close(); - return -1; - } + do { + port = usbip_vhci_get_free_port(); + if (port < 0) { + err("no free port"); + goto err_driver_close; + } - 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; - } + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, + udev->devnum, udev->speed); + if (rc < 0 && errno != EBUSY) { + err("import device"); + goto err_driver_close; + } + } while (rc < 0); usbip_vhci_driver_close(); return port; + +err_driver_close: + usbip_vhci_driver_close(); +err_out: + return -1; } static int query_import_device(int sockfd, char *busid) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 2/2] usbip: vhci extension: dynamic extension
Modification for dynamic device registration and unregistration. 1. kernel config Following parameters are added. USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host controller. The default is 8 - same as current VHCI_NPORTS. USBIP_VHCI_MAX_HCS: Muximum number of USB/IP virtual host controllers. The default is 1. USBIP_VHCI_INIT_HCS: Initial number of USB/IP virtual host controllers. The default is 1. Static number of devices: USBIP_VHCI_NR_HCS is removed with this patch. 2. view from sysfs Sysfs structure is changed as following. BEFORE this patchset: /sys/devices/platform +-- vhci +-- status +-- attach +-- detach +-- usbip_debug AFTER: example for CONFIG_USBIP_INIT_HCS=2 CONFIG_USBIP_MAX_HCS=4 At the beginning /sys/devices/platform +-- vhci | +-- nports | +-- status | +-- status.1 | +-- status.2 | +-- status.3 | +-- attach | +-- detach | +-- usbip_debug +-- vhci.1 The status files are shown to the maximum number of devices. Port status in status.2 and status.3 represents as free but corresponding devices are not yes registered. When all ports in status and status.1 are used, userspace tool requests 'attach' to a port in status.2 then vhci.2 will be registred. The limit is defined with USBIP_VHCI_MAX_NCS. By preparing muximum number of status files, there's no need to introduce additional operations for userspace tool. When number of free ports becomes more than USBIP_VHCI_HC_PORTS * VHCI_FREE_HCS(2), a free controller other than the first one will be unregistered. It will be invoked by 'detach' operation and other error situations which ports are released. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/Kconfig | 17 ++- drivers/usb/usbip/vhci.h | 36 - drivers/usb/usbip/vhci_hcd.c | 250 - drivers/usb/usbip/vhci_rx.c| 10 +- drivers/usb/usbip/vhci_sysfs.c | 46 +++--- drivers/usb/usbip/vhci_tx.c| 6 +- 6 files changed, 291 insertions(+), 74 deletions(-) diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index eeefa29..42d8979 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -35,8 +35,8 @@ config USBIP_VHCI_HC_PORTS host controller driver, this defines number of ports per USB/IP virtual host controller. -config USBIP_VHCI_NR_HCS - int "Number of USB/IP virtual host controllers" +config USBIP_VHCI_MAX_HCS + int "Maximum number of USB/IP virtual host controllers" range 1 128 default 1 depends on USBIP_VHCI_HCD @@ -44,7 +44,18 @@ config USBIP_VHCI_NR_HCS To increase number of ports available for USB/IP virtual host controller driver, this defines number of USB/IP virtual host controllers as if adding physical host - controllers. + controllers. This defines the maximum number. + +config USBIP_VHCI_INIT_HCS + int "Initial number of USB/IP virtual host controllers" + range 1 USBIP_VHCI_MAX_HCS + default 1 + depends on USBIP_VHCI_MAX_HCS + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of USB/IP + virtual host controllers as if adding physical host + controllers. This defines the number at initializing. config USBIP_HOST tristate "Host driver" diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..ba893a7 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -51,6 +51,9 @@ struct vhci_device { /* vhci_tx thread sleeps for this queue */ wait_queue_head_t waitq_tx; + + /* denotes port is in-use */ + atomic_t using_port; }; /* urb->hcpriv, use container_of() */ @@ -79,12 +82,21 @@ struct vhci_unlink { #define VHCI_HC_PORTS 8 #endif -#ifdef CONFIG_USBIP_VHCI_NR_HCS -#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS +#ifdef CONFIG_USBIP_VHCI_MAX_HCS +#define VHCI_MAX_HCS CONFIG_USBIP_VHCI_MAX_HCS +#else +#define VHCI_MAX_HCS 1 +#endif + +#ifdef CONFIG_USBIP_VHCI_INIT_HCS +#define VHCI_INIT_HCS CONFIG_USBIP_VHCI_INIT_HCS #else -#define VHCI_NR_HCS 1 +#define VHCI_INIT_HCS 1 #endif +/* VHCI_FREE_HCS * VHCI_HC_PORTS: ports to keep free at unregister */ +#define VHCI_FREE_HCS 2 + #define MAX_STATUS_NAME 16 /* for usb_bus.hcpriv */ @@ -98,6 +110,8 @@ struct vhci_hcd { atomic_t seqnum; + unsigned int using_ports; + /* * NOTE: * wIndex shows the port number and begins from 1. @@ -106,12 +120,18 @@ struct vhci_hcd { struct vhci_device vdev[VHCI_HC_PORTS]; }; +extern int vhci_max_controllers; +extern int vhci_init_controllers; extern int vhci_num_controllers; extern st
[PATCH v8 1/2] usbip: vhci extension: modifications to userspace
Modification to the userspace tools including usbip/libsrc and usbip/src. Changed corresponding to new vhci_sysfs.c. nports in sysfs is used to get total number of ports. Old get_nports() ignores the last status line because udev_device_get_sysattr_value() drops last new line. New version uses nports attribute so it's doesn't have this problem. status[.N] in sysfs are used. parse_status() which reads all status lines is broken into open, close, read-line and parse-line. Parse-line is reused to find free port and get imported device. In daemon, status was loaded into memory by usbip_vhci_refresh_device_list() at receiving every request. The loaded status is used to find free port. It is changed to read status directly to find free port. Wording inconsistencies are fixed according to the rule below. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 396 ++- tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 12 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 31 +-- 5 files changed, 242 insertions(+), 255 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 8b94ab5..844187d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -15,11 +15,24 @@ #undef PROGNAME #define PROGNAME "libusbip" -struct usbip_vhci_driver *vhci_driver; -struct udev *udev_context; +static struct udev_device *vhci_hc_device; +static struct udev *udev_context; +static int vhci_nports; -static struct usbip_imported_device * -imported_device_init(struct usbip_imported_device *idev, char *busid) +struct usbip_vhci_device { + int port; + uint32_t status; + + uint32_t devid; + + uint8_t busnum; + uint8_t devnum; + + /* usbip_class_device list */ + struct usbip_usb_device udev; +}; + +static int imported_device_init(struct usbip_vhci_device *vdev, char *busid) { struct udev_device *sudev; @@ -27,132 +40,131 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) "usb", busid); if (!sudev) { dbg("udev_device_new_from_subsystem_sysname failed: %s", busid); - goto err; + return -1; } - read_usb_device(sudev, >udev); + read_usb_device(sudev, >udev); udev_device_unref(sudev); - return idev; - -err: - return NULL; + return 0; } +struct status_context { + int controller; + const char *c; +}; +#define OPEN_MODE_FIRST 0 +#define OPEN_MODE_REOPEN 1 -static int parse_status(const char *value) -{ - int ret = 0; - char *c; +static int open_hc_device(int mode); +#define MAX_STATUS_NAME 16 - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); +static int open_status(struct status_context *ctx, int mode) +{ + char name[MAX_STATUS_NAME+1]; + if (mode == OPEN_MODE_FIRST) + ctx->controller = 0; + else + (ctx->controller)++; - /* skip a header line */ - c = strchr(value, '\n'); - if (!c) + if (open_hc_device(OPEN_MODE_REOPEN)) return -1; - c++; - while (*c != '\0') { - int port, status, speed, devid; - unsigned long socket; - char lbusid[SYSFS_BUS_ID_SIZE]; - - ret = sscanf(c, "%d %d %d %x %lx %31s\n", - , , , - , , lbusid); - - if (ret < 5) { - dbg("sscanf failed: %d", ret); - BUG(); - } - - dbg("port %d status %d speed %d devid %x", - port, status, speed, devid); - dbg("socket %lx lbusid %s", socket, lbusid); + if (ctx->controller == 0) + strcpy(name, "status"); + else + snprintf(name, MAX_STATUS_NAME + 1, + "status.%d", ctx->controller); + ctx->c = udev_device_get_sysattr_value(vhci_hc_device, name); + if (ctx->c == NULL) + return -1; + return 0; +} - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; +static void close_status(struct status_context *ctx) +{ + ctx->c = NULL; +} - idev->port = po
[PATCH v8 0/2] usbip: vhci number of ports extension
This series of patches extends number of ports limitaion in application (vhci) side. Driver portion of static extension has been merged at 4.9-rc1. 1/2 modifies userspace tools. It's effective not only for static extension but also for dynamic. 2/2 modifies driver for dynamic extenstion. 1. Background Assuming a system shown below that services distributerd devices in home or office via USB/IP, if the devices are set at every doors and windows, number devices may be up to tens. Home/SOHO/Enterprise Intranet/Internet +--+ +--+ USB/IP+-+ +|device|--+|Linux |---|Service | |+--+ |+--+---|on Linux | +--+ +--++-+ ex) Device Service sensors ... environment analysis cameras ... monitoring, recording ID/biometric readers .. authentication If USB/IP is used for ubiqitous devices or IoT devices, many devices might be handled. 2. About this patch set In current USB/IP, available number of ports (ie. number of supported devices) is VHCI_NPORTS(8) in drivers/usb/usbip/vhci.h. The value of the macro can be altered to USB_MAXCHILDREN(31). This limit is came from hub status bit array. See also the comment at USB_MAXCHILDREN include/uapi/linux/usb/ch11.h. There are two way to increase number of available ports. The first way is to put hub emulator under vhci. This can add ports up to 255 - the limit of USB 2.0 host controller. The second way is to add host controller. It's as same as machines have several host controllers: most desktop or note PCs have more than one host controller. Current USB/IP supports only one controller defined as 'the_controller' in drivers/usb/usbip/vhci_hcd.c. This patch takes the second way described above and adds virtual controllers. In this patch, the number is specified by kernel configuration. 3. Dynamic extension According to kernel configuration, vhci devices (platform device) will be added and removed when they are not used. When the vhci driver is loaded, USBIP_VHCI_INIT_HCS (default is 1) drivers are registered. They will be further registered upto USBIP_VHCI_MAX_HCS (default is 1). They are unregistered when number of free devices becomes more than VHCI_FREE_HCS(2) except the first device. 4. Wording Wording inconsistencies in function and variable names are corrected according to the rule below. They were not strict because only one host controller was handled. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. 5. Dependencies This series depends on 'usbip: exporting devices' patch set because this includes changes to application side daemon which introduced the patch set. --- Version information v8) # Recreated based on linux-next 20161224 and v14 of 'usbip: exporting devices'. v7) # Recreated based on linux-next 20161117. # Removed a reference to merged path was '1/3 usbip: vhci extension: modifications to vhci driver' from change log of current 2/2. v6) # Recreated based on linux-next 20160928. # Was '1/3 usbip: vhci extension: modifications to vhci driver' is excluded because it has been merged at 4.9-rc1. v5) # Fixed dynamically allocated sysfs attribute checking error when CONFIG_DEBUG_LOCK_ALLOC is set. # Recreated based on linux-next 20160810. v4) # Changed the method to set number of controllers from a module parameter to kernel config. # Excluded event thread patch merged to 4.7-rc1. # Added dynamic extension. v3) # Fixed conflicts against linux-next 20160209. # Changed sysfs object and attribute name for old tools compatibility. # Changed nports status format not to include num_controllers value. # Fixed checkpatch errors and warnings. v2) # Added static to some functions and variables not called from other files. *** BLURB HERE *** Nobuo Iwata (2): usbip: vhci extension: modifications to userspace usbip: vhci extension: dynamic extension drivers/usb/usbip/Kconfig| 17 +- drivers/usb/usbip/vhci.h | 36 ++- drivers/usb/usbip/vhci_hcd.c | 250 ++--- drivers/usb/usbip/vhci_rx.c | 10 +- drivers/usb/usbip/vhci_sysfs.c | 46 ++-- drivers/usb/usbip/vhci_tx.c | 6 +- tools/usb/usbip/libsrc/vhci_driver.c | 396 ++- tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 12 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 31 +-- 11 files changed, 533 insertions(+), 329 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v14 08/10] usbip: exporting devices: change to usbip_list.c
Correction to wording inconsistency around import and export in usbip_list.c regarding output title, help and function names. 'exported' was used for devices bound in remote and to be attached with 'import' request. This patch set uses pre-defined 'export' request to connect device. To avoid mixed usage of 'export', 'importable' is used for devices to be attached with 'import' request. The word 'imported' has already been used in output of port operation. It is consistent to this patch. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> Reviewed-by: Krzysztof Opasiak <k.opas...@samsung.com> --- tools/usb/usbip/src/usbip_list.c | 21 +++-- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index f1b38e8..1f9fa5e 100644 --- a/tools/usb/usbip/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c @@ -44,7 +44,7 @@ static const char usbip_list_usage_string[] = "usbip list [-p|--parsable] \n" "-p, --parsable Parsable list format\n" - "-r, --remote=List the exportable USB devices on \n" + "-r, --remote=List the importable USB devices on \n" "-l, --localList the local USB devices\n"; void usbip_list_usage(void) @@ -52,7 +52,7 @@ void usbip_list_usage(void) printf("usage: %s", usbip_list_usage_string); } -static int get_exported_devices(char *host, int sockfd) +static int get_importable_devices(char *host, int sockfd) { char product_name[100]; char class_name[100]; @@ -82,14 +82,14 @@ static int get_exported_devices(char *host, int sockfd) return -1; } PACK_OP_DEVLIST_REPLY(0, ); - dbg("exportable devices: %d\n", reply.ndev); + dbg("importable devices: %d\n", reply.ndev); if (reply.ndev == 0) { - info("no exportable devices found on %s", host); + info("no importable devices found on %s", host); return 0; } - printf("Exportable USB devices\n"); + printf("Importable USB devices\n"); printf("==\n"); printf(" - %s\n", host); @@ -134,7 +134,7 @@ static int get_exported_devices(char *host, int sockfd) return 0; } -static int list_exported_devices(char *host) +static int list_importable_devices(char *host) { int rc; int sockfd; @@ -147,14 +147,15 @@ static int list_exported_devices(char *host) } dbg("connected to %s:%s", host, usbip_port_string); - rc = get_exported_devices(host, sockfd); + rc = get_importable_devices(host, sockfd); + + close(sockfd); + if (rc < 0) { err("failed to get device list from %s", host); return -1; } - close(sockfd); - return 0; } @@ -351,7 +352,7 @@ int usbip_list(int argc, char *argv[]) parsable = true; break; case 'r': - ret = list_exported_devices(optarg); + ret = list_importable_devices(optarg); goto out; case 'l': ret = list_devices(parsable); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v14 07/10] usbip: exporting devices: new application-side daemon
This patch is the new application(vhci)-side daemon specific code. The daemons are consisting three files. usbip.c : common code. usbip_dev.c: device(stub)-side specific code. usbip_app.c: application(vhci)-side specific code - this patch. Here, device-side daemon is EXISTING-1 and application-side daemon is NEW-1 in figure below. libsrc/vhci_driver.c:read_record() is refactored to be reused for function vhci_find_device() which finds attached device from requested remote host. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (server) (client) 1) # usbipd ... start daemon = = = 2) # usbip list --local 3) # usbip bind <--- list bound devices --- 4) # usbip list --remote <--- import a device -- 5) # usbip attach = = = X disconnected6) # usbip detach 7) usbip unbind NEW) - dedicates devices from device(stub)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (client) (server) 1) # usbipa ... start daemon = = = 2) # usbip list --local 3) # usbip connect--- export a device --> = = = 4) # usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 105 +- tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/Makefile.am | 7 +- tools/usb/usbip/src/usbipd.c | 29 ++-- tools/usb/usbip/src/usbipd.h | 2 +- tools/usb/usbip/src/usbipd_app.c | 200 +++ tools/usb/usbip/src/usbipd_dev.c | 10 +- 7 files changed, 307 insertions(+), 47 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 5843f43..8b94ab5 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015-2016 Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> */ #include "usbip_common.h" @@ -154,67 +155,78 @@ static int get_nports(void) return nports; } -/* - * Read the given port's record. - * - * To avoid buffer overflow we will read the entire line and - * validate each part's size. The initial buffer is padded by 4 to - * accommodate the 2 spaces, 1 newline and an additional character - * which is needed to properly validate the 3rd part without it being - * truncated to an acceptable length. - */ -static int read_record(int rhport, char *host, unsigned long host_len, - char *port, unsigned long port_len, char *busid) +static int __read_record(int rhport, char *buffer, size_t buffer_len) { - int part; FILE *file; char path[PATH_MAX+1]; - char *buffer, *start, *end; - char delim[] = {' ', ' ', '\n'}; - int max_len[] = {(int)host_len, (int)port_len, SYSFS_BUS_ID_SIZE}; - size_t buffer_len = host_len + port_len + SYSFS_BUS_ID_SIZE + 4; - - buffer = malloc(buffer_len); - if (!buffer) - return -1; snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); file = fopen(path, "r"); if (!file) { err("fopen"); - free(buffer); return -1; } - if (fgets(buffer, buffer_len, file) == NULL) { err("fgets"); - free(buffer); fclose(file); return -1; } fclose(file); + return 0; +} + +/* + * Read the given port's record. + * + * To avoid buffer overflow we will read the entire line and + * validate each part's size. The initial buffer is padded by 4 to + * accommodate the 2 spaces, 1 newline and an additional character + * which is needed to properly validate the 3rd part without it being + * truncated to an acceptable length. + */ +static int read_record(int rhport, char *host, int host_len, + char *port, int port_len, char *busid, int busid_len) +{ + int part; + char *buffer, *start, *end; + char delim[] = {' ', ' ', '\n'}; + char * const str[] = {host, port, busid}; + int max_len[] = {host_len, port_len, busid_len}; + int str_len; + size_t buffer_len = host_len + port_len + busid_len + 4; + + buffer = malloc(buffer_len); + if (!buffer) + goto err_out; + +
[PATCH v14 10/10] usbip: exporting devices: modifications to protocol text
This patch adds export and un-export request/response to Documentation/usb/usbip_protocol.txt. The definition of the structs has been defined in original code of tools/usb/usbip/usbip_network.h but not described in the document. Adding the request and response, words 'server' and 'client' are ambiguous in several place. To avoid confusion, 'device-side' and 'application-side' are written together with 'server' and 'client'. 'export' was used in the counter side of 'import' request. This patch organizes usage of 'import' and 'export'. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Documentation/usb/usbip_protocol.txt | 238 ++- 1 file changed, 200 insertions(+), 38 deletions(-) diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe2..2b60e54 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -1,20 +1,26 @@ PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! 28 Jun 2011 +Added export and un-export. +07 March 2016 -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. +The USB/IP protocol follows a server/client architecture between two computers +one has USB devices and the other runs application using the devices. There are +two ways for initiation. -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. +The first way is to import devices from application-side. In this way, the +server runs in device-side and the client runs in application-side. In device +side user makes devices importable with 'bind' operation. +The client may ask for the list of the importable USB devices. To get the list +the client opens a TCP/IP connection towards the server, and sends an +OP_REQ_DEVLIST packet on top of the TCP/IP connection (so the actual +OP_REQ_DEVLIST may be sent in one or more pieces at the low level transport +layer). The server sends back the OP_REP_DEVLIST packet which lists the +importable USB devices. Finally the TCP/IP connection is closed. + + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (lists importable devices)"server" | | | OP_REQ_DEVLIST | | --> | @@ -23,18 +29,13 @@ TCP/IP connection is closed. | <-- | | | -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. +Once the client knows the list of importable USB devices it may decide to use +one of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (imports a USB device) "server" | | | OP_REQ_IMPORT | | --> | @@ -42,6 +43,32 @@ server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | OP_REP_IMPORT | | <-- | | | + +
[PATCH v14 09/10] usbip: exporting devices: chage to documenattion
This patch adds function and usage of new connect operation, disconnect operation and application(vhci)-side daemon to README and manuals. At this point, the wording, 'server' and 'client' are ambiguous in several place. For existing attach command, the daemon runs device side machine and attach command is executed in application side machine. Then 'server' is used for device side and 'client' is for application side. For the new connect command, the daemon runs applications side machine and connect command is executed in device side machine. Now, 'server' and 'client' run in different machine than before. To avoid confusion, to represent things to be done in device side node by both command and daemon, words 'device-side' is used instead of 'server'. To represent things to be done is application side node by both command and daemon, 'applicationr-side' are used instead of 'client'. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (server) (client) 1) # usbipd ... start daemon = = = 2) # usbip list --local 3) # usbip bind <--- list bound devices --- 4) # usbip list --remote <--- import a device -- 5) # usbip attach = = = X disconnected6) # usbip detach 7) usbip unbind NEW) - dedicates devices from device(stub)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (client) (server) 1) # usbipa ... start daemon = = = 2) # usbip list --local 3) # usbip connect--- export a device --> = = = 4) # usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/Makefile.am | 2 +- tools/usb/usbip/README | 81 - tools/usb/usbip/doc/usbip.8 | 136 --- tools/usb/usbip/doc/usbipa.8 | 78 tools/usb/usbip/doc/usbipd.8 | 38 +- 5 files changed, 275 insertions(+), 60 deletions(-) diff --git a/tools/usb/usbip/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf0..f371ed9 100644 --- a/tools/usb/usbip/Makefile.am +++ b/tools/usb/usbip/Makefile.am @@ -3,4 +3,4 @@ includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ usbip_common.h vhci_driver.h usbip_host_driver.h) -dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) +dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbipa.8) diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 831f49f..d3cae75 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -3,6 +3,7 @@ # # Copyright (C) 2011 matt mooney <m...@muteddisk.com> # 2005-2008 Takahiro Hirofuchi +# Copyright (C) 2015-2016 Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> [Requirements] @@ -36,41 +37,70 @@ [Usage] -server:# (Physically attach your USB device.) +Device-side: a machine has USB device(s). +Application-side: a machine runs an application software uses remote USB device. -server:# insmod usbip-core.ko -server:# insmod usbip-host.ko +1) Connect from application-side to device-side. -server:# usbipd -D +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbipd -D - Start usbip daemon. -server:# usbip list -l - - List driver assignments for USB devices. +dev:# usbip list -l + - List driver assignments for USB devices and their busid. -server:# usbip bind --busid 1-2 - - Bind usbip-host.ko to the device with busid 1-2. - - The USB device 1-2 is now exportable to other hosts! - - Use `usbip unbind --busid 1-2' to stop exporting the device. +dev:# usbip bind --busid + - Bind usbip-host.ko to the device with . + - The USB device with is now exportable to other hosts! + - Use `usbip unbind --busid ` to stop exporting the device. -client:# insmod usbip-core.ko -client:# insmod vhci-hcd.ko +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko -client:# usbip list --remote +app:# usbip list --remote - List exported USB devices on the . -client:# usbip attach --remote --busid 1-2 +app:# usbip attach --remote --busid - Connect the remote USB device. -client:# usbip port +app:# usbip port - Show virtual port status. -client:# usbip detach -
[PATCH v14 02/10] usbip: exporting devices: modifications to host side libraries
Modifications to host driver wrapper and its related operations (i.e. bind/unbind). usbip_get_device() method was not used. The implementation of the method searches a bound devices list by list index. The position in the list is meaningless for any operations so it is assumed not to be used in future. For this patch set, a method to find a bound device in the bound devices list by bus-id is needed. usbip_get_device() is re-implemented as a function to find a bound device by bus-id. bind and unbind function are exported to reuse by new connect and disconnect operation. Here, connect and disconnect is NEW-3 and NEW-4 respactively in diagram below. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (server) (client) 1) # usbipd ... start daemon = = = 2) # usbip list --local 3) # usbip bind <--- list bound devices --- 4) # usbip list --remote <--- import a device -- 5) # usbip attach = = = X disconnected6) # usbip detach 7) usbip unbind NEW) - dedicates devices from device(stub)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (client) (server) 1) # usbipa ... start daemon = = = 2) # usbip list --local 3) # usbip connect--- export a device --> = = = 4) # usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/usbip_host_common.c | 6 ++ tools/usb/usbip/libsrc/usbip_host_common.h | 8 tools/usb/usbip/src/usbip.h| 3 +++ tools/usb/usbip/src/usbip_bind.c | 4 ++-- tools/usb/usbip/src/usbip_unbind.c | 4 ++-- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..6a98d6c 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -256,17 +256,15 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num) + struct usbip_host_driver *hdriver, char *busid) { struct list_head *i; struct usbip_exported_device *edev; - int cnt = 0; list_for_each(i, >edev_list) { edev = list_entry(i, struct usbip_exported_device, node); - if (num == cnt) + if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) return edev; - cnt++; } return NULL; diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h index a64b803..f9a9def 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.h +++ b/tools/usb/usbip/libsrc/usbip_host_common.h @@ -38,7 +38,7 @@ struct usbip_host_driver_ops { void (*close)(struct usbip_host_driver *hdriver); int (*refresh_device_list)(struct usbip_host_driver *hdriver); struct usbip_exported_device * (*get_device)( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); int (*read_device)(struct udev_device *sdev, struct usbip_usb_device *dev); @@ -86,11 +86,11 @@ static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver) } static inline struct usbip_exported_device * -usbip_get_device(struct usbip_host_driver *hdriver, int num) +usbip_get_device(struct usbip_host_driver *hdriver, char *busid) { if (!hdriver->ops.get_device) return NULL; - return hdriver->ops.get_device(hdriver, num); + return hdriver->ops.get_device(hdriver, busid); } /* Helper functions for implementing driver backend */ @@ -99,6 +99,6 @@ void usbip_generic_driver_close(struct usbip_host_driver *hdriver); int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver); int usbip_export_device(struct usbip_exported_device *edev, int sockfd); struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); #endif /* __USBIP_HOST_COMMON_H */ diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a..c296910
[PATCH v14 01/10] usbip: exporting devices: modifications to network header
This patch set implements operations to export and unexport device using pre-defined but un-used export and un-export request and reply. This patch modifies export and un-export reply in tools/usb/usbip/src/usbip_network.h. The 'returncode' of each response is removed. The status is set in op_common.status. Following status codes are added for this patch set. ST_NO_FREE_POR ST_NOT_FOUND The reason to use op_common.status: 1) usbip_net_recv_op_common() hanles as error when the status is other than ST_OK. 2) The status has a commnet "add more error code". They become empty struct. Other empty struct, 'op_devlist_request', defined. This patch also includes string translation of the status codes. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_network.c | 26 +- tools/usb/usbip/src/usbip_network.h | 8 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/tools/usb/usbip/src/usbip_network.c b/tools/usb/usbip/src/usbip_network.c index b4c37e7..069ec54 100644 --- a/tools/usb/usbip/src/usbip_network.c +++ b/tools/usb/usbip/src/usbip_network.c @@ -163,6 +163,29 @@ int usbip_net_send_op_common(int sockfd, uint32_t code, uint32_t status) return 0; } +struct op_common_error { + uint32_tstatus; + const char *str; +}; + +struct op_common_error op_common_errors[] = { + {ST_NA, "not available"}, + {ST_NO_FREE_PORT, "no free port"}, + {ST_DEVICE_NOT_FOUND, "device not found"}, + {0, NULL} +}; + +static const char *op_common_strerror(uint32_t status) +{ + struct op_common_error *err; + + for (err = op_common_errors; err->str != NULL; err++) { + if (err->status == status) + return err->str; + } + return "unknown error"; +} + int usbip_net_recv_op_common(int sockfd, uint16_t *code) { struct op_common op_common; @@ -196,7 +219,8 @@ int usbip_net_recv_op_common(int sockfd, uint16_t *code) } if (op_common.status != ST_OK) { - dbg("request failed at peer: %d", op_common.status); + dbg("request failed at peer: %s", + op_common_strerror(op_common.status)); goto err; } diff --git a/tools/usb/usbip/src/usbip_network.h b/tools/usb/usbip/src/usbip_network.h index c1e875c..86c3ff0 100644 --- a/tools/usb/usbip/src/usbip_network.h +++ b/tools/usb/usbip/src/usbip_network.h @@ -27,8 +27,10 @@ struct op_common { uint16_t code; /* add more error code */ -#define ST_OK 0x00 -#define ST_NA 0x01 +#define ST_OK 0x00 +#define ST_NA 0x01 +#define ST_NO_FREE_PORT0x02 +#define ST_DEVICE_NOT_FOUND0x03 uint32_t status; /* op_code status (for reply) */ } __attribute__((packed)); @@ -93,7 +95,6 @@ struct op_export_request { } __attribute__((packed)); struct op_export_reply { - int returncode; } __attribute__((packed)); @@ -115,7 +116,6 @@ struct op_unexport_request { } __attribute__((packed)); struct op_unexport_reply { - int returncode; } __attribute__((packed)); #define PACK_OP_UNEXPORT_REQUEST(pack, request) do {\ -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v14 03/10] usbip: exporting devices: new connect operation
Implementation of new connect operation. This is linked as a part of usbip command. With this patch, usbip command has following operations. bind unbind list (local/remote) attach detach port connect ... this patch In device side node, this binds a device internally, sends an export request and receives export response. The definition of the request and response are defined in original code: tools/usb/usbip/usbip_network.h but was not used. They are corresponding to NEW-3 in following diagram. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (server) (client) 1) # usbipd ... start daemon = = = 2) # usbip list --local 3) # usbip bind <--- list bound devices --- 4) # usbip list --remote <--- import a device -- 5) # usbip attach = = = X disconnected6) # usbip detach 7) usbip unbind NEW) - dedicates devices from device(stub)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (client) (server) 1) # usbipa ... start daemon = = = 2) # usbip list --local 3) # usbip connect--- export a device --> = = = 4) # usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 3 +- tools/usb/usbip/src/usbip.c | 7 + tools/usb/usbip/src/usbip.h | 3 + tools/usb/usbip/src/usbip_connect.c | 212 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4eb..0947476 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ -usbip_bind.c usbip_unbind.c usbip_port.c +usbip_bind.c usbip_unbind.c usbip_port.c \ +usbip_connect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d9..ad2a259 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -4,6 +4,7 @@ * * Copyright (C) 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015-2016 Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> * * 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 @@ -76,6 +77,12 @@ static const struct command cmds[] = { .usage = usbip_detach_usage }, { + .name = "connect", + .fn= usbip_connect, + .help = "Connect a USB device to a remote computer", + .usage = usbip_connect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index c296910..3c22c27 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -1,6 +1,7 @@ /* * Copyright (C) 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015-2016 Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,12 +31,14 @@ int usbip_list(int argc, char *argv[]); int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); +int usbip_connect(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); +void usbip_connect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_connect.c b/tools/usb/usbip/src/usbip_connect.c new file mode 100644 index 000..73668db2 --- /dev/null +++ b/tools/usb/usbip/src/usbip_connect.c @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + *
[PATCH v14 06/10] usbip: exporting devices: modifications to attach and detach
Refactoring to attach and detach operation to reuse common portion to application(vhci)-side daemon. The new application(vhci)-side daemon executes same procedures as attach and detach. Most of common code to access vhci has been implemented in VHCI userspace wrapper(libsrc/vhci_driver.c) but left in attach and detach. With this patch, an accessor of vhci driver and tracking of vhci connections in attach and detach are moved to the VHCI userspace wrapper. Functions to create and delete port status file also moved to the wrapper. Timing to execute these function are corrected to keep consistent with attached status of vhci. Here, attach, detach and application(vhci)-side daemon is EXISTING-5, EXISTING-6 and NEW-1 respectively in diagram below. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (server) (client) 1) # usbipd ... start daemon = = = 2) # usbip list --local 3) # usbip bind <--- list bound devices --- 4) # usbip list --remote <--- import a device -- 5) # usbip attach = = = X disconnected6) # usbip detach 7) usbip unbind NEW) - dedicates devices from device(stub)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (client) (server) 1) # usbipa ... start daemon = = = 2) # usbip list --local 3) # usbip connect--- export a device --> = = = 4) # usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 96 +++ tools/usb/usbip/libsrc/vhci_driver.h | 3 + tools/usb/usbip/src/usbip_attach.c | 99 +--- tools/usb/usbip/src/usbip_detach.c | 17 ++--- 4 files changed, 124 insertions(+), 91 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..5843f43 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -215,6 +217,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +#define OPEN_HC_MODE_FIRST 0 +#define OPEN_HC_MODE_REOPEN1 + +static int open_hc_device(int mode) +{ + if (mode == OPEN_HC_MODE_REOPEN) + udev_device_unref(vhci_driver->hc_device); + + vhci_driver->hc_device = + udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + USBIP_VHCI_DRV_NAME); + if (!vhci_driver->hc_device) { + err("udev_device_new_from_subsystem_sysname failed"); + return -1; + } + return 0; +} + /* -- */ int usbip_vhci_driver_open(void) @@ -227,28 +248,21 @@ int usbip_vhci_driver_open(void) vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); - if (!vhci_driver->hc_device) { - err("udev_device_new_from_subsystem_sysname failed"); - goto err; - } + if (open_hc_device(OPEN_HC_MODE_FIRST)) + goto err_free_driver; vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); if (refresh_imported_device_list()) - goto err; + goto err_unref_device; return 0; -err: +err_unref_device: udev_device_unref(vhci_driver->hc_device); - +err_free_driver: if (vhci_driver) free(vhci_driver); @@ -277,7 +291,8 @@ void usbip_vhci_driver_close(void) int usbip_vhci_refresh_device_list(void) { - + if (open_hc_device(OPEN_HC_MODE_REOPEN)) + goto err; if (refresh_imported_device_list()) goto err; @@ -409,3 +424,58 @@ int usbip_vhci_imported_device_dump(struct
[PATCH v14 00/10] usbip: exporting devices
t; patch. # Added background to cover letter. # Added server/client to each diagrams. # Updated ending part of usecase, firewall diagram and description. # Added device level security consideration to cover letter. # Added security consideration to README. # Added auto retry for false no-free-port in concurrent processing of export request. # Removed returncode from export and un-export reply. # Renamed abstraction of driver functions for daemons from usbip_.*_driver() to usbipd_driver_.*(). # Renamed usbip_update_driver() to usbipd_driver_set(). # Introduced usbipd_driver_ops for these driver functions for daemons. # Refactored recv_pdu functions as one. # Introduced usbipd_recv_pdu_ops. # Refactored libsrc/vhci_driver.c:read_record(). # Modified not to call read_record() for unused port from vhci_find_device. # Modified to use driver->ndevs is used insted of counting list in send_reply_devlist(). # Fixed according to review comments for v13. unnecessary zero clear for reply buffer. unnecessary read for empty struct. sizeof usage from struct name to variable name. implicit size for buffer arguments. # Added email address to copyrights. # Moved copyright position to bottom. v13) # Recreated based on linux-next 20161117. # Updated cover letter: added goal, rewrote overview as explanation of 'exporting' and added that this patch dosn't affect security condition in existing usage. # Moved protocol documentation as the last patch. # Added explanation to each patch. # Removed copyright from usbip_bind.c, usbip_unbind.c, usbip_network.h and usb_list.c in which size of modification is small and functional change is not included. # Fixed help string about position of --parsable option. v12) # Recreated based on linux-next 20161012. # Fixed checkpatch a warning about symbolic permission. # Fixed checkpatch warnings about traling space in a document. v11) # Corrected program name of each daemon which are used in version string, info messages and daemon name for tcp wrappers. # Added description about tcp wrappers in security consideration of cover letter. # Added security consideration for existing requests in contradistinction to new requests. # Recreated based on linux-next 20160928. v10) # Recreated based on linux-next 20160810. v9) # Moved a set_nodelay() from usbipd_dev.c to usbipd.c to affect both device side and application side daemon. # Removed redundant blank line at the end of files. v8) # Divided into smaller patches. # Excluded low-related patches. # Improved change log. # Changed info level logs in usbip_ux.c to debug level logs. # Added options to vUDC. # Tested with vUDC. v7) # Removed userspace transmission and WebSocket command/daemon. # Fixed checkpatch errors and warnings. v6) # Added __rcu annotation to a RCU pointer to clear sparse warnings. # Corrected a copy to RCU pointer with rcu_rcu_assign_pointer(). # Added __user annotations to arguments of read/write method. # Added static to some functions which are not called from other files. # Removed unnecessary EXPORT_SYMBOLs. v5) # Added vendor/pruduct name conversion to port command. # Put initial value to pool_head in name.c. # Fixed list command exception when host option is omitted. # Fixed exception in case gai_strerror() returns NULL. # Fixed WebSocket connection close via proxy. # Fixed to stop WebSocket ping-pong on connection close. # Removed redundant usbipd daemon option. # Removed redundant SSL code had not been deleted. # Removed an unused local variable in WebSocket code. # Modified C++ reserved word in names.c as same as headers. v4) # Fixed regression of usbip list --remote v3) # Coding style for goto err labels are fixed. # Defined magic numbers for open_hc_device() argument. # Corrected include .../uapi/linux/usbip_ux.h as . # Modified parameter notation in manuals not to use '='. # Fixed inappropriate version definition in tools/.../websocket/configure.ac. # Remved unnecessary COPYING and AUTHORS fil from tools/.../websocket/. # Added -version-info to libraries in tools/.../src. v2) # Formatted patches from linux-next. # Fixed change log word wrapping. # Removed SSL patches. # Fixed a bug that vendor and product names are not shown by 'usbws list -l' because usbip_names_init() was not called in libusbip.la. Thank you, Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> // *** BLURB HERE *** Nobuo Iwata (10): usbip: exporting devices: modifications to network header usbip: exporting devices: modifications to host side libraries usbip: exporting devices: new connect operation usbip: exporting devices: new disconnect operation usbip: exporting devices: modifications to daemon usbip: exporting devices: modifications to attach and detach usbip: exporting devices: new application-side daemon usbip: exporting devices: change to usbip_list.c usbip: exporting devices: chage to documenattion usbip: exporting devices: modifications to protocol text Documentation/us
[PATCH v14 05/10] usbip: exporting devices: modifications to daemon
Refactoring to the daemon to reuse common portion for new application side daemon. It's divided into two portions. usbipd.c : common code for both device and application side daemon. usbipd_dev.c : device-side specific code extracted from usbipd.c. To do so, host driver dependent headers and declaration (i.e. static struct usbip_host_driver *driver;) are moved from usbipd.c to usbipd_dev.c. usbipd_driver_ops is introduced to call device-side specific driver operations from usbipd.c. It will also be used for application-side specific driver operation in succeeding patch. usbipd_driver_()s are wrappers for the operations. usbipd_recv_pdu_op is introduced to share recv_pdu() routine. In diagram below, usbipd EXISTING-1 is the device-side daemon and NEW-1 is the application side daemon. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (server) (client) 1) # usbipd ... start daemon = = = 2) # usbip list --local 3) # usbip bind <--- list bound devices --- 4) # usbip list --remote <--- import a device -- 5) # usbip attach = = = X disconnected6) # usbip detach 7) usbip unbind NEW) - dedicates devices from device(stub)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (client) (server) 1) # usbipa ... start daemon = = = 2) # usbip list --local 3) # usbip connect--- export a device --> = = = 4) # usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. usbip_net_set_nodelay() was in the middle of device side daemon procedure. There's no effect by the defferring. It is moved to right after accept() to affect it both device and application side. In the client operation, it's already in right after connect(). In send_reply_devlist(), driver->ndevs is used insted of counting list. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 2 +- tools/usb/usbip/src/usbipd.c | 236 ++- tools/usb/usbip/src/usbipd.h | 84 +++ tools/usb/usbip/src/usbipd_dev.c | 230 ++ 4 files changed, 360 insertions(+), 192 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 42760c3..1aa5156 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -9,4 +9,4 @@ usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c -usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c +usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 009afb4..14fdb40 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -4,6 +4,7 @@ * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> * Krzysztof Opasiak <k.opas...@samsung.com> + * Copyright (C) 2015-2016 Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> * * 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 @@ -43,25 +44,19 @@ #include #include -#include "usbip_host_driver.h" -#include "usbip_host_common.h" -#include "usbip_device_driver.h" #include "usbip_common.h" #include "usbip_network.h" +#include "usbipd.h" #include "list.h" -#undef PROGNAME -#define PROGNAME "usbipd" #define MAXSOCKFD 20 #define MAIN_LOOP_TIMEOUT 10 -#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" - static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options]\n" + "usage: %s [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" @@ -82,7 +77,7 @@ static const char usbipd_help_string[] = "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" - " If no FILE specified, use " DEFAULT_PID_FILE "\n" + "
[PATCH v14 04/10] usbip: exporting devices: new disconnect operation
Implementation of new disconnect operation. This is linked as a part of usbip command. With this patch, usbip command has following operations. bind unbind list (local/remote) attach detach port connect ... previous patch disconnect ... this patch In device side node, this sends an un-export request, receives an un-export response and unbind corresponding device internally. The definition of the request and response are defined in original code: tools/usb/usbip/usbip_network.h but was not used. It's corresponding to NEW-4 in following diagram. To find disconnecting device, requesting host and requested bus-id-in-requester identifies the target. So it cannot to disconnect a device from other host than a host which connected the device. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (server) (client) 1) # usbipd ... start daemon = = = 2) # usbip list --local 3) # usbip bind <--- list bound devices --- 4) # usbip list --remote <--- import a device -- 5) # usbip attach = = = X disconnected6) # usbip detach 7) usbip unbind NEW) - dedicates devices from device(stub)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ (client) (server) 1) # usbipa ... start daemon = = = 2) # usbip list --local 3) # usbip connect--- export a device --> = = = 4) # usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am| 2 +- tools/usb/usbip/src/usbip.c| 6 + tools/usb/usbip/src/usbip.h| 2 + tools/usb/usbip/src/usbip_disconnect.c | 200 + 4 files changed, 209 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 0947476..42760c3 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ -usbip_connect.c +usbip_connect.c usbip_disconnect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index ad2a259..ead88a2 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -83,6 +83,12 @@ static const struct command cmds[] = { .usage = usbip_connect_usage }, { + .name = "disconnect", + .fn= usbip_disconnect, + .help = "Disconnect a USB device from a remote computer", + .usage = usbip_disconnect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 3c22c27..b6537ef 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); int usbip_connect(int argc, char *argv[]); +int usbip_disconnect(int argc, char *argv[]); void usbip_attach_usage(void); void usbip_detach_usage(void); @@ -39,6 +40,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); void usbip_connect_usage(void); +void usbip_disconnect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_disconnect.c b/tools/usb/usbip/src/usbip_disconnect.c new file mode 100644 index 000..4ee7feb --- /dev/null +++ b/tools/usb/usbip/src/usbip_disconnect.c @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015-2016 Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> + * + * 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.
[PATCH v1 1/1] usbip: auto retry for concurrent attach
This patch adds recovery from false busy state on concurrent attach operation. The procedure of attach operation is as below. 1) Find an unused port in /sys/devices/platform/vhci_hcd/status. (userspace) 2) Request attach found port to driver through /sys/devices/platform/vhci_hcd/attach. (userspace) 3) Lock table, reserve requested port and unlock table. (vhci driver) Attaching more than one remote devices concurrently, same unused port number will be found in step-1. Then one request will succeed and others will fail even though there are some unused ports. It is possible to avoid this fail by introdocing userspace exclusive control. But it's exaggerated for this special condition. The locking itself is done in driver. With this patch, driver returns EBUSY when requested port has already been used. In this case, attach command retries from step-1: finding another unused port. If there's no unused port, the attach operation will fail. Othrwise it retries automatically using new free port. Currunt userspace src/usbip_attach.c:import_device() doesn't use the errno. vhci-hcd's interface (only errno) is changed as following. Current errno New errno Condition EINVAL same as leftspecified port numbre is in invalid range EAGAIN same as leftplatform_get_drvdata() failed EINVAL same as leftspecified socket fd is not valid EINVAL EBUSY specified port status is not free Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/vhci_sysfs.c | 8 ++-- tools/usb/usbip/src/usbip_attach.c | 28 +++- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index b96e5b1..5d4be4b 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -214,7 +214,7 @@ static ssize_t store_detach(struct device *dev, struct device_attribute *attr, ret = vhci_port_disconnect(hcd_to_vhci(hcd), rhport); if (ret < 0) - return -EINVAL; + return ret; usbip_dbg_vhci_sysfs("Leave\n"); @@ -314,7 +314,11 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, sockfd_put(socket); dev_err(dev, "port %d already used\n", rhport); - return -EINVAL; + /* +* Will be retried from userspace +* if there's another free port. +*/ + return -EBUSY; } dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n", diff --git a/tools/usb/usbip/src/usbip_attach.c b/tools/usb/usbip/src/usbip_attach.c index 70a6b50..695b2e5 100644 --- a/tools/usb/usbip/src/usbip_attach.c +++ b/tools/usb/usbip/src/usbip_attach.c @@ -101,20 +101,22 @@ static int import_device(int sockfd, struct usbip_usb_device *udev) return -1; } - port = usbip_vhci_get_free_port(); - if (port < 0) { - err("no free port"); - usbip_vhci_driver_close(); - return -1; - } + do { + 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; - } + rc = usbip_vhci_attach_device(port, sockfd, udev->busnum, + udev->devnum, udev->speed); + if (rc < 0 && errno != EBUSY) { + err("import device"); + usbip_vhci_driver_close(); + return -1; + } + } while (rc < 0); usbip_vhci_driver_close(); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v7 2/2] usbip: vhci extension: dynamic extension
Modification for dynamic device registration and unregistration. 1. kernel config Followings are added. USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host controller. The default is 8 - same as current VHCI_NPORTS. USBIP_VHCI_MAX_HCS: Muximum number of USB/IP virtual host controllers. The default is 1. USBIP_VHCI_INIT_HCS: Initial number of USB/IP virtual host controllers. The default is 1. Static number of devices: USBIP_VHCI_NR_HCS is removed with this patch. 2. view from sysfs Sysfs structure is changed as following. BEFORE this patchset: /sys/devices/platform +-- vhci +-- status +-- attach +-- detach +-- usbip_debug AFTER: example for CONFIG_USBIP_INIT_HCS=2 CONFIG_USBIP_MAX_HCS=4 At the beginning /sys/devices/platform +-- vhci | +-- nports | +-- status | +-- status.1 | +-- status.2 | +-- status.3 | +-- attach | +-- detach | +-- usbip_debug +-- vhci.1 The status files are shown to the maximum number of devices. Port status in status.2 and status.3 represents as free but corresponding devices are not yes registered. When all ports in status and status.1 are used, userspace tool requests 'attach' to a port in status.2 then vhci.2 will be registred. The limit is defined with USBIP_VHCI_MAX_NCS. By preparing muximum number of status files, there's no need to introduce additional operations for userspace tool. When number of free ports becomes more than USBIP_VHCI_HC_PORTS * VHCI_FREE_HCS(2), a free controller other than the first one will be unregistered. It will be invoked by 'detach' operation and other error situations which ports are released. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/Kconfig | 17 ++- drivers/usb/usbip/vhci.h | 36 - drivers/usb/usbip/vhci_hcd.c | 250 - drivers/usb/usbip/vhci_rx.c| 10 +- drivers/usb/usbip/vhci_sysfs.c | 49 --- drivers/usb/usbip/vhci_tx.c| 6 +- 6 files changed, 293 insertions(+), 75 deletions(-) diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index eeefa29..42d8979 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -35,8 +35,8 @@ config USBIP_VHCI_HC_PORTS host controller driver, this defines number of ports per USB/IP virtual host controller. -config USBIP_VHCI_NR_HCS - int "Number of USB/IP virtual host controllers" +config USBIP_VHCI_MAX_HCS + int "Maximum number of USB/IP virtual host controllers" range 1 128 default 1 depends on USBIP_VHCI_HCD @@ -44,7 +44,18 @@ config USBIP_VHCI_NR_HCS To increase number of ports available for USB/IP virtual host controller driver, this defines number of USB/IP virtual host controllers as if adding physical host - controllers. + controllers. This defines the maximum number. + +config USBIP_VHCI_INIT_HCS + int "Initial number of USB/IP virtual host controllers" + range 1 USBIP_VHCI_MAX_HCS + default 1 + depends on USBIP_VHCI_MAX_HCS + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of USB/IP + virtual host controllers as if adding physical host + controllers. This defines the number at initializing. config USBIP_HOST tristate "Host driver" diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..ba893a7 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -51,6 +51,9 @@ struct vhci_device { /* vhci_tx thread sleeps for this queue */ wait_queue_head_t waitq_tx; + + /* denotes port is in-use */ + atomic_t using_port; }; /* urb->hcpriv, use container_of() */ @@ -79,12 +82,21 @@ struct vhci_unlink { #define VHCI_HC_PORTS 8 #endif -#ifdef CONFIG_USBIP_VHCI_NR_HCS -#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS +#ifdef CONFIG_USBIP_VHCI_MAX_HCS +#define VHCI_MAX_HCS CONFIG_USBIP_VHCI_MAX_HCS +#else +#define VHCI_MAX_HCS 1 +#endif + +#ifdef CONFIG_USBIP_VHCI_INIT_HCS +#define VHCI_INIT_HCS CONFIG_USBIP_VHCI_INIT_HCS #else -#define VHCI_NR_HCS 1 +#define VHCI_INIT_HCS 1 #endif +/* VHCI_FREE_HCS * VHCI_HC_PORTS: ports to keep free at unregister */ +#define VHCI_FREE_HCS 2 + #define MAX_STATUS_NAME 16 /* for usb_bus.hcpriv */ @@ -98,6 +110,8 @@ struct vhci_hcd { atomic_t seqnum; + unsigned int using_ports; + /* * NOTE: * wIndex shows the port number and begins from 1. @@ -106,12 +120,18 @@ struct vhci_hcd { struct vhci_device vdev[VHCI_HC_PORTS]; }; +extern int vhci_max_controllers; +extern int vhci_init_controllers; extern int vhci_num_controllers; extern st
[PATCH v7 1/2] usbip: vhci extension: modifications to userspace
Modification to the userspace tools including usbip/libsrc and usbip/src. Changed corresponding to new vhci_sysfs.c. nports in sysfs is used to get total number of ports. Old get_nports() ignores the last status line because udev_device_get_sysattr_value() drops last new line. New version uses nports attribute so it's doesn't have this problem. status[.N] in sysfs are used. parse_status() which reads all status lines is broken into open, close, read-line and parse-line. Parse-line is reused to find free port and get imported device. In daemon, status was loaded into memory by usbip_vhci_refresh_device_list() at receiving every request. The loaded status is used to find free port. It is changed to read status directly to find free port. Wording inconsistencies are fixed according to the rule below. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 398 +++ tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 48 ++-- 5 files changed, 253 insertions(+), 259 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 3fe92ff..720a0e9 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -15,11 +15,24 @@ #undef PROGNAME #define PROGNAME "libusbip" -struct usbip_vhci_driver *vhci_driver; -struct udev *udev_context; +static struct udev_device *vhci_hc_device; +static struct udev *udev_context; +static int vhci_nports; -static struct usbip_imported_device * -imported_device_init(struct usbip_imported_device *idev, char *busid) +struct usbip_vhci_device { + int port; + uint32_t status; + + uint32_t devid; + + uint8_t busnum; + uint8_t devnum; + + /* usbip_class_device list */ + struct usbip_usb_device udev; +}; + +static int imported_device_init(struct usbip_vhci_device *vdev, char *busid) { struct udev_device *sudev; @@ -27,132 +40,131 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) "usb", busid); if (!sudev) { dbg("udev_device_new_from_subsystem_sysname failed: %s", busid); - goto err; + return -1; } - read_usb_device(sudev, >udev); + read_usb_device(sudev, >udev); udev_device_unref(sudev); - return idev; - -err: - return NULL; + return 0; } +struct status_context { + int controller; + const char *c; +}; +#define OPEN_MODE_FIRST 0 +#define OPEN_MODE_REOPEN 1 -static int parse_status(const char *value) -{ - int ret = 0; - char *c; +static int open_hc_device(int mode); +#define MAX_STATUS_NAME 16 - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); +static int open_status(struct status_context *ctx, int mode) +{ + char name[MAX_STATUS_NAME+1]; + if (mode == OPEN_MODE_FIRST) + ctx->controller = 0; + else + (ctx->controller)++; - /* skip a header line */ - c = strchr(value, '\n'); - if (!c) + if (open_hc_device(OPEN_MODE_REOPEN)) return -1; - c++; - - while (*c != '\0') { - int port, status, speed, devid; - unsigned long socket; - char lbusid[SYSFS_BUS_ID_SIZE]; - - ret = sscanf(c, "%d %d %d %x %lx %31s\n", - , , , - , , lbusid); - - if (ret < 5) { - dbg("sscanf failed: %d", ret); - BUG(); - } - dbg("port %d status %d speed %d devid %x", - port, status, speed, devid); - dbg("socket %lx lbusid %s", socket, lbusid); + if (ctx->controller == 0) + strcpy(name, "status"); + else + snprintf(name, MAX_STATUS_NAME + 1, + "status.%d", ctx->controller); + ctx->c = udev_device_get_sysattr_value(vhci_hc_device, name); + if (ctx->c == NULL) + return -1; + return 0; +} - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; +static void close_status(struct status_context *ctx) +{ + ctx->c = NULL; +} - idev->port = po
[PATCH v7 0/2] usbip: vhci number of ports extension
This series of patches extends number of ports limitaion in application (vhci) side. Driver portion of static extension has been merged at 4.9-rc1. 1/2 modifies userspace tools. It's effective not only for static extension but also for dynamic. 2/2 modifies driver for dynamic extenstion. 1. Background Assuming a system shown below that services distributerd devices in home or office via USB/IP, if the devices are set at every doors and windows, number devices may be up to tens. Home/SOHO/Enterprise Intranet/Internet +--+ +--+ USB/IP+-+ +|device|--+|Linux |---|Service | |+--+ |+--+---|on Linux | +--+ +--++-+ ex) Device Service sensors ... environment analysis cameras ... monitoring, recording ID/biometric readers .. authentication If USB/IP is used for ubiqitous devices or IoT devices, many devices might be handled. 2. About this patch set In current USB/IP, available number of ports (ie. number of supported devices) is VHCI_NPORTS(8) in drivers/usb/usbip/vhci.h. The value of the macro can be altered to USB_MAXCHILDREN(31). This limit is came from hub status bit array. See also the comment at USB_MAXCHILDREN include/uapi/linux/usb/ch11.h. There are two way to increase number of available ports. The first way is to put hub emulator under vhci. This can add ports up to 255 - the limit of USB 2.0 host controller. The second way is to add host controller. It's as same as machines have several host controllers: most desktop or note PCs have more than one host controller. Current USB/IP supports only one controller defined as 'the_controller' in drivers/usb/usbip/vhci_hcd.c. This patch takes the second way described above and adds virtual controllers. In this patch, the number is specified by kernel configuration. 3. Dynamic extension According to kernel configuration, vhci devices (platform device) will be added and removed when they are not used. When the vhci driver is loaded, USBIP_VHCI_INIT_HCS (default is 1) drivers are registered. They will be further registered upto USBIP_VHCI_MAX_HCS (default is 1). They are unregistered when number of free devices becomes more than VHCI_FREE_HCS(2) except the first device. 4. Wording Wording inconsistencies in function and variable names are corrected according to the rule below. They were not strict because only one host controller was handled. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. 5. Dependencies This series depends on 'usbip: exporting devices' patch set because this includes changes to application side daemon which introduced the patch set. --- Version information v7) # Recreated based on linux-next 20161117. # Removed a reference to merged path was '1/3 usbip: vhci extension: modifications to vhci driver' from change log of current 2/2. v6) # Recreated based on linux-next 20160928. # Was '1/3 usbip: vhci extension: modifications to vhci driver' is excluded because it has been merged at 4.9-rc1. v5) # Fixed dynamically allocated sysfs attribute checking error when CONFIG_DEBUG_LOCK_ALLOC is set. # Recreated based on linux-next 20160810. v4) # Changed the method to set number of controllers from a module parameter to kernel config. # Excluded event thread patch merged to 4.7-rc1. # Added dynamic extension. v3) # Fixed conflicts against linux-next 20160209. # Changed sysfs object and attribute name for old tools compatibility. # Changed nports status format not to include num_controllers value. # Fixed checkpatch errors and warnings. v2) # Added static to some functions and variables not called from other files. *** BLURB HERE *** Nobuo Iwata (2): usbip: vhci extension: modifications to userspace usbip: vhci extension: dynamic extension drivers/usb/usbip/Kconfig| 17 +- drivers/usb/usbip/vhci.h | 36 ++- drivers/usb/usbip/vhci_hcd.c | 250 ++--- drivers/usb/usbip/vhci_rx.c | 10 +- drivers/usb/usbip/vhci_sysfs.c | 49 ++-- drivers/usb/usbip/vhci_tx.c | 6 +- tools/usb/usbip/libsrc/vhci_driver.c | 398 +++ tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 48 ++-- 11 files changed, 546 insertions(+), 334 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v13 07/10] usbip: exporting devices: new application-side daemon
This patch is the new application(vhci)-side daemon specific code. The daemons are consisting three files. usbip.c : common code. usbip_dev.c: device(stub)-side specific code. usbip_app.c: application(vhci)-side specific code - this patch. Here, device-side daemon is EXISTING-1 and application-side daemon is NEW-1 in figure below. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipd ... start daemon = = = 2) usbip list --local 3) usbip bind <--- list bound devices --- 4) usbip list --remote <--- import a device -- 5) usbip attach = = = X disconnected 6) usbip detach 7) usbip unbind NEW) - dedicates devices from device(stb)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipa ... start daemon = = = 2) usbip list --local 3) usbip connect --- export a device --> = = = 4) usbip disconnect --- un-export a device ---> Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 19 +++ tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/Makefile.am | 7 +- tools/usb/usbip/src/usbipd.c | 12 +- tools/usb/usbip/src/usbipd_app.c | 242 +++ 5 files changed, 279 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index d2221c5..3fe92ff 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -314,6 +314,25 @@ int usbip_vhci_get_free_port(void) return -1; } +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid) +{ + int ret; + char rhost[NI_MAXHOST] = "unknown host"; + char rserv[NI_MAXSERV] = "unknown port"; + char rbusid[SYSFS_BUS_ID_SIZE]; + + for (int i = 0; i < vhci_driver->nports; i++) { + ret = read_record(vhci_driver->idev[i].port, rhost, NI_MAXHOST, + rserv, NI_MAXSERV, rbusid); + if (!ret && + !strncmp(host, rhost, NI_MAXHOST) && + !strncmp(busid, rbusid, SYSFS_BUS_ID_SIZE)) { + return vhci_driver->idev + i; + } + } + return NULL; +} + int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed) { char buff[200]; /* what size should be ? */ diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index f955ada..acb427d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -46,6 +46,7 @@ int usbip_vhci_refresh_device_list(void); int usbip_vhci_get_free_port(void); +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid); int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed); diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 1aa5156..8fdebce 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -2,11 +2,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' AM_CFLAGS = @EXTRA_CFLAGS@ LDADD = $(top_builddir)/libsrc/libusbip.la -sbin_PROGRAMS := usbip usbipd +sbin_PROGRAMS := usbip usbipd usbipa usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c +usbip_CFLAGS := $(AM_CFLAGS) usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c +usbipd_CFLAGS := $(AM_CFLAGS) + +usbipa_SOURCES := usbip_network.h usbipd.c usbipd_app.c usbip_network.c +usbipa_CFLAGS := $(AM_CFLAGS) -DUSBIP_DAEMON_APP diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index bc4775f..8fe89d9 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -64,11 +64,13 @@ static const char usbipd_help_string[] = " -6, --ipv6\n" " Bind to IPv6. Default is both.\n" "\n" +#ifndef USBIP_DAEMON_APP " -e, --device\n" " Run in device mode.\n" " Rather than drive an attached device, create\n" "
[PATCH v13 10/10] usbip: exporting devices: modifications to protocol text
This patch adds export and un-export request/response to Documentation/usb/usbip_protocol.txt. The definition of the structs has been defined in original code of tools/usb/usbip/usbip_network.h but not described in the document. Adding the request and response, words 'server' and 'client' are ambiguous in several place. To avoid confusion, 'device-side' and 'application-side' are written together with 'server' and 'client'. 'export' was used in the counter side of 'import' request. This patch organizes usage of 'import' and 'export'. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Documentation/usb/usbip_protocol.txt | 204 --- 1 file changed, 181 insertions(+), 23 deletions(-) diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe2..d4be5b6 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -1,20 +1,26 @@ PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! 28 Jun 2011 +MODIFIED FOR CONNECT AND DISCONNECT OPERARION. +07 March 2016 -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. +The USB/IP protocol follows a server/client architecture between two computers +one has USB devices and the other runs application using the devices. There are +two ways for initiation. -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. +The first way is to import devices from application-side. In this way, the +server runs in device-side and the client runs in application-side. In device +side user makes devices importable with 'bind' operation. +The client may ask for the list of the importable USB devices. To get the list +the client opens a TCP/IP connection towards the server, and sends an +OP_REQ_DEVLIST packet on top of the TCP/IP connection (so the actual +OP_REQ_DEVLIST may be sent in one or more pieces at the low level transport +layer). The server sends back the OP_REP_DEVLIST packet which lists the +importable USB devices. Finally the TCP/IP connection is closed. + + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (lists importable devices)"server" | | | OP_REQ_DEVLIST | | --> | @@ -23,18 +29,13 @@ TCP/IP connection is closed. | <-- | | | -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. +Once the client knows the list of importable USB devices it may decide to use +one of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (imports a USB device) "server" | | | OP_REQ_IMPORT | | --> | @@ -42,6 +43,32 @@ server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | OP_REP_IMPORT | | <-- | |
[PATCH v13 09/10] usbip: exporting devices: chage to documenattion
This patch adds function and usage of new connect operation, disconnect operation and application(vhci)-side daemon to README and manuals. At this point, the wording, 'server' and 'client' are ambiguous in several place. For existing attach command, the daemon runs device side machine and attach command is executed in application side machine. Then 'server' is used for device side and 'client' is for application side. For the new connect command, the daemon runs applications side machine and connect command is executed in device side machine. Now, 'server' and 'client' run in different machine than before. To avoid confusion, to represent things to be done in device side node by both command and daemon, words 'device-side' is used instead of 'server'. To represent things to be done is application side node by both command and daemon, 'applicationr-side' are used instead of 'client'. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipd ... start daemon = = = 2) usbip list --local 3) usbip bind <--- list bound devices --- 4) usbip list --remote <--- import a device -- 5) usbip attach = = = X disconnected 6) usbip detach 7) usbip unbind NEW) - dedicates devices from device(stb)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipa ... start daemon = = = 2) usbip list --local 3) usbip connect --- export a device --> = = = 4) usbip disconnect --- un-export a device ---> Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/Makefile.am | 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8 | 136 --- tools/usb/usbip/doc/usbipa.8 | 78 tools/usb/usbip/doc/usbipd.8 | 38 +- 5 files changed, 263 insertions(+), 61 deletions(-) diff --git a/tools/usb/usbip/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf0..f371ed9 100644 --- a/tools/usb/usbip/Makefile.am +++ b/tools/usb/usbip/Makefile.am @@ -3,4 +3,4 @@ includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ usbip_common.h vhci_driver.h usbip_host_driver.h) -dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) +dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbipa.8) diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 831f49f..74f4afb 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -1,7 +1,8 @@ # # README for usbip-utils # -# Copyright (C) 2011 matt mooney <m...@muteddisk.com> +# Copyright (C) 2015 Nobuo Iwata +# 2011 matt mooney <m...@muteddisk.com> # 2005-2008 Takahiro Hirofuchi @@ -36,41 +37,70 @@ [Usage] -server:# (Physically attach your USB device.) +Device-side: a machine has USB device(s). +Application-side: a machine runs an application software uses remote USB device. -server:# insmod usbip-core.ko -server:# insmod usbip-host.ko +1) Connect from application-side to device-side. -server:# usbipd -D +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbipd -D - Start usbip daemon. -server:# usbip list -l - - List driver assignments for USB devices. +dev:# usbip list -l + - List driver assignments for USB devices and their busid. -server:# usbip bind --busid 1-2 - - Bind usbip-host.ko to the device with busid 1-2. - - The USB device 1-2 is now exportable to other hosts! - - Use `usbip unbind --busid 1-2' to stop exporting the device. +dev:# usbip bind --busid + - Bind usbip-host.ko to the device with . + - The USB device with is now exportable to other hosts! + - Use `usbip unbind --busid ` to stop exporting the device. -client:# insmod usbip-core.ko -client:# insmod vhci-hcd.ko +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko -client:# usbip list --remote +app:# usbip list --remote - List exported USB devices on the . -client:# usbip attach --remote --busid 1-2 +app:# usbip attach --remote --busid - Connect the remote USB device. -client:# usbip port +app:# usbip port - Show virtual port status. -client:# usbip detach --port +app:# usbip detach --port - Detach the USB device. +2) Connect from device-side to application-side. + +app:# insmod u
[PATCH v13 08/10] usbip: exporting devices: change to usbip_list.c
Correction to wording inconsistency around import and export in usbip_list.c regarding output title, help and function names. 'exported' was used for devices bound in remote and to be attached with 'import' request. This patch set uses pre-defined 'export' request to connect device. To avoid mixed usage of 'export', 'importable' is used for devices to be attached with 'import' request. The word 'imported' has already been used in output of port operation. It is consistent to this patch. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_list.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index f1b38e8..cf69f31 100644 --- a/tools/usb/usbip/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c @@ -44,7 +44,7 @@ static const char usbip_list_usage_string[] = "usbip list [-p|--parsable] \n" "-p, --parsable Parsable list format\n" - "-r, --remote=List the exportable USB devices on \n" + "-r, --remote=List the importable USB devices on \n" "-l, --localList the local USB devices\n"; void usbip_list_usage(void) @@ -52,7 +52,7 @@ void usbip_list_usage(void) printf("usage: %s", usbip_list_usage_string); } -static int get_exported_devices(char *host, int sockfd) +static int get_importable_devices(char *host, int sockfd) { char product_name[100]; char class_name[100]; @@ -82,14 +82,14 @@ static int get_exported_devices(char *host, int sockfd) return -1; } PACK_OP_DEVLIST_REPLY(0, ); - dbg("exportable devices: %d\n", reply.ndev); + dbg("importable devices: %d\n", reply.ndev); if (reply.ndev == 0) { - info("no exportable devices found on %s", host); + info("no importable devices found on %s", host); return 0; } - printf("Exportable USB devices\n"); + printf("Importable USB devices\n"); printf("==\n"); printf(" - %s\n", host); @@ -134,7 +134,7 @@ static int get_exported_devices(char *host, int sockfd) return 0; } -static int list_exported_devices(char *host) +static int list_importable_devices(char *host) { int rc; int sockfd; @@ -147,9 +147,10 @@ static int list_exported_devices(char *host) } dbg("connected to %s:%s", host, usbip_port_string); - rc = get_exported_devices(host, sockfd); + rc = get_importable_devices(host, sockfd); if (rc < 0) { err("failed to get device list from %s", host); + close(sockfd); return -1; } @@ -351,7 +352,7 @@ int usbip_list(int argc, char *argv[]) parsable = true; break; case 'r': - ret = list_exported_devices(optarg); + ret = list_importable_devices(optarg); goto out; case 'l': ret = list_devices(parsable); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v13 06/10] usbip: exporting devices: modifications to attach and detach
Refactoring to attach and detach operation to reuse common portion to application(vhci)-side daemon. The new application(vhci)-side daemon executes same procedures as attach and detach. Most of common code to access vhci has been implemented in VHCI userspace wrapper(libsrc/vhci_driver.c) but left in attach and detach. With this patch, an accessor of vhci driver and tracking of vhci connections in attach and detach are moved to the VHCI userspace wrapper. Here, attach, detach and application(vhci)-side daemon is EXISTING-5, EXISTING-6 and NEW-1 respectively in diagram below. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipd ... start daemon = = = 2) usbip list --local 3) usbip bind <--- list bound devices --- 4) usbip list --remote <--- import a device -- 5) usbip attach = = = X disconnected 6) usbip detach 7) usbip unbind NEW) - dedicates devices from device(stb)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipa ... start daemon = = = 2) usbip list --local 3) usbip connect --- export a device --> = = = 4) usbip disconnect --- un-export a device ---> Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 99 tools/usb/usbip/libsrc/vhci_driver.h | 6 +- tools/usb/usbip/src/usbip_attach.c | 50 ++ tools/usb/usbip/src/usbip_detach.c | 13 ++-- 4 files changed, 100 insertions(+), 68 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..d2221c5 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata + * 2005-2007 Takahiro Hirofuchi */ #include "usbip_common.h" @@ -7,6 +8,8 @@ #include #include #include +#include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -215,6 +218,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +#define OPEN_HC_MODE_FIRST 0 +#define OPEN_HC_MODE_REOPEN1 + +static int open_hc_device(int mode) +{ + if (mode == OPEN_HC_MODE_REOPEN) + udev_device_unref(vhci_driver->hc_device); + + vhci_driver->hc_device = + udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + USBIP_VHCI_DRV_NAME); + if (!vhci_driver->hc_device) { + err("udev_device_new_from_subsystem_sysname failed"); + return -1; + } + return 0; +} + /* -- */ int usbip_vhci_driver_open(void) @@ -227,28 +249,21 @@ int usbip_vhci_driver_open(void) vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); - if (!vhci_driver->hc_device) { - err("udev_device_new_from_subsystem_sysname failed"); - goto err; - } + if (open_hc_device(OPEN_HC_MODE_FIRST)) + goto err_free_driver; vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); if (refresh_imported_device_list()) - goto err; + goto err_unref_device; return 0; -err: +err_unref_device: udev_device_unref(vhci_driver->hc_device); - +err_free_driver: if (vhci_driver) free(vhci_driver); @@ -277,7 +292,8 @@ void usbip_vhci_driver_close(void) int usbip_vhci_refresh_device_list(void) { - + if (open_hc_device(OPEN_HC_MODE_REOPEN)) + goto err; if (refresh_imported_device_list()) goto err; @@ -409,3 +425,58 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) return 0; } + +#define MAX_BUFF 100 +int usbip_vhci_create_record(char *host, char *port, char *busid, int rhport) +{ + int fd; +
[PATCH v13 03/10] usbip: exporting devices: new connect operation
Implementation of new connect operation. This is linked as a part of usbip commnad. With this patch, usbip command has following operations. bind unbind list (local/remote) attach detach port connect ... this patch In device side node, this binds a device internally, sends an export request and receives export response. The definition of the request and response are defined in original code: tools/usb/usbip/usbip_network.h but was not used. They are corresponding to NEW-3 in following diagram. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipd ... start daemon = = = 2) usbip list --local 3) usbip bind <--- list bound devices --- 4) usbip list --remote <--- import a device -- 5) usbip attach = = = X disconnected 6) usbip detach 7) usbip unbind NEW) - dedicates devices from device(stb)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipa ... start daemon = = = 2) usbip list --local 3) usbip connect --- export a device --> = = = 4) usbip disconnect --- un-export a device ---> Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 3 +- tools/usb/usbip/src/usbip.c | 9 +- tools/usb/usbip/src/usbip.h | 5 +- tools/usb/usbip/src/usbip_connect.c | 228 4 files changed, 242 insertions(+), 3 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4eb..0947476 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ -usbip_bind.c usbip_unbind.c usbip_port.c +usbip_bind.c usbip_unbind.c usbip_port.c \ +usbip_connect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d9..584d7d5 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -2,7 +2,8 @@ * command structure borrowed from udev * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) * - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -76,6 +77,12 @@ static const struct command cmds[] = { .usage = usbip_detach_usage }, { + .name = "connect", + .fn= usbip_connect, + .help = "Connect a USB device to a remote computer", + .usage = usbip_connect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index c296910..f365353 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -30,12 +31,14 @@ int usbip_list(int argc, char *argv[]); int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); +int usbip_connect(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); +void usbip_connect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_connect.c b/tools/usb/usbip/src/usbip_connect.c new file mode 100644 index 000..bbecc7e --- /dev/null +++ b/tools/usb/usbip/src/usbip_connect.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 G
[PATCH v13 04/10] usbip: exporting devices: new disconnect operation
Implementation of new disconnect operation. This is linked as a part of usbip commnad. With this patch, usbip command has following operations. bind unbind list (local/remote) attach detach port connect ... previous patch disconnect ... this patch In device side node, this sends an un-export request, receives an un-export response and unbind corresponding device internally. The definition of the request and response are defined in original code: tools/usb/usbip/usbip_network.h but was not used. It's corresponding to NEW-4 in following diagram. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipd ... start daemon = = = 2) usbip list --local 3) usbip bind <--- list bound devices --- 4) usbip list --remote <--- import a device -- 5) usbip attach = = = X disconnected 6) usbip detach 7) usbip unbind NEW) - dedicates devices from device(stb)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipa ... start daemon = = = 2) usbip list --local 3) usbip connect --- export a device --> = = = 4) usbip disconnect --- un-export a device ---> Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am| 2 +- tools/usb/usbip/src/usbip.c| 6 + tools/usb/usbip/src/usbip.h| 2 + tools/usb/usbip/src/usbip_disconnect.c | 215 + 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 0947476..42760c3 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ -usbip_connect.c +usbip_connect.c usbip_disconnect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index 584d7d5..f0e9e06 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -83,6 +83,12 @@ static const struct command cmds[] = { .usage = usbip_connect_usage }, { + .name = "disconnect", + .fn= usbip_disconnect, + .help = "Disconnect a USB device from a remote computer", + .usage = usbip_disconnect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index f365353..a8cbd16 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); int usbip_connect(int argc, char *argv[]); +int usbip_disconnect(int argc, char *argv[]); void usbip_attach_usage(void); void usbip_detach_usage(void); @@ -39,6 +40,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); void usbip_connect_usage(void); +void usbip_disconnect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_disconnect.c b/tools/usb/usbip/src/usbip_disconnect.c new file mode 100644 index 000..8155384 --- /dev/null +++ b/tools/usb/usbip/src/usbip_disconnect.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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
[PATCH v13 05/10] usbip: exporting devices: modifications to daemon
Refactoring to the daemon to reuse common portion for new application side daemon. It's divided into two portions. usbipd.c : common code for both device and application side daemon. usbipd_dev.c : device-side specific code extracted from usbipd.c. In following diagram, usbipd EXISTING-1 is the device-side daemon and NEW-1 is the application side daemon. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipd ... start daemon = = = 2) usbip list --local 3) usbip bind <--- list bound devices --- 4) usbip list --remote <--- import a device -- 5) usbip attach = = = X disconnected 6) usbip detach 7) usbip unbind NEW) - dedicates devices from device(stb)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipa ... start daemon = = = 2) usbip list --local 3) usbip connect --- export a device --> = = = usbip_net_set_nodelay() was in the middle of device side daemon procedure. There's no effect by the defferring. It is moved to right after accept() to affect it both device and application side. In the client operation, it's already in right after connect(). Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 2 +- tools/usb/usbip/src/usbipd.c | 246 -- tools/usb/usbip/src/usbipd.h | 39 + tools/usb/usbip/src/usbipd_dev.c | 252 +++ 4 files changed, 319 insertions(+), 220 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 42760c3..1aa5156 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -9,4 +9,4 @@ usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c -usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c +usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 009afb4..bc4775f 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -43,25 +44,19 @@ #include #include -#include "usbip_host_driver.h" -#include "usbip_host_common.h" -#include "usbip_device_driver.h" #include "usbip_common.h" #include "usbip_network.h" +#include "usbipd.h" #include "list.h" -#undef PROGNAME -#define PROGNAME "usbipd" #define MAXSOCKFD 20 #define MAIN_LOOP_TIMEOUT 10 -#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" - static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options]\n" + "usage: %s [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" @@ -82,7 +77,7 @@ static const char usbipd_help_string[] = "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" - " If no FILE specified, use " DEFAULT_PID_FILE "\n" + " If no FILE specified, use %s.\n" "\n" " -tPORT, --tcp-port PORT\n" " Listen on TCP/IP port PORT.\n" @@ -93,198 +88,9 @@ static const char usbipd_help_string[] = " -v, --version\n" " Show version.\n"; -static struct usbip_host_driver *driver; - static void usbipd_help(void) { - printf("%s\n", usbipd_help_string); -} - -static int recv_request_import(int sockfd) -{ - struct op_import_request req; - struct usbip_exported_device *edev; - struct usbip_usb_device pdu_udev; - struct list_head *i; - int found = 0; - int error = 0; - int rc; - - memset(, 0, sizeof(req)); - - rc = usbip_net_recv(sockfd, , sizeof(req)); - if (rc
[PATCH v13 01/10] usbip: exporting devices: modifications to network header
Modification to export and un-export response in tools/usb/usbip/src/usbip_network.h. It just changes return code type from int to uint32_t as same as other responses. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_network.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/src/usbip_network.h b/tools/usb/usbip/src/usbip_network.h index c1e875c..e1ca86a 100644 --- a/tools/usb/usbip/src/usbip_network.h +++ b/tools/usb/usbip/src/usbip_network.h @@ -93,7 +93,7 @@ struct op_export_request { } __attribute__((packed)); struct op_export_reply { - int returncode; + uint32_t returncode; } __attribute__((packed)); @@ -115,7 +115,7 @@ struct op_unexport_request { } __attribute__((packed)); struct op_unexport_reply { - int returncode; + uint32_t returncode; } __attribute__((packed)); #define PACK_OP_UNEXPORT_REQUEST(pack, request) do {\ -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v13 00/10] usbip: exporting devices
tion. # Removed redundant SSL code had not been deleted. # Removed an unused local variable in WebSocket code. # Modified C++ reserved word in names.c as same as headers. v4) # Fixed regression of usbip list --remote v3) # Coding style for goto err labels are fixed. # Defined magic numbers for open_hc_device() argument. # Corrected include .../uapi/linux/usbip_ux.h as . # Modified parameter notation in manuals not to use '='. # Fixed inappropriate version definition in tools/.../websocket/configure.ac. # Remved unnecessary COPYING and AUTHORS fil from tools/.../websocket/. # Added -version-info to libraries in tools/.../src. v2) # Formatted patches from linux-next. # Fixed change log word wrapping. # Removed SSL patches. # Fixed a bug that vendor and product names are not shown by 'usbws list -l' because usbip_names_init() was not called in libusbip.la. Thank you, Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> // *** BLURB HERE *** Nobuo Iwata (10): usbip: exporting devices: modifications to network header usbip: exporting devices: modifications to host side libraries usbip: exporting devices: new connect operation usbip: exporting devices: new disconnect operation usbip: exporting devices: modifications to daemon usbip: exporting devices: modifications to attach and detach usbip: exporting devices: new application-side daemon usbip: exporting devices: change to usbip_list.c usbip: exporting devices: chage to documenattion usbip: exporting devices: modifications to protocol text Documentation/usb/usbip_protocol.txt | 204 ++-- tools/usb/usbip/Makefile.am| 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8| 136 +-- tools/usb/usbip/doc/usbipa.8 | 78 +++ tools/usb/usbip/doc/usbipd.8 | 38 +-- tools/usb/usbip/libsrc/usbip_host_common.c | 6 +- tools/usb/usbip/libsrc/usbip_host_common.h | 8 +- tools/usb/usbip/libsrc/vhci_driver.c | 118 -- tools/usb/usbip/libsrc/vhci_driver.h | 7 +- tools/usb/usbip/src/Makefile.am| 12 +- tools/usb/usbip/src/usbip.c| 15 +- tools/usb/usbip/src/usbip.h| 10 +- tools/usb/usbip/src/usbip_attach.c | 50 +--- tools/usb/usbip/src/usbip_bind.c | 4 +- tools/usb/usbip/src/usbip_connect.c| 228 ++ tools/usb/usbip/src/usbip_detach.c | 13 +- tools/usb/usbip/src/usbip_disconnect.c | 215 + tools/usb/usbip/src/usbip_list.c | 17 +- tools/usb/usbip/src/usbip_network.h| 4 +- tools/usb/usbip/src/usbip_unbind.c | 4 +- tools/usb/usbip/src/usbipd.c | 258 +++-- tools/usb/usbip/src/usbipd.h | 39 tools/usb/usbip/src/usbipd_app.c | 242 +++ tools/usb/usbip/src/usbipd_dev.c | 252 25 files changed, 1631 insertions(+), 399 deletions(-) create mode 100644 tools/usb/usbip/doc/usbipa.8 create mode 100644 tools/usb/usbip/src/usbip_connect.c create mode 100644 tools/usb/usbip/src/usbip_disconnect.c create mode 100644 tools/usb/usbip/src/usbipd.h create mode 100644 tools/usb/usbip/src/usbipd_app.c create mode 100644 tools/usb/usbip/src/usbipd_dev.c -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v13 02/10] usbip: exporting devices: modifications to host side libraries
usbip_get_device() method in usbip_host_driver_ops was not used. It is modified as a function to find an exported device for new operations 'connect' and 'disconnect'. bind and unbind function are exported to reuse by new connect and disconnect operation. Here, connect and disconnect is NEW-3 and NEW-4 respactively in diagram below. EXISTING) - invites devices from application(vhci)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipd ... start daemon = = = 2) usbip list --local 3) usbip bind <--- list bound devices --- 4) usbip list --remote <--- import a device -- 5) usbip attach = = = X disconnected 6) usbip detach 7) usbip unbind NEW) - dedicates devices from device(stb)-side +--+ +--+ device--+ STUB | | application/VHCI | +--+ +--+ 1) usbipa ... start daemon = = = 2) usbip list --local 3) usbip connect --- export a device --> = = = 4) usbip disconnect --- un-export a device ---> Bind and unbind are done in connect and disconnect internally. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/usbip_host_common.c | 6 ++ tools/usb/usbip/libsrc/usbip_host_common.h | 8 tools/usb/usbip/src/usbip.h| 3 +++ tools/usb/usbip/src/usbip_bind.c | 4 ++-- tools/usb/usbip/src/usbip_unbind.c | 4 ++-- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..6a98d6c 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -256,17 +256,15 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num) + struct usbip_host_driver *hdriver, char *busid) { struct list_head *i; struct usbip_exported_device *edev; - int cnt = 0; list_for_each(i, >edev_list) { edev = list_entry(i, struct usbip_exported_device, node); - if (num == cnt) + if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) return edev; - cnt++; } return NULL; diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h index a64b803..f9a9def 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.h +++ b/tools/usb/usbip/libsrc/usbip_host_common.h @@ -38,7 +38,7 @@ struct usbip_host_driver_ops { void (*close)(struct usbip_host_driver *hdriver); int (*refresh_device_list)(struct usbip_host_driver *hdriver); struct usbip_exported_device * (*get_device)( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); int (*read_device)(struct udev_device *sdev, struct usbip_usb_device *dev); @@ -86,11 +86,11 @@ static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver) } static inline struct usbip_exported_device * -usbip_get_device(struct usbip_host_driver *hdriver, int num) +usbip_get_device(struct usbip_host_driver *hdriver, char *busid) { if (!hdriver->ops.get_device) return NULL; - return hdriver->ops.get_device(hdriver, num); + return hdriver->ops.get_device(hdriver, busid); } /* Helper functions for implementing driver backend */ @@ -99,6 +99,6 @@ void usbip_generic_driver_close(struct usbip_host_driver *hdriver); int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver); int usbip_export_device(struct usbip_exported_device *edev, int sockfd); struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); #endif /* __USBIP_HOST_COMMON_H */ diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a..c296910 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -37,4 +37,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); +int usbip_bind_device(char *busid); +int usbip_unbind_device(char *busid); + #endif /* __USBIP_H */ diff --git a/tools/usb/usbip/src/usbip_bind.c b/tools/usb/usbip/src/usbip_bind.c index fa46141..2401745 100644 --- a/tools/usb/usbip/src/usbip
[PATCH v12 6/9] usbip: exporting devices: modifications to attach and detach
Refactoring to attach and detatch operation. Common parts to new application(vhci)-side daemon are moved to libsrc/vhci_driver.c. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 99 tools/usb/usbip/libsrc/vhci_driver.h | 6 +- tools/usb/usbip/src/usbip_attach.c | 50 ++ tools/usb/usbip/src/usbip_detach.c | 13 ++-- 4 files changed, 100 insertions(+), 68 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..d2221c5 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata + * 2005-2007 Takahiro Hirofuchi */ #include "usbip_common.h" @@ -7,6 +8,8 @@ #include #include #include +#include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -215,6 +218,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +#define OPEN_HC_MODE_FIRST 0 +#define OPEN_HC_MODE_REOPEN1 + +static int open_hc_device(int mode) +{ + if (mode == OPEN_HC_MODE_REOPEN) + udev_device_unref(vhci_driver->hc_device); + + vhci_driver->hc_device = + udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + USBIP_VHCI_DRV_NAME); + if (!vhci_driver->hc_device) { + err("udev_device_new_from_subsystem_sysname failed"); + return -1; + } + return 0; +} + /* -- */ int usbip_vhci_driver_open(void) @@ -227,28 +249,21 @@ int usbip_vhci_driver_open(void) vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); - if (!vhci_driver->hc_device) { - err("udev_device_new_from_subsystem_sysname failed"); - goto err; - } + if (open_hc_device(OPEN_HC_MODE_FIRST)) + goto err_free_driver; vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); if (refresh_imported_device_list()) - goto err; + goto err_unref_device; return 0; -err: +err_unref_device: udev_device_unref(vhci_driver->hc_device); - +err_free_driver: if (vhci_driver) free(vhci_driver); @@ -277,7 +292,8 @@ void usbip_vhci_driver_close(void) int usbip_vhci_refresh_device_list(void) { - + if (open_hc_device(OPEN_HC_MODE_REOPEN)) + goto err; if (refresh_imported_device_list()) goto err; @@ -409,3 +425,58 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) return 0; } + +#define MAX_BUFF 100 +int usbip_vhci_create_record(char *host, char *port, char *busid, int rhport) +{ + int fd; + char path[PATH_MAX+1]; + char buff[MAX_BUFF+1]; + int ret; + + ret = mkdir(VHCI_STATE_PATH, 0700); + if (ret < 0) { + /* if VHCI_STATE_PATH exists, then it better be a directory */ + if (errno == EEXIST) { + struct stat s; + + ret = stat(VHCI_STATE_PATH, ); + if (ret < 0) + return -1; + if (!(s.st_mode & S_IFDIR)) + return -1; + } else + return -1; + } + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + + fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0700); + 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; +} + +int usbip_vhci_delete_record(int rhport) +{ + char path[PATH_MAX+1]; + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + + remove(path); + rmdir(VHCI_STATE_PATH); + + return 0; +} diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..f955ada 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb
[PATCH v12 8/9] usbip: exporting devices: change to usbip_list.c
Correction to wording inconsistency around import and export in usbip_list.c. Please, see also cover letter about wording. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_list.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index f1b38e8..37f9afa 100644 --- a/tools/usb/usbip/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -42,9 +43,9 @@ #include "usbip.h" static const char usbip_list_usage_string[] = - "usbip list [-p|--parsable] \n" + "usbip list \n" "-p, --parsable Parsable list format\n" - "-r, --remote=List the exportable USB devices on \n" + "-r, --remote=List the importable USB devices on \n" "-l, --localList the local USB devices\n"; void usbip_list_usage(void) @@ -52,7 +53,7 @@ void usbip_list_usage(void) printf("usage: %s", usbip_list_usage_string); } -static int get_exported_devices(char *host, int sockfd) +static int get_importable_devices(char *host, int sockfd) { char product_name[100]; char class_name[100]; @@ -82,14 +83,14 @@ static int get_exported_devices(char *host, int sockfd) return -1; } PACK_OP_DEVLIST_REPLY(0, ); - dbg("exportable devices: %d\n", reply.ndev); + dbg("importable devices: %d\n", reply.ndev); if (reply.ndev == 0) { - info("no exportable devices found on %s", host); + info("no importable devices found on %s", host); return 0; } - printf("Exportable USB devices\n"); + printf("Importable USB devices\n"); printf("==\n"); printf(" - %s\n", host); @@ -134,7 +135,7 @@ static int get_exported_devices(char *host, int sockfd) return 0; } -static int list_exported_devices(char *host) +static int list_importable_devices(char *host) { int rc; int sockfd; @@ -147,9 +148,10 @@ static int list_exported_devices(char *host) } dbg("connected to %s:%s", host, usbip_port_string); - rc = get_exported_devices(host, sockfd); + rc = get_importable_devices(host, sockfd); if (rc < 0) { err("failed to get device list from %s", host); + close(sockfd); return -1; } @@ -351,7 +353,7 @@ int usbip_list(int argc, char *argv[]) parsable = true; break; case 'r': - ret = list_exported_devices(optarg); + ret = list_importable_devices(optarg); goto out; case 'l': ret = list_devices(parsable); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v12 9/9] usbip: exporting devices: chage to documenattion
This patch adds function and usage of new connect operation, disconnect operation and application(vhci)-side daemon to README and manuals. At this point, the wording, 'server' and 'client' are ambiguous in several place. For existing attach command, the daemon runs device side machine and attach command is executed in application side machine. Then 'server' is used for device side and 'client' is for application side. For the new connect command, the daemon runs applications side machine and connect command is executed in device side machine. Now, 'server' and 'client' run in different machine than before. So, to avoid confusion, words 'device side (machine)' and 'application side (machine)' are used instead of 'client' and 'server' as needed. Please, see also diagrams in the cover letter. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/Makefile.am | 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8 | 136 --- tools/usb/usbip/doc/usbipa.8 | 78 tools/usb/usbip/doc/usbipd.8 | 38 +- 5 files changed, 263 insertions(+), 61 deletions(-) diff --git a/tools/usb/usbip/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf0..f371ed9 100644 --- a/tools/usb/usbip/Makefile.am +++ b/tools/usb/usbip/Makefile.am @@ -3,4 +3,4 @@ includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ usbip_common.h vhci_driver.h usbip_host_driver.h) -dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) +dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbipa.8) diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 831f49f..74f4afb 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -1,7 +1,8 @@ # # README for usbip-utils # -# Copyright (C) 2011 matt mooney <m...@muteddisk.com> +# Copyright (C) 2015 Nobuo Iwata +# 2011 matt mooney <m...@muteddisk.com> # 2005-2008 Takahiro Hirofuchi @@ -36,41 +37,70 @@ [Usage] -server:# (Physically attach your USB device.) +Device-side: a machine has USB device(s). +Application-side: a machine runs an application software uses remote USB device. -server:# insmod usbip-core.ko -server:# insmod usbip-host.ko +1) Connect from application-side to device-side. -server:# usbipd -D +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbipd -D - Start usbip daemon. -server:# usbip list -l - - List driver assignments for USB devices. +dev:# usbip list -l + - List driver assignments for USB devices and their busid. -server:# usbip bind --busid 1-2 - - Bind usbip-host.ko to the device with busid 1-2. - - The USB device 1-2 is now exportable to other hosts! - - Use `usbip unbind --busid 1-2' to stop exporting the device. +dev:# usbip bind --busid + - Bind usbip-host.ko to the device with . + - The USB device with is now exportable to other hosts! + - Use `usbip unbind --busid ` to stop exporting the device. -client:# insmod usbip-core.ko -client:# insmod vhci-hcd.ko +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko -client:# usbip list --remote +app:# usbip list --remote - List exported USB devices on the . -client:# usbip attach --remote --busid 1-2 +app:# usbip attach --remote --busid - Connect the remote USB device. -client:# usbip port +app:# usbip port - Show virtual port status. -client:# usbip detach --port +app:# usbip detach --port - Detach the USB device. +2) Connect from device-side to application-side. + +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko + +app:# usbipa -D + - Start usbip daemon. + +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbip list -l + - List driver assignments for USB devices and their busid. + +dev:# usbip connect --remote --busid + - Bind usbip-host.ko to the device with . + - The USB device of is connected to remote host! + +dev:# usbip disconnect --remote --busid + - The USB device with is disconnected from remote host. + - Unbind usbip-host.ko from the device. + [Example] --- - SERVER SIDE + DEVICE SIDE --- Physically attach your USB devices to this host. @@ -131,7 +161,7 @@ Mark the device of busid 3-3.2 as exportable: ... --- - CLIENT SIDE + APPLICATION SIDE --- First, let's list available remote devices that are marked as exportable on the host. @@ -170,7 +200,7 @@ Attach a remote USB device: deux:# usbip attach --remote 10.0.0.3 --bus
[PATCH v12 7/9] usbip: exporting devices: new application-side daemon
New application(vhci)-side daemon. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 19 +++ tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/Makefile.am | 7 +- tools/usb/usbip/src/usbipd.c | 12 +- tools/usb/usbip/src/usbipd_app.c | 242 +++ 5 files changed, 279 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index d2221c5..3fe92ff 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -314,6 +314,25 @@ int usbip_vhci_get_free_port(void) return -1; } +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid) +{ + int ret; + char rhost[NI_MAXHOST] = "unknown host"; + char rserv[NI_MAXSERV] = "unknown port"; + char rbusid[SYSFS_BUS_ID_SIZE]; + + for (int i = 0; i < vhci_driver->nports; i++) { + ret = read_record(vhci_driver->idev[i].port, rhost, NI_MAXHOST, + rserv, NI_MAXSERV, rbusid); + if (!ret && + !strncmp(host, rhost, NI_MAXHOST) && + !strncmp(busid, rbusid, SYSFS_BUS_ID_SIZE)) { + return vhci_driver->idev + i; + } + } + return NULL; +} + int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed) { char buff[200]; /* what size should be ? */ diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index f955ada..acb427d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -46,6 +46,7 @@ int usbip_vhci_refresh_device_list(void); int usbip_vhci_get_free_port(void); +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid); int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed); diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 1aa5156..8fdebce 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -2,11 +2,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' AM_CFLAGS = @EXTRA_CFLAGS@ LDADD = $(top_builddir)/libsrc/libusbip.la -sbin_PROGRAMS := usbip usbipd +sbin_PROGRAMS := usbip usbipd usbipa usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c +usbip_CFLAGS := $(AM_CFLAGS) usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c +usbipd_CFLAGS := $(AM_CFLAGS) + +usbipa_SOURCES := usbip_network.h usbipd.c usbipd_app.c usbip_network.c +usbipa_CFLAGS := $(AM_CFLAGS) -DUSBIP_DAEMON_APP diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 4b15bb1..5f6b040 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -64,11 +64,13 @@ static const char usbipd_help_string[] = " -6, --ipv6\n" " Bind to IPv6. Default is both.\n" "\n" +#ifndef USBIP_DAEMON_APP " -e, --device\n" " Run in device mode.\n" " Rather than drive an attached device, create\n" " a virtual UDC to bind gadgets to.\n" "\n" +#endif " -D, --daemon\n" " Run as a daemon process.\n" "\n" @@ -404,7 +406,9 @@ int main(int argc, char *argv[]) { "ipv6", no_argument, NULL, '6' }, { "daemon", no_argument, NULL, 'D' }, { "debug",no_argument, NULL, 'd' }, +#ifndef USBIP_DAEMON_APP { "device", no_argument, NULL, 'e' }, +#endif { "pid", optional_argument, NULL, 'P' }, { "tcp-port", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, @@ -433,7 +437,11 @@ int main(int argc, char *argv[]) cmd = cmd_standalone_mode; usbip_init_driver(); for (;;) { - opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL); + opt = getopt_long(argc, argv, "46Dd" +#ifndef USBIP_DAEMON_APP + "e" +#endif + "P::t:hv", longopts, NULL); if (opt == -1) break; @@ -463,9 +471,11 @@ int mai
[PATCH v12 5/9] usbip: exporting devices: modifications to daemon
Refactoring to the daemon. usbipd_dev.c is device-side specific code extracted from usbipd.c. usbipd.c is left as common parts for both device(stub)-side and application(vhci)-side daemon. usbip_net_set_nodelay() is the middle of device side daemon operation and it does not make mush sence. In the client operation, it's in right after connect(). So, in daemon, it is moved to right after accept() to affect it both device and application side. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 2 +- tools/usb/usbip/src/usbipd.c | 246 -- tools/usb/usbip/src/usbipd.h | 39 + tools/usb/usbip/src/usbipd_dev.c | 252 +++ 4 files changed, 319 insertions(+), 220 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 42760c3..1aa5156 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -9,4 +9,4 @@ usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c -usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c +usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index a0972de..4b15bb1 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -43,25 +44,19 @@ #include #include -#include "usbip_host_driver.h" -#include "usbip_host_common.h" -#include "usbip_device_driver.h" #include "usbip_common.h" #include "usbip_network.h" +#include "usbipd.h" #include "list.h" -#undef PROGNAME -#define PROGNAME "usbipd" #define MAXSOCKFD 20 #define MAIN_LOOP_TIMEOUT 10 -#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" - static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options]\n" + "usage: %s [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" @@ -82,7 +77,7 @@ static const char usbipd_help_string[] = "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" - " If no FILE specified, use " DEFAULT_PID_FILE "\n" + " If no FILE specified, use %s.\n" "\n" " -tPORT, --tcp-port PORT\n" " Listen on TCP/IP port PORT.\n" @@ -93,198 +88,9 @@ static const char usbipd_help_string[] = " -v, --version\n" " Show version.\n"; -static struct usbip_host_driver *driver; - static void usbipd_help(void) { - printf("%s\n", usbipd_help_string); -} - -static int recv_request_import(int sockfd) -{ - struct op_import_request req; - struct usbip_exported_device *edev; - struct usbip_usb_device pdu_udev; - struct list_head *i; - int found = 0; - int error = 0; - int rc; - - memset(, 0, sizeof(req)); - - rc = usbip_net_recv(sockfd, , sizeof(req)); - if (rc < 0) { - dbg("usbip_net_recv failed: import request"); - return -1; - } - PACK_OP_IMPORT_REQUEST(0, ); - - list_for_each(i, >edev_list) { - edev = list_entry(i, struct usbip_exported_device, node); - if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { - info("found requested device: %s", req.busid); - found = 1; - break; - } - } - - if (found) { - /* should set TCP_NODELAY for usbip */ - usbip_net_set_nodelay(sockfd); - - /* export device needs a TCP/IP socket descriptor */ - rc = usbip_export_device(edev, sockfd); - if (rc < 0) - error = 1; - } else { - info("requested device not found: %s", req.busid); - error = 1; - } - - rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT, - (!error ? ST_OK : ST_NA)); - if (rc < 0) { - dbg("usbip_net_send_op_comm
[PATCH v12 4/9] usbip: exporting devices: new disconnect operation
New disconnect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am| 2 +- tools/usb/usbip/src/usbip.c| 6 + tools/usb/usbip/src/usbip.h| 2 + tools/usb/usbip/src/usbip_disconnect.c | 215 + 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 0947476..42760c3 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ -usbip_connect.c +usbip_connect.c usbip_disconnect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index 584d7d5..f0e9e06 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -83,6 +83,12 @@ static const struct command cmds[] = { .usage = usbip_connect_usage }, { + .name = "disconnect", + .fn= usbip_disconnect, + .help = "Disconnect a USB device from a remote computer", + .usage = usbip_disconnect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index f365353..a8cbd16 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); int usbip_connect(int argc, char *argv[]); +int usbip_disconnect(int argc, char *argv[]); void usbip_attach_usage(void); void usbip_detach_usage(void); @@ -39,6 +40,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); void usbip_connect_usage(void); +void usbip_disconnect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_disconnect.c b/tools/usb/usbip/src/usbip_disconnect.c new file mode 100644 index 000..8155384 --- /dev/null +++ b/tools/usb/usbip/src/usbip_disconnect.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_disconnect_usage_string[] = + "usbip disconnect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be disconnected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_disconnect_usage(void) +{ + printf("usage: %s", usbip_disconnect_usage_string); +} + +static int send_unexport_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_unexport_request request; + struct op_unexport_reply reply; + uint16_t code = OP_REP_UNEXPORT; + + memset(, 0, sizeof(request)); + memset(, 0, sizeof(reply)); + + /* send a request */ + rc = usbip_net_send_op_common(sockfd, OP_REQ_UNEXPORT, 0); + if (rc < 0) { + err("send op_common"); + return -1; + } + + memcpy(, udev, sizeof(struct usbip_usb_device)); + + PACK_OP_UNEXPORT_REQUEST(0, ); + + rc = usbip_net_send(sockfd, (void *) , sizeof(request)); + if (rc < 0) { + err("send op_export_request"); +
[PATCH v12 3/9] usbip: exporting devices: new connect operation
New connect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 3 +- tools/usb/usbip/src/usbip.c | 9 +- tools/usb/usbip/src/usbip.h | 5 +- tools/usb/usbip/src/usbip_connect.c | 228 4 files changed, 242 insertions(+), 3 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4eb..0947476 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ -usbip_bind.c usbip_unbind.c usbip_port.c +usbip_bind.c usbip_unbind.c usbip_port.c \ +usbip_connect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d9..584d7d5 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -2,7 +2,8 @@ * command structure borrowed from udev * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) * - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -76,6 +77,12 @@ static const struct command cmds[] = { .usage = usbip_detach_usage }, { + .name = "connect", + .fn= usbip_connect, + .help = "Connect a USB device to a remote computer", + .usage = usbip_connect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index c296910..f365353 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -30,12 +31,14 @@ int usbip_list(int argc, char *argv[]); int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); +int usbip_connect(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); +void usbip_connect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_connect.c b/tools/usb/usbip/src/usbip_connect.c new file mode 100644 index 000..bbecc7e --- /dev/null +++ b/tools/usb/usbip/src/usbip_connect.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_connect_usage_string[] = + "usbip connect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be connected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_connect_usage(void) +{ + printf("usage: %s", usbip_connect_usage_string); +} + +static int send_export_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_export_request request; + struct op_export_reply reply
[PATCH v12 1/9] usbip: exporting devices: modifications to network header
Modification to export and un-export response in tools/usb/usbip/src/usbip_network.h. It just changes return code type from int to uint32_t as same as other responses. Added export and un-export request/response to Documentation/usb/usbip_protocol.txt. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Documentation/usb/usbip_protocol.txt | 204 --- tools/usb/usbip/src/usbip_network.h | 5 +- 2 files changed, 184 insertions(+), 25 deletions(-) diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe2..d4be5b6 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -1,20 +1,26 @@ PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! 28 Jun 2011 +MODIFIED FOR CONNECT AND DISCONNECT OPERARION. +07 March 2016 -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. +The USB/IP protocol follows a server/client architecture between two computers +one has USB devices and the other runs application using the devices. There are +two ways for initiation. -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. +The first way is to import devices from application-side. In this way, the +server runs in device-side and the client runs in application-side. In device +side user makes devices importable with 'bind' operation. +The client may ask for the list of the importable USB devices. To get the list +the client opens a TCP/IP connection towards the server, and sends an +OP_REQ_DEVLIST packet on top of the TCP/IP connection (so the actual +OP_REQ_DEVLIST may be sent in one or more pieces at the low level transport +layer). The server sends back the OP_REP_DEVLIST packet which lists the +importable USB devices. Finally the TCP/IP connection is closed. + + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (lists importable devices)"server" | | | OP_REQ_DEVLIST | | --> | @@ -23,18 +29,13 @@ TCP/IP connection is closed. | <-- | | | -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. +Once the client knows the list of importable USB devices it may decide to use +one of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (imports a USB device) "server" | | | OP_REQ_IMPORT | | --> | @@ -42,6 +43,32 @@ server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | OP_REP_IMPORT | | <-- | | | + +The second way is to export devices from device-side. In this way, the server +runs in application-side and the client runs in device-side. The client binds a +device to export, opens a TCP/IP connection towards the server
[PATCH v12 2/9] usbip: exporting devices: modifications to host side libraries
usbip_get_device() method in usbip_host_driver_ops was not used. It is modified as a function to find an exported device for new operations 'connect' and 'disconnect'. bind and unbind function are exported for the new operations. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/usbip_host_common.c | 6 ++ tools/usb/usbip/libsrc/usbip_host_common.h | 8 tools/usb/usbip/src/usbip.h| 3 +++ tools/usb/usbip/src/usbip_bind.c | 7 --- tools/usb/usbip/src/usbip_unbind.c | 7 --- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..6a98d6c 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -256,17 +256,15 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num) + struct usbip_host_driver *hdriver, char *busid) { struct list_head *i; struct usbip_exported_device *edev; - int cnt = 0; list_for_each(i, >edev_list) { edev = list_entry(i, struct usbip_exported_device, node); - if (num == cnt) + if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) return edev; - cnt++; } return NULL; diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h index a64b803..f9a9def 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.h +++ b/tools/usb/usbip/libsrc/usbip_host_common.h @@ -38,7 +38,7 @@ struct usbip_host_driver_ops { void (*close)(struct usbip_host_driver *hdriver); int (*refresh_device_list)(struct usbip_host_driver *hdriver); struct usbip_exported_device * (*get_device)( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); int (*read_device)(struct udev_device *sdev, struct usbip_usb_device *dev); @@ -86,11 +86,11 @@ static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver) } static inline struct usbip_exported_device * -usbip_get_device(struct usbip_host_driver *hdriver, int num) +usbip_get_device(struct usbip_host_driver *hdriver, char *busid) { if (!hdriver->ops.get_device) return NULL; - return hdriver->ops.get_device(hdriver, num); + return hdriver->ops.get_device(hdriver, busid); } /* Helper functions for implementing driver backend */ @@ -99,6 +99,6 @@ void usbip_generic_driver_close(struct usbip_host_driver *hdriver); int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver); int usbip_export_device(struct usbip_exported_device *edev, int sockfd); struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); #endif /* __USBIP_HOST_COMMON_H */ diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a..c296910 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -37,4 +37,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); +int usbip_bind_device(char *busid); +int usbip_unbind_device(char *busid); + #endif /* __USBIP_H */ diff --git a/tools/usb/usbip/src/usbip_bind.c b/tools/usb/usbip/src/usbip_bind.c index fa46141..1c09338 100644 --- a/tools/usb/usbip/src/usbip_bind.c +++ b/tools/usb/usbip/src/usbip_bind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -139,7 +140,7 @@ static int unbind_other(char *busid) return status; } -static int bind_device(char *busid) +int usbip_bind_device(char *busid) { int rc; struct udev *udev; @@ -200,7 +201,7 @@ int usbip_bind(int argc, char *argv[]) switch (opt) { case 'b': - ret = bind_device(optarg); + ret = usbip_bind_device(optarg); goto out; default: goto err_out; diff --git a/tools/usb/usbip/src/usbip_unbind.c b/tools/usb/usbip/src/usbip_unbind.c index a4a496c..cc1ff26 100644 --- a/tools/usb/usbip/src/usbip_unbind.c +++ b/tools/usb/usbip/src/usbip_unbind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + *
[PATCH v12 0/9] usbip: exporting devices
nd internally. With vUDC, they do not execute bind and unbind. They are done by UDC interface. 4. Security consideration Daemons accept following requests form network : EXISTING) 'list --remote' and 'attach' NEW) 'connect' and 'desconnect' TCP wrappers allows and/or denies network access. It is enabled when the daemons are compiled with ./configure --with-tcp-wrappers. When the daemons are running with SSL or Secure WebSocket tunneling proxy, the proxy can use client authentication with certificate files. 5. Mixed usage Both existing and new way work in same machines simultaneously. Status of devices and ports are controlled in stub and vhci driver. 6. Wording Adding the new operation, some inconsistnecies in wording are appeared in documentation, function name, etc. If needed, they are fixed. 'export' is used for bind and 'exported' is used for bound. They are changed to 'make importable' and 'imported' respectively. The words not new. For example, in the output of port operation, 'imported devices' is already used. They are sorted out. 'client' and 'server' are switched between existing and new operation. So, words 'device-side' and 'application-side' are used in documentations as needed for clarity. --- Version information This series is divided from "USB/IP over WebSocket" patch set. Rest of the set will be sent as another series. v12) # Recreated based on linux-next 20161012. # Fixed checkpatch a warning about symbolic permission. # Fixed checkpatch warnings about traling space in a document. v11) # Corrected program name of each daemon which are used in version string, info messages and daemon name for tcp wrappers. # Added description about tcp wrappers in security consideration of cover letter. # Added security consideration for existing requests in contradistinction to new requests. # Recreated based on linux-next 20160928. v10) # Recreated based on linux-next 20160810. v9) # Moved a set_nodelay() from usbipd_dev.c to usbipd.c to affect both device side and application side daemon. # Removed redundant blank line at the end of files. v8) # Divided into smaller patches. # Excluded low-related patches. # Improved change log. # Changed info level logs in usbip_ux.c to debug level logs. # Added options to vUDC. # Tested with vUDC. v7) # Removed userspace transmission and WebSocket command/daemon. # Fixed checkpatch errors and warnings. v6) # Added __rcu annotation to a RCU pointer to clear sparse warnings. # Corrected a copy to RCU pointer with rcu_rcu_assign_pointer(). # Added __user annotations to arguments of read/write method. # Added static to some functions which are not called from other files. # Removed unnecessary EXPORT_SYMBOLs. v5) # Added vendor/pruduct name conversion to port command. # Put initial value to pool_head in name.c. # Fixed list command exception when host option is omitted. # Fixed exception in case gai_strerror() returns NULL. # Fixed WebSocket connection close via proxy. # Fixed to stop WebSocket ping-pong on connection close. # Removed redundant usbipd daemon option. # Removed redundant SSL code had not been deleted. # Removed an unused local variable in WebSocket code. # Modified C++ reserved word in names.c as same as headers. v4) # Fixed regression of usbip list --remote v3) # Coding style for goto err labels are fixed. # Defined magic numbers for open_hc_device() argument. # Corrected include .../uapi/linux/usbip_ux.h as . # Modified parameter notation in manuals not to use '='. # Fixed inappropriate version definition in tools/.../websocket/configure.ac. # Remved unnecessary COPYING and AUTHORS fil from tools/.../websocket/. # Added -version-info to libraries in tools/.../src. v2) # Formatted patches from linux-next. # Fixed change log word wrapping. # Removed SSL patches. # Fixed a bug that vendor and product names are not shown by 'usbws list -l' because usbip_names_init() was not called in libusbip.la. Thank you, Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> // *** BLURB HERE *** Nobuo Iwata (9): usbip: exporting devices: modifications to network header usbip: exporting devices: modifications to host side libraries usbip: exporting devices: new connect operation usbip: exporting devices: new disconnect operation usbip: exporting devices: modifications to daemon usbip: exporting devices: modifications to attach and detach usbip: exporting devices: new application-side daemon usbip: exporting devices: change to usbip_list.c usbip: exporting devices: chage to documenattion Documentation/usb/usbip_protocol.txt | 204 ++-- tools/usb/usbip/Makefile.am| 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8| 136 +-- tools/usb/usbip/doc/usbipa.8 | 78 +++ tools/usb/usbip/doc/usbipd.8 | 38 +-- tools/usb/usbip/libsrc/usbip_host_common.c | 6 +- tools/us
[PATCH v1 1/1] usbip: fix possibility of dereference by NULLL pointer in vhci_hcd.c
This patch fixes possibility of dereference by NULLL pointer in "[PATCH v5 1/3] usbip: vhci extension: modifications to vhci driver" which has been merged to 4.9-rc1. It occurs when a URB with pointer to invalid USB/IP device is enqueued in race condition against detach operation. A pointer was passed to vdev_to_vhci() before NULL check. In vdev_to_vhci(), there's a dereference by the pointer. This patch moves vdev_to_vhci() after NULL check of the pointer. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/vhci_hcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index 03eccf2..c4724fb 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -460,13 +460,14 @@ static void vhci_tx_urb(struct urb *urb) { struct vhci_device *vdev = get_vdev(urb->dev); struct vhci_priv *priv; - struct vhci_hcd *vhci = vdev_to_vhci(vdev); + struct vhci_hcd *vhci; unsigned long flags; if (!vdev) { pr_err("could not get virtual device"); return; } + vhci = vdev_to_vhci(vdev); priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); if (!priv) { -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 1/2] usbip: vhci extension: modifications to userspace
Modification to the userspace tools including usbip/libsrc and usbip/src. Changed corresponding to new vhci_sysfs.c. nports in sysfs is used to get total number of ports. Old get_nports() ignores the last status line because udev_device_get_sysattr_value() drops last new line. New version uses nports attribute so it's doesn't have this problem. status[.N] in sysfs are used. parse_status() which reads all status lines is broken into open, close, read-line and parse-line. Parse-line is reused to find free port and get imported device. In daemon, status was loaded into memory by usbip_vhci_refresh_device_list() at receiving every request. The loaded status is used to find free port. It is changed to read status directly to find free port. Wording inconsistencies are fixed according to the rule below. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 398 +++ tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 48 ++-- 5 files changed, 253 insertions(+), 259 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 50c723d..4d1b986 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -15,11 +15,24 @@ #undef PROGNAME #define PROGNAME "libusbip" -struct usbip_vhci_driver *vhci_driver; -struct udev *udev_context; +static struct udev_device *vhci_hc_device; +static struct udev *udev_context; +static int vhci_nports; -static struct usbip_imported_device * -imported_device_init(struct usbip_imported_device *idev, char *busid) +struct usbip_vhci_device { + int port; + uint32_t status; + + uint32_t devid; + + uint8_t busnum; + uint8_t devnum; + + /* usbip_class_device list */ + struct usbip_usb_device udev; +}; + +static int imported_device_init(struct usbip_vhci_device *vdev, char *busid) { struct udev_device *sudev; @@ -27,132 +40,131 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) "usb", busid); if (!sudev) { dbg("udev_device_new_from_subsystem_sysname failed: %s", busid); - goto err; + return -1; } - read_usb_device(sudev, >udev); + read_usb_device(sudev, >udev); udev_device_unref(sudev); - return idev; - -err: - return NULL; + return 0; } +struct status_context { + int controller; + const char *c; +}; +#define OPEN_MODE_FIRST 0 +#define OPEN_MODE_REOPEN 1 -static int parse_status(const char *value) -{ - int ret = 0; - char *c; +static int open_hc_device(int mode); +#define MAX_STATUS_NAME 16 - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); +static int open_status(struct status_context *ctx, int mode) +{ + char name[MAX_STATUS_NAME+1]; + if (mode == OPEN_MODE_FIRST) + ctx->controller = 0; + else + (ctx->controller)++; - /* skip a header line */ - c = strchr(value, '\n'); - if (!c) + if (open_hc_device(OPEN_MODE_REOPEN)) return -1; - c++; - - while (*c != '\0') { - int port, status, speed, devid; - unsigned long socket; - char lbusid[SYSFS_BUS_ID_SIZE]; - - ret = sscanf(c, "%d %d %d %x %lx %31s\n", - , , , - , , lbusid); - - if (ret < 5) { - dbg("sscanf failed: %d", ret); - BUG(); - } - dbg("port %d status %d speed %d devid %x", - port, status, speed, devid); - dbg("socket %lx lbusid %s", socket, lbusid); + if (ctx->controller == 0) + strcpy(name, "status"); + else + snprintf(name, MAX_STATUS_NAME + 1, + "status.%d", ctx->controller); + ctx->c = udev_device_get_sysattr_value(vhci_hc_device, name); + if (ctx->c == NULL) + return -1; + return 0; +} - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; +static void close_status(struct status_context *ctx) +{ + ctx->c = NULL; +} - idev->port = po
[PATCH v11 5/9] usbip: exporting devices: modifications to daemon
Refactoring to the daemon. usbipd_dev.c is device-side specific code extracted from usbipd.c. usbipd.c is left as common parts for both device(stub)-side and application(vhci)-side daemon. usbip_net_set_nodelay() is the middle of device side daemon operation and it does not make mush sence. In the client operation, it's in right after connect(). So, in daemon, it is moved to right after accept() to affect it both device and application side. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/doc/usbipd.8 | 1 - tools/usb/usbip/src/Makefile.am | 2 +- tools/usb/usbip/src/usbipd.c | 246 -- tools/usb/usbip/src/usbipd.h | 39 + tools/usb/usbip/src/usbipd_dev.c | 252 +++ 5 files changed, 319 insertions(+), 221 deletions(-) diff --git a/tools/usb/usbip/doc/usbipd.8 b/tools/usb/usbip/doc/usbipd.8 index ac4635d..6e1a008 100644 --- a/tools/usb/usbip/doc/usbipd.8 +++ b/tools/usb/usbip/doc/usbipd.8 @@ -88,4 +88,3 @@ USB/IP client can connect and use exported devices. .SH "SEE ALSO" \fBusbip\fP\fB(8)\fB\fP - diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 42760c3..1aa5156 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -9,4 +9,4 @@ usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c -usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c +usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index a0972de..4b15bb1 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -43,25 +44,19 @@ #include #include -#include "usbip_host_driver.h" -#include "usbip_host_common.h" -#include "usbip_device_driver.h" #include "usbip_common.h" #include "usbip_network.h" +#include "usbipd.h" #include "list.h" -#undef PROGNAME -#define PROGNAME "usbipd" #define MAXSOCKFD 20 #define MAIN_LOOP_TIMEOUT 10 -#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" - static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options]\n" + "usage: %s [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" @@ -82,7 +77,7 @@ static const char usbipd_help_string[] = "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" - " If no FILE specified, use " DEFAULT_PID_FILE "\n" + " If no FILE specified, use %s.\n" "\n" " -tPORT, --tcp-port PORT\n" " Listen on TCP/IP port PORT.\n" @@ -93,198 +88,9 @@ static const char usbipd_help_string[] = " -v, --version\n" " Show version.\n"; -static struct usbip_host_driver *driver; - static void usbipd_help(void) { - printf("%s\n", usbipd_help_string); -} - -static int recv_request_import(int sockfd) -{ - struct op_import_request req; - struct usbip_exported_device *edev; - struct usbip_usb_device pdu_udev; - struct list_head *i; - int found = 0; - int error = 0; - int rc; - - memset(, 0, sizeof(req)); - - rc = usbip_net_recv(sockfd, , sizeof(req)); - if (rc < 0) { - dbg("usbip_net_recv failed: import request"); - return -1; - } - PACK_OP_IMPORT_REQUEST(0, ); - - list_for_each(i, >edev_list) { - edev = list_entry(i, struct usbip_exported_device, node); - if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { - info("found requested device: %s", req.busid); - found = 1; - break; - } - } - - if (found) { - /* should set TCP_NODELAY for usbip */ - usbip_net_set_nodelay(sockfd); - - /* export device needs a TCP/IP socket descriptor */ - rc = usbip_export_device(edev, sockfd); - if (rc < 0) - erro
[PATCH v11 7/9] usbip: exporting devices: new application-side daemon
New application(vhci)-side daemon. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 19 +++ tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/Makefile.am | 7 +- tools/usb/usbip/src/usbipd.c | 12 +- tools/usb/usbip/src/usbipd_app.c | 242 +++ 5 files changed, 279 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index b7ca63d..50c723d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -314,6 +314,25 @@ int usbip_vhci_get_free_port(void) return -1; } +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid) +{ + int ret; + char rhost[NI_MAXHOST] = "unknown host"; + char rserv[NI_MAXSERV] = "unknown port"; + char rbusid[SYSFS_BUS_ID_SIZE]; + + for (int i = 0; i < vhci_driver->nports; i++) { + ret = read_record(vhci_driver->idev[i].port, rhost, NI_MAXHOST, + rserv, NI_MAXSERV, rbusid); + if (!ret && + !strncmp(host, rhost, NI_MAXHOST) && + !strncmp(busid, rbusid, SYSFS_BUS_ID_SIZE)) { + return vhci_driver->idev + i; + } + } + return NULL; +} + int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed) { char buff[200]; /* what size should be ? */ diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index f955ada..acb427d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -46,6 +46,7 @@ int usbip_vhci_refresh_device_list(void); int usbip_vhci_get_free_port(void); +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid); int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed); diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 1aa5156..8fdebce 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -2,11 +2,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' AM_CFLAGS = @EXTRA_CFLAGS@ LDADD = $(top_builddir)/libsrc/libusbip.la -sbin_PROGRAMS := usbip usbipd +sbin_PROGRAMS := usbip usbipd usbipa usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c +usbip_CFLAGS := $(AM_CFLAGS) usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c +usbipd_CFLAGS := $(AM_CFLAGS) + +usbipa_SOURCES := usbip_network.h usbipd.c usbipd_app.c usbip_network.c +usbipa_CFLAGS := $(AM_CFLAGS) -DUSBIP_DAEMON_APP diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 4b15bb1..5f6b040 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -64,11 +64,13 @@ static const char usbipd_help_string[] = " -6, --ipv6\n" " Bind to IPv6. Default is both.\n" "\n" +#ifndef USBIP_DAEMON_APP " -e, --device\n" " Run in device mode.\n" " Rather than drive an attached device, create\n" " a virtual UDC to bind gadgets to.\n" "\n" +#endif " -D, --daemon\n" " Run as a daemon process.\n" "\n" @@ -404,7 +406,9 @@ int main(int argc, char *argv[]) { "ipv6", no_argument, NULL, '6' }, { "daemon", no_argument, NULL, 'D' }, { "debug",no_argument, NULL, 'd' }, +#ifndef USBIP_DAEMON_APP { "device", no_argument, NULL, 'e' }, +#endif { "pid", optional_argument, NULL, 'P' }, { "tcp-port", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, @@ -433,7 +437,11 @@ int main(int argc, char *argv[]) cmd = cmd_standalone_mode; usbip_init_driver(); for (;;) { - opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL); + opt = getopt_long(argc, argv, "46Dd" +#ifndef USBIP_DAEMON_APP + "e" +#endif + "P::t:hv", longopts, NULL); if (opt == -1) break; @@ -463,9 +471,11 @@ int mai
[PATCH v11 0/9] usbip: exporting devices
nd internally. With vUDC, they do not execute bind and unbind. They are done by UDC interface. 4. Security consideration Daemons accept following requests form network : EXISTING) 'list --remote' and 'attach' NEW) 'connect' and 'desconnect' TCP wrappers allows and/or denies network access. It is enabled when the daemons are compiled with ./configure --with-tcp-wrappers. When the daemons are running with SSL or Secure WebSocket tunneling proxy, the proxy can use client authentication with certificate files. 5. Mixed usage Both existing and new way work in same machines simultaneously. Status of devices and ports are controlled in stub and vhci driver. 6. Wording Adding the new operation, some inconsistnecies in wording are appeared in documentation, function name, etc. If needed, they are fixed. 'export' is used for bind and 'exported' is used for bound. They are changed to 'make importable' and 'imported' respectively. The words not new. For example, in the output of port operation, 'imported devices' is already used. They are sorted out. 'client' and 'server' are switched between existing and new operation. So, words 'device-side' and 'application-side' are used in documentations as needed for clarity. --- Version information This series is divided from "USB/IP over WebSocket" patch set. Rest of the set will be sent as another series. v11) # Corrected program name of each daemon which are used in version string, info messages and daemon name for tcp wrappers. # Added description about tcp wrappers in security consideration of cover letter. # Added security consideration for existing requests in contradistinction to new requests. # Recreated based on linux-next 20160928. v10) # Recreated based on linux-next 20160810. v9) # Moved a set_nodelay() from usbipd_dev.c to usbipd.c to affect both device side and application side daemon. # Removed redundant blank line at the end of files. v8) # Divided into smaller patches. # Excluded low-related patches. # Improved change log. # Changed info level logs in usbip_ux.c to debug level logs. # Added options to vUDC. # Tested with vUDC. v7) # Removed userspace transmission and WebSocket command/daemon. # Fixed checkpatch errors and warnings. v6) # Added __rcu annotation to a RCU pointer to clear sparse warnings. # Corrected a copy to RCU pointer with rcu_rcu_assign_pointer(). # Added __user annotations to arguments of read/write method. # Added static to some functions which are not called from other files. # Removed unnecessary EXPORT_SYMBOLs. v5) # Added vendor/pruduct name conversion to port command. # Put initial value to pool_head in name.c. # Fixed list command exception when host option is omitted. # Fixed exception in case gai_strerror() returns NULL. # Fixed WebSocket connection close via proxy. # Fixed to stop WebSocket ping-pong on connection close. # Removed redundant usbipd daemon option. # Removed redundant SSL code had not been deleted. # Removed an unused local variable in WebSocket code. # Modified C++ reserved word in names.c as same as headers. v4) # Fixed regression of usbip list --remote v3) # Coding style for goto err labels are fixed. # Defined magic numbers for open_hc_device() argument. # Corrected include .../uapi/linux/usbip_ux.h as . # Modified parameter notation in manuals not to use '='. # Fixed inappropriate version definition in tools/.../websocket/configure.ac. # Remved unnecessary COPYING and AUTHORS fil from tools/.../websocket/. # Added -version-info to libraries in tools/.../src. v2) # Formatted patches from linux-next. # Fixed change log word wrapping. # Removed SSL patches. # Fixed a bug that vendor and product names are not shown by 'usbws list -l' because usbip_names_init() was not called in libusbip.la. Thank you, Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> // *** BLURB HERE *** Nobuo Iwata (9): usbip: exporting devices: modifications to network header usbip: exporting devices: modifications to host side libraries usbip: exporting devices: new connect operation usbip: exporting devices: new disconnect operation usbip: exporting devices: modifications to daemon usbip: exporting devices: modifications to attach and detach usbip: exporting devices: new application-side daemon usbip: exporting devices: change to usbip_list.c usbip: exporting devices: chage to documenattion Documentation/usb/usbip_protocol.txt | 204 ++-- tools/usb/usbip/Makefile.am| 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8| 136 +-- tools/usb/usbip/doc/usbipa.8 | 78 +++ tools/usb/usbip/doc/usbipd.8 | 38 +-- tools/usb/usbip/libsrc/usbip_host_common.c | 6 +- tools/usb/usbip/libsrc/usbip_host_common.h | 8 +- tools/usb/usbip/libsrc/vhci_driver.c | 118 -- tools/usb/usbip/libsrc/vhci_driver.h | 7 +- tools/usb/usbip/sr
[PATCH v11 8/9] usbip: exporting devices: change to usbip_list.c
Correction to wording inconsistency around import and export in usbip_list.c. Please, see also cover letter about wording. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_list.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index f1b38e8..37f9afa 100644 --- a/tools/usb/usbip/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -42,9 +43,9 @@ #include "usbip.h" static const char usbip_list_usage_string[] = - "usbip list [-p|--parsable] \n" + "usbip list \n" "-p, --parsable Parsable list format\n" - "-r, --remote=List the exportable USB devices on \n" + "-r, --remote=List the importable USB devices on \n" "-l, --localList the local USB devices\n"; void usbip_list_usage(void) @@ -52,7 +53,7 @@ void usbip_list_usage(void) printf("usage: %s", usbip_list_usage_string); } -static int get_exported_devices(char *host, int sockfd) +static int get_importable_devices(char *host, int sockfd) { char product_name[100]; char class_name[100]; @@ -82,14 +83,14 @@ static int get_exported_devices(char *host, int sockfd) return -1; } PACK_OP_DEVLIST_REPLY(0, ); - dbg("exportable devices: %d\n", reply.ndev); + dbg("importable devices: %d\n", reply.ndev); if (reply.ndev == 0) { - info("no exportable devices found on %s", host); + info("no importable devices found on %s", host); return 0; } - printf("Exportable USB devices\n"); + printf("Importable USB devices\n"); printf("==\n"); printf(" - %s\n", host); @@ -134,7 +135,7 @@ static int get_exported_devices(char *host, int sockfd) return 0; } -static int list_exported_devices(char *host) +static int list_importable_devices(char *host) { int rc; int sockfd; @@ -147,9 +148,10 @@ static int list_exported_devices(char *host) } dbg("connected to %s:%s", host, usbip_port_string); - rc = get_exported_devices(host, sockfd); + rc = get_importable_devices(host, sockfd); if (rc < 0) { err("failed to get device list from %s", host); + close(sockfd); return -1; } @@ -351,7 +353,7 @@ int usbip_list(int argc, char *argv[]) parsable = true; break; case 'r': - ret = list_exported_devices(optarg); + ret = list_importable_devices(optarg); goto out; case 'l': ret = list_devices(parsable); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v6 0/2] usbip: vhci number of ports extension
This series of patches extends number of ports limitaion in application (vhci) side. 1. Background Assuming a system shown below that services distributerd devices in home or office via USB/IP, if the devices are set at every doors and windows, number devices may be up to tens. Home/SOHO/Enterprise Intranet/Internet +--+ +--+ USB/IP+-+ +|device|--+|Linux |---|Service | |+--+ |+--+---|on Linux | +--+ +--++-+ ex) Device Service sensors ... environment analysis cameras ... monitoring, recording ID/biometric readers .. authentication If USB/IP is used for ubiqitous devices or IoT devices, many devices might be handled. 2. About this patch set In current USB/IP, available number of ports (ie. number of supported devices) is VHCI_NPORTS(8) in drivers/usb/usbip/vhci.h. The value of the macro can be altered to USB_MAXCHILDREN(31). This limit is came from hub status bit array. See also the comment at USB_MAXCHILDREN include/uapi/linux/usb/ch11.h. There are two way to increase number of available ports. The first way is to put hub emulator under vhci. This can add ports up to 255 - the limit of USB 2.0 host controller. The second way is to add host controller. It's as same as machines have several host controllers: most desktop or note PCs have more than one host controller. Current USB/IP supports only one controller defined as 'the_controller' in drivers/usb/usbip/vhci_hcd.c. This patch takes the second way described above and adds virtual controllers. In this patch, the number is specified by kernel configuration. 3. Dynamic extension According to kernel configuration, vhci devices (platform device) will be added and removed when they are not used. When the vhci driver is loaded, USBIP_VHCI_INIT_HCS (default is 1) drivers are registered. They will be further registered upto USBIP_VHCI_MAX_HCS (default is 1). They are unregistered when number of free devices becomes more than VHCI_FREE_HCS(2) except the first device. 4. Wording Wording inconsistencies in function and variable names are corrected according to the rule below. They were not strict because only one host controller was handled. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. 5. Dependencies This series depends on 'usbip: exporting devices' patch set because this includes changes to application side daemon which introduced the patch set. --- Version information v6) # Recreated based on linux-next 20160928. # Was '3/1 usbip: vhci extension: modifications to vhci driver' is excluded because it has been merged. v5) # Fixed dynamically allocated sysfs attribute checking error when CONFIG_DEBUG_LOCK_ALLOC is set. # Recreated based on linux-next 20160810. v4) # Changed the method to set number of controllers from a module parameter to kernel config. # Excluded event thread patch merged to 4.7-rc1. # Added dynamic extension. v3) # Fixed conflicts against linux-next 20160209. # Changed sysfs object and attribute name for old tools compatibility. # Changed nports status format not to include num_controllers value. # Fixed checkpatch errors and warnings. v2) # Added static to some functions and variables not called from other files. *** BLURB HERE *** Nobuo Iwata (2): usbip: vhci extension: modifications to userspace usbip: vhci extension: dynamic extension drivers/usb/usbip/Kconfig| 17 +- drivers/usb/usbip/vhci.h | 36 ++- drivers/usb/usbip/vhci_hcd.c | 250 ++--- drivers/usb/usbip/vhci_rx.c | 10 +- drivers/usb/usbip/vhci_sysfs.c | 49 ++-- drivers/usb/usbip/vhci_tx.c | 6 +- tools/usb/usbip/libsrc/vhci_driver.c | 398 +++ tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 48 ++-- 11 files changed, 546 insertions(+), 334 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 1/1] usbip: deletion of incorrect socket descriptor checking
This patch removes checking of socket descriptor value in daemons. It was checked to be less than FD_SETSIZE(1024 usually) but it's not correct. To be exact, the maximum value of descriptor comes from rlimit(RLIMIT_NOFILE). Following kernel code determines the value : get_unused_fd_flags() : fs/files.c __alloc_fd() : fs/files.c expand_files() : fs/files.c The defalut (soft limit) is defines as INR_OPEN_CUR(1024) in include/linux/fs.h which is referenced form INIT_RLIMS in include/asm-generic/resource.h. The value may be modified with ulimt, sysctl, security configuration and etc. With the kernel code above, when socket() system call returns positive value, the value must be within rlimit(RLIMIT_NOFILE). No extra checking is needed when socket() returns positive. Without 'usbip: vhci number of ports extension' patch set, there's no practical problem because of number of USB port restriction. With the patch set, the value of socket descriptor can exceed FD_SETSIZE(1024 usually) if the rlimit is changed. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbipd.c | 7 --- 1 file changed, 7 deletions(-) diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 5f6b040..8fe89d9 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -209,13 +209,6 @@ static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[], * (see do_standalone_mode()) */ usbip_net_set_v6only(sock); - if (sock >= FD_SETSIZE) { - err("FD_SETSIZE: %s: sock=%d, max=%d", - ai_buf, sock, FD_SETSIZE); - close(sock); - continue; - } - ret = bind(sock, ai->ai_addr, ai->ai_addrlen); if (ret < 0) { err("bind: %s: %d (%s)", -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v11 2/9] usbip: exporting devices: modifications to host side libraries
usbip_get_device() method in usbip_host_driver_ops was not used. It is modified as a function to find an exported device for new operations 'connect' and 'disconnect'. bind and unbind function are exported for the new operations. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/usbip_host_common.c | 6 ++ tools/usb/usbip/libsrc/usbip_host_common.h | 8 tools/usb/usbip/src/usbip.h| 3 +++ tools/usb/usbip/src/usbip_bind.c | 7 --- tools/usb/usbip/src/usbip_unbind.c | 7 --- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..6a98d6c 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -256,17 +256,15 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num) + struct usbip_host_driver *hdriver, char *busid) { struct list_head *i; struct usbip_exported_device *edev; - int cnt = 0; list_for_each(i, >edev_list) { edev = list_entry(i, struct usbip_exported_device, node); - if (num == cnt) + if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) return edev; - cnt++; } return NULL; diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h index a64b803..f9a9def 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.h +++ b/tools/usb/usbip/libsrc/usbip_host_common.h @@ -38,7 +38,7 @@ struct usbip_host_driver_ops { void (*close)(struct usbip_host_driver *hdriver); int (*refresh_device_list)(struct usbip_host_driver *hdriver); struct usbip_exported_device * (*get_device)( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); int (*read_device)(struct udev_device *sdev, struct usbip_usb_device *dev); @@ -86,11 +86,11 @@ static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver) } static inline struct usbip_exported_device * -usbip_get_device(struct usbip_host_driver *hdriver, int num) +usbip_get_device(struct usbip_host_driver *hdriver, char *busid) { if (!hdriver->ops.get_device) return NULL; - return hdriver->ops.get_device(hdriver, num); + return hdriver->ops.get_device(hdriver, busid); } /* Helper functions for implementing driver backend */ @@ -99,6 +99,6 @@ void usbip_generic_driver_close(struct usbip_host_driver *hdriver); int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver); int usbip_export_device(struct usbip_exported_device *edev, int sockfd); struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); #endif /* __USBIP_HOST_COMMON_H */ diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a..c296910 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -37,4 +37,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); +int usbip_bind_device(char *busid); +int usbip_unbind_device(char *busid); + #endif /* __USBIP_H */ diff --git a/tools/usb/usbip/src/usbip_bind.c b/tools/usb/usbip/src/usbip_bind.c index fa46141..1c09338 100644 --- a/tools/usb/usbip/src/usbip_bind.c +++ b/tools/usb/usbip/src/usbip_bind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -139,7 +140,7 @@ static int unbind_other(char *busid) return status; } -static int bind_device(char *busid) +int usbip_bind_device(char *busid) { int rc; struct udev *udev; @@ -200,7 +201,7 @@ int usbip_bind(int argc, char *argv[]) switch (opt) { case 'b': - ret = bind_device(optarg); + ret = usbip_bind_device(optarg); goto out; default: goto err_out; diff --git a/tools/usb/usbip/src/usbip_unbind.c b/tools/usb/usbip/src/usbip_unbind.c index a4a496c..cc1ff26 100644 --- a/tools/usb/usbip/src/usbip_unbind.c +++ b/tools/usb/usbip/src/usbip_unbind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + *
[PATCH v11 9/9] usbip: exporting devices: chage to documenattion
This patch adds function and usage of new connect operation, disconnect operation and application(vhci)-side daemon to README and manuals. At this point, the wording, 'server' and 'client' are ambiguous in several place. For existing attach command, the daemon runs device side machine and attach command is executed in application side machine. Then 'server' is used for device side and 'client' is for application side. For the new connect command, the daemon runs applications side machine and connect command is executed in device side machine. Now, 'server' and 'client' run in different machine than before. So, to avoid confusion, words 'device side (machine)' and 'application side (machine)' are used instead of 'client' and 'server' as needed. Please, see also diagrams in the cover letter. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/Makefile.am | 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8 | 136 --- tools/usb/usbip/doc/usbipa.8 | 78 tools/usb/usbip/doc/usbipd.8 | 37 ++ 5 files changed, 263 insertions(+), 60 deletions(-) diff --git a/tools/usb/usbip/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf0..f371ed9 100644 --- a/tools/usb/usbip/Makefile.am +++ b/tools/usb/usbip/Makefile.am @@ -3,4 +3,4 @@ includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ usbip_common.h vhci_driver.h usbip_host_driver.h) -dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) +dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbipa.8) diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 831f49f..74f4afb 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -1,7 +1,8 @@ # # README for usbip-utils # -# Copyright (C) 2011 matt mooney <m...@muteddisk.com> +# Copyright (C) 2015 Nobuo Iwata +# 2011 matt mooney <m...@muteddisk.com> # 2005-2008 Takahiro Hirofuchi @@ -36,41 +37,70 @@ [Usage] -server:# (Physically attach your USB device.) +Device-side: a machine has USB device(s). +Application-side: a machine runs an application software uses remote USB device. -server:# insmod usbip-core.ko -server:# insmod usbip-host.ko +1) Connect from application-side to device-side. -server:# usbipd -D +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbipd -D - Start usbip daemon. -server:# usbip list -l - - List driver assignments for USB devices. +dev:# usbip list -l + - List driver assignments for USB devices and their busid. -server:# usbip bind --busid 1-2 - - Bind usbip-host.ko to the device with busid 1-2. - - The USB device 1-2 is now exportable to other hosts! - - Use `usbip unbind --busid 1-2' to stop exporting the device. +dev:# usbip bind --busid + - Bind usbip-host.ko to the device with . + - The USB device with is now exportable to other hosts! + - Use `usbip unbind --busid ` to stop exporting the device. -client:# insmod usbip-core.ko -client:# insmod vhci-hcd.ko +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko -client:# usbip list --remote +app:# usbip list --remote - List exported USB devices on the . -client:# usbip attach --remote --busid 1-2 +app:# usbip attach --remote --busid - Connect the remote USB device. -client:# usbip port +app:# usbip port - Show virtual port status. -client:# usbip detach --port +app:# usbip detach --port - Detach the USB device. +2) Connect from device-side to application-side. + +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko + +app:# usbipa -D + - Start usbip daemon. + +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbip list -l + - List driver assignments for USB devices and their busid. + +dev:# usbip connect --remote --busid + - Bind usbip-host.ko to the device with . + - The USB device of is connected to remote host! + +dev:# usbip disconnect --remote --busid + - The USB device with is disconnected from remote host. + - Unbind usbip-host.ko from the device. + [Example] --- - SERVER SIDE + DEVICE SIDE --- Physically attach your USB devices to this host. @@ -131,7 +161,7 @@ Mark the device of busid 3-3.2 as exportable: ... --- - CLIENT SIDE + APPLICATION SIDE --- First, let's list available remote devices that are marked as exportable on the host. @@ -170,7 +200,7 @@ Attach a remote USB device: deux:# usbip attach --remote 10.0.0.3 --bus
[PATCH v6 2/2] usbip: vhci extension: dynamic extension
Modification for dynamic device registration and unregistration. 1. kernel config Followings are added. USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host controller. The default is 8 - same as current VHCI_NPORTS. USBIP_VHCI_MAX_HCS: Muximum number of USB/IP virtual host controllers. The default is 1. USBIP_VHCI_INIT_HCS: Initial number of USB/IP virtual host controllers. The default is 1. Static number of devices: USBIP_VHCI_NR_HCS in patch 1/3 is removed with this patch. 2. view from sysfs Sysfs structure is changed as following. BEFORE this patchset: /sys/devices/platform +-- vhci +-- status +-- attach +-- detach +-- usbip_debug AFTER: example for CONFIG_USBIP_INIT_HCS=2 CONFIG_USBIP_MAX_HCS=4 At the beginning /sys/devices/platform +-- vhci | +-- nports | +-- status | +-- status.1 | +-- status.2 | +-- status.3 | +-- attach | +-- detach | +-- usbip_debug +-- vhci.1 The status files are shown to the maximum number of devices. Port status in status.2 and status.3 represents as free but corresponding devices are not yes registered. When all ports in status and status.1 are used, userspace tool requests 'attach' to a port in status.2 then vhci.2 will be registred. The limit is defined with USBIP_VHCI_MAX_NCS. By preparing muximum number of status files, there's no need to introduce additional operations for userspace tool. When number of free ports becomes more than USBIP_VHCI_HC_PORTS * VHCI_FREE_HCS(2), a free controller other than the first one will be unregistered. It will be invoked by 'detach' operation and other error situations which ports are released. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/Kconfig | 17 ++- drivers/usb/usbip/vhci.h | 36 - drivers/usb/usbip/vhci_hcd.c | 250 - drivers/usb/usbip/vhci_rx.c| 10 +- drivers/usb/usbip/vhci_sysfs.c | 49 --- drivers/usb/usbip/vhci_tx.c| 6 +- 6 files changed, 293 insertions(+), 75 deletions(-) diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index 29492c7..d11b548 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -34,8 +34,8 @@ config USBIP_VHCI_HC_PORTS host controller driver, this defines number of ports per USB/IP virtual host controller. -config USBIP_VHCI_NR_HCS - int "Number of USB/IP virtual host controllers" +config USBIP_VHCI_MAX_HCS + int "Maximum number of USB/IP virtual host controllers" range 1 128 default 1 depends on USBIP_VHCI_HCD @@ -43,7 +43,18 @@ config USBIP_VHCI_NR_HCS To increase number of ports available for USB/IP virtual host controller driver, this defines number of USB/IP virtual host controllers as if adding physical host - controllers. + controllers. This defines the maximum number. + +config USBIP_VHCI_INIT_HCS + int "Initial number of USB/IP virtual host controllers" + range 1 USBIP_VHCI_MAX_HCS + default 1 + depends on USBIP_VHCI_MAX_HCS + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of USB/IP + virtual host controllers as if adding physical host + controllers. This defines the number at initializing. config USBIP_HOST tristate "Host driver" diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..ba893a7 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -51,6 +51,9 @@ struct vhci_device { /* vhci_tx thread sleeps for this queue */ wait_queue_head_t waitq_tx; + + /* denotes port is in-use */ + atomic_t using_port; }; /* urb->hcpriv, use container_of() */ @@ -79,12 +82,21 @@ struct vhci_unlink { #define VHCI_HC_PORTS 8 #endif -#ifdef CONFIG_USBIP_VHCI_NR_HCS -#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS +#ifdef CONFIG_USBIP_VHCI_MAX_HCS +#define VHCI_MAX_HCS CONFIG_USBIP_VHCI_MAX_HCS +#else +#define VHCI_MAX_HCS 1 +#endif + +#ifdef CONFIG_USBIP_VHCI_INIT_HCS +#define VHCI_INIT_HCS CONFIG_USBIP_VHCI_INIT_HCS #else -#define VHCI_NR_HCS 1 +#define VHCI_INIT_HCS 1 #endif +/* VHCI_FREE_HCS * VHCI_HC_PORTS: ports to keep free at unregister */ +#define VHCI_FREE_HCS 2 + #define MAX_STATUS_NAME 16 /* for usb_bus.hcpriv */ @@ -98,6 +110,8 @@ struct vhci_hcd { atomic_t seqnum; + unsigned int using_ports; + /* * NOTE: * wIndex shows the port number and begins from 1. @@ -106,12 +120,18 @@ struct vhci_hcd { struct vhci_device vdev[VHCI_HC_PORTS]; }; +extern int vhci_max_controllers; +extern int vhci_init_controllers; extern int vhci_num_controllers; extern st
[PATCH v11 4/9] usbip: exporting devices: new disconnect operation
New disconnect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am| 2 +- tools/usb/usbip/src/usbip.c| 6 + tools/usb/usbip/src/usbip.h| 2 + tools/usb/usbip/src/usbip_disconnect.c | 215 + 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 0947476..42760c3 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ -usbip_connect.c +usbip_connect.c usbip_disconnect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index 584d7d5..f0e9e06 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -83,6 +83,12 @@ static const struct command cmds[] = { .usage = usbip_connect_usage }, { + .name = "disconnect", + .fn= usbip_disconnect, + .help = "Disconnect a USB device from a remote computer", + .usage = usbip_disconnect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index f365353..a8cbd16 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); int usbip_connect(int argc, char *argv[]); +int usbip_disconnect(int argc, char *argv[]); void usbip_attach_usage(void); void usbip_detach_usage(void); @@ -39,6 +40,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); void usbip_connect_usage(void); +void usbip_disconnect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_disconnect.c b/tools/usb/usbip/src/usbip_disconnect.c new file mode 100644 index 000..8155384 --- /dev/null +++ b/tools/usb/usbip/src/usbip_disconnect.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_disconnect_usage_string[] = + "usbip disconnect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be disconnected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_disconnect_usage(void) +{ + printf("usage: %s", usbip_disconnect_usage_string); +} + +static int send_unexport_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_unexport_request request; + struct op_unexport_reply reply; + uint16_t code = OP_REP_UNEXPORT; + + memset(, 0, sizeof(request)); + memset(, 0, sizeof(reply)); + + /* send a request */ + rc = usbip_net_send_op_common(sockfd, OP_REQ_UNEXPORT, 0); + if (rc < 0) { + err("send op_common"); + return -1; + } + + memcpy(, udev, sizeof(struct usbip_usb_device)); + + PACK_OP_UNEXPORT_REQUEST(0, ); + + rc = usbip_net_send(sockfd, (void *) , sizeof(request)); + if (rc < 0) { + err("send op_export_request"); +
[PATCH v11 1/9] usbip: exporting devices: modifications to network header
Modification to export and un-export response in tools/usb/usbip/src/usbip_network.h. It just changes return code type from int to uint32_t as same as other responses. Added export and un-export request/response to Documentation/usb/usbip_protocol.txt. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Documentation/usb/usbip_protocol.txt | 204 --- tools/usb/usbip/src/usbip_network.h | 5 +- 2 files changed, 184 insertions(+), 25 deletions(-) diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe2..d4be5b6 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -1,20 +1,26 @@ PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! 28 Jun 2011 +MODIFIED FOR CONNECT AND DISCONNECT OPERARION. +07 March 2016 -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. +The USB/IP protocol follows a server/client architecture between two computers +one has USB devices and the other runs application using the devices. There are +two ways for initiation. -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. +The first way is to import devices from application-side. In this way, the +server runs in device-side and the client runs in application-side. In device +side user makes devices importable with 'bind' operation. +The client may ask for the list of the importable USB devices. To get the list +the client opens a TCP/IP connection towards the server, and sends an +OP_REQ_DEVLIST packet on top of the TCP/IP connection (so the actual +OP_REQ_DEVLIST may be sent in one or more pieces at the low level transport +layer). The server sends back the OP_REP_DEVLIST packet which lists the +importable USB devices. Finally the TCP/IP connection is closed. + + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (lists importable devices)"server" | | | OP_REQ_DEVLIST | | --> | @@ -23,18 +29,13 @@ TCP/IP connection is closed. | <-- | | | -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. +Once the client knows the list of importable USB devices it may decide to use +one of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (imports a USB device) "server" | | | OP_REQ_IMPORT | | --> | @@ -42,6 +43,32 @@ server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | OP_REP_IMPORT | | <-- | | | + +The second way is to export devices from device-side. In this way, the server +runs in application-side and the client runs in device-side. The client binds a +device to export, opens a TCP/IP connection towards the server
[PATCH v11 3/9] usbip: exporting devices: new connect operation
New connect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 3 +- tools/usb/usbip/src/usbip.c | 9 +- tools/usb/usbip/src/usbip.h | 5 +- tools/usb/usbip/src/usbip_connect.c | 228 4 files changed, 242 insertions(+), 3 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4eb..0947476 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ -usbip_bind.c usbip_unbind.c usbip_port.c +usbip_bind.c usbip_unbind.c usbip_port.c \ +usbip_connect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d9..584d7d5 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -2,7 +2,8 @@ * command structure borrowed from udev * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) * - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -76,6 +77,12 @@ static const struct command cmds[] = { .usage = usbip_detach_usage }, { + .name = "connect", + .fn= usbip_connect, + .help = "Connect a USB device to a remote computer", + .usage = usbip_connect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index c296910..f365353 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -30,12 +31,14 @@ int usbip_list(int argc, char *argv[]); int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); +int usbip_connect(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); +void usbip_connect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_connect.c b/tools/usb/usbip/src/usbip_connect.c new file mode 100644 index 000..bbecc7e --- /dev/null +++ b/tools/usb/usbip/src/usbip_connect.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_connect_usage_string[] = + "usbip connect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be connected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_connect_usage(void) +{ + printf("usage: %s", usbip_connect_usage_string); +} + +static int send_export_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_export_request request; + struct op_export_reply reply
[PATCH v11 6/9] usbip: exporting devices: modifications to attach and detach
Refactoring to attach and detatch operation. Common parts to new application(vhci)-side daemon are moved to libsrc/vhci_driver.c. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 99 tools/usb/usbip/libsrc/vhci_driver.h | 6 +- tools/usb/usbip/src/usbip_attach.c | 50 ++ tools/usb/usbip/src/usbip_detach.c | 13 ++-- 4 files changed, 100 insertions(+), 68 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..b7ca63d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata + * 2005-2007 Takahiro Hirofuchi */ #include "usbip_common.h" @@ -7,6 +8,8 @@ #include #include #include +#include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -215,6 +218,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +#define OPEN_HC_MODE_FIRST 0 +#define OPEN_HC_MODE_REOPEN1 + +static int open_hc_device(int mode) +{ + if (mode == OPEN_HC_MODE_REOPEN) + udev_device_unref(vhci_driver->hc_device); + + vhci_driver->hc_device = + udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + USBIP_VHCI_DRV_NAME); + if (!vhci_driver->hc_device) { + err("udev_device_new_from_subsystem_sysname failed"); + return -1; + } + return 0; +} + /* -- */ int usbip_vhci_driver_open(void) @@ -227,28 +249,21 @@ int usbip_vhci_driver_open(void) vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); - if (!vhci_driver->hc_device) { - err("udev_device_new_from_subsystem_sysname failed"); - goto err; - } + if (open_hc_device(OPEN_HC_MODE_FIRST)) + goto err_free_driver; vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); if (refresh_imported_device_list()) - goto err; + goto err_unref_device; return 0; -err: +err_unref_device: udev_device_unref(vhci_driver->hc_device); - +err_free_driver: if (vhci_driver) free(vhci_driver); @@ -277,7 +292,8 @@ void usbip_vhci_driver_close(void) int usbip_vhci_refresh_device_list(void) { - + if (open_hc_device(OPEN_HC_MODE_REOPEN)) + goto err; if (refresh_imported_device_list()) goto err; @@ -409,3 +425,58 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) return 0; } + +#define MAX_BUFF 100 +int usbip_vhci_create_record(char *host, char *port, char *busid, int rhport) +{ + int fd; + char path[PATH_MAX+1]; + char buff[MAX_BUFF+1]; + int ret; + + ret = mkdir(VHCI_STATE_PATH, 0700); + if (ret < 0) { + /* if VHCI_STATE_PATH exists, then it better be a directory */ + if (errno == EEXIST) { + struct stat s; + + ret = stat(VHCI_STATE_PATH, ); + if (ret < 0) + return -1; + if (!(s.st_mode & S_IFDIR)) + return -1; + } else + return -1; + } + + 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; +} + +int usbip_vhci_delete_record(int rhport) +{ + char path[PATH_MAX+1]; + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + + remove(path); + rmdir(VHCI_STATE_PATH); + + return 0; +} diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..f955ada 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/too
[PATCH v5 3/3] usbip: vhci extension: dynamic extension
Modification for dynamic device registration and unregistration. 1. kernel config Followings are added. USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host controller. The default is 8 - same as current VHCI_NPORTS. USBIP_VHCI_MAX_HCS: Muximum number of USB/IP virtual host controllers. The default is 1. USBIP_VHCI_INIT_HCS: Initial number of USB/IP virtual host controllers. The default is 1. Static number of devices: USBIP_VHCI_NR_HCS in patch 1/3 is removed with this patch. 2. view from sysfs Sysfs structure is changed as following. BEFORE this patchset: /sys/devices/platform +-- vhci +-- status +-- attach +-- detach +-- usbip_debug AFTER: example for CONFIG_USBIP_INIT_HCS=2 CONFIG_USBIP_MAX_HCS=4 At the beginning /sys/devices/platform +-- vhci | +-- nports | +-- status | +-- status.1 | +-- status.2 | +-- status.3 | +-- attach | +-- detach | +-- usbip_debug +-- vhci.1 The status files are shown to the maximum number of devices. Port status in status.2 and status.3 represents as free but corresponding devices are not yes registered. When all ports in status and status.1 are used, userspace tool requests 'attach' to a port in status.2 then vhci.2 will be registred. The limit is defined with USBIP_VHCI_MAX_NCS. By preparing muximum number of status files, there's no need to introduce additional operations for userspace tool. When number of free ports becomes more than USBIP_VHCI_HC_PORTS * VHCI_FREE_HCS(2), a free controller other than the first one will be unregistered. It will be invoked by 'detach' operation and other error situations which ports are released. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/Kconfig | 17 ++- drivers/usb/usbip/vhci.h | 36 - drivers/usb/usbip/vhci_hcd.c | 251 - drivers/usb/usbip/vhci_rx.c| 10 +- drivers/usb/usbip/vhci_sysfs.c | 49 --- drivers/usb/usbip/vhci_tx.c| 6 +- 6 files changed, 294 insertions(+), 75 deletions(-) diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index 29492c7..d11b548 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -34,8 +34,8 @@ config USBIP_VHCI_HC_PORTS host controller driver, this defines number of ports per USB/IP virtual host controller. -config USBIP_VHCI_NR_HCS - int "Number of USB/IP virtual host controllers" +config USBIP_VHCI_MAX_HCS + int "Maximum number of USB/IP virtual host controllers" range 1 128 default 1 depends on USBIP_VHCI_HCD @@ -43,7 +43,18 @@ config USBIP_VHCI_NR_HCS To increase number of ports available for USB/IP virtual host controller driver, this defines number of USB/IP virtual host controllers as if adding physical host - controllers. + controllers. This defines the maximum number. + +config USBIP_VHCI_INIT_HCS + int "Initial number of USB/IP virtual host controllers" + range 1 USBIP_VHCI_MAX_HCS + default 1 + depends on USBIP_VHCI_MAX_HCS + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of USB/IP + virtual host controllers as if adding physical host + controllers. This defines the number at initializing. config USBIP_HOST tristate "Host driver" diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..ba893a7 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -51,6 +51,9 @@ struct vhci_device { /* vhci_tx thread sleeps for this queue */ wait_queue_head_t waitq_tx; + + /* denotes port is in-use */ + atomic_t using_port; }; /* urb->hcpriv, use container_of() */ @@ -79,12 +82,21 @@ struct vhci_unlink { #define VHCI_HC_PORTS 8 #endif -#ifdef CONFIG_USBIP_VHCI_NR_HCS -#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS +#ifdef CONFIG_USBIP_VHCI_MAX_HCS +#define VHCI_MAX_HCS CONFIG_USBIP_VHCI_MAX_HCS +#else +#define VHCI_MAX_HCS 1 +#endif + +#ifdef CONFIG_USBIP_VHCI_INIT_HCS +#define VHCI_INIT_HCS CONFIG_USBIP_VHCI_INIT_HCS #else -#define VHCI_NR_HCS 1 +#define VHCI_INIT_HCS 1 #endif +/* VHCI_FREE_HCS * VHCI_HC_PORTS: ports to keep free at unregister */ +#define VHCI_FREE_HCS 2 + #define MAX_STATUS_NAME 16 /* for usb_bus.hcpriv */ @@ -98,6 +110,8 @@ struct vhci_hcd { atomic_t seqnum; + unsigned int using_ports; + /* * NOTE: * wIndex shows the port number and begins from 1. @@ -106,12 +120,18 @@ struct vhci_hcd { struct vhci_device vdev[VHCI_HC_PORTS]; }; +extern int vhci_max_controllers; +extern int vhci_init_controllers; extern int vhci_num_controllers; extern st
[PATCH v5 2/3] usbip: vhci extension: modifications to userspace
Modification to the userspace tools including usbip/libsrc and usbip/src. Changed corresponding to new vhci_sysfs.c. nports in sysfs is used to get total number of ports. Old get_nports() ignores the last status line because udev_device_get_sysattr_value() drops last new line. New version uses nports attribute so it's doesn't have this problem. status[.N] in sysfs are used. parse_status() which reads all status lines is broken into open, close, read-line and parse-line. Parse-line is reused to find free port and get imported device. In daemon, status was loaded into memory by usbip_vhci_refresh_device_list() at receiving every request. The loaded status is used to find free port. It is changed to read status directly to find free port. Wording inconsistencies are fixed according to the rule below. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 398 +++ tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 48 ++-- 5 files changed, 253 insertions(+), 259 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 50c723d..4d1b986 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -15,11 +15,24 @@ #undef PROGNAME #define PROGNAME "libusbip" -struct usbip_vhci_driver *vhci_driver; -struct udev *udev_context; +static struct udev_device *vhci_hc_device; +static struct udev *udev_context; +static int vhci_nports; -static struct usbip_imported_device * -imported_device_init(struct usbip_imported_device *idev, char *busid) +struct usbip_vhci_device { + int port; + uint32_t status; + + uint32_t devid; + + uint8_t busnum; + uint8_t devnum; + + /* usbip_class_device list */ + struct usbip_usb_device udev; +}; + +static int imported_device_init(struct usbip_vhci_device *vdev, char *busid) { struct udev_device *sudev; @@ -27,132 +40,131 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) "usb", busid); if (!sudev) { dbg("udev_device_new_from_subsystem_sysname failed: %s", busid); - goto err; + return -1; } - read_usb_device(sudev, >udev); + read_usb_device(sudev, >udev); udev_device_unref(sudev); - return idev; - -err: - return NULL; + return 0; } +struct status_context { + int controller; + const char *c; +}; +#define OPEN_MODE_FIRST 0 +#define OPEN_MODE_REOPEN 1 -static int parse_status(const char *value) -{ - int ret = 0; - char *c; +static int open_hc_device(int mode); +#define MAX_STATUS_NAME 16 - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); +static int open_status(struct status_context *ctx, int mode) +{ + char name[MAX_STATUS_NAME+1]; + if (mode == OPEN_MODE_FIRST) + ctx->controller = 0; + else + (ctx->controller)++; - /* skip a header line */ - c = strchr(value, '\n'); - if (!c) + if (open_hc_device(OPEN_MODE_REOPEN)) return -1; - c++; - - while (*c != '\0') { - int port, status, speed, devid; - unsigned long socket; - char lbusid[SYSFS_BUS_ID_SIZE]; - - ret = sscanf(c, "%d %d %d %x %lx %31s\n", - , , , - , , lbusid); - - if (ret < 5) { - dbg("sscanf failed: %d", ret); - BUG(); - } - dbg("port %d status %d speed %d devid %x", - port, status, speed, devid); - dbg("socket %lx lbusid %s", socket, lbusid); + if (ctx->controller == 0) + strcpy(name, "status"); + else + snprintf(name, MAX_STATUS_NAME + 1, + "status.%d", ctx->controller); + ctx->c = udev_device_get_sysattr_value(vhci_hc_device, name); + if (ctx->c == NULL) + return -1; + return 0; +} - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; +static void close_status(struct status_context *ctx) +{ + ctx->c = NULL; +} - idev->port = po
[PATCH v5 1/3] usbip: vhci extension: modifications to vhci driver
Modification to Kconfig, vhci_hc.c, vhci.h and vhci_sysfs.c. 1. kernel config Followings are added. USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host controller. The default is 8 - same as current VHCI_NPORTS. USBIP_VHCI_NR_HCS: Number of USB/IP virtual host controllers. The default is 1. This paratmeter is replaced with USBIP_VHCI_INIT_HCS and USBIP_VHCI_MAX_HCS included in succeeding dynamic extension patch. 2. the_controller to controllers the_controller is changed to vhci_pdevs: array of struct platform_device. 3. vhci_sysfs.c Sysfs structure is changed as following. BEFORE: /sys/devices/platform +-- vhci +-- status +-- attach +-- detach +-- usbip_debug AFTER: example for CONFIG_USBIP_NR_HCS=4 /sys/devices/platform +-- vhci | +-- nports | +-- status | +-- status.1 | +-- status.2 | +-- status.3 | +-- attach | +-- detach | +-- usbip_debug +-- vhci.1 +-- vhci.2 +-- vhci.3 vhci[.N] is shown for each host controller kobj. vhch.1, vhci.2, ... are shown only when CONFIG_USBIP_NR_HCS is more than 1. Only 'vhci' (without number) has user space interfaces. 'nports' is newly added to give ports-per-controller and number of controlles. Before that, number of ports is acquired by reading status lines. Status is divided for each controller to avoid page size (4KB) limitation. Old userspace tool binaries work with the first status within the first controller. Inconsistency between status header and content is fixed. 4th and 5th column are header: "dev bus" content(unused): "000 000" content(used): "%08x", devid Only 1st and 2nd column are used by program. In old version, sscanf() in parse_status expect no bus column. And bus_id string is shown in the last column. Then bus in the header is removed and unused content is replaced with 8 zeros. The sscanf() expects more than 5 columns and new has 6 columns so there's no compatibility issue in this change. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/Kconfig | 21 +++ drivers/usb/usbip/vhci.h | 54 -- drivers/usb/usbip/vhci_hcd.c | 285 --- drivers/usb/usbip/vhci_rx.c| 21 +-- drivers/usb/usbip/vhci_sysfs.c | 297 + 5 files changed, 498 insertions(+), 180 deletions(-) diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index 17646b2..29492c7 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -24,6 +24,27 @@ config USBIP_VHCI_HCD To compile this driver as a module, choose M here: the module will be called vhci-hcd. +config USBIP_VHCI_HC_PORTS + int "Number of ports per USB/IP virtual host controller" + range 1 31 + default 8 + depends on USBIP_VHCI_HCD + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of ports per + USB/IP virtual host controller. + +config USBIP_VHCI_NR_HCS + int "Number of USB/IP virtual host controllers" + range 1 128 + default 1 + depends on USBIP_VHCI_HCD + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of USB/IP + virtual host controllers as if adding physical host + controllers. + config USBIP_HOST tristate "Host driver" depends on USBIP_CORE && USB diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index a863a98..88b71c4 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2003-2008 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,13 +73,25 @@ struct vhci_unlink { }; /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ -#define VHCI_NPORTS 8 +#ifdef CONFIG_USBIP_VHCI_HC_PORTS +#define VHCI_HC_PORTS CONFIG_USBIP_VHCI_HC_PORTS +#else +#define VHCI_HC_PORTS 8 +#endif + +#ifdef CONFIG_USBIP_VHCI_NR_HCS +#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS +#else +#define VHCI_NR_HCS 1 +#endif + +#define MAX_STATUS_NAME 16 /* for usb_bus.hcpriv */ struct vhci_hcd { spinlock_t lock; - u32 port_status[VHCI_NPORTS]; + u32 port_status[VHCI_HC_PORTS]; unsigned resuming:1; unsigned long re_timeout; @@ -90,14 +103,19 @@ struct vhci_hcd { * wIndex shows the port number and begins from 1. * But, the index of this array begins from 0. */ - struct vhci_device vdev[VHCI_NPORTS]; + struct vhci_device vdev[VH
[PATCH v5 0/3] usbip: vhci number of ports extension
This series of patches extends number of ports limitaion in application (vhci) side. 1. Background Assuming a system shown below that services distributerd devices in home or office via USB/IP, if the devices are set at every doors and windows, number devices may be up to tens. Home/SOHO/Enterprise Intranet/Internet +--+ +--+ USB/IP+-+ +|device|--+|Linux |---|Service | |+--+ |+--+---|on Linux | +--+ +--++-+ ex) Device Service sensors ... environment analysis cameras ... monitoring, recording ID/biometric readers .. authentication If USB/IP is used for ubiqitous devices or IoT devices, many devices might be handled. 2. About this patch set In current USB/IP, available number of ports (ie. number of supported devices) is VHCI_NPORTS(8) in drivers/usb/usbip/vhci.h. The value of the macro can be altered to USB_MAXCHILDREN(31). This limit is came from hub status bit array. See also the comment at USB_MAXCHILDREN include/uapi/linux/usb/ch11.h. There are two way to increase number of available ports. The first way is to put hub emulator under vhci. This can add ports up to 255 - the limit of USB 2.0 host controller. The second way is to add host controller. It's as same as machines have several host controllers: most desktop or note PCs have more than one host controller. Current USB/IP supports only one controller defined as 'the_controller' in drivers/usb/usbip/vhci_hcd.c. This patch takes the second way described above and adds virtual controllers. In this patch, the number is specified by kernel configuration. 3. Dynamic extension According to kernel configuration, vhci devices (platform device) will be added and removed when they are not used. When the vhci driver is loaded, USBIP_VHCI_INIT_HCS (default is 1) drivers are registered. They will be further registered upto USBIP_VHCI_MAX_HCS (default is 1). They are unregistered when number of free devices becomes more than VHCI_FREE_HCS(2) except the first device. 4. Wording Wording inconsistencies in function and variable names are corrected according to the rule below. They were not strict because only one host controller was handled. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. 5. Dependencies This series depends on 'usbip: exporting devices' patch set because this includes changes to application side daemon which introduced the patch set. --- Version information v5) # Fixed dynamically allocated sysfs attribute checking error when CONFIG_DEBUG_LOCK_ALLOC is set. # Recreated based on linux-next 20160810. v4) # Changed the method to set number of controllers from a module parameter to kernel config. # Excluded event thread patch merged to 4.7-rc1. # Added dynamic extension. v3) # Fixed conflicts against linux-next 20160209. # Changed sysfs object and attribute name for old tools compatibility. # Changed nports status format not to include num_controllers value. # Fixed checkpatch errors and warnings. v2) # Added static to some functions and variables not called from other files. *** BLURB HERE *** Nobuo Iwata (3): usbip: vhci extension: modifications to vhci driver usbip: vhci extension: modifications to userspace usbip: vhci extension: dynamic extension drivers/usb/usbip/Kconfig| 32 ++ drivers/usb/usbip/vhci.h | 84 - drivers/usb/usbip/vhci_hcd.c | 468 +-- drivers/usb/usbip/vhci_rx.c | 31 +- drivers/usb/usbip/vhci_sysfs.c | 304 + drivers/usb/usbip/vhci_tx.c | 6 +- tools/usb/usbip/libsrc/vhci_driver.c | 398 --- tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 48 ++- 11 files changed, 984 insertions(+), 453 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 9/9] usbip: exporting devices: chage to documenattion
This patch adds function and usage of new connect operation, disconnect operation and application(vhci)-side daemon to README and manuals. At this point, the wording, 'server' and 'client' are ambiguous in several place. For existing attach command, the daemon runs device side machine and attach command is executed in application side machine. Then 'server' is used for device side and 'client' is for application side. For the new connect command, the daemon runs applications side machine and connect command is executed in device side machine. Now, 'server' and 'client' run in different machine than before. So, to avoid confusion, words 'device side (machine)' and 'application side (machine)' are used instead of 'client' and 'server' as needed. Please, see also diagrams in the cover letter. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/Makefile.am | 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8 | 136 --- tools/usb/usbip/doc/usbipa.8 | 78 tools/usb/usbip/doc/usbipd.8 | 37 ++ 5 files changed, 263 insertions(+), 60 deletions(-) diff --git a/tools/usb/usbip/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf0..f371ed9 100644 --- a/tools/usb/usbip/Makefile.am +++ b/tools/usb/usbip/Makefile.am @@ -3,4 +3,4 @@ includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ usbip_common.h vhci_driver.h usbip_host_driver.h) -dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) +dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbipa.8) diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 831f49f..74f4afb 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -1,7 +1,8 @@ # # README for usbip-utils # -# Copyright (C) 2011 matt mooney <m...@muteddisk.com> +# Copyright (C) 2015 Nobuo Iwata +# 2011 matt mooney <m...@muteddisk.com> # 2005-2008 Takahiro Hirofuchi @@ -36,41 +37,70 @@ [Usage] -server:# (Physically attach your USB device.) +Device-side: a machine has USB device(s). +Application-side: a machine runs an application software uses remote USB device. -server:# insmod usbip-core.ko -server:# insmod usbip-host.ko +1) Connect from application-side to device-side. -server:# usbipd -D +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbipd -D - Start usbip daemon. -server:# usbip list -l - - List driver assignments for USB devices. +dev:# usbip list -l + - List driver assignments for USB devices and their busid. -server:# usbip bind --busid 1-2 - - Bind usbip-host.ko to the device with busid 1-2. - - The USB device 1-2 is now exportable to other hosts! - - Use `usbip unbind --busid 1-2' to stop exporting the device. +dev:# usbip bind --busid + - Bind usbip-host.ko to the device with . + - The USB device with is now exportable to other hosts! + - Use `usbip unbind --busid ` to stop exporting the device. -client:# insmod usbip-core.ko -client:# insmod vhci-hcd.ko +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko -client:# usbip list --remote +app:# usbip list --remote - List exported USB devices on the . -client:# usbip attach --remote --busid 1-2 +app:# usbip attach --remote --busid - Connect the remote USB device. -client:# usbip port +app:# usbip port - Show virtual port status. -client:# usbip detach --port +app:# usbip detach --port - Detach the USB device. +2) Connect from device-side to application-side. + +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko + +app:# usbipa -D + - Start usbip daemon. + +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbip list -l + - List driver assignments for USB devices and their busid. + +dev:# usbip connect --remote --busid + - Bind usbip-host.ko to the device with . + - The USB device of is connected to remote host! + +dev:# usbip disconnect --remote --busid + - The USB device with is disconnected from remote host. + - Unbind usbip-host.ko from the device. + [Example] --- - SERVER SIDE + DEVICE SIDE --- Physically attach your USB devices to this host. @@ -131,7 +161,7 @@ Mark the device of busid 3-3.2 as exportable: ... --- - CLIENT SIDE + APPLICATION SIDE --- First, let's list available remote devices that are marked as exportable on the host. @@ -170,7 +200,7 @@ Attach a remote USB device: deux:# usbip attach --remote 10.0.0.3 --bus
[PATCH v10 8/9] usbip: exporting devices: change to usbip_list.c
Correction to wording inconsistency around import and export in usbip_list.c. Please, see also cover letter about wording. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_list.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index f1b38e8..37f9afa 100644 --- a/tools/usb/usbip/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -42,9 +43,9 @@ #include "usbip.h" static const char usbip_list_usage_string[] = - "usbip list [-p|--parsable] \n" + "usbip list \n" "-p, --parsable Parsable list format\n" - "-r, --remote=List the exportable USB devices on \n" + "-r, --remote=List the importable USB devices on \n" "-l, --localList the local USB devices\n"; void usbip_list_usage(void) @@ -52,7 +53,7 @@ void usbip_list_usage(void) printf("usage: %s", usbip_list_usage_string); } -static int get_exported_devices(char *host, int sockfd) +static int get_importable_devices(char *host, int sockfd) { char product_name[100]; char class_name[100]; @@ -82,14 +83,14 @@ static int get_exported_devices(char *host, int sockfd) return -1; } PACK_OP_DEVLIST_REPLY(0, ); - dbg("exportable devices: %d\n", reply.ndev); + dbg("importable devices: %d\n", reply.ndev); if (reply.ndev == 0) { - info("no exportable devices found on %s", host); + info("no importable devices found on %s", host); return 0; } - printf("Exportable USB devices\n"); + printf("Importable USB devices\n"); printf("==\n"); printf(" - %s\n", host); @@ -134,7 +135,7 @@ static int get_exported_devices(char *host, int sockfd) return 0; } -static int list_exported_devices(char *host) +static int list_importable_devices(char *host) { int rc; int sockfd; @@ -147,9 +148,10 @@ static int list_exported_devices(char *host) } dbg("connected to %s:%s", host, usbip_port_string); - rc = get_exported_devices(host, sockfd); + rc = get_importable_devices(host, sockfd); if (rc < 0) { err("failed to get device list from %s", host); + close(sockfd); return -1; } @@ -351,7 +353,7 @@ int usbip_list(int argc, char *argv[]) parsable = true; break; case 'r': - ret = list_exported_devices(optarg); + ret = list_importable_devices(optarg); goto out; case 'l': ret = list_devices(parsable); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v10 7/9] usbip: exporting devices: new application-side daemon
New application(vhci)-side daemon. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 19 +++ tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/Makefile.am | 7 +- tools/usb/usbip/src/usbipd.c | 12 +- tools/usb/usbip/src/usbipd_app.c | 242 +++ 5 files changed, 279 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index b7ca63d..50c723d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -314,6 +314,25 @@ int usbip_vhci_get_free_port(void) return -1; } +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid) +{ + int ret; + char rhost[NI_MAXHOST] = "unknown host"; + char rserv[NI_MAXSERV] = "unknown port"; + char rbusid[SYSFS_BUS_ID_SIZE]; + + for (int i = 0; i < vhci_driver->nports; i++) { + ret = read_record(vhci_driver->idev[i].port, rhost, NI_MAXHOST, + rserv, NI_MAXSERV, rbusid); + if (!ret && + !strncmp(host, rhost, NI_MAXHOST) && + !strncmp(busid, rbusid, SYSFS_BUS_ID_SIZE)) { + return vhci_driver->idev + i; + } + } + return NULL; +} + int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed) { char buff[200]; /* what size should be ? */ diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index f955ada..acb427d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -46,6 +46,7 @@ int usbip_vhci_refresh_device_list(void); int usbip_vhci_get_free_port(void); +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid); int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed); diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 1aa5156..8fdebce 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -2,11 +2,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' AM_CFLAGS = @EXTRA_CFLAGS@ LDADD = $(top_builddir)/libsrc/libusbip.la -sbin_PROGRAMS := usbip usbipd +sbin_PROGRAMS := usbip usbipd usbipa usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c +usbip_CFLAGS := $(AM_CFLAGS) usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c +usbipd_CFLAGS := $(AM_CFLAGS) + +usbipa_SOURCES := usbip_network.h usbipd.c usbipd_app.c usbip_network.c +usbipa_CFLAGS := $(AM_CFLAGS) -DUSBIP_DAEMON_APP diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 0ca5de5..4e8bee6 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -64,11 +64,13 @@ static const char usbipd_help_string[] = " -6, --ipv6\n" " Bind to IPv6. Default is both.\n" "\n" +#ifndef USBIP_DAEMON_APP " -e, --device\n" " Run in device mode.\n" " Rather than drive an attached device, create\n" " a virtual UDC to bind gadgets to.\n" "\n" +#endif " -D, --daemon\n" " Run as a daemon process.\n" "\n" @@ -404,7 +406,9 @@ int main(int argc, char *argv[]) { "ipv6", no_argument, NULL, '6' }, { "daemon", no_argument, NULL, 'D' }, { "debug",no_argument, NULL, 'd' }, +#ifndef USBIP_DAEMON_APP { "device", no_argument, NULL, 'e' }, +#endif { "pid", optional_argument, NULL, 'P' }, { "tcp-port", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, @@ -433,7 +437,11 @@ int main(int argc, char *argv[]) cmd = cmd_standalone_mode; usbip_init_driver(); for (;;) { - opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL); + opt = getopt_long(argc, argv, "46Dd" +#ifndef USBIP_DAEMON_APP + "e" +#endif + "P::t:hv", longopts, NULL); if (opt == -1) break; @@ -463,9 +471,11 @@ int mai
[PATCH v10 6/9] usbip: exporting devices: modifications to attach and detach
Refactoring to attach and detatch operation. Common parts to new application(vhci)-side daemon are moved to libsrc/vhci_driver.c. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 99 tools/usb/usbip/libsrc/vhci_driver.h | 6 +- tools/usb/usbip/src/usbip_attach.c | 50 ++ tools/usb/usbip/src/usbip_detach.c | 13 ++-- 4 files changed, 100 insertions(+), 68 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..b7ca63d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata + * 2005-2007 Takahiro Hirofuchi */ #include "usbip_common.h" @@ -7,6 +8,8 @@ #include #include #include +#include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -215,6 +218,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +#define OPEN_HC_MODE_FIRST 0 +#define OPEN_HC_MODE_REOPEN1 + +static int open_hc_device(int mode) +{ + if (mode == OPEN_HC_MODE_REOPEN) + udev_device_unref(vhci_driver->hc_device); + + vhci_driver->hc_device = + udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + USBIP_VHCI_DRV_NAME); + if (!vhci_driver->hc_device) { + err("udev_device_new_from_subsystem_sysname failed"); + return -1; + } + return 0; +} + /* -- */ int usbip_vhci_driver_open(void) @@ -227,28 +249,21 @@ int usbip_vhci_driver_open(void) vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); - if (!vhci_driver->hc_device) { - err("udev_device_new_from_subsystem_sysname failed"); - goto err; - } + if (open_hc_device(OPEN_HC_MODE_FIRST)) + goto err_free_driver; vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); if (refresh_imported_device_list()) - goto err; + goto err_unref_device; return 0; -err: +err_unref_device: udev_device_unref(vhci_driver->hc_device); - +err_free_driver: if (vhci_driver) free(vhci_driver); @@ -277,7 +292,8 @@ void usbip_vhci_driver_close(void) int usbip_vhci_refresh_device_list(void) { - + if (open_hc_device(OPEN_HC_MODE_REOPEN)) + goto err; if (refresh_imported_device_list()) goto err; @@ -409,3 +425,58 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) return 0; } + +#define MAX_BUFF 100 +int usbip_vhci_create_record(char *host, char *port, char *busid, int rhport) +{ + int fd; + char path[PATH_MAX+1]; + char buff[MAX_BUFF+1]; + int ret; + + ret = mkdir(VHCI_STATE_PATH, 0700); + if (ret < 0) { + /* if VHCI_STATE_PATH exists, then it better be a directory */ + if (errno == EEXIST) { + struct stat s; + + ret = stat(VHCI_STATE_PATH, ); + if (ret < 0) + return -1; + if (!(s.st_mode & S_IFDIR)) + return -1; + } else + return -1; + } + + 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; +} + +int usbip_vhci_delete_record(int rhport) +{ + char path[PATH_MAX+1]; + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + + remove(path); + rmdir(VHCI_STATE_PATH); + + return 0; +} diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..f955ada 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/too
[PATCH v10 4/9] usbip: exporting devices: new disconnect operation
New disconnect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am| 2 +- tools/usb/usbip/src/usbip.c| 6 + tools/usb/usbip/src/usbip.h| 2 + tools/usb/usbip/src/usbip_disconnect.c | 215 + 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 0947476..42760c3 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ -usbip_connect.c +usbip_connect.c usbip_disconnect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index 584d7d5..f0e9e06 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -83,6 +83,12 @@ static const struct command cmds[] = { .usage = usbip_connect_usage }, { + .name = "disconnect", + .fn= usbip_disconnect, + .help = "Disconnect a USB device from a remote computer", + .usage = usbip_disconnect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index f365353..a8cbd16 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); int usbip_connect(int argc, char *argv[]); +int usbip_disconnect(int argc, char *argv[]); void usbip_attach_usage(void); void usbip_detach_usage(void); @@ -39,6 +40,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); void usbip_connect_usage(void); +void usbip_disconnect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_disconnect.c b/tools/usb/usbip/src/usbip_disconnect.c new file mode 100644 index 000..8155384 --- /dev/null +++ b/tools/usb/usbip/src/usbip_disconnect.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_disconnect_usage_string[] = + "usbip disconnect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be disconnected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_disconnect_usage(void) +{ + printf("usage: %s", usbip_disconnect_usage_string); +} + +static int send_unexport_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_unexport_request request; + struct op_unexport_reply reply; + uint16_t code = OP_REP_UNEXPORT; + + memset(, 0, sizeof(request)); + memset(, 0, sizeof(reply)); + + /* send a request */ + rc = usbip_net_send_op_common(sockfd, OP_REQ_UNEXPORT, 0); + if (rc < 0) { + err("send op_common"); + return -1; + } + + memcpy(, udev, sizeof(struct usbip_usb_device)); + + PACK_OP_UNEXPORT_REQUEST(0, ); + + rc = usbip_net_send(sockfd, (void *) , sizeof(request)); + if (rc < 0) { + err("send op_export_request"); +
[PATCH v10 5/9] usbip: exporting devices: modifications to daemon
Refactoring to the daemon. usbipd_dev.c is device-side specific code extracted from usbipd.c. usbipd.c is left as common parts for both device(stub)-side and application(vhci)-side daemon. usbip_net_set_nodelay() is the middle of device side daemon operation and it does not make mush sence. In the client operation, it's in right after connect(). So, in daemon, it is moved to right after accept() to affect it both device and application side. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/doc/usbipd.8 | 1 - tools/usb/usbip/src/Makefile.am | 2 +- tools/usb/usbip/src/usbipd.c | 238 +++-- tools/usb/usbip/src/usbipd.h | 39 + tools/usb/usbip/src/usbipd_dev.c | 252 +++ 5 files changed, 315 insertions(+), 217 deletions(-) diff --git a/tools/usb/usbip/doc/usbipd.8 b/tools/usb/usbip/doc/usbipd.8 index ac4635d..6e1a008 100644 --- a/tools/usb/usbip/doc/usbipd.8 +++ b/tools/usb/usbip/doc/usbipd.8 @@ -88,4 +88,3 @@ USB/IP client can connect and use exported devices. .SH "SEE ALSO" \fBusbip\fP\fB(8)\fB\fP - diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 42760c3..1aa5156 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -9,4 +9,4 @@ usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c -usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c +usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index a0972de..0ca5de5 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -43,25 +44,19 @@ #include #include -#include "usbip_host_driver.h" -#include "usbip_host_common.h" -#include "usbip_device_driver.h" #include "usbip_common.h" #include "usbip_network.h" +#include "usbipd.h" #include "list.h" -#undef PROGNAME -#define PROGNAME "usbipd" #define MAXSOCKFD 20 #define MAIN_LOOP_TIMEOUT 10 -#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" - static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options]\n" + "usage: %s [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" @@ -82,7 +77,7 @@ static const char usbipd_help_string[] = "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" - " If no FILE specified, use " DEFAULT_PID_FILE "\n" + " If no FILE specified, use %s.\n" "\n" " -tPORT, --tcp-port PORT\n" " Listen on TCP/IP port PORT.\n" @@ -93,198 +88,9 @@ static const char usbipd_help_string[] = " -v, --version\n" " Show version.\n"; -static struct usbip_host_driver *driver; - static void usbipd_help(void) { - printf("%s\n", usbipd_help_string); -} - -static int recv_request_import(int sockfd) -{ - struct op_import_request req; - struct usbip_exported_device *edev; - struct usbip_usb_device pdu_udev; - struct list_head *i; - int found = 0; - int error = 0; - int rc; - - memset(, 0, sizeof(req)); - - rc = usbip_net_recv(sockfd, , sizeof(req)); - if (rc < 0) { - dbg("usbip_net_recv failed: import request"); - return -1; - } - PACK_OP_IMPORT_REQUEST(0, ); - - list_for_each(i, >edev_list) { - edev = list_entry(i, struct usbip_exported_device, node); - if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { - info("found requested device: %s", req.busid); - found = 1; - break; - } - } - - if (found) { - /* should set TCP_NODELAY for usbip */ - usbip_net_set_nodelay(sockfd); - - /* export device needs a TCP/IP socket descriptor */ - rc = usbip_export_device(edev, sockfd); - if (rc < 0) - erro
[PATCH v10 1/9] usbip: exporting devices: modifications to network header
Modification to export and un-export response in tools/usb/usbip/src/usbip_network.h. It just changes return code type from int to uint32_t as same as other responses. Added export and un-export request/response to Documentation/usb/usbip_protocol.txt. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Documentation/usb/usbip_protocol.txt | 204 --- tools/usb/usbip/src/usbip_network.h | 5 +- 2 files changed, 184 insertions(+), 25 deletions(-) diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe2..d4be5b6 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -1,20 +1,26 @@ PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! 28 Jun 2011 +MODIFIED FOR CONNECT AND DISCONNECT OPERARION. +07 March 2016 -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. +The USB/IP protocol follows a server/client architecture between two computers +one has USB devices and the other runs application using the devices. There are +two ways for initiation. -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. +The first way is to import devices from application-side. In this way, the +server runs in device-side and the client runs in application-side. In device +side user makes devices importable with 'bind' operation. +The client may ask for the list of the importable USB devices. To get the list +the client opens a TCP/IP connection towards the server, and sends an +OP_REQ_DEVLIST packet on top of the TCP/IP connection (so the actual +OP_REQ_DEVLIST may be sent in one or more pieces at the low level transport +layer). The server sends back the OP_REP_DEVLIST packet which lists the +importable USB devices. Finally the TCP/IP connection is closed. + + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (lists importable devices)"server" | | | OP_REQ_DEVLIST | | --> | @@ -23,18 +29,13 @@ TCP/IP connection is closed. | <-- | | | -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. +Once the client knows the list of importable USB devices it may decide to use +one of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (imports a USB device) "server" | | | OP_REQ_IMPORT | | --> | @@ -42,6 +43,32 @@ server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | OP_REP_IMPORT | | <-- | | | + +The second way is to export devices from device-side. In this way, the server +runs in application-side and the client runs in device-side. The client binds a +device to export, opens a TCP/IP connection towards the server
[PATCH v10 3/9] usbip: exporting devices: new connect operation
New connect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 3 +- tools/usb/usbip/src/usbip.c | 9 +- tools/usb/usbip/src/usbip.h | 5 +- tools/usb/usbip/src/usbip_connect.c | 228 4 files changed, 242 insertions(+), 3 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4eb..0947476 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ -usbip_bind.c usbip_unbind.c usbip_port.c +usbip_bind.c usbip_unbind.c usbip_port.c \ +usbip_connect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d9..584d7d5 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -2,7 +2,8 @@ * command structure borrowed from udev * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) * - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -76,6 +77,12 @@ static const struct command cmds[] = { .usage = usbip_detach_usage }, { + .name = "connect", + .fn= usbip_connect, + .help = "Connect a USB device to a remote computer", + .usage = usbip_connect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index c296910..f365353 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -30,12 +31,14 @@ int usbip_list(int argc, char *argv[]); int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); +int usbip_connect(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); +void usbip_connect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_connect.c b/tools/usb/usbip/src/usbip_connect.c new file mode 100644 index 000..bbecc7e --- /dev/null +++ b/tools/usb/usbip/src/usbip_connect.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_connect_usage_string[] = + "usbip connect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be connected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_connect_usage(void) +{ + printf("usage: %s", usbip_connect_usage_string); +} + +static int send_export_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_export_request request; + struct op_export_reply reply
[PATCH v10 0/9] usbip: exporting devices
nd internally. With vUDC, they do not execute bind and unbind. They are done by UDC interface. 4. Security consideration In new operation, when the daemon is running, SSL or Secure WebSocket tunneling proxy can reject unauthorized access. 5. Mixed usage Both existing and new way work in same machines simultaneously. Status of devices and ports are controlled in stub and vhci driver. 6. Wording Adding the new operation, some inconsistnecies in wording are appeared in documentation, function name, etc. If needed, they are fixed. 'export' is used for bind and 'exported' is used for bound. They are changed to 'make importable' and 'imported' respectively. The words not new. For example, in the output of port operation, 'imported devices' is already used. They are sorted out. 'client' and 'server' are switched between existing and new operation. So, words 'device-side' and 'application-side' are used in documentations as needed for clarity. --- Version information This series is divided from "USB/IP over WebSocket" patch set. Rest of the set will be sent as another series. v10) # Recreated based n linux-next 20160810. v9) # Moved a set_nodelay() from usbipd_dev.c to usbipd.c to affect both device side and application side daemon. # Removed redundant blank line at the end of files. v8) # Divided into smaller patches. # Excluded low-related patches. # Improved change log. # Changed info level logs in usbip_ux.c to debug level logs. # Added options to vUDC. # Tested with vUDC. v7) # Removed userspace transmission and WebSocket command/daemon. # Fixed checkpatch errors and warnings. v6) # Added __rcu annotation to a RCU pointer to clear sparse warnings. # Corrected a copy to RCU pointer with rcu_rcu_assign_pointer(). # Added __user annotations to arguments of read/write method. # Added static to some functions which are not called from other files. # Removed unnecessary EXPORT_SYMBOLs. v5) # Added vendor/pruduct name conversion to port command. # Put initial value to pool_head in name.c. # Fixed list command exception when host option is omitted. # Fixed exception in case gai_strerror() returns NULL. # Fixed WebSocket connection close via proxy. # Fixed to stop WebSocket ping-pong on connection close. # Removed redundant usbipd daemon option. # Removed redundant SSL code had not been deleted. # Removed an unused local variable in WebSocket code. # Modified C++ reserved word in names.c as same as headers. v4) # Fixed regression of usbip list --remote v3) # Coding style for goto err labels are fixed. # Defined magic numbers for open_hc_device() argument. # Corrected include .../uapi/linux/usbip_ux.h as . # Modified parameter notation in manuals not to use '='. # Fixed inappropriate version definition in tools/.../websocket/configure.ac. # Remved unnecessary COPYING and AUTHORS fil from tools/.../websocket/. # Added -version-info to libraries in tools/.../src. v2) # Formatted patches from linux-next. # Fixed change log word wrapping. # Removed SSL patches. # Fixed a bug that vendor and product names are not shown by 'usbws list -l' because usbip_names_init() was not called in libusbip.la. Thank you, Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> // *** BLURB HERE *** Nobuo Iwata (9): usbip: exporting devices: modifications to network header usbip: exporting devices: modifications to host side libraries usbip: exporting devices: new connect operation usbip: exporting devices: new disconnect operation usbip: exporting devices: modifications to daemon usbip: exporting devices: modifications to attach and detach usbip: exporting devices: new application-side daemon usbip: exporting devices: change to usbip_list.c usbip: exporting devices: chage to documenattion Documentation/usb/usbip_protocol.txt | 204 +++-- tools/usb/usbip/Makefile.am| 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8| 136 +-- tools/usb/usbip/doc/usbipa.8 | 78 +++ tools/usb/usbip/doc/usbipd.8 | 38 ++-- tools/usb/usbip/libsrc/usbip_host_common.c | 6 +- tools/usb/usbip/libsrc/usbip_host_common.h | 8 +- tools/usb/usbip/libsrc/vhci_driver.c | 118 -- tools/usb/usbip/libsrc/vhci_driver.h | 7 +- tools/usb/usbip/src/Makefile.am| 12 +- tools/usb/usbip/src/usbip.c| 15 +- tools/usb/usbip/src/usbip.h| 10 +- tools/usb/usbip/src/usbip_attach.c | 50 +--- tools/usb/usbip/src/usbip_bind.c | 7 +- tools/usb/usbip/src/usbip_connect.c| 228 +++ tools/usb/usbip/src/usbip_detach.c | 13 +- tools/usb/usbip/src/usbip_disconnect.c | 215 ++ tools/usb/usbip/src/usbip_list.c | 22 +- tools/usb/usbip/src/usbip_network.h| 5 +- tools/usb/usbip/src/usbip_unbind.c | 7 +- tools/us
[PATCH v10 2/9] usbip: exporting devices: modifications to host side libraries
usbip_get_device() method in usbip_host_driver_ops was not used. It is modified as a function to find an exported device for new operations 'connect' and 'disconnect'. bind and unbind function are exported for the new operations. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/usbip_host_common.c | 6 ++ tools/usb/usbip/libsrc/usbip_host_common.h | 8 tools/usb/usbip/src/usbip.h| 3 +++ tools/usb/usbip/src/usbip_bind.c | 7 --- tools/usb/usbip/src/usbip_unbind.c | 7 --- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..6a98d6c 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -256,17 +256,15 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num) + struct usbip_host_driver *hdriver, char *busid) { struct list_head *i; struct usbip_exported_device *edev; - int cnt = 0; list_for_each(i, >edev_list) { edev = list_entry(i, struct usbip_exported_device, node); - if (num == cnt) + if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) return edev; - cnt++; } return NULL; diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h index a64b803..f9a9def 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.h +++ b/tools/usb/usbip/libsrc/usbip_host_common.h @@ -38,7 +38,7 @@ struct usbip_host_driver_ops { void (*close)(struct usbip_host_driver *hdriver); int (*refresh_device_list)(struct usbip_host_driver *hdriver); struct usbip_exported_device * (*get_device)( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); int (*read_device)(struct udev_device *sdev, struct usbip_usb_device *dev); @@ -86,11 +86,11 @@ static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver) } static inline struct usbip_exported_device * -usbip_get_device(struct usbip_host_driver *hdriver, int num) +usbip_get_device(struct usbip_host_driver *hdriver, char *busid) { if (!hdriver->ops.get_device) return NULL; - return hdriver->ops.get_device(hdriver, num); + return hdriver->ops.get_device(hdriver, busid); } /* Helper functions for implementing driver backend */ @@ -99,6 +99,6 @@ void usbip_generic_driver_close(struct usbip_host_driver *hdriver); int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver); int usbip_export_device(struct usbip_exported_device *edev, int sockfd); struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); #endif /* __USBIP_HOST_COMMON_H */ diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a..c296910 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -37,4 +37,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); +int usbip_bind_device(char *busid); +int usbip_unbind_device(char *busid); + #endif /* __USBIP_H */ diff --git a/tools/usb/usbip/src/usbip_bind.c b/tools/usb/usbip/src/usbip_bind.c index fa46141..1c09338 100644 --- a/tools/usb/usbip/src/usbip_bind.c +++ b/tools/usb/usbip/src/usbip_bind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -139,7 +140,7 @@ out: return status; } -static int bind_device(char *busid) +int usbip_bind_device(char *busid) { int rc; struct udev *udev; @@ -200,7 +201,7 @@ int usbip_bind(int argc, char *argv[]) switch (opt) { case 'b': - ret = bind_device(optarg); + ret = usbip_bind_device(optarg); goto out; default: goto err_out; diff --git a/tools/usb/usbip/src/usbip_unbind.c b/tools/usb/usbip/src/usbip_unbind.c index a4a496c..cc1ff26 100644 --- a/tools/usb/usbip/src/usbip_unbind.c +++ b/tools/usb/usbip/src/usbip_unbind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com>
[PATCH v9 7/9] usbip: exporting devices: new application-side daemon
New application(vhci)-side daemon. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 19 +++ tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/Makefile.am | 7 +- tools/usb/usbip/src/usbipd.c | 12 +- tools/usb/usbip/src/usbipd_app.c | 242 +++ 5 files changed, 279 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index b7ca63d..50c723d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -314,6 +314,25 @@ int usbip_vhci_get_free_port(void) return -1; } +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid) +{ + int ret; + char rhost[NI_MAXHOST] = "unknown host"; + char rserv[NI_MAXSERV] = "unknown port"; + char rbusid[SYSFS_BUS_ID_SIZE]; + + for (int i = 0; i < vhci_driver->nports; i++) { + ret = read_record(vhci_driver->idev[i].port, rhost, NI_MAXHOST, + rserv, NI_MAXSERV, rbusid); + if (!ret && + !strncmp(host, rhost, NI_MAXHOST) && + !strncmp(busid, rbusid, SYSFS_BUS_ID_SIZE)) { + return vhci_driver->idev + i; + } + } + return NULL; +} + int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed) { char buff[200]; /* what size should be ? */ diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index f955ada..acb427d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -46,6 +46,7 @@ int usbip_vhci_refresh_device_list(void); int usbip_vhci_get_free_port(void); +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid); int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed); diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 1aa5156..8fdebce 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -2,11 +2,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' AM_CFLAGS = @EXTRA_CFLAGS@ LDADD = $(top_builddir)/libsrc/libusbip.la -sbin_PROGRAMS := usbip usbipd +sbin_PROGRAMS := usbip usbipd usbipa usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c +usbip_CFLAGS := $(AM_CFLAGS) usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c +usbipd_CFLAGS := $(AM_CFLAGS) + +usbipa_SOURCES := usbip_network.h usbipd.c usbipd_app.c usbip_network.c +usbipa_CFLAGS := $(AM_CFLAGS) -DUSBIP_DAEMON_APP diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index 0ca5de5..4e8bee6 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -64,11 +64,13 @@ static const char usbipd_help_string[] = " -6, --ipv6\n" " Bind to IPv6. Default is both.\n" "\n" +#ifndef USBIP_DAEMON_APP " -e, --device\n" " Run in device mode.\n" " Rather than drive an attached device, create\n" " a virtual UDC to bind gadgets to.\n" "\n" +#endif " -D, --daemon\n" " Run as a daemon process.\n" "\n" @@ -404,7 +406,9 @@ int main(int argc, char *argv[]) { "ipv6", no_argument, NULL, '6' }, { "daemon", no_argument, NULL, 'D' }, { "debug",no_argument, NULL, 'd' }, +#ifndef USBIP_DAEMON_APP { "device", no_argument, NULL, 'e' }, +#endif { "pid", optional_argument, NULL, 'P' }, { "tcp-port", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, @@ -433,7 +437,11 @@ int main(int argc, char *argv[]) cmd = cmd_standalone_mode; usbip_init_driver(); for (;;) { - opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL); + opt = getopt_long(argc, argv, "46Dd" +#ifndef USBIP_DAEMON_APP + "e" +#endif + "P::t:hv", longopts, NULL); if (opt == -1) break; @@ -463,9 +471,11 @@ int mai
[PATCH v9 9/9] usbip: exporting devices: chage to documenattion
This patch adds function and usage of new connect operation, disconnect operation and application(vhci)-side daemon to README and manuals. At this point, the wording, 'server' and 'client' are ambiguous in several place. For existing attach command, the daemon runs device side machine and attach command is executed in application side machine. Then 'server' is used for device side and 'client' is for application side. For the new connect command, the daemon runs applications side machine and connect command is executed in device side machine. Now, 'server' and 'client' run in different machine than before. So, to avoid confusion, words 'device side (machine)' and 'application side (machine)' are used instead of 'client' and 'server' as needed. Please, see also diagrams in the cover letter. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/Makefile.am | 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8 | 136 --- tools/usb/usbip/doc/usbipa.8 | 78 tools/usb/usbip/doc/usbipd.8 | 37 ++ 5 files changed, 263 insertions(+), 60 deletions(-) diff --git a/tools/usb/usbip/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf0..f371ed9 100644 --- a/tools/usb/usbip/Makefile.am +++ b/tools/usb/usbip/Makefile.am @@ -3,4 +3,4 @@ includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ usbip_common.h vhci_driver.h usbip_host_driver.h) -dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) +dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbipa.8) diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 831f49f..74f4afb 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -1,7 +1,8 @@ # # README for usbip-utils # -# Copyright (C) 2011 matt mooney <m...@muteddisk.com> +# Copyright (C) 2015 Nobuo Iwata +# 2011 matt mooney <m...@muteddisk.com> # 2005-2008 Takahiro Hirofuchi @@ -36,41 +37,70 @@ [Usage] -server:# (Physically attach your USB device.) +Device-side: a machine has USB device(s). +Application-side: a machine runs an application software uses remote USB device. -server:# insmod usbip-core.ko -server:# insmod usbip-host.ko +1) Connect from application-side to device-side. -server:# usbipd -D +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbipd -D - Start usbip daemon. -server:# usbip list -l - - List driver assignments for USB devices. +dev:# usbip list -l + - List driver assignments for USB devices and their busid. -server:# usbip bind --busid 1-2 - - Bind usbip-host.ko to the device with busid 1-2. - - The USB device 1-2 is now exportable to other hosts! - - Use `usbip unbind --busid 1-2' to stop exporting the device. +dev:# usbip bind --busid + - Bind usbip-host.ko to the device with . + - The USB device with is now exportable to other hosts! + - Use `usbip unbind --busid ` to stop exporting the device. -client:# insmod usbip-core.ko -client:# insmod vhci-hcd.ko +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko -client:# usbip list --remote +app:# usbip list --remote - List exported USB devices on the . -client:# usbip attach --remote --busid 1-2 +app:# usbip attach --remote --busid - Connect the remote USB device. -client:# usbip port +app:# usbip port - Show virtual port status. -client:# usbip detach --port +app:# usbip detach --port - Detach the USB device. +2) Connect from device-side to application-side. + +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko + +app:# usbipa -D + - Start usbip daemon. + +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbip list -l + - List driver assignments for USB devices and their busid. + +dev:# usbip connect --remote --busid + - Bind usbip-host.ko to the device with . + - The USB device of is connected to remote host! + +dev:# usbip disconnect --remote --busid + - The USB device with is disconnected from remote host. + - Unbind usbip-host.ko from the device. + [Example] --- - SERVER SIDE + DEVICE SIDE --- Physically attach your USB devices to this host. @@ -131,7 +161,7 @@ Mark the device of busid 3-3.2 as exportable: ... --- - CLIENT SIDE + APPLICATION SIDE --- First, let's list available remote devices that are marked as exportable on the host. @@ -170,7 +200,7 @@ Attach a remote USB device: deux:# usbip attach --remote 10.0.0.3 --bus
[PATCH v9 5/9] usbip: exporting devices: modifications to daemon
Refactoring to the daemon. usbipd_dev.c is device-side specific code extracted from usbipd.c. usbipd.c is left as common parts for both device(stub)-side and application(vhci)-side daemon. usbip_net_set_nodelay() is the middle of device side daemon operation and it does not make mush sence. In the client operation, it's in right after connect(). So, in daemon, it is moved to right after accept() to affect it both device and application side. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/doc/usbipd.8 | 1 - tools/usb/usbip/src/Makefile.am | 2 +- tools/usb/usbip/src/usbipd.c | 238 +++-- tools/usb/usbip/src/usbipd.h | 39 + tools/usb/usbip/src/usbipd_dev.c | 252 +++ 5 files changed, 315 insertions(+), 217 deletions(-) diff --git a/tools/usb/usbip/doc/usbipd.8 b/tools/usb/usbip/doc/usbipd.8 index ac4635d..6e1a008 100644 --- a/tools/usb/usbip/doc/usbipd.8 +++ b/tools/usb/usbip/doc/usbipd.8 @@ -88,4 +88,3 @@ USB/IP client can connect and use exported devices. .SH "SEE ALSO" \fBusbip\fP\fB(8)\fB\fP - diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 42760c3..1aa5156 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -9,4 +9,4 @@ usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c -usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c +usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index a0972de..0ca5de5 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -43,25 +44,19 @@ #include #include -#include "usbip_host_driver.h" -#include "usbip_host_common.h" -#include "usbip_device_driver.h" #include "usbip_common.h" #include "usbip_network.h" +#include "usbipd.h" #include "list.h" -#undef PROGNAME -#define PROGNAME "usbipd" #define MAXSOCKFD 20 #define MAIN_LOOP_TIMEOUT 10 -#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" - static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options]\n" + "usage: %s [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" @@ -82,7 +77,7 @@ static const char usbipd_help_string[] = "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" - " If no FILE specified, use " DEFAULT_PID_FILE "\n" + " If no FILE specified, use %s.\n" "\n" " -tPORT, --tcp-port PORT\n" " Listen on TCP/IP port PORT.\n" @@ -93,198 +88,9 @@ static const char usbipd_help_string[] = " -v, --version\n" " Show version.\n"; -static struct usbip_host_driver *driver; - static void usbipd_help(void) { - printf("%s\n", usbipd_help_string); -} - -static int recv_request_import(int sockfd) -{ - struct op_import_request req; - struct usbip_exported_device *edev; - struct usbip_usb_device pdu_udev; - struct list_head *i; - int found = 0; - int error = 0; - int rc; - - memset(, 0, sizeof(req)); - - rc = usbip_net_recv(sockfd, , sizeof(req)); - if (rc < 0) { - dbg("usbip_net_recv failed: import request"); - return -1; - } - PACK_OP_IMPORT_REQUEST(0, ); - - list_for_each(i, >edev_list) { - edev = list_entry(i, struct usbip_exported_device, node); - if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { - info("found requested device: %s", req.busid); - found = 1; - break; - } - } - - if (found) { - /* should set TCP_NODELAY for usbip */ - usbip_net_set_nodelay(sockfd); - - /* export device needs a TCP/IP socket descriptor */ - rc = usbip_export_device(edev, sockfd); - if (rc < 0) - erro
[PATCH v9 3/9] usbip: exporting devices: new connect operation
New connect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 3 +- tools/usb/usbip/src/usbip.c | 9 +- tools/usb/usbip/src/usbip.h | 5 +- tools/usb/usbip/src/usbip_connect.c | 228 4 files changed, 242 insertions(+), 3 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4eb..0947476 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ -usbip_bind.c usbip_unbind.c usbip_port.c +usbip_bind.c usbip_unbind.c usbip_port.c \ +usbip_connect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d9..584d7d5 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -2,7 +2,8 @@ * command structure borrowed from udev * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) * - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -76,6 +77,12 @@ static const struct command cmds[] = { .usage = usbip_detach_usage }, { + .name = "connect", + .fn= usbip_connect, + .help = "Connect a USB device to a remote computer", + .usage = usbip_connect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index c296910..f365353 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -30,12 +31,14 @@ int usbip_list(int argc, char *argv[]); int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); +int usbip_connect(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); +void usbip_connect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_connect.c b/tools/usb/usbip/src/usbip_connect.c new file mode 100644 index 000..bbecc7e --- /dev/null +++ b/tools/usb/usbip/src/usbip_connect.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_connect_usage_string[] = + "usbip connect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be connected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_connect_usage(void) +{ + printf("usage: %s", usbip_connect_usage_string); +} + +static int send_export_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_export_request request; + struct op_export_reply reply
[PATCH v9 2/9] usbip: exporting devices: modifications to host side libraries
usbip_get_device() method in usbip_host_driver_ops was not used. It is modified as a function to find an exported device for new operations 'connect' and 'disconnect'. bind and unbind function are exported for the new operations. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/usbip_host_common.c | 6 ++ tools/usb/usbip/libsrc/usbip_host_common.h | 8 tools/usb/usbip/src/usbip.h| 3 +++ tools/usb/usbip/src/usbip_bind.c | 7 --- tools/usb/usbip/src/usbip_unbind.c | 7 --- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..6a98d6c 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -256,17 +256,15 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num) + struct usbip_host_driver *hdriver, char *busid) { struct list_head *i; struct usbip_exported_device *edev; - int cnt = 0; list_for_each(i, >edev_list) { edev = list_entry(i, struct usbip_exported_device, node); - if (num == cnt) + if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) return edev; - cnt++; } return NULL; diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h index a64b803..f9a9def 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.h +++ b/tools/usb/usbip/libsrc/usbip_host_common.h @@ -38,7 +38,7 @@ struct usbip_host_driver_ops { void (*close)(struct usbip_host_driver *hdriver); int (*refresh_device_list)(struct usbip_host_driver *hdriver); struct usbip_exported_device * (*get_device)( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); int (*read_device)(struct udev_device *sdev, struct usbip_usb_device *dev); @@ -86,11 +86,11 @@ static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver) } static inline struct usbip_exported_device * -usbip_get_device(struct usbip_host_driver *hdriver, int num) +usbip_get_device(struct usbip_host_driver *hdriver, char *busid) { if (!hdriver->ops.get_device) return NULL; - return hdriver->ops.get_device(hdriver, num); + return hdriver->ops.get_device(hdriver, busid); } /* Helper functions for implementing driver backend */ @@ -99,6 +99,6 @@ void usbip_generic_driver_close(struct usbip_host_driver *hdriver); int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver); int usbip_export_device(struct usbip_exported_device *edev, int sockfd); struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); #endif /* __USBIP_HOST_COMMON_H */ diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a..c296910 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -37,4 +37,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); +int usbip_bind_device(char *busid); +int usbip_unbind_device(char *busid); + #endif /* __USBIP_H */ diff --git a/tools/usb/usbip/src/usbip_bind.c b/tools/usb/usbip/src/usbip_bind.c index fa46141..1c09338 100644 --- a/tools/usb/usbip/src/usbip_bind.c +++ b/tools/usb/usbip/src/usbip_bind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -139,7 +140,7 @@ out: return status; } -static int bind_device(char *busid) +int usbip_bind_device(char *busid) { int rc; struct udev *udev; @@ -200,7 +201,7 @@ int usbip_bind(int argc, char *argv[]) switch (opt) { case 'b': - ret = bind_device(optarg); + ret = usbip_bind_device(optarg); goto out; default: goto err_out; diff --git a/tools/usb/usbip/src/usbip_unbind.c b/tools/usb/usbip/src/usbip_unbind.c index a4a496c..cc1ff26 100644 --- a/tools/usb/usbip/src/usbip_unbind.c +++ b/tools/usb/usbip/src/usbip_unbind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com>
[PATCH v9 1/9] usbip: exporting devices: modifications to network header
Modification to export and un-export response in tools/usb/usbip/src/usbip_network.h. It just changes return code type from int to uint32_t as same as other responses. Added export and un-export request/response to Documentation/usb/usbip_protocol.txt. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Documentation/usb/usbip_protocol.txt | 204 --- tools/usb/usbip/src/usbip_network.h | 5 +- 2 files changed, 184 insertions(+), 25 deletions(-) diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe2..d4be5b6 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -1,20 +1,26 @@ PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! 28 Jun 2011 +MODIFIED FOR CONNECT AND DISCONNECT OPERARION. +07 March 2016 -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. +The USB/IP protocol follows a server/client architecture between two computers +one has USB devices and the other runs application using the devices. There are +two ways for initiation. -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. +The first way is to import devices from application-side. In this way, the +server runs in device-side and the client runs in application-side. In device +side user makes devices importable with 'bind' operation. +The client may ask for the list of the importable USB devices. To get the list +the client opens a TCP/IP connection towards the server, and sends an +OP_REQ_DEVLIST packet on top of the TCP/IP connection (so the actual +OP_REQ_DEVLIST may be sent in one or more pieces at the low level transport +layer). The server sends back the OP_REP_DEVLIST packet which lists the +importable USB devices. Finally the TCP/IP connection is closed. + + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (lists importable devices)"server" | | | OP_REQ_DEVLIST | | --> | @@ -23,18 +29,13 @@ TCP/IP connection is closed. | <-- | | | -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. +Once the client knows the list of importable USB devices it may decide to use +one of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (imports a USB device) "server" | | | OP_REQ_IMPORT | | --> | @@ -42,6 +43,32 @@ server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | OP_REP_IMPORT | | <-- | | | + +The second way is to export devices from device-side. In this way, the server +runs in application-side and the client runs in device-side. The client binds a +device to export, opens a TCP/IP connection towards the server
[PATCH v9 4/9] usbip: exporting devices: new disconnect operation
New disconnect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am| 2 +- tools/usb/usbip/src/usbip.c| 6 + tools/usb/usbip/src/usbip.h| 2 + tools/usb/usbip/src/usbip_disconnect.c | 215 + 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 0947476..42760c3 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ -usbip_connect.c +usbip_connect.c usbip_disconnect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index 584d7d5..f0e9e06 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -83,6 +83,12 @@ static const struct command cmds[] = { .usage = usbip_connect_usage }, { + .name = "disconnect", + .fn= usbip_disconnect, + .help = "Disconnect a USB device from a remote computer", + .usage = usbip_disconnect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index f365353..a8cbd16 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); int usbip_connect(int argc, char *argv[]); +int usbip_disconnect(int argc, char *argv[]); void usbip_attach_usage(void); void usbip_detach_usage(void); @@ -39,6 +40,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); void usbip_connect_usage(void); +void usbip_disconnect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_disconnect.c b/tools/usb/usbip/src/usbip_disconnect.c new file mode 100644 index 000..8155384 --- /dev/null +++ b/tools/usb/usbip/src/usbip_disconnect.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_disconnect_usage_string[] = + "usbip disconnect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be disconnected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_disconnect_usage(void) +{ + printf("usage: %s", usbip_disconnect_usage_string); +} + +static int send_unexport_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_unexport_request request; + struct op_unexport_reply reply; + uint16_t code = OP_REP_UNEXPORT; + + memset(, 0, sizeof(request)); + memset(, 0, sizeof(reply)); + + /* send a request */ + rc = usbip_net_send_op_common(sockfd, OP_REQ_UNEXPORT, 0); + if (rc < 0) { + err("send op_common"); + return -1; + } + + memcpy(, udev, sizeof(struct usbip_usb_device)); + + PACK_OP_UNEXPORT_REQUEST(0, ); + + rc = usbip_net_send(sockfd, (void *) , sizeof(request)); + if (rc < 0) { + err("send op_export_request"); +
[PATCH v9 6/9] usbip: exporting devices: modifications to attach and detach
Refactoring to attach and detatch operation. Common parts to new application(vhci)-side daemon are moved to libsrc/vhci_driver.c. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 99 tools/usb/usbip/libsrc/vhci_driver.h | 6 +- tools/usb/usbip/src/usbip_attach.c | 50 ++ tools/usb/usbip/src/usbip_detach.c | 13 ++-- 4 files changed, 100 insertions(+), 68 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..b7ca63d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata + * 2005-2007 Takahiro Hirofuchi */ #include "usbip_common.h" @@ -7,6 +8,8 @@ #include #include #include +#include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -215,6 +218,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +#define OPEN_HC_MODE_FIRST 0 +#define OPEN_HC_MODE_REOPEN1 + +static int open_hc_device(int mode) +{ + if (mode == OPEN_HC_MODE_REOPEN) + udev_device_unref(vhci_driver->hc_device); + + vhci_driver->hc_device = + udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + USBIP_VHCI_DRV_NAME); + if (!vhci_driver->hc_device) { + err("udev_device_new_from_subsystem_sysname failed"); + return -1; + } + return 0; +} + /* -- */ int usbip_vhci_driver_open(void) @@ -227,28 +249,21 @@ int usbip_vhci_driver_open(void) vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); - if (!vhci_driver->hc_device) { - err("udev_device_new_from_subsystem_sysname failed"); - goto err; - } + if (open_hc_device(OPEN_HC_MODE_FIRST)) + goto err_free_driver; vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); if (refresh_imported_device_list()) - goto err; + goto err_unref_device; return 0; -err: +err_unref_device: udev_device_unref(vhci_driver->hc_device); - +err_free_driver: if (vhci_driver) free(vhci_driver); @@ -277,7 +292,8 @@ void usbip_vhci_driver_close(void) int usbip_vhci_refresh_device_list(void) { - + if (open_hc_device(OPEN_HC_MODE_REOPEN)) + goto err; if (refresh_imported_device_list()) goto err; @@ -409,3 +425,58 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) return 0; } + +#define MAX_BUFF 100 +int usbip_vhci_create_record(char *host, char *port, char *busid, int rhport) +{ + int fd; + char path[PATH_MAX+1]; + char buff[MAX_BUFF+1]; + int ret; + + ret = mkdir(VHCI_STATE_PATH, 0700); + if (ret < 0) { + /* if VHCI_STATE_PATH exists, then it better be a directory */ + if (errno == EEXIST) { + struct stat s; + + ret = stat(VHCI_STATE_PATH, ); + if (ret < 0) + return -1; + if (!(s.st_mode & S_IFDIR)) + return -1; + } else + return -1; + } + + 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; +} + +int usbip_vhci_delete_record(int rhport) +{ + char path[PATH_MAX+1]; + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + + remove(path); + rmdir(VHCI_STATE_PATH); + + return 0; +} diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..f955ada 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/too
[PATCH v9 8/9] usbip: exporting devices: change to usbip_list.c
Correction to wording inconsistency around import and export in usbip_list.c. Please, see also cover letter about wording. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_list.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index f1b38e8..37f9afa 100644 --- a/tools/usb/usbip/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -42,9 +43,9 @@ #include "usbip.h" static const char usbip_list_usage_string[] = - "usbip list [-p|--parsable] \n" + "usbip list \n" "-p, --parsable Parsable list format\n" - "-r, --remote=List the exportable USB devices on \n" + "-r, --remote=List the importable USB devices on \n" "-l, --localList the local USB devices\n"; void usbip_list_usage(void) @@ -52,7 +53,7 @@ void usbip_list_usage(void) printf("usage: %s", usbip_list_usage_string); } -static int get_exported_devices(char *host, int sockfd) +static int get_importable_devices(char *host, int sockfd) { char product_name[100]; char class_name[100]; @@ -82,14 +83,14 @@ static int get_exported_devices(char *host, int sockfd) return -1; } PACK_OP_DEVLIST_REPLY(0, ); - dbg("exportable devices: %d\n", reply.ndev); + dbg("importable devices: %d\n", reply.ndev); if (reply.ndev == 0) { - info("no exportable devices found on %s", host); + info("no importable devices found on %s", host); return 0; } - printf("Exportable USB devices\n"); + printf("Importable USB devices\n"); printf("==\n"); printf(" - %s\n", host); @@ -134,7 +135,7 @@ static int get_exported_devices(char *host, int sockfd) return 0; } -static int list_exported_devices(char *host) +static int list_importable_devices(char *host) { int rc; int sockfd; @@ -147,9 +148,10 @@ static int list_exported_devices(char *host) } dbg("connected to %s:%s", host, usbip_port_string); - rc = get_exported_devices(host, sockfd); + rc = get_importable_devices(host, sockfd); if (rc < 0) { err("failed to get device list from %s", host); + close(sockfd); return -1; } @@ -351,7 +353,7 @@ int usbip_list(int argc, char *argv[]) parsable = true; break; case 'r': - ret = list_exported_devices(optarg); + ret = list_importable_devices(optarg); goto out; case 'l': ret = list_devices(parsable); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v9 0/9] usbip: exporting devices
nd internally. With vUDC, they do not execute bind and unbind. They are done by UDC interface. 4. Security consideration In new operation, when the daemon is running, SSL or Secure WebSocket tunneling poxy can reject unauthorized access. 5. Mixed usage Both existing and new way work in same machines simultaneously. Status of devices and ports are controlled in stub and vhci driver. 6. Wording Adding the new operation, some inconsistnecies in wording are appeared in documentation, function name, etc. If needed, they are fixed. 'export' is used for bind and 'exported' is used for bound. They are changed to 'make importable' and 'imported' respectively. The words not new. For example, in the output of port operation, 'imported devices' is already used. They are sorted out. 'client' and 'server' are switched between existing and new operation. So, words 'device-side' and 'application-side' are used in documentations as needed for clarity. --- Version information This series is divided from "USB/IP over WebSocket" patch set. Rest of the set will be sent as another series. v9) # Moved a set_nodelay() from usbipd_dev.c to usbipd.c to affect both device side and application side daemon. # Removed redundant blank line at the end of files. v8) # Divided into smaller patches. # Excluded low-related patches. # Improved change log. # Changed info level logs in usbip_ux.c to debug level logs. # Added options to vUDC. # Tested with vUDC. v7) # Removed userspace transmission and WebSocket command/daemon. # Fixed checkpatch errors and warnings. v6) # Added __rcu annotation to a RCU pointer to clear sparse warnings. # Corrected a copy to RCU pointer with rcu_rcu_assign_pointer(). # Added __user annotations to arguments of read/write method. # Added static to some functions which are not called from other files. # Removed unnecessary EXPORT_SYMBOLs. v5) # Added vendor/pruduct name conversion to port command. # Put initial value to pool_head in name.c. # Fixed list command exception when host option is omitted. # Fixed exception in case gai_strerror() returns NULL. # Fixed WebSocket connection close via proxy. # Fixed to stop WebSocket ping-pong on connection close. # Removed redundant usbipd daemon option. # Removed redundant SSL code had not been deleted. # Removed an unused local variable in WebSocket code. # Modified C++ reserved word in names.c as same as headers. v4) # Fixed regression of usbip list --remote v3) # Coding style for goto err labels are fixed. # Defined magic numbers for open_hc_device() argument. # Corrected include .../uapi/linux/usbip_ux.h as . # Modified parameter notation in manuals not to use '='. # Fixed inappropriate version definition in tools/.../websocket/configure.ac. # Remved unnecessary COPYING and AUTHORS fil from tools/.../websocket/. # Added -version-info to libraries in tools/.../src. v2) # Formatted patches from linux-next. # Fixed change log word wrapping. # Removed SSL patches. # Fixed a bug that vendor and product names are not shown by 'usbws list -l' because usbip_names_init() was not called in libusbip.la. Thank you, Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> // *** BLURB HERE *** Nobuo Iwata (9): usbip: exporting devices: modifications to network header usbip: exporting devices: modifications to host side libraries usbip: exporting devices: new connect operation usbip: exporting devices: new disconnect operation usbip: exporting devices: modifications to daemon usbip: exporting devices: modifications to attach and detach usbip: exporting devices: new application-side daemon usbip: exporting devices: change to usbip_list.c usbip: exporting devices: chage to documenattion Documentation/usb/usbip_protocol.txt | 204 +++-- tools/usb/usbip/Makefile.am| 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8| 136 +-- tools/usb/usbip/doc/usbipa.8 | 78 +++ tools/usb/usbip/doc/usbipd.8 | 38 ++-- tools/usb/usbip/libsrc/usbip_host_common.c | 6 +- tools/usb/usbip/libsrc/usbip_host_common.h | 8 +- tools/usb/usbip/libsrc/vhci_driver.c | 118 -- tools/usb/usbip/libsrc/vhci_driver.h | 7 +- tools/usb/usbip/src/Makefile.am| 12 +- tools/usb/usbip/src/usbip.c| 15 +- tools/usb/usbip/src/usbip.h| 10 +- tools/usb/usbip/src/usbip_attach.c | 50 +--- tools/usb/usbip/src/usbip_bind.c | 7 +- tools/usb/usbip/src/usbip_connect.c| 228 +++ tools/usb/usbip/src/usbip_detach.c | 13 +- tools/usb/usbip/src/usbip_disconnect.c | 215 ++ tools/usb/usbip/src/usbip_list.c | 22 +- tools/usb/usbip/src/usbip_network.h| 5 +- tools/usb/usbip/src/usbip_unbind.c | 7 +- tools/usb/usbip/src/usbipd.c | 250 +++---
[PATCH v4 1/3] usbip: vhci extension: modifications to vhci driver
Modification to Kconfig, vhci_hc.c, vhci.h and vhci_sysfs.c. 1. kernel config Followings are added. USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host controller. The default is 8 - same as current VHCI_NPORTS. USBIP_VHCI_NR_HCS: Number of USB/IP virtual host controllers. The default is 1. This paratmeter is replaced with USBIP_VHCI_INIT_HCS and USBIP_VHCI_MAX_HCS included in succeeding dynamic extension patch. 2. the_controller to controllers the_controller is changed to vhci_pdevs: array of struct platform_device. 3. vhci_sysfs.c Sysfs structure is changed as following. BEFORE: /sys/devices/platform +-- vhci +-- status +-- attach +-- detach +-- usbip_debug AFTER: example for CONFIG_USBIP_NR_HCS=4 /sys/devices/platform +-- vhci | +-- nports | +-- status | +-- status.1 | +-- status.2 | +-- status.3 | +-- attach | +-- detach | +-- usbip_debug +-- vhci.1 +-- vhci.2 +-- vhci.3 vhci[.N] is shown for each host controller kobj. vhch.1, vhci.2, ... are shown only when CONFIG_USBIP_NR_HCS is more than 1. Only 'vhci' (without number) has user space interfaces. 'nports' is newly added to give ports-per-controller and number of controlles. Before that, number of ports is acquired by reading status lines. Status is divided for each controller to avoid page size (4KB) limitation. Old userspace tool binaries work with the first status within the first controller. Inconsistency between status header and content is fixed. 4th and 5th column are header: "dev bus" content(unused): "000 000" content(used): "%08x", devid Only 1st and 2nd column are used by program. In old version, sscanf() in parse_status expect no bus column. And bus_id string is shown in the last column. Then bus in the header is removed and unused content is replaced with 8 zeros. The sscanf() expects more than 5 columns and new has 6 columns so there's no compatibility issue in this change. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/Kconfig | 21 +++ drivers/usb/usbip/vhci.h | 54 -- drivers/usb/usbip/vhci_hcd.c | 285 --- drivers/usb/usbip/vhci_rx.c| 21 +-- drivers/usb/usbip/vhci_sysfs.c | 296 + 5 files changed, 497 insertions(+), 180 deletions(-) diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index 17646b2..29492c7 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -24,6 +24,27 @@ config USBIP_VHCI_HCD To compile this driver as a module, choose M here: the module will be called vhci-hcd. +config USBIP_VHCI_HC_PORTS + int "Number of ports per USB/IP virtual host controller" + range 1 31 + default 8 + depends on USBIP_VHCI_HCD + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of ports per + USB/IP virtual host controller. + +config USBIP_VHCI_NR_HCS + int "Number of USB/IP virtual host controllers" + range 1 128 + default 1 + depends on USBIP_VHCI_HCD + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of USB/IP + virtual host controllers as if adding physical host + controllers. + config USBIP_HOST tristate "Host driver" depends on USBIP_CORE && USB diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index a863a98..88b71c4 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2003-2008 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,13 +73,25 @@ struct vhci_unlink { }; /* Number of supported ports. Value has an upperbound of USB_MAXCHILDREN */ -#define VHCI_NPORTS 8 +#ifdef CONFIG_USBIP_VHCI_HC_PORTS +#define VHCI_HC_PORTS CONFIG_USBIP_VHCI_HC_PORTS +#else +#define VHCI_HC_PORTS 8 +#endif + +#ifdef CONFIG_USBIP_VHCI_NR_HCS +#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS +#else +#define VHCI_NR_HCS 1 +#endif + +#define MAX_STATUS_NAME 16 /* for usb_bus.hcpriv */ struct vhci_hcd { spinlock_t lock; - u32 port_status[VHCI_NPORTS]; + u32 port_status[VHCI_HC_PORTS]; unsigned resuming:1; unsigned long re_timeout; @@ -90,14 +103,19 @@ struct vhci_hcd { * wIndex shows the port number and begins from 1. * But, the index of this array begins from 0. */ - struct vhci_device vdev[VHCI_NPORTS]; + struct vhci_device vdev[VH
[PATCH v4 2/3] usbip: vhci extension: modifications to userspace
Modification to the userspace tools including usbip/libsrc and usbip/src. Changed corresponding to new vhci_sysfs.c. nports in sysfs is used to get total number of ports. Old get_nports() ignores the last status line because udev_device_get_sysattr_value() drops last new line. New version uses nports attribute so it's doesn't have this problem. status[.N] in sysfs are used. parse_status() which reads all status lines is broken into open, close, read-line and parse-line. Parse-line is reused to find free port and get imported device. In daemon, status was loaded into memory by usbip_vhci_refresh_device_list() at receiving every request. The loaded status is used to find free port. It is changed to read status directly to find free port. Wording inconsistencies are fixed according to the rule below. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 398 +++ tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 49 ++-- 5 files changed, 253 insertions(+), 260 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index 50c723d..4d1b986 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -15,11 +15,24 @@ #undef PROGNAME #define PROGNAME "libusbip" -struct usbip_vhci_driver *vhci_driver; -struct udev *udev_context; +static struct udev_device *vhci_hc_device; +static struct udev *udev_context; +static int vhci_nports; -static struct usbip_imported_device * -imported_device_init(struct usbip_imported_device *idev, char *busid) +struct usbip_vhci_device { + int port; + uint32_t status; + + uint32_t devid; + + uint8_t busnum; + uint8_t devnum; + + /* usbip_class_device list */ + struct usbip_usb_device udev; +}; + +static int imported_device_init(struct usbip_vhci_device *vdev, char *busid) { struct udev_device *sudev; @@ -27,132 +40,131 @@ imported_device_init(struct usbip_imported_device *idev, char *busid) "usb", busid); if (!sudev) { dbg("udev_device_new_from_subsystem_sysname failed: %s", busid); - goto err; + return -1; } - read_usb_device(sudev, >udev); + read_usb_device(sudev, >udev); udev_device_unref(sudev); - return idev; - -err: - return NULL; + return 0; } +struct status_context { + int controller; + const char *c; +}; +#define OPEN_MODE_FIRST 0 +#define OPEN_MODE_REOPEN 1 -static int parse_status(const char *value) -{ - int ret = 0; - char *c; +static int open_hc_device(int mode); +#define MAX_STATUS_NAME 16 - for (int i = 0; i < vhci_driver->nports; i++) - memset(_driver->idev[i], 0, sizeof(vhci_driver->idev[i])); +static int open_status(struct status_context *ctx, int mode) +{ + char name[MAX_STATUS_NAME+1]; + if (mode == OPEN_MODE_FIRST) + ctx->controller = 0; + else + (ctx->controller)++; - /* skip a header line */ - c = strchr(value, '\n'); - if (!c) + if (open_hc_device(OPEN_MODE_REOPEN)) return -1; - c++; - - while (*c != '\0') { - int port, status, speed, devid; - unsigned long socket; - char lbusid[SYSFS_BUS_ID_SIZE]; - - ret = sscanf(c, "%d %d %d %x %lx %31s\n", - , , , - , , lbusid); - - if (ret < 5) { - dbg("sscanf failed: %d", ret); - BUG(); - } - dbg("port %d status %d speed %d devid %x", - port, status, speed, devid); - dbg("socket %lx lbusid %s", socket, lbusid); + if (ctx->controller == 0) + strcpy(name, "status"); + else + snprintf(name, MAX_STATUS_NAME + 1, + "status.%d", ctx->controller); + ctx->c = udev_device_get_sysattr_value(vhci_hc_device, name); + if (ctx->c == NULL) + return -1; + return 0; +} - /* if a device is connected, look at it */ - { - struct usbip_imported_device *idev = _driver->idev[port]; +static void close_status(struct status_context *ctx) +{ + ctx->c = NULL; +} - idev->port = po
[PATCH v4 3/3] usbip: vhci extension: dynamic extension
Modification for dynamic device registration and unregistration. 1. kernel config Followings are added. USBIP_VHCI_HC_PORTS: Number of ports per USB/IP virtual host controller. The default is 8 - same as current VHCI_NPORTS. USBIP_VHCI_MAX_HCS: Muximum number of USB/IP virtual host controllers. The default is 1. USBIP_VHCI_INIT_HCS: Initial number of USB/IP virtual host controllers. The default is 1. Static number of devices: USBIP_VHCI_NR_HCS in patch 1/3 is removed with this patch. 2. view from sysfs Sysfs structure is changed as following. BEFORE this patchset: /sys/devices/platform +-- vhci +-- status +-- attach +-- detach +-- usbip_debug AFTER: example for CONFIG_USBIP_INIT_HCS=2 CONFIG_USBIP_MAX_HCS=4 At the beginning /sys/devices/platform +-- vhci | +-- nports | +-- status | +-- status.1 | +-- status.2 | +-- status.3 | +-- attach | +-- detach | +-- usbip_debug +-- vhci.1 The status files are shown to the maximum number of devices. Port status in status.2 and status.3 represents as free but corresponding devices are not yes registered. When all ports in status and status.1 are used, userspace tool requests 'attach' to a port in status.2 then vhci.2 will be registred. The limit is defined with USBIP_VHCI_MAX_NCS. By preparing muximum number of status files, there's no need to introduce additional operations for userspace tool. When number of free ports becomes more than USBIP_VHCI_HC_PORTS * VHCI_FREE_HCS(2), a free controller other than the first one will be unregistered. It will be invoked by 'detach' operation and other error situations which ports are released. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/Kconfig | 17 ++- drivers/usb/usbip/vhci.h | 36 - drivers/usb/usbip/vhci_hcd.c | 251 - drivers/usb/usbip/vhci_rx.c| 10 +- drivers/usb/usbip/vhci_sysfs.c | 49 --- drivers/usb/usbip/vhci_tx.c| 6 +- 6 files changed, 294 insertions(+), 75 deletions(-) diff --git a/drivers/usb/usbip/Kconfig b/drivers/usb/usbip/Kconfig index 29492c7..d11b548 100644 --- a/drivers/usb/usbip/Kconfig +++ b/drivers/usb/usbip/Kconfig @@ -34,8 +34,8 @@ config USBIP_VHCI_HC_PORTS host controller driver, this defines number of ports per USB/IP virtual host controller. -config USBIP_VHCI_NR_HCS - int "Number of USB/IP virtual host controllers" +config USBIP_VHCI_MAX_HCS + int "Maximum number of USB/IP virtual host controllers" range 1 128 default 1 depends on USBIP_VHCI_HCD @@ -43,7 +43,18 @@ config USBIP_VHCI_NR_HCS To increase number of ports available for USB/IP virtual host controller driver, this defines number of USB/IP virtual host controllers as if adding physical host - controllers. + controllers. This defines the maximum number. + +config USBIP_VHCI_INIT_HCS + int "Initial number of USB/IP virtual host controllers" + range 1 USBIP_VHCI_MAX_HCS + default 1 + depends on USBIP_VHCI_MAX_HCS + ---help--- + To increase number of ports available for USB/IP virtual + host controller driver, this defines number of USB/IP + virtual host controllers as if adding physical host + controllers. This defines the number at initializing. config USBIP_HOST tristate "Host driver" diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h index 88b71c4..ba893a7 100644 --- a/drivers/usb/usbip/vhci.h +++ b/drivers/usb/usbip/vhci.h @@ -51,6 +51,9 @@ struct vhci_device { /* vhci_tx thread sleeps for this queue */ wait_queue_head_t waitq_tx; + + /* denotes port is in-use */ + atomic_t using_port; }; /* urb->hcpriv, use container_of() */ @@ -79,12 +82,21 @@ struct vhci_unlink { #define VHCI_HC_PORTS 8 #endif -#ifdef CONFIG_USBIP_VHCI_NR_HCS -#define VHCI_NR_HCS CONFIG_USBIP_VHCI_NR_HCS +#ifdef CONFIG_USBIP_VHCI_MAX_HCS +#define VHCI_MAX_HCS CONFIG_USBIP_VHCI_MAX_HCS +#else +#define VHCI_MAX_HCS 1 +#endif + +#ifdef CONFIG_USBIP_VHCI_INIT_HCS +#define VHCI_INIT_HCS CONFIG_USBIP_VHCI_INIT_HCS #else -#define VHCI_NR_HCS 1 +#define VHCI_INIT_HCS 1 #endif +/* VHCI_FREE_HCS * VHCI_HC_PORTS: ports to keep free at unregister */ +#define VHCI_FREE_HCS 2 + #define MAX_STATUS_NAME 16 /* for usb_bus.hcpriv */ @@ -98,6 +110,8 @@ struct vhci_hcd { atomic_t seqnum; + unsigned int using_ports; + /* * NOTE: * wIndex shows the port number and begins from 1. @@ -106,12 +120,18 @@ struct vhci_hcd { struct vhci_device vdev[VHCI_HC_PORTS]; }; +extern int vhci_max_controllers; +extern int vhci_init_controllers; extern int vhci_num_controllers; extern st
[PATCH v4 0/3] usbip: vhci number of ports extension
This series of patches extends number of ports limitaion in application (vhci) side. 1. Background Assuming a system shown below that services distributerd devices in home or office via USB/IP, if the devices are set at every doors and windows, number devices may be up to tens. Home/SOHO/Enterprise Intranet/Internet +--+ +--+ USB/IP+-+ +|device|--+|Linux |---|Service | |+--+ |+--+---|on Linux | +--+ +--++-+ ex) Device Service sensors ... environment analysis cameras ... monitoring, recording ID/biometric readers .. authentication If USB/IP is used for ubiqitous devices or IoT devices, many devices might be handled. 2. About this patch set In current USB/IP, available number of ports (ie. number of supported devices) is VHCI_NPORTS(8) in drivers/usb/usbip/vhci.h. The value of the macro can be altered to USB_MAXCHILDREN(31). This limit is came from hub status bit array. See also the comment at USB_MAXCHILDREN include/uapi/linux/usb/ch11.h. There are two way to increase number of available ports. The first way is to put hub emulator under vhci. This can add ports up to 255 - the limit of USB 2.0 host controller. The second way is to add host controller. It's as same as machines have several host controllers: most desktop or note PCs have more than one host controller. Current USB/IP supports only one controller defined as 'the_controller' in drivers/usb/usbip/vhci_hcd.c. This patch takes the second way described above and adds virtual controllers. In this patch, the number is specified by kernel configuration. 3. Dynamic extension According to kernel configuration, vhci devices (platform device) will be added and removed when they are not used. When the vhci driver is loaded, USBIP_VHCI_INIT_HCS (default is 1) drivers are registered. They will be further registered upto USBIP_VHCI_MAX_HCS (default is 1). They are unregistered when number of free devices becomes more than VHCI_FREE_HCS(2) except the first device. 4. Wording Wording inconsistencies in function and variable names are corrected according to the rule below. They were not strict because only one host controller was handled. rhport, HC_PORTS: ports within a controller (or root hub). port, nports: ports across the controllers. 5. Dependencis This series depends on 'usbip: exporting devices' patch set because this includes changes to application side daemon which introduced the patch set. --- Version information v4) # Changed the method to set number of controllers from a module parameter to kernel config. # Excluded event thread patch merged to 4.7-rc1. # Added dynamic extension. v3) # Fixed conflicts against linux-next 20160209. # Changed sysfs object and attribute name for old tools compatibility. # Changed nports status format not to include num_controllers value. # Fixed checkpatch errors and warnings. v2) # Added static to some functions and variables not called from other files. *** BLURB HERE *** Nobuo Iwata (3): usbip: vhci extension: modifications to vhci driver usbip: vhci extension: modifications to userspace usbip: vhci extension: dynamic extension drivers/usb/usbip/Kconfig| 32 ++ drivers/usb/usbip/vhci.h | 84 - drivers/usb/usbip/vhci_hcd.c | 468 +-- drivers/usb/usbip/vhci_rx.c | 31 +- drivers/usb/usbip/vhci_sysfs.c | 303 + drivers/usb/usbip/vhci_tx.c | 6 +- tools/usb/usbip/libsrc/vhci_driver.c | 398 --- tools/usb/usbip/libsrc/vhci_driver.h | 45 +-- tools/usb/usbip/src/usbip_attach.c | 8 +- tools/usb/usbip/src/usbip_port.c | 13 +- tools/usb/usbip/src/usbipd_app.c | 49 ++- 11 files changed, 983 insertions(+), 454 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v8 0/9] usbip: exporting devices
nd internally. With vUDC, they do not execute bind and unbind. They are done by UDC interface. 4. Security consideration In new operation, when the daemon is running, SSL or Secure WebSocket tunneling poxy can reject unauthorized access. 5. Mixed usage Both existing and new way work in same machines simultaneously. Status of devices and ports are controlled in stub and vhci driver. 6. Wording Adding the new operation, some inconsistnecies in wording are appeared in documentation, function name, etc. If needed, they are fixed. 'export' is used for bind and 'exported' is used for bound. They are changed to 'make importable' and 'imported' respectively. The words not new. For example, in the output of port operation, 'imported devices' is already used. They are sorted out. 'client' and 'server' are switched between existing and new operation. So, words 'device-side' and 'application-side' are used in documentations as needed for clarity. --- Version information This series is divided from "USB/IP over WebSocket" patch set. Rest of the set will be sent as another series. v8) # Divided into smaller patches. # Excluded low-related patches. # Improved change log. # Changed info level logs in usbip_ux.c to debug level logs. # Added options to vUDC. # Tested with vUDC. v7) # Removed userspace transmission and WebSocket command/daemon. # Fixed checkpatch errors and warnings. v6) # Added __rcu annotation to a RCU pointer to clear sparse warnings. # Corrected a copy to RCU pointer with rcu_rcu_assign_pointer(). # Added __user annotations to arguments of read/write method. # Added static to some functions which are not called from other files. # Removed unnecessary EXPORT_SYMBOLs. v5) # Added vendor/pruduct name conversion to port command. # Put initial value to pool_head in name.c. # Fixed list command exception when host option is omitted. # Fixed exception in case gai_strerror() returns NULL. # Fixed WebSocket connection close via proxy. # Fixed to stop WebSocket ping-pong on connection close. # Removed redundant usbipd daemon option. # Removed redundant SSL code had not been deleted. # Removed an unused local variable in WebSocket code. # Modified C++ reserved word in names.c as same as headers. v4) # Fixed regression of usbip list --remote v3) # Coding style for goto err labels are fixed. # Defined magic numbers for open_hc_device() argument. # Corrected include .../uapi/linux/usbip_ux.h as . # Modified parameter notation in manuals not to use '='. # Fixed inappropriate version definition in tools/.../websocket/configure.ac. # Remved unnecessary COPYING and AUTHORS fil from tools/.../websocket/. # Added -version-info to libraries in tools/.../src. v2) # Formatted patches from linux-next. # Fixed change log word wrapping. # Removed SSL patches. # Fixed a bug that vendor and product names are not shown by 'usbws list -l' because usbip_names_init() was not called in libusbip.la. Thank you, Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> // *** BLURB HERE *** Nobuo Iwata (9): usbip: exporting devices: modifications to network header usbip: exporting devices: modifications to host side libraries usbip: exporting devices: new connect operation usbip: exporting devices: new disconnect operation usbip: exporting devices: modifications to daemon usbip: exporting devices: modifications to attach and detach usbip: exporting devices: new application-side daemon usbip: exporting devices: change to usbip_list.c usbip: exporting devices: chage to documenattion Documentation/usb/usbip_protocol.txt | 204 ++-- tools/usb/usbip/Makefile.am| 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8| 136 +-- tools/usb/usbip/doc/usbipa.8 | 79 +++ tools/usb/usbip/doc/usbipd.8 | 37 +-- tools/usb/usbip/libsrc/usbip_host_common.c | 6 +- tools/usb/usbip/libsrc/usbip_host_common.h | 8 +- tools/usb/usbip/libsrc/vhci_driver.c | 118 -- tools/usb/usbip/libsrc/vhci_driver.h | 7 +- tools/usb/usbip/src/Makefile.am| 12 +- tools/usb/usbip/src/usbip.c| 15 +- tools/usb/usbip/src/usbip.h| 10 +- tools/usb/usbip/src/usbip_attach.c | 50 +--- tools/usb/usbip/src/usbip_bind.c | 7 +- tools/usb/usbip/src/usbip_connect.c| 228 ++ tools/usb/usbip/src/usbip_detach.c | 13 +- tools/usb/usbip/src/usbip_disconnect.c | 215 + tools/usb/usbip/src/usbip_list.c | 22 +- tools/usb/usbip/src/usbip_network.h| 5 +- tools/usb/usbip/src/usbip_unbind.c | 7 +- tools/usb/usbip/src/usbipd.c | 247 +++- tools/usb/usbip/src/usbipd.h | 39 tools/usb/usbip/src/usbipd_app.c | 243 +++ tools/usb/usbip/src/usbipd_dev.c | 256
[PATCH v8 5/9] usbip: exporting devices: modifications to daemon
Refactoring to the daemon. usbipd_dev.c is device-side specific code extracted from usbipd.c. usbipd.c is left as common parts for both device(stub)-side and application(vhci)-side daemon. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 2 +- tools/usb/usbip/src/usbipd.c | 235 +++- tools/usb/usbip/src/usbipd.h | 39 + tools/usb/usbip/src/usbipd_dev.c | 256 +++ 4 files changed, 316 insertions(+), 216 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 42760c3..1aa5156 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -9,4 +9,4 @@ usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c -usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c +usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index a0972de..ef60026 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -43,25 +44,19 @@ #include #include -#include "usbip_host_driver.h" -#include "usbip_host_common.h" -#include "usbip_device_driver.h" #include "usbip_common.h" #include "usbip_network.h" +#include "usbipd.h" #include "list.h" -#undef PROGNAME -#define PROGNAME "usbipd" #define MAXSOCKFD 20 #define MAIN_LOOP_TIMEOUT 10 -#define DEFAULT_PID_FILE "/var/run/" PROGNAME ".pid" - static const char usbip_version_string[] = PACKAGE_STRING; static const char usbipd_help_string[] = - "usage: usbipd [options]\n" + "usage: %s [options]\n" "\n" " -4, --ipv4\n" " Bind to IPv4. Default is both.\n" @@ -82,7 +77,7 @@ static const char usbipd_help_string[] = "\n" " -PFILE, --pid FILE\n" " Write process id to FILE.\n" - " If no FILE specified, use " DEFAULT_PID_FILE "\n" + " If no FILE specified, use %s.\n" "\n" " -tPORT, --tcp-port PORT\n" " Listen on TCP/IP port PORT.\n" @@ -93,198 +88,9 @@ static const char usbipd_help_string[] = " -v, --version\n" " Show version.\n"; -static struct usbip_host_driver *driver; - static void usbipd_help(void) { - printf("%s\n", usbipd_help_string); -} - -static int recv_request_import(int sockfd) -{ - struct op_import_request req; - struct usbip_exported_device *edev; - struct usbip_usb_device pdu_udev; - struct list_head *i; - int found = 0; - int error = 0; - int rc; - - memset(, 0, sizeof(req)); - - rc = usbip_net_recv(sockfd, , sizeof(req)); - if (rc < 0) { - dbg("usbip_net_recv failed: import request"); - return -1; - } - PACK_OP_IMPORT_REQUEST(0, ); - - list_for_each(i, >edev_list) { - edev = list_entry(i, struct usbip_exported_device, node); - if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) { - info("found requested device: %s", req.busid); - found = 1; - break; - } - } - - if (found) { - /* should set TCP_NODELAY for usbip */ - usbip_net_set_nodelay(sockfd); - - /* export device needs a TCP/IP socket descriptor */ - rc = usbip_export_device(edev, sockfd); - if (rc < 0) - error = 1; - } else { - info("requested device not found: %s", req.busid); - error = 1; - } - - rc = usbip_net_send_op_common(sockfd, OP_REP_IMPORT, - (!error ? ST_OK : ST_NA)); - if (rc < 0) { - dbg("usbip_net_send_op_common failed: %#0x", OP_REP_IMPORT); - return -1; - } - - if (error) { - dbg("import request busid %s: failed", req.busid); - return -1; - } - - memcpy(_udev, >udev, sizeof(pd
[PATCH v8 1/9] usbip: exporting devices: modifications to network header
Modification to export and un-export response in tools/usb/usbip/src/usbip_network.h. It just changes return code type from int to uint32_t as same as other responses. Added export and un-export request/response to Documentation/usb/usbip_protocol.txt. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- Documentation/usb/usbip_protocol.txt | 204 --- tools/usb/usbip/src/usbip_network.h | 5 +- 2 files changed, 184 insertions(+), 25 deletions(-) diff --git a/Documentation/usb/usbip_protocol.txt b/Documentation/usb/usbip_protocol.txt index 16b6fe2..d4be5b6 100644 --- a/Documentation/usb/usbip_protocol.txt +++ b/Documentation/usb/usbip_protocol.txt @@ -1,20 +1,26 @@ PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! 28 Jun 2011 +MODIFIED FOR CONNECT AND DISCONNECT OPERARION. +07 March 2016 -The USB/IP protocol follows a server/client architecture. The server exports the -USB devices and the clients imports them. The device driver for the exported -USB device runs on the client machine. +The USB/IP protocol follows a server/client architecture between two computers +one has USB devices and the other runs application using the devices. There are +two ways for initiation. -The client may ask for the list of the exported USB devices. To get the list the -client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST -packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent -in one or more pieces at the low level transport layer). The server sends back -the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the -TCP/IP connection is closed. +The first way is to import devices from application-side. In this way, the +server runs in device-side and the client runs in application-side. In device +side user makes devices importable with 'bind' operation. +The client may ask for the list of the importable USB devices. To get the list +the client opens a TCP/IP connection towards the server, and sends an +OP_REQ_DEVLIST packet on top of the TCP/IP connection (so the actual +OP_REQ_DEVLIST may be sent in one or more pieces at the low level transport +layer). The server sends back the OP_REP_DEVLIST packet which lists the +importable USB devices. Finally the TCP/IP connection is closed. + + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (lists importable devices)"server" | | | OP_REQ_DEVLIST | | --> | @@ -23,18 +29,13 @@ TCP/IP connection is closed. | <-- | | | -Once the client knows the list of exported USB devices it may decide to use one -of them. First the client opens a TCP/IP connection towards the server and -sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the -import was successful the TCP/IP connection remains open and will be used -to transfer the URB traffic between the client and the server. The client may -send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and -USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the -server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. +Once the client knows the list of importable USB devices it may decide to use +one of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. + application-sidedevice-side virtual host controller usb host - "client" "server" - (imports USB devices) (exports USB devices) + "client" (imports a USB device) "server" | | | OP_REQ_IMPORT | | --> | @@ -42,6 +43,32 @@ server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. | OP_REP_IMPORT | | <-- | | | + +The second way is to export devices from device-side. In this way, the server +runs in application-side and the client runs in device-side. The client binds a +device to export, opens a TCP/IP connection towards the server
[PATCH v8 2/9] usbip: exporting devices: modifications to host side libraries
usbip_host_find_device() is created based on usbip_host_get_device(). usbip_host_get_device() was not used yet. bind and unbind function are exported for new operations. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/usbip_host_common.c | 6 ++ tools/usb/usbip/libsrc/usbip_host_common.h | 8 tools/usb/usbip/src/usbip.h| 3 +++ tools/usb/usbip/src/usbip_bind.c | 7 --- tools/usb/usbip/src/usbip_unbind.c | 7 --- 5 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/usb/usbip/libsrc/usbip_host_common.c b/tools/usb/usbip/libsrc/usbip_host_common.c index 9d41522..6a98d6c 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.c +++ b/tools/usb/usbip/libsrc/usbip_host_common.c @@ -256,17 +256,15 @@ int usbip_export_device(struct usbip_exported_device *edev, int sockfd) } struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num) + struct usbip_host_driver *hdriver, char *busid) { struct list_head *i; struct usbip_exported_device *edev; - int cnt = 0; list_for_each(i, >edev_list) { edev = list_entry(i, struct usbip_exported_device, node); - if (num == cnt) + if (!strncmp(busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) return edev; - cnt++; } return NULL; diff --git a/tools/usb/usbip/libsrc/usbip_host_common.h b/tools/usb/usbip/libsrc/usbip_host_common.h index a64b803..f9a9def 100644 --- a/tools/usb/usbip/libsrc/usbip_host_common.h +++ b/tools/usb/usbip/libsrc/usbip_host_common.h @@ -38,7 +38,7 @@ struct usbip_host_driver_ops { void (*close)(struct usbip_host_driver *hdriver); int (*refresh_device_list)(struct usbip_host_driver *hdriver); struct usbip_exported_device * (*get_device)( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); int (*read_device)(struct udev_device *sdev, struct usbip_usb_device *dev); @@ -86,11 +86,11 @@ static inline int usbip_refresh_device_list(struct usbip_host_driver *hdriver) } static inline struct usbip_exported_device * -usbip_get_device(struct usbip_host_driver *hdriver, int num) +usbip_get_device(struct usbip_host_driver *hdriver, char *busid) { if (!hdriver->ops.get_device) return NULL; - return hdriver->ops.get_device(hdriver, num); + return hdriver->ops.get_device(hdriver, busid); } /* Helper functions for implementing driver backend */ @@ -99,6 +99,6 @@ void usbip_generic_driver_close(struct usbip_host_driver *hdriver); int usbip_generic_refresh_device_list(struct usbip_host_driver *hdriver); int usbip_export_device(struct usbip_exported_device *edev, int sockfd); struct usbip_exported_device *usbip_generic_get_device( - struct usbip_host_driver *hdriver, int num); + struct usbip_host_driver *hdriver, char *busid); #endif /* __USBIP_HOST_COMMON_H */ diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index 84fe66a..c296910 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -37,4 +37,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); +int usbip_bind_device(char *busid); +int usbip_unbind_device(char *busid); + #endif /* __USBIP_H */ diff --git a/tools/usb/usbip/src/usbip_bind.c b/tools/usb/usbip/src/usbip_bind.c index fa46141..1c09338 100644 --- a/tools/usb/usbip/src/usbip_bind.c +++ b/tools/usb/usbip/src/usbip_bind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -139,7 +140,7 @@ out: return status; } -static int bind_device(char *busid) +int usbip_bind_device(char *busid) { int rc; struct udev *udev; @@ -200,7 +201,7 @@ int usbip_bind(int argc, char *argv[]) switch (opt) { case 'b': - ret = bind_device(optarg); + ret = usbip_bind_device(optarg); goto out; default: goto err_out; diff --git a/tools/usb/usbip/src/usbip_unbind.c b/tools/usb/usbip/src/usbip_unbind.c index a4a496c..cc1ff26 100644 --- a/tools/usb/usbip/src/usbip_unbind.c +++ b/tools/usb/usbip/src/usbip_unbind.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This p
[PATCH v8 3/9] usbip: exporting devices: new connect operation
New connect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am | 3 +- tools/usb/usbip/src/usbip.c | 9 +- tools/usb/usbip/src/usbip.h | 5 +- tools/usb/usbip/src/usbip_connect.c | 228 4 files changed, 242 insertions(+), 3 deletions(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index e81a4eb..0947476 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -6,6 +6,7 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ -usbip_bind.c usbip_unbind.c usbip_port.c +usbip_bind.c usbip_unbind.c usbip_port.c \ +usbip_connect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index d7599d9..584d7d5 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -2,7 +2,8 @@ * command structure borrowed from udev * (git://git.kernel.org/pub/scm/linux/hotplug/udev.git) * - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -76,6 +77,12 @@ static const struct command cmds[] = { .usage = usbip_detach_usage }, { + .name = "connect", + .fn= usbip_connect, + .help = "Connect a USB device to a remote computer", + .usage = usbip_connect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index c296910..f365353 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * * This program is free software: you can redistribute it and/or modify @@ -30,12 +31,14 @@ int usbip_list(int argc, char *argv[]); int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); +int usbip_connect(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); +void usbip_connect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_connect.c b/tools/usb/usbip/src/usbip_connect.c new file mode 100644 index 000..bbecc7e --- /dev/null +++ b/tools/usb/usbip/src/usbip_connect.c @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_connect_usage_string[] = + "usbip connect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be connected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_connect_usage(void) +{ + printf("usage: %s", usbip_connect_usage_string); +} + +static int send_export_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_export_request request; + struct op_export_reply reply
[PATCH v8 6/9] usbip: exporting devices: modifications to attach and detach
Refactoring to attach and detatch operation. Common parts to new application(vhci)-side daemon are moved to libsrc/vhci_driver.c. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 99 tools/usb/usbip/libsrc/vhci_driver.h | 6 +- tools/usb/usbip/src/usbip_attach.c | 50 ++ tools/usb/usbip/src/usbip_detach.c | 13 ++-- 4 files changed, 100 insertions(+), 68 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index ad92047..b7ca63d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2005-2007 Takahiro Hirofuchi + * Copyright (C) 2015 Nobuo Iwata + * 2005-2007 Takahiro Hirofuchi */ #include "usbip_common.h" @@ -7,6 +8,8 @@ #include #include #include +#include +#include #include "sysfs_utils.h" #undef PROGNAME @@ -215,6 +218,25 @@ static int read_record(int rhport, char *host, unsigned long host_len, return 0; } +#define OPEN_HC_MODE_FIRST 0 +#define OPEN_HC_MODE_REOPEN1 + +static int open_hc_device(int mode) +{ + if (mode == OPEN_HC_MODE_REOPEN) + udev_device_unref(vhci_driver->hc_device); + + vhci_driver->hc_device = + udev_device_new_from_subsystem_sysname(udev_context, + USBIP_VHCI_BUS_TYPE, + USBIP_VHCI_DRV_NAME); + if (!vhci_driver->hc_device) { + err("udev_device_new_from_subsystem_sysname failed"); + return -1; + } + return 0; +} + /* -- */ int usbip_vhci_driver_open(void) @@ -227,28 +249,21 @@ int usbip_vhci_driver_open(void) vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver)); - /* will be freed in usbip_driver_close() */ - vhci_driver->hc_device = - udev_device_new_from_subsystem_sysname(udev_context, - USBIP_VHCI_BUS_TYPE, - USBIP_VHCI_DRV_NAME); - if (!vhci_driver->hc_device) { - err("udev_device_new_from_subsystem_sysname failed"); - goto err; - } + if (open_hc_device(OPEN_HC_MODE_FIRST)) + goto err_free_driver; vhci_driver->nports = get_nports(); dbg("available ports: %d", vhci_driver->nports); if (refresh_imported_device_list()) - goto err; + goto err_unref_device; return 0; -err: +err_unref_device: udev_device_unref(vhci_driver->hc_device); - +err_free_driver: if (vhci_driver) free(vhci_driver); @@ -277,7 +292,8 @@ void usbip_vhci_driver_close(void) int usbip_vhci_refresh_device_list(void) { - + if (open_hc_device(OPEN_HC_MODE_REOPEN)) + goto err; if (refresh_imported_device_list()) goto err; @@ -409,3 +425,58 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev) return 0; } + +#define MAX_BUFF 100 +int usbip_vhci_create_record(char *host, char *port, char *busid, int rhport) +{ + int fd; + char path[PATH_MAX+1]; + char buff[MAX_BUFF+1]; + int ret; + + ret = mkdir(VHCI_STATE_PATH, 0700); + if (ret < 0) { + /* if VHCI_STATE_PATH exists, then it better be a directory */ + if (errno == EEXIST) { + struct stat s; + + ret = stat(VHCI_STATE_PATH, ); + if (ret < 0) + return -1; + if (!(s.st_mode & S_IFDIR)) + return -1; + } else + return -1; + } + + 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; +} + +int usbip_vhci_delete_record(int rhport) +{ + char path[PATH_MAX+1]; + + snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); + + remove(path); + rmdir(VHCI_STATE_PATH); + + return 0; +} diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index fa2316c..f955ada 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/too
[PATCH v8 4/9] usbip: exporting devices: new disconnect operation
New disconnect operation. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/Makefile.am| 2 +- tools/usb/usbip/src/usbip.c| 6 + tools/usb/usbip/src/usbip.h| 2 + tools/usb/usbip/src/usbip_disconnect.c | 215 + 4 files changed, 224 insertions(+), 1 deletion(-) diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 0947476..42760c3 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -7,6 +7,6 @@ sbin_PROGRAMS := usbip usbipd usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ -usbip_connect.c +usbip_connect.c usbip_disconnect.c usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c diff --git a/tools/usb/usbip/src/usbip.c b/tools/usb/usbip/src/usbip.c index 584d7d5..f0e9e06 100644 --- a/tools/usb/usbip/src/usbip.c +++ b/tools/usb/usbip/src/usbip.c @@ -83,6 +83,12 @@ static const struct command cmds[] = { .usage = usbip_connect_usage }, { + .name = "disconnect", + .fn= usbip_disconnect, + .help = "Disconnect a USB device from a remote computer", + .usage = usbip_disconnect_usage + }, + { .name = "list", .fn= usbip_list, .help = "List exportable or local USB devices", diff --git a/tools/usb/usbip/src/usbip.h b/tools/usb/usbip/src/usbip.h index f365353..a8cbd16 100644 --- a/tools/usb/usbip/src/usbip.h +++ b/tools/usb/usbip/src/usbip.h @@ -32,6 +32,7 @@ int usbip_bind(int argc, char *argv[]); int usbip_unbind(int argc, char *argv[]); int usbip_port_show(int argc, char *argv[]); int usbip_connect(int argc, char *argv[]); +int usbip_disconnect(int argc, char *argv[]); void usbip_attach_usage(void); void usbip_detach_usage(void); @@ -39,6 +40,7 @@ void usbip_list_usage(void); void usbip_bind_usage(void); void usbip_unbind_usage(void); void usbip_connect_usage(void); +void usbip_disconnect_usage(void); int usbip_bind_device(char *busid); int usbip_unbind_device(char *busid); diff --git a/tools/usb/usbip/src/usbip_disconnect.c b/tools/usb/usbip/src/usbip_disconnect.c new file mode 100644 index 000..8155384 --- /dev/null +++ b/tools/usb/usbip/src/usbip_disconnect.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@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 + +#include +#include +#include +#include + +#include +#include + +#include "usbip_host_driver.h" +#include "usbip_host_common.h" +#include "usbip_device_driver.h" +#include "usbip_common.h" +#include "usbip_network.h" +#include "usbip.h" + +static struct usbip_host_driver *driver = _driver; + +static const char usbip_disconnect_usage_string[] = + "usbip disconnect \n" + "-r, --remote=Address of a remote computer\n" + "-b, --busid=Bus ID of a device to be disconnected\n" + "-d, --device Run with an alternate driver, e.g. vUDC\n"; + +void usbip_disconnect_usage(void) +{ + printf("usage: %s", usbip_disconnect_usage_string); +} + +static int send_unexport_device(int sockfd, struct usbip_usb_device *udev) +{ + int rc; + struct op_unexport_request request; + struct op_unexport_reply reply; + uint16_t code = OP_REP_UNEXPORT; + + memset(, 0, sizeof(request)); + memset(, 0, sizeof(reply)); + + /* send a request */ + rc = usbip_net_send_op_common(sockfd, OP_REQ_UNEXPORT, 0); + if (rc < 0) { + err("send op_common"); + return -1; + } + + memcpy(, udev, sizeof(struct usbip_usb_device)); + + PACK_OP_UNEXPORT_REQUEST(0, ); + + rc = usbip_net_send(sockfd, (void *) , sizeof(request)); + if (rc < 0) { + err("send op_export_request"); +
[PATCH v8 9/9] usbip: exporting devices: chage to documenattion
This patch adds function and usage of new connect operation, disconnect operation and application(vhci)-side daemon to README and manuals. At this point, the wording, 'server' and 'client' are ambiguous in several place. For existing attach command, the daemon runs device side machine and attach command is executed in application side machine. Then 'server' is used for device side and 'client' is for application side. For the new connect command, the daemon runs applications side machine and connect command is executed in device side machine. Now, 'server' and 'client' run in different machine than before. So, to avoid confusion, words 'device side (machine)' and 'application side (machine)' are used instead of 'client' and 'server'. Please, see also diagrams in the cover letter. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/Makefile.am | 2 +- tools/usb/usbip/README | 70 -- tools/usb/usbip/doc/usbip.8 | 136 --- tools/usb/usbip/doc/usbipa.8 | 79 tools/usb/usbip/doc/usbipd.8 | 37 ++ 5 files changed, 264 insertions(+), 60 deletions(-) diff --git a/tools/usb/usbip/Makefile.am b/tools/usb/usbip/Makefile.am index 66f8bf0..f371ed9 100644 --- a/tools/usb/usbip/Makefile.am +++ b/tools/usb/usbip/Makefile.am @@ -3,4 +3,4 @@ includedir = @includedir@/usbip include_HEADERS := $(addprefix libsrc/, \ usbip_common.h vhci_driver.h usbip_host_driver.h) -dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8) +dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbipa.8) diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 831f49f..74f4afb 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -1,7 +1,8 @@ # # README for usbip-utils # -# Copyright (C) 2011 matt mooney <m...@muteddisk.com> +# Copyright (C) 2015 Nobuo Iwata +# 2011 matt mooney <m...@muteddisk.com> # 2005-2008 Takahiro Hirofuchi @@ -36,41 +37,70 @@ [Usage] -server:# (Physically attach your USB device.) +Device-side: a machine has USB device(s). +Application-side: a machine runs an application software uses remote USB device. -server:# insmod usbip-core.ko -server:# insmod usbip-host.ko +1) Connect from application-side to device-side. -server:# usbipd -D +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbipd -D - Start usbip daemon. -server:# usbip list -l - - List driver assignments for USB devices. +dev:# usbip list -l + - List driver assignments for USB devices and their busid. -server:# usbip bind --busid 1-2 - - Bind usbip-host.ko to the device with busid 1-2. - - The USB device 1-2 is now exportable to other hosts! - - Use `usbip unbind --busid 1-2' to stop exporting the device. +dev:# usbip bind --busid + - Bind usbip-host.ko to the device with . + - The USB device with is now exportable to other hosts! + - Use `usbip unbind --busid ` to stop exporting the device. -client:# insmod usbip-core.ko -client:# insmod vhci-hcd.ko +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko -client:# usbip list --remote +app:# usbip list --remote - List exported USB devices on the . -client:# usbip attach --remote --busid 1-2 +app:# usbip attach --remote --busid - Connect the remote USB device. -client:# usbip port +app:# usbip port - Show virtual port status. -client:# usbip detach --port +app:# usbip detach --port - Detach the USB device. +2) Connect from device-side to application-side. + +app:# insmod usbip-core.ko +app:# insmod vhci-hcd.ko + +app:# usbipa -D + - Start usbip daemon. + +dev:# (Physically attach your USB device.) + +dev:# insmod usbip-core.ko +dev:# insmod usbip-host.ko + +dev:# usbip list -l + - List driver assignments for USB devices and their busid. + +dev:# usbip connect --remote --busid + - Bind usbip-host.ko to the device with . + - The USB device of is connected to remote host! + +dev:# usbip disconnect --remote --busid + - The USB device with is disconnected from remote host. + - Unbind usbip-host.ko from the device. + [Example] --- - SERVER SIDE + DEVICE SIDE --- Physically attach your USB devices to this host. @@ -131,7 +161,7 @@ Mark the device of busid 3-3.2 as exportable: ... --- - CLIENT SIDE + APPLICATION SIDE --- First, let's list available remote devices that are marked as exportable on the host. @@ -170,7 +200,7 @@ Attach a remote USB device: deux:# usbip attach --remote 10.0.0.3 --busid 1-1
[PATCH v8 7/9] usbip: exporting devices: new application-side daemon
New application(vhci)-side daemon. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/libsrc/vhci_driver.c | 19 +++ tools/usb/usbip/libsrc/vhci_driver.h | 1 + tools/usb/usbip/src/Makefile.am | 7 +- tools/usb/usbip/src/usbipd.c | 12 +- tools/usb/usbip/src/usbipd_app.c | 243 +++ 5 files changed, 280 insertions(+), 2 deletions(-) diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c index b7ca63d..50c723d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.c +++ b/tools/usb/usbip/libsrc/vhci_driver.c @@ -314,6 +314,25 @@ int usbip_vhci_get_free_port(void) return -1; } +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid) +{ + int ret; + char rhost[NI_MAXHOST] = "unknown host"; + char rserv[NI_MAXSERV] = "unknown port"; + char rbusid[SYSFS_BUS_ID_SIZE]; + + for (int i = 0; i < vhci_driver->nports; i++) { + ret = read_record(vhci_driver->idev[i].port, rhost, NI_MAXHOST, + rserv, NI_MAXSERV, rbusid); + if (!ret && + !strncmp(host, rhost, NI_MAXHOST) && + !strncmp(busid, rbusid, SYSFS_BUS_ID_SIZE)) { + return vhci_driver->idev + i; + } + } + return NULL; +} + int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed) { char buff[200]; /* what size should be ? */ diff --git a/tools/usb/usbip/libsrc/vhci_driver.h b/tools/usb/usbip/libsrc/vhci_driver.h index f955ada..acb427d 100644 --- a/tools/usb/usbip/libsrc/vhci_driver.h +++ b/tools/usb/usbip/libsrc/vhci_driver.h @@ -46,6 +46,7 @@ int usbip_vhci_refresh_device_list(void); int usbip_vhci_get_free_port(void); +struct usbip_imported_device *usbip_vhci_find_device(char *host, char *busid); int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid, uint32_t speed); diff --git a/tools/usb/usbip/src/Makefile.am b/tools/usb/usbip/src/Makefile.am index 1aa5156..8fdebce 100644 --- a/tools/usb/usbip/src/Makefile.am +++ b/tools/usb/usbip/src/Makefile.am @@ -2,11 +2,16 @@ AM_CPPFLAGS = -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"' AM_CFLAGS = @EXTRA_CFLAGS@ LDADD = $(top_builddir)/libsrc/libusbip.la -sbin_PROGRAMS := usbip usbipd +sbin_PROGRAMS := usbip usbipd usbipa usbip_SOURCES := usbip.h utils.h usbip.c utils.c usbip_network.c \ usbip_attach.c usbip_detach.c usbip_list.c \ usbip_bind.c usbip_unbind.c usbip_port.c \ usbip_connect.c usbip_disconnect.c +usbip_CFLAGS := $(AM_CFLAGS) usbipd_SOURCES := usbip_network.h usbipd.c usbipd_dev.c usbip_network.c +usbipd_CFLAGS := $(AM_CFLAGS) + +usbipa_SOURCES := usbip_network.h usbipd.c usbipd_app.c usbip_network.c +usbipa_CFLAGS := $(AM_CFLAGS) -DUSBIP_DAEMON_APP diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c index ef60026..71e2d52 100644 --- a/tools/usb/usbip/src/usbipd.c +++ b/tools/usb/usbip/src/usbipd.c @@ -64,11 +64,13 @@ static const char usbipd_help_string[] = " -6, --ipv6\n" " Bind to IPv6. Default is both.\n" "\n" +#ifndef USBIP_DAEMON_APP " -e, --device\n" " Run in device mode.\n" " Rather than drive an attached device, create\n" " a virtual UDC to bind gadgets to.\n" "\n" +#endif " -D, --daemon\n" " Run as a daemon process.\n" "\n" @@ -401,7 +403,9 @@ int main(int argc, char *argv[]) { "ipv6", no_argument, NULL, '6' }, { "daemon", no_argument, NULL, 'D' }, { "debug",no_argument, NULL, 'd' }, +#ifndef USBIP_DAEMON_APP { "device", no_argument, NULL, 'e' }, +#endif { "pid", optional_argument, NULL, 'P' }, { "tcp-port", required_argument, NULL, 't' }, { "help", no_argument, NULL, 'h' }, @@ -430,7 +434,11 @@ int main(int argc, char *argv[]) cmd = cmd_standalone_mode; usbip_init_driver(); for (;;) { - opt = getopt_long(argc, argv, "46DdeP::t:hv", longopts, NULL); + opt = getopt_long(argc, argv, "46Dd" +#ifndef USBIP_DAEMON_APP + "e" +#endif + "P::t:hv", longopts, NULL); if (opt == -1) break; @@ -460,9 +468,11 @@ int mai
[PATCH v8 8/9] usbip: exporting devices: change to usbip_list.c
Correction to wording inconsistency around import and export in usbip_list.c. Please, see also cover letter about wording. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- tools/usb/usbip/src/usbip_list.c | 22 -- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tools/usb/usbip/src/usbip_list.c b/tools/usb/usbip/src/usbip_list.c index f1b38e8..37f9afa 100644 --- a/tools/usb/usbip/src/usbip_list.c +++ b/tools/usb/usbip/src/usbip_list.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 matt mooney <m...@muteddisk.com> + * Copyright (C) 2015 Nobuo Iwata + * 2011 matt mooney <m...@muteddisk.com> * 2005-2007 Takahiro Hirofuchi * Copyright (C) 2015-2016 Samsung Electronics * Igor Kotrasinski <i.kotrasi...@samsung.com> @@ -42,9 +43,9 @@ #include "usbip.h" static const char usbip_list_usage_string[] = - "usbip list [-p|--parsable] \n" + "usbip list \n" "-p, --parsable Parsable list format\n" - "-r, --remote=List the exportable USB devices on \n" + "-r, --remote=List the importable USB devices on \n" "-l, --localList the local USB devices\n"; void usbip_list_usage(void) @@ -52,7 +53,7 @@ void usbip_list_usage(void) printf("usage: %s", usbip_list_usage_string); } -static int get_exported_devices(char *host, int sockfd) +static int get_importable_devices(char *host, int sockfd) { char product_name[100]; char class_name[100]; @@ -82,14 +83,14 @@ static int get_exported_devices(char *host, int sockfd) return -1; } PACK_OP_DEVLIST_REPLY(0, ); - dbg("exportable devices: %d\n", reply.ndev); + dbg("importable devices: %d\n", reply.ndev); if (reply.ndev == 0) { - info("no exportable devices found on %s", host); + info("no importable devices found on %s", host); return 0; } - printf("Exportable USB devices\n"); + printf("Importable USB devices\n"); printf("==\n"); printf(" - %s\n", host); @@ -134,7 +135,7 @@ static int get_exported_devices(char *host, int sockfd) return 0; } -static int list_exported_devices(char *host) +static int list_importable_devices(char *host) { int rc; int sockfd; @@ -147,9 +148,10 @@ static int list_exported_devices(char *host) } dbg("connected to %s:%s", host, usbip_port_string); - rc = get_exported_devices(host, sockfd); + rc = get_importable_devices(host, sockfd); if (rc < 0) { err("failed to get device list from %s", host); + close(sockfd); return -1; } @@ -351,7 +353,7 @@ int usbip_list(int argc, char *argv[]) parsable = true; break; case 'r': - ret = list_exported_devices(optarg); + ret = list_importable_devices(optarg); goto out; case 'l': ret = list_devices(parsable); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/1] usbip: safe completion against unbind operation
This patch adds a code fragment to ignore completing URBs in closing connection. Regarding this patch, 2 execution contexts are related. 1) stub_tx.c: stub_complete() which is called from USB core 1-1) add to unlink list and free URB or 1-2) move to tx list 2) stub_dev.c: stub_shutdown_connection() which is invoked by unbind operation through sysfs. 2-1) stop TX/RX threads 2-2) close TCP connection and set ud.tcp_socket to NULL 2-3) cleanup pending URBs by stub_device_cleanup_urbs(sdev) 2-4) free unlink list (no lock) In the race condition, URBs which will be cleared in 2-3) may be handled in 1). In case 1-1), it will not be transferred bcause tx threads are stooped in 2-1). In case 1-2), may be freed in 2-4). With this patch, after 2-2), completing URBs in 1) will not be handled and cleared in 2-3). The kernel log with this patch is as below. kernel: usbip_core: usbip_kernel_unlink:792: shutting down tcp_socket ef61d980 kernel: usbip-host 1-3: free sdev f5df6180 kernel: usbip-host 1-3: free urb f5df6700 kernel: usbip-host 1-3: Enter kernel: usbip_core: usbip_stop_eh:132: usbip_eh waiting completion 5 kernel: usbip_host: stub_complete:71: complete! status 0 kernel: usbip_host: stub_complete:102: ignore urb for closed connection e725fc00 (*) kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: free urb e725fc00 (**) kernel: usbip-host 1-3: free urb e725e000 kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: free urb e725f800 kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: free urb e725e800 kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: device reset kernel: usbip-host 1-3: lock for reset kernel: usbip_host: store_match_busid:178: del busid 1-3 kernel: uvcvideo: Found UVC 1.00 device Venus USB2.0 Camera (056e:700a) kernel: input: Venus USB2.0 Camera as /devices/pci:00/:00:1a.7/usb1/1-3/1-3:1.0/input/input22 (*) skipped with this patch in completion (**) released in 2-3 --- Version information v3) # Fixed misoperation that changing log level in v2 was not included. v2) # Changed log level of ignore message from info to debug. # Updated log capture in changelog with the log level modification. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/stub_tx.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c index dbcabc9..dc223af 100644 --- a/drivers/usb/usbip/stub_tx.c +++ b/drivers/usb/usbip/stub_tx.c @@ -97,7 +97,10 @@ void stub_complete(struct urb *urb) /* link a urb to the queue of tx. */ spin_lock_irqsave(>priv_lock, flags); - if (priv->unlinking) { + if (sdev->ud.tcp_socket == NULL) { + usbip_dbg_stub_tx("ignore urb for closed connection %p", urb); + /* It will be freed in stub_device_cleanup_urbs(). */ + } else if (priv->unlinking) { stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); stub_free_priv_and_urb(priv); } else { -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/1] usbip: safe completion against unbind operation
This patch adds a code fragment to ignore completing URBs in closing connection. Regarding this patch, 2 execution contexts are related. 1) stub_tx.c: stub_complete() which is called from USB core 1-1) add to unlink list and free URB or 1-2) move to tx list 2) stub_dev.c: stub_shutdown_connection() which is invoked by unbind operation through sysfs. 2-1) stop TX/RX threads 2-2) close TCP connection and set ud.tcp_socket to NULL 2-3) cleanup pending URBs by stub_device_cleanup_urbs(sdev) 2-4) free unlink list (no lock) In the race condition, URBs which will be cleared in 2-3) may be handled in 1). In case 1-1), it will not be transferred bcause tx threads are stooped in 2-1). In case 1-2), may be freed in 2-4). With this patch, after 2-2), completing URBs in 1) will not be handled and cleared in 2-3). The kernel log with this patch is as below. kernel: usbip_core: usbip_kernel_unlink:792: shutting down tcp_socket ef61d980 kernel: usbip-host 1-3: free sdev f5df6180 kernel: usbip-host 1-3: free urb f5df6700 kernel: usbip-host 1-3: Enter kernel: usbip_core: usbip_stop_eh:132: usbip_eh waiting completion 5 kernel: usbip_host: stub_complete:71: complete! status 0 kernel: usbip_host: stub_complete:102: ignore urb for closed connection e725fc00 (*) kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: free urb e725fc00 (**) kernel: usbip-host 1-3: free urb e725e000 kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: free urb e725f800 kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: free urb e725e800 kernel: usbip_host: stub_complete:71: complete! status -2 kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: device reset kernel: usbip-host 1-3: lock for reset kernel: usbip_host: store_match_busid:178: del busid 1-3 kernel: uvcvideo: Found UVC 1.00 device Venus USB2.0 Camera (056e:700a) kernel: input: Venus USB2.0 Camera as /devices/pci:00/:00:1a.7/usb1/1-3/1-3:1.0/input/input22 (*) skipped with this patch in completion (**) released in 2-3 A. version info v2) # Changed log level of ignore message from info to debug. # Updated log capture in changelog with the log level modification. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/stub_tx.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c index dbcabc9..a4efc5a 100644 --- a/drivers/usb/usbip/stub_tx.c +++ b/drivers/usb/usbip/stub_tx.c @@ -97,7 +97,11 @@ void stub_complete(struct urb *urb) /* link a urb to the queue of tx. */ spin_lock_irqsave(>priv_lock, flags); - if (priv->unlinking) { + if (sdev->ud.tcp_socket == NULL) { + dev_info(>dev->dev, +"ignore urb for closed connection %p", urb); + /* It will be freed in stub_device_cleanup_urbs(). */ + } else if (priv->unlinking) { stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); stub_free_priv_and_urb(priv); } else { -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/1] usbip: event handler as one thread
Dear all, 1. Overview In current USB/IP implementation, event kernel threads are created for each port. The functions of the threads are closing connection and error handling so they don't have not so many events to handle. There's no need to have thread for each port. BEFORE) vhci side - VHCI_NPORTS(8) threads are created. $ ps aux | grep usbip root 10059 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10060 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10061 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10062 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10063 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10064 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10065 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10066 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] BEFORE) stub side - threads will be created every bind operation. $ ps aux | grep usbip root 8368 0.0 0.0 0 0 ?S17:56 0:00 [usbip_eh] root 8399 0.0 0.0 0 0 ?S17:56 0:00 [usbip_eh] This patch put event threads of stub and vhci driver as one workqueue. AFTER) only one event threads in each vhci and stub side. $ ps aux | grep usbip root 10457 0.0 0.0 0 0 ?S< 17:47 0:00 [usbip_event] 2. Modification to usbip_event.c BEFORE) kernel threads are created in usbip_start_eh(). AFTER) one workqueue is created in new usbip_init_eh(). Event handler which was main loop of kernel thread is modified to workqueue handler. Events themselves are stored in struct usbip_device - same as before. usbip_devices which have event are listed in event_list. The handler picks an element from the list and wakeup usbip_device. The wakeup method is same as before. usbip_in_eh() substitutes statement which checks whether functions are called from eh_ops or not. In this function, the worker context is used for the checking. The context will be set in a variable in the beginning of first event handling. usbip_in_eh() is used in event handler so it works well. 3. Modifications to programs using usbip_event.c Initialization and termination of workqueue are added to init and exit routine of usbip_core respectively. A. version info v2) # Merged 1/2 event handler itself and 2/2 user programs because of auto build fail at 1/2 casued unmodified user programs in 1/2. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/stub_dev.c | 3 +- drivers/usb/usbip/usbip_common.c | 7 ++ drivers/usb/usbip/usbip_common.h | 4 +- drivers/usb/usbip/usbip_event.c | 168 +++ 4 files changed, 137 insertions(+), 45 deletions(-) diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index a3ec49b..e286346 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -388,7 +388,6 @@ err_files: err_port: dev_set_drvdata(>dev, NULL); usb_put_dev(udev); - kthread_stop_put(sdev->ud.eh); busid_priv->sdev = NULL; stub_device_free(sdev); @@ -449,7 +448,7 @@ static void stub_disconnect(struct usb_device *udev) } /* If usb reset is called from event handler */ - if (busid_priv->sdev->ud.eh == current) + if (usbip_in_eh(current)) return; /* shutdown the current connection */ diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index facaaf0..aec2d65c 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -758,12 +758,19 @@ EXPORT_SYMBOL_GPL(usbip_recv_xbuff); static int __init usbip_core_init(void) { + int ret; + pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); + ret = usbip_init_eh(); + if (ret) + return ret; + return 0; } static void __exit usbip_core_exit(void) { + usbip_finish_eh(); return; } diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h index 86b0847..2fbbc64 100644 --- a/drivers/usb/usbip/usbip_common.h +++ b/drivers/usb/usbip/usbip_common.h @@ -267,7 +267,6 @@ struct usbip_device { struct task_struct *tcp_tx; unsigned long event; - struct task_struct *eh; wait_queue_head_t eh_waitq; struct eh_ops { @@ -313,10 +312,13 @@ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb); int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb); /* usbip_event.c */ +int usbip_init_eh(void); +void usbip_finish_eh(void); int usbip_start_eh(struct usbip_device *ud); 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); +int usbip_in_eh(str
[PATCH v1 0/2] usbip: event handler as one thread
Dear all, In existing implementation, event kernel threads are created for each port. The functions of the threads are closing connection and error handling so they don't have not so many events to handle. There' no need to have thread for each port. BEFORE) vhci side - VHCI_NPORTS(8) threads are created. $ ps aux | grep usbip root 10059 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10060 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10061 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10062 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10063 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10064 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10065 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] root 10066 0.0 0.0 0 0 ?S17:06 0:00 [usbip_eh] BEFORE) stub side - threads will be created every bind operation. $ ps aux | grep usbip root 8368 0.0 0.0 0 0 ?S17:56 0:00 [usbip_eh] root 8399 0.0 0.0 0 0 ?S17:56 0:00 [usbip_eh] This series of patches put event threads of stub and vhci driver as one workqueue. AFTER) only one event threads in each vhci and stub side. $ ps aux | grep usbip root 10457 0.0 0.0 0 0 ?S< 17:47 0:00 [usbip_event] *** BLURB HERE *** Nobuo Iwata (2): usbip: modifications to event handler usbip: modifications to drivers using event handler drivers/usb/usbip/stub_dev.c | 3 +- drivers/usb/usbip/usbip_common.c | 7 ++ drivers/usb/usbip/usbip_common.h | 4 +- drivers/usb/usbip/usbip_event.c | 168 +++ 4 files changed, 137 insertions(+), 45 deletions(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 2/2] usbip: modifications to drivers using event handler
Modifications to code using usbip_event.c Initialization and termination of workqueue are added to init and exit routine of usbip_core respectively. Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/stub_dev.c | 3 +-- drivers/usb/usbip/usbip_common.c | 7 +++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index a3ec49b..e286346 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -388,7 +388,6 @@ err_files: err_port: dev_set_drvdata(>dev, NULL); usb_put_dev(udev); - kthread_stop_put(sdev->ud.eh); busid_priv->sdev = NULL; stub_device_free(sdev); @@ -449,7 +448,7 @@ static void stub_disconnect(struct usb_device *udev) } /* If usb reset is called from event handler */ - if (busid_priv->sdev->ud.eh == current) + if (usbip_in_eh(current)) return; /* shutdown the current connection */ diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index facaaf0..aec2d65c 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -758,12 +758,19 @@ EXPORT_SYMBOL_GPL(usbip_recv_xbuff); static int __init usbip_core_init(void) { + int ret; + pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); + ret = usbip_init_eh(); + if (ret) + return ret; + return 0; } static void __exit usbip_core_exit(void) { + usbip_finish_eh(); return; } -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v1 1/1] usbip: safe completion against unbind operation
This patch adds a code fragment to ignore completing URBs in closing connection. Regarding this patch, 2 execution contexts are related. 1) stub_tx.c: stub_complete() which is called from USB core 1-1) add to unlink list and free URB or 1-2) move to tx list 2) stub_dev.c: stub_shutdown_connection() which is invoked by unbind operation through sysfs. 2-1) stop TX/RX threads 2-2) close TCP connection and set ud.tcp_socket to NULL 2-3) cleanup pending URBs by stub_device_cleanup_urbs(sdev) 2-4) free unlink list (no lock) In race condition URBs will be cleared in 2-3) may handled in 1). In case 1-1), it will not be transferred bcause tx threads are stooped in 2-1). In case 1-2), may be freed in 2-4). With this patch, after 2-2), completing URBs in 1) will not be handled and cleared in 2-3). The kernel log with patch is as below. kernel: usbip-host 1-3: free sdev f680 kernel: usbip-host 1-3: free urb efcb8080 kernel: usbip-host 1-3: Enter kernel: usbip-host 1-3: ignore urb for closed connection efc80c00 (*) kernel: usbip-host 1-3: stopped by a call to usb_kill_urb() because of cleaning up a virtual connection kernel: usbip-host 1-3: free urb efc80c00 (**) kernel: usbip-host 1-3: device reset kernel: usbip-host 1-3: lock for reset kernel: usbip_host: store_match_busid:178: del busid 1-3 kernel: uvcvideo: Found UVC 1.00 device Venus USB2.0 Camera (056e:700a) kernel: input: Venus USB2.0 Camera as /devices/pci:00/:00:1a.7/usb1/1-3/1-3:1.0/input/input18 (*) skipped with this patch in completion (**) released in 2-3 Signed-off-by: Nobuo Iwata <nobuo.iw...@fujixerox.co.jp> --- drivers/usb/usbip/stub_tx.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c index dbcabc9..a4efc5a 100644 --- a/drivers/usb/usbip/stub_tx.c +++ b/drivers/usb/usbip/stub_tx.c @@ -97,7 +97,11 @@ void stub_complete(struct urb *urb) /* link a urb to the queue of tx. */ spin_lock_irqsave(>priv_lock, flags); - if (priv->unlinking) { + if (sdev->ud.tcp_socket == NULL) { + dev_info(>dev->dev, +"ignore urb for closed connection %p", urb); + /* It will be freed in stub_device_cleanup_urbs(). */ + } else if (priv->unlinking) { stub_enqueue_ret_unlink(sdev, priv->seqnum, urb->status); stub_free_priv_and_urb(priv); } else { -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html