summaryrefslogtreecommitdiffstats
path: root/drivers/staging/usbip/userspace
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/usbip/userspace')
-rw-r--r--drivers/staging/usbip/userspace/README8
-rw-r--r--drivers/staging/usbip/userspace/configure.ac12
-rw-r--r--drivers/staging/usbip/userspace/libsrc/Makefile.am3
-rw-r--r--drivers/staging/usbip/userspace/libsrc/list.h136
-rw-r--r--drivers/staging/usbip/userspace/libsrc/sysfs_utils.c31
-rw-r--r--drivers/staging/usbip/userspace/libsrc/sysfs_utils.h8
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_common.c93
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_common.h41
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c303
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h7
-rw-r--r--drivers/staging/usbip/userspace/libsrc/vhci_driver.c397
-rw-r--r--drivers/staging/usbip/userspace/libsrc/vhci_driver.h14
-rw-r--r--drivers/staging/usbip/userspace/src/Makefile.am1
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_attach.c1
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_bind.c195
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_detach.c2
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_list.c146
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_network.h1
-rw-r--r--drivers/staging/usbip/userspace/src/usbip_unbind.c129
-rw-r--r--drivers/staging/usbip/userspace/src/usbipd.c21
-rw-r--r--drivers/staging/usbip/userspace/src/utils.c48
21 files changed, 631 insertions, 966 deletions
diff --git a/drivers/staging/usbip/userspace/README b/drivers/staging/usbip/userspace/README
index 00a1658..f528ba4 100644
--- a/drivers/staging/usbip/userspace/README
+++ b/drivers/staging/usbip/userspace/README
@@ -9,8 +9,8 @@
- USB/IP device drivers
Found in the staging directory of the Linux kernel.
- - sysfsutils >= 2.0.0
- sysfsutils library
+ - libudev >= 2.0
+ libudev library
- libwrap0-dev
tcp wrapper library
@@ -19,6 +19,10 @@
- libtool, automake >= 1.9, autoconf >= 2.5.0, pkg-config
+[Optional]
+ - hwdata
+ Contains USB device identification data.
+
[Install]
0. Generate configuration scripts.
diff --git a/drivers/staging/usbip/userspace/configure.ac b/drivers/staging/usbip/userspace/configure.ac
index 0ee5d92..607d05c 100644
--- a/drivers/staging/usbip/userspace/configure.ac
+++ b/drivers/staging/usbip/userspace/configure.ac
@@ -1,7 +1,7 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
-AC_INIT([usbip-utils], [1.1.1], [linux-usb@vger.kernel.org])
+AC_INIT([usbip-utils], [2.0], [linux-usb@vger.kernel.org])
AC_DEFINE([USBIP_VERSION], [0x00000111], [binary-coded decimal version number])
CURRENT=0
@@ -44,11 +44,11 @@ AC_FUNC_REALLOC
AC_CHECK_FUNCS([memset mkdir regcomp socket strchr strerror strstr dnl
strtoul])
-AC_CHECK_HEADER([sysfs/libsysfs.h],
- [AC_CHECK_LIB([sysfs], [sysfs_open_directory_list],
- [LIBS="$LIBS -lsysfs"],
- [AC_MSG_ERROR([Missing sysfs2 library!])])],
- [AC_MSG_ERROR([Missing /usr/include/sysfs/libsysfs.h])])
+AC_CHECK_HEADER([libudev.h],
+ [AC_CHECK_LIB([udev], [udev_new],
+ [LIBS="$LIBS -ludev"],
+ [AC_MSG_ERROR([Missing udev library!])])],
+ [AC_MSG_ERROR([Missing /usr/include/libudev.h])])
# Checks for libwrap library.
AC_MSG_CHECKING([whether to use the libwrap (TCP wrappers) library])
diff --git a/drivers/staging/usbip/userspace/libsrc/Makefile.am b/drivers/staging/usbip/userspace/libsrc/Makefile.am
index 4921189..7c8f8a4 100644
--- a/drivers/staging/usbip/userspace/libsrc/Makefile.am
+++ b/drivers/staging/usbip/userspace/libsrc/Makefile.am
@@ -4,4 +4,5 @@ libusbip_la_LDFLAGS = -version-info @LIBUSBIP_VERSION@
lib_LTLIBRARIES := libusbip.la
libusbip_la_SOURCES := names.c names.h usbip_host_driver.c usbip_host_driver.h \
- usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h
+ usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h \
+ sysfs_utils.c sysfs_utils.h
diff --git a/drivers/staging/usbip/userspace/libsrc/list.h b/drivers/staging/usbip/userspace/libsrc/list.h
new file mode 100644
index 0000000..8d0c936
--- /dev/null
+++ b/drivers/staging/usbip/userspace/libsrc/list.h
@@ -0,0 +1,136 @@
+#ifndef _LIST_H
+#define _LIST_H
+
+/* Stripped down implementation of linked list taken
+ * from the Linux Kernel.
+ */
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+ list->next = list;
+ list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+#define POISON_POINTER_DELTA 0
+#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)
+#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void __list_del_entry(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos: the &struct list_head to use as a loop cursor.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+#endif
diff --git a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c b/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c
new file mode 100644
index 0000000..36ac88e
--- /dev/null
+++ b/drivers/staging/usbip/userspace/libsrc/sysfs_utils.c
@@ -0,0 +1,31 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "sysfs_utils.h"
+#include "usbip_common.h"
+
+int write_sysfs_attribute(const char *attr_path, const char *new_value,
+ size_t len)
+{
+ int fd;
+ int length;
+
+ fd = open(attr_path, O_WRONLY);
+ if (fd < 0) {
+ dbg("error opening attribute %s", attr_path);
+ return -1;
+ }
+
+ length = write(fd, new_value, len);
+ if (length < 0) {
+ dbg("error writing to attribute %s", attr_path);
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
diff --git a/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h b/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h
new file mode 100644
index 0000000..32ac1d1
--- /dev/null
+++ b/drivers/staging/usbip/userspace/libsrc/sysfs_utils.h
@@ -0,0 +1,8 @@
+
+#ifndef __SYSFS_UTILS_H
+#define __SYSFS_UTILS_H
+
+int write_sysfs_attribute(const char *attr_path, const char *new_value,
+ size_t len);
+
+#endif
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.c b/drivers/staging/usbip/userspace/libsrc/usbip_common.c
index 66f03cc..238bf5b 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_common.c
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.c
@@ -2,6 +2,7 @@
* Copyright (C) 2005-2007 Takahiro Hirofuchi
*/
+#include <libudev.h>
#include "usbip_common.h"
#include "names.h"
@@ -12,6 +13,8 @@ int usbip_use_syslog;
int usbip_use_stderr;
int usbip_use_debug;
+extern struct udev *udev_context;
+
struct speed_string {
int num;
char *speed;
@@ -23,6 +26,8 @@ static const struct speed_string speed_strings[] = {
{ USB_SPEED_LOW, "1.5", "Low Speed(1.5Mbps)" },
{ USB_SPEED_FULL, "12", "Full Speed(12Mbps)" },
{ USB_SPEED_HIGH, "480", "High Speed(480Mbps)" },
+ { USB_SPEED_WIRELESS, "53.3-480", "Wireless"},
+ { USB_SPEED_SUPER, "5000", "Super Speed(5000Mbps)" },
{ 0, NULL, NULL }
};
@@ -109,75 +114,61 @@ void dump_usb_device(struct usbip_usb_device *udev)
}
-int read_attr_value(struct sysfs_device *dev, const char *name,
+int read_attr_value(struct udev_device *dev, const char *name,
const char *format)
{
- char attrpath[SYSFS_PATH_MAX];
- struct sysfs_attribute *attr;
+ const char *attr;
int num = 0;
int ret;
- snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, name);
-
- attr = sysfs_open_attribute(attrpath);
+ attr = udev_device_get_sysattr_value(dev, name);
if (!attr) {
- dbg("sysfs_open_attribute failed: %s", attrpath);
- return 0;
- }
-
- ret = sysfs_read_attribute(attr);
- if (ret < 0) {
- dbg("sysfs_read_attribute failed");
+ err("udev_device_get_sysattr_value failed");
goto err;
}
- ret = sscanf(attr->value, format, &num);
+ /* The client chooses the device configuration
+ * when attaching it so right after being bound
+ * to usbip-host on the server the device will
+ * have no configuration.
+ * Therefore, attributes such as bConfigurationValue
+ * and bNumInterfaces will not exist and sscanf will
+ * fail. Check for these cases and don't treat them
+ * as errors.
+ */
+
+ ret = sscanf(attr, format, &num);
if (ret < 1) {
- dbg("sscanf failed");
- goto err;
+ if (strcmp(name, "bConfigurationValue") &&
+ strcmp(name, "bNumInterfaces")) {
+ err("sscanf failed for attribute %s", name);
+ goto err;
+ }
}
err:
- sysfs_close_attribute(attr);
return num;
}
-int read_attr_speed(struct sysfs_device *dev)
+int read_attr_speed(struct udev_device *dev)
{
- char attrpath[SYSFS_PATH_MAX];
- struct sysfs_attribute *attr;
- char speed[100];
- int ret;
-
- snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, "speed");
-
- attr = sysfs_open_attribute(attrpath);
- if (!attr) {
- dbg("sysfs_open_attribute failed: %s", attrpath);
- return 0;
- }
+ const char *speed;
- ret = sysfs_read_attribute(attr);
- if (ret < 0) {
- dbg("sysfs_read_attribute failed");
+ speed = udev_device_get_sysattr_value(dev, "speed");
+ if (!speed) {
+ err("udev_device_get_sysattr_value failed");
goto err;
}
- ret = sscanf(attr->value, "%99s\n", speed);
- if (ret < 1) {
- dbg("sscanf failed");
- goto err;
- }
-err:
- sysfs_close_attribute(attr);
-
for (int i = 0; speed_strings[i].speed != NULL; i++) {
if (!strcmp(speed, speed_strings[i].speed))
return speed_strings[i].num;
}
+err:
+
return USB_SPEED_UNKNOWN;
}
@@ -188,9 +179,10 @@ err:
} while (0)
-int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev)
+int read_usb_device(struct udev_device *sdev, struct usbip_usb_device *udev)
{
uint32_t busnum, devnum;
+ const char *path, *name;
READ_ATTR(udev, uint8_t, sdev, bDeviceClass, "%02x\n");
READ_ATTR(udev, uint8_t, sdev, bDeviceSubClass, "%02x\n");
@@ -207,10 +199,13 @@ int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev)
READ_ATTR(udev, uint8_t, sdev, devnum, "%d\n");
udev->speed = read_attr_speed(sdev);
- strncpy(udev->path, sdev->path, SYSFS_PATH_MAX);
- strncpy(udev->busid, sdev->name, SYSFS_BUS_ID_SIZE);
+ path = udev_device_get_syspath(sdev);
+ name = udev_device_get_sysname(sdev);
- sscanf(sdev->name, "%u-%u", &busnum, &devnum);
+ strncpy(udev->path, path, SYSFS_PATH_MAX);
+ strncpy(udev->busid, name, SYSFS_BUS_ID_SIZE);
+
+ sscanf(name, "%u-%u", &busnum, &devnum);
udev->busnum = busnum;
return 0;
@@ -220,13 +215,13 @@ int read_usb_interface(struct usbip_usb_device *udev, int i,
struct usbip_usb_interface *uinf)
{
char busid[SYSFS_BUS_ID_SIZE];
- struct sysfs_device *sif;
+ struct udev_device *sif;
sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i);
- sif = sysfs_open_device("usb", busid);
+ sif = udev_device_new_from_subsystem_sysname(udev_context, "usb", busid);
if (!sif) {
- dbg("sysfs_open_device(\"usb\", \"%s\") failed", busid);
+ err("udev_device_new_from_subsystem_sysname %s failed", busid);
return -1;
}
@@ -234,8 +229,6 @@ int read_usb_interface(struct usbip_usb_device *udev, int i,
READ_ATTR(uinf, uint8_t, sif, bInterfaceSubClass, "%02x\n");
READ_ATTR(uinf, uint8_t, sif, bInterfaceProtocol, "%02x\n");
- sysfs_close_device(sif);
-
return 0;
}
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_common.h b/drivers/staging/usbip/userspace/libsrc/usbip_common.h
index 938ad1c..23be848 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_common.h
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_common.h
@@ -5,7 +5,7 @@
#ifndef __USBIP_COMMON_H
#define __USBIP_COMMON_H
-#include <sysfs/libsysfs.h>
+#include <libudev.h>
#include <stdint.h>
#include <stdio.h>
@@ -14,6 +14,8 @@
#include <syslog.h>
#include <unistd.h>
+#include <linux/usb/ch9.h>
+#include "../../uapi/usbip.h"
#ifndef USBIDS_FILE
#define USBIDS_FILE "/usr/share/hwdata/usb.ids"
@@ -28,6 +30,15 @@
#define USBIP_HOST_DRV_NAME "usbip-host"
#define USBIP_VHCI_DRV_NAME "vhci_hcd"
+/* sysfs constants */
+#define SYSFS_MNT_PATH "/sys"
+#define SYSFS_BUS_NAME "bus"
+#define SYSFS_BUS_TYPE "usb"
+#define SYSFS_DRIVERS_NAME "drivers"
+
+#define SYSFS_PATH_MAX 256
+#define SYSFS_BUS_ID_SIZE 32
+
extern int usbip_use_syslog;
extern int usbip_use_stderr;
extern int usbip_use_debug ;
@@ -76,30 +87,6 @@ extern int usbip_use_debug ;
abort(); \
} while (0)
-enum usb_device_speed {
- USB_SPEED_UNKNOWN = 0, /* enumerating */
- USB_SPEED_LOW, USB_SPEED_FULL, /* usb 1.1 */
- USB_SPEED_HIGH, /* usb 2.0 */
- USB_SPEED_VARIABLE /* wireless (usb 2.5) */
-};
-
-/* FIXME: how to sync with drivers/usbip_common.h ? */
-enum usbip_device_status {
- /* sdev is available. */
- SDEV_ST_AVAILABLE = 0x01,
- /* sdev is now used. */
- SDEV_ST_USED,
- /* sdev is unusable because of a fatal error. */
- SDEV_ST_ERROR,
-
- /* vdev does not connect a remote device. */
- VDEV_ST_NULL,
- /* vdev is used, but the USB address is not assigned yet */
- VDEV_ST_NOTASSIGNED,
- VDEV_ST_USED,
- VDEV_ST_ERROR
-};
-
struct usbip_usb_interface {
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
@@ -131,8 +118,8 @@ struct usbip_usb_device {
void dump_usb_interface(struct usbip_usb_interface *);
void dump_usb_device(struct usbip_usb_device *);
-int read_usb_device(struct sysfs_device *sdev, struct usbip_usb_device *udev);
-int read_attr_value(struct sysfs_device *dev, const char *name,
+int read_usb_device(struct udev_device *sdev, struct usbip_usb_device *udev);
+int read_attr_value(struct udev_device *dev, const char *name,
const char *format);
int read_usb_interface(struct usbip_usb_device *udev, int i,
struct usbip_usb_interface *uinf);
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
index 71a449c..c5bf60b 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
@@ -18,102 +18,65 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
+#include <libudev.h>
+
#include "usbip_common.h"
#include "usbip_host_driver.h"
+#include "list.h"
+#include "sysfs_utils.h"
#undef PROGNAME
#define PROGNAME "libusbip"
struct usbip_host_driver *host_driver;
+struct udev *udev_context;
-#define SYSFS_OPEN_RETRIES 100
-
-/* only the first interface value is true! */
static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
{
- char attrpath[SYSFS_PATH_MAX];
- struct sysfs_attribute *attr;
+ char status_attr_path[SYSFS_PATH_MAX];
+ int fd;
+ int length;
+ char status;
int value = 0;
- int rc;
- struct stat s;
- int retries = SYSFS_OPEN_RETRIES;
-
- /* This access is racy!
- *
- * Just after detach, our driver removes the sysfs
- * files and recreates them.
- *
- * We may try and fail to open the usbip_status of
- * an exported device in the (short) window where
- * it has been removed and not yet recreated.
- *
- * This is a bug in the interface. Nothing we can do
- * except work around it here by polling for the sysfs
- * usbip_status to reappear.
- */
-
- snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status",
- udev->path, udev->busid, udev->bConfigurationValue, 0);
-
- while (retries > 0) {
- if (stat(attrpath, &s) == 0)
- break;
-
- if (errno != ENOENT) {
- dbg("stat failed: %s", attrpath);
- return -1;
- }
-
- usleep(10000); /* 10ms */
- retries--;
- }
- if (retries == 0)
- dbg("usbip_status not ready after %d retries",
- SYSFS_OPEN_RETRIES);
- else if (retries < SYSFS_OPEN_RETRIES)
- dbg("warning: usbip_status ready after %d retries",
- SYSFS_OPEN_RETRIES - retries);
+ snprintf(status_attr_path, SYSFS_PATH_MAX, "%s/usbip_status",
+ udev->path);
- attr = sysfs_open_attribute(attrpath);
- if (!attr) {
- dbg("sysfs_open_attribute failed: %s", attrpath);
+ if ((fd = open(status_attr_path, O_RDONLY)) < 0) {
+ err("error opening attribute %s", status_attr_path);
return -1;
}
- rc = sysfs_read_attribute(attr);
- if (rc) {
- dbg("sysfs_read_attribute failed: %s", attrpath);
- sysfs_close_attribute(attr);
+ length = read(fd, &status, 1);
+ if (length < 0) {
+ err("error reading attribute %s", status_attr_path);
+ close(fd);
return -1;
}
- value = atoi(attr->value);
-
- sysfs_close_attribute(attr);
+ value = atoi(&status);
return value;
}
-static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath)
+static
+struct usbip_exported_device *usbip_exported_device_new(const char *sdevpath)
{
struct usbip_exported_device *edev = NULL;
+ struct usbip_exported_device *edev_old;
size_t size;
int i;
- edev = calloc(1, sizeof(*edev));
- if (!edev) {
- dbg("calloc failed");
- return NULL;
- }
+ edev = calloc(1, sizeof(struct usbip_exported_device));
- edev->sudev = sysfs_open_device_path(sdevpath);
+ edev->sudev = udev_device_new_from_syspath(udev_context, sdevpath);
if (!edev->sudev) {
- dbg("sysfs_open_device_path failed: %s", sdevpath);
+ err("udev_device_new_from_syspath: %s", sdevpath);
goto err;
}
@@ -124,11 +87,13 @@ static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath)
goto err;
/* reallocate buffer to include usb interface data */
- size = sizeof(*edev) + edev->udev.bNumInterfaces *
+ size = sizeof(struct usbip_exported_device) + edev->udev.bNumInterfaces *
sizeof(struct usbip_usb_interface);
+ edev_old = edev;
edev = realloc(edev, size);
if (!edev) {
+ edev = edev_old;
dbg("realloc failed");
goto err;
}
@@ -138,160 +103,88 @@ static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath)
return edev;
err:
- if (edev && edev->sudev)
- sysfs_close_device(edev->sudev);
+ if (edev->sudev)
+ udev_device_unref(edev->sudev);
if (edev)
free(edev);
return NULL;
}
-static int check_new(struct dlist *dlist, struct sysfs_device *target)
-{
- struct sysfs_device *dev;
-
- dlist_for_each_data(dlist, dev, struct sysfs_device) {
- if (!strncmp(dev->bus_id, target->bus_id, SYSFS_BUS_ID_SIZE))
- /* device found and is not new */
- return 0;
- }
- return 1;
-}
-
-static void delete_nothing(void *unused_data)
-{
- /*
- * NOTE: Do not delete anything, but the container will be deleted.
- */
- (void) unused_data;
-}
-
static int refresh_exported_devices(void)
{
- /* sysfs_device of usb_interface */
- struct sysfs_device *suintf;
- struct dlist *suintf_list;
- /* sysfs_device of usb_device */
- struct sysfs_device *sudev;
- struct dlist *sudev_list;
struct usbip_exported_device *edev;
-
- sudev_list = dlist_new_with_delete(sizeof(struct sysfs_device),
- delete_nothing);
-
- suintf_list = sysfs_get_driver_devices(host_driver->sysfs_driver);
- if (!suintf_list) {
- /*
- * Not an error condition. There are simply no devices bound to
- * the driver yet.
- */
- dbg("bind " USBIP_HOST_DRV_NAME ".ko to a usb device to be "
- "exportable!");
- return 0;
- }
-
- /* collect unique USB devices (not interfaces) */
- dlist_for_each_data(suintf_list, suintf, struct sysfs_device) {
- /* get usb device of this usb interface */
- sudev = sysfs_get_device_parent(suintf);
- if (!sudev) {
- dbg("sysfs_get_device_parent failed: %s", suintf->name);
- continue;
- }
-
- if (check_new(sudev_list, sudev)) {
- /* insert item at head of list */
- dlist_unshift(sudev_list, sudev);
- }
- }
-
- dlist_for_each_data(sudev_list, sudev, struct sysfs_device) {
- edev = usbip_exported_device_new(sudev->path);
- if (!edev) {
- dbg("usbip_exported_device_new failed");
- continue;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ struct udev_device *dev;
+ const char *path;
+
+ enumerate = udev_enumerate_new(udev_context);
+ udev_enumerate_add_match_subsystem(enumerate, "usb");
+ udev_enumerate_scan_devices(enumerate);
+
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ path = udev_list_entry_get_name(dev_list_entry);
+ dev = udev_device_new_from_syspath(udev_context, path);
+
+ /* Check whether device uses usbip-host driver. */
+ if (!strcmp(udev_device_get_driver(dev),
+ USBIP_HOST_DRV_NAME)) {
+ edev = usbip_exported_device_new(path);
+ if (!edev) {
+ dbg("usbip_exported_device_new failed");
+ continue;
+ }
+
+ list_add(&edev->node, &host_driver->edev_list);
+ host_driver->ndevs++;
}
-
- dlist_unshift(host_driver->edev_list, edev);
- host_driver->ndevs++;
}
- dlist_destroy(sudev_list);
-
return 0;
}
-static struct sysfs_driver *open_sysfs_host_driver(void)
+static void usbip_exported_device_destroy(void)
{
- char bus_type[] = "usb";
- char sysfs_mntpath[SYSFS_PATH_MAX];
- char host_drv_path[SYSFS_PATH_MAX];
- struct sysfs_driver *host_drv;
- int rc;
-
- rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
- if (rc < 0) {
- dbg("sysfs_get_mnt_path failed");
- return NULL;
- }
-
- snprintf(host_drv_path, SYSFS_PATH_MAX, "%s/%s/%s/%s/%s",
- sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
- USBIP_HOST_DRV_NAME);
+ struct list_head *i, *tmp;
+ struct usbip_exported_device *edev;
- host_drv = sysfs_open_driver_path(host_drv_path);
- if (!host_drv) {
- dbg("sysfs_open_driver_path failed");
- return NULL;
+ list_for_each_safe(i, tmp, &host_driver->edev_list) {
+ edev = list_entry(i, struct usbip_exported_device, node);
+ list_del(i);
+ free(edev);
}
-
- return host_drv;
-}
-
-static void usbip_exported_device_delete(void *dev)
-{
- struct usbip_exported_device *edev = dev;
- sysfs_close_device(edev->sudev);
- free(dev);
}
int usbip_host_driver_open(void)
{
int rc;
- host_driver = calloc(1, sizeof(*host_driver));
- if (!host_driver) {
- dbg("calloc failed");
+ udev_context = udev_new();
+ if (!udev_context) {
+ err("udev_new failed");
return -1;
}
- host_driver->ndevs = 0;
- host_driver->edev_list =
- dlist_new_with_delete(sizeof(struct usbip_exported_device),
- usbip_exported_device_delete);
- if (!host_driver->edev_list) {
- dbg("dlist_new_with_delete failed");
- goto err_free_host_driver;
- }
+ host_driver = calloc(1, sizeof(*host_driver));
- host_driver->sysfs_driver = open_sysfs_host_driver();
- if (!host_driver->sysfs_driver)
- goto err_destroy_edev_list;
+ host_driver->ndevs = 0;
+ INIT_LIST_HEAD(&host_driver->edev_list);
rc = refresh_exported_devices();
if (rc < 0)
- goto err_close_sysfs_driver;
+ goto err_free_host_driver;
return 0;
-err_close_sysfs_driver:
- sysfs_close_driver(host_driver->sysfs_driver);
-err_destroy_edev_list:
- dlist_destroy(host_driver->edev_list);
err_free_host_driver:
free(host_driver);
host_driver = NULL;
+ udev_unref(udev_context);
+
return -1;
}
@@ -300,30 +193,22 @@ void usbip_host_driver_close(void)
if (!host_driver)
return;
- if (host_driver->edev_list)
- dlist_destroy(host_driver->edev_list);
- if (host_driver->sysfs_driver)
- sysfs_close_driver(host_driver->sysfs_driver);
+ usbip_exported_device_destroy();
free(host_driver);
host_driver = NULL;
+
+ udev_unref(udev_context);
}
int usbip_host_refresh_device_list(void)
{
int rc;
- if (host_driver->edev_list)
- dlist_destroy(host_driver->edev_list);
+ usbip_exported_device_destroy();
host_driver->ndevs = 0;
- host_driver->edev_list =
- dlist_new_with_delete(sizeof(struct usbip_exported_device),
- usbip_exported_device_delete);
- if (!host_driver->edev_list) {
- dbg("dlist_new_with_delete failed");
- return -1;
- }
+ INIT_LIST_HEAD(&host_driver->edev_list);
rc = refresh_exported_devices();
if (rc < 0)
@@ -335,8 +220,7 @@ int usbip_host_refresh_device_list(void)
int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd)
{
char attr_name[] = "usbip_sockfd";
- char attr_path[SYSFS_PATH_MAX];
- struct sysfs_attribute *attr;
+ char sockfd_attr_path[SYSFS_PATH_MAX];
char sockfd_buff[30];
int ret;
@@ -356,41 +240,32 @@ int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd)
}
/* only the first interface is true */
- snprintf(attr_path, sizeof(attr_path), "%s/%s:%d.%d/%s",
- edev->udev.path, edev->udev.busid,
- edev->udev.bConfigurationValue, 0, attr_name);
-
- attr = sysfs_open_attribute(attr_path);
- if (!attr) {
- dbg("sysfs_open_attribute failed: %s", attr_path);
- return -1;
- }
+ snprintf(sockfd_attr_path, sizeof(sockfd_attr_path), "%s/%s",
+ edev->udev.path, attr_name);
snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
- dbg("write: %s", sockfd_buff);
- ret = sysfs_write_attribute(attr, sockfd_buff, strlen(sockfd_buff));
+ ret = write_sysfs_attribute(sockfd_attr_path, sockfd_buff,
+ strlen(sockfd_buff));
if (ret < 0) {
- dbg("sysfs_write_attribute failed: sockfd %s to %s",
- sockfd_buff, attr_path);
- goto err_write_sockfd;
+ err("write_sysfs_attribute failed: sockfd %s to %s",
+ sockfd_buff, sockfd_attr_path);
+ return ret;
}
- dbg("connect: %s", edev->udev.busid);
-
-err_write_sockfd:
- sysfs_close_attribute(attr);
+ info("connect: %s", edev->udev.busid);
return ret;
}
struct usbip_exported_device *usbip_host_get_device(int num)
{
+ struct list_head *i;
struct usbip_exported_device *edev;
- struct dlist *dlist = host_driver->edev_list;
int cnt = 0;
- dlist_for_each_data(dlist, edev, struct usbip_exported_device) {
+ list_for_each(i, &host_driver->edev_list) {
+ edev = list_entry(i, struct usbip_exported_device, node);
if (num == cnt)
return edev;
else
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h
index 34fd14c..2a31f85 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.h
@@ -21,18 +21,19 @@
#include <stdint.h>
#include "usbip_common.h"
+#include "list.h"
struct usbip_host_driver {
int ndevs;
- struct sysfs_driver *sysfs_driver;
/* list of exported device */
- struct dlist *edev_list;
+ struct list_head edev_list;
};
struct usbip_exported_device {
- struct sysfs_device *sudev;
+ struct udev_device *sudev;
int32_t status;
struct usbip_usb_device udev;
+ struct list_head node;
struct usbip_usb_interface uinf[];
};
diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
index 209df9b..8901fcb 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
@@ -6,44 +6,28 @@
#include "vhci_driver.h"
#include <limits.h>
#include <netdb.h>
+#include <libudev.h>
+#include "sysfs_utils.h"
#undef PROGNAME
#define PROGNAME "libusbip"
struct usbip_vhci_driver *vhci_driver;
+struct udev *udev_context;
static struct usbip_imported_device *
imported_device_init(struct usbip_imported_device *idev, char *busid)
{
- struct sysfs_device *sudev;
+ struct udev_device *sudev;
- sudev = sysfs_open_device("usb", busid);
+ sudev = udev_device_new_from_subsystem_sysname(udev_context,
+ "usb", busid);
if (!sudev) {
- dbg("sysfs_open_device failed: %s", busid);
+ dbg("udev_device_new_from_subsystem_sysname failed: %s", busid);
goto err;
}
read_usb_device(sudev, &idev->udev);
- sysfs_close_device(sudev);
-
- /* add class devices of this imported device */
- struct usbip_class_device *cdev;
- dlist_for_each_data(vhci_driver->cdev_list, cdev,
- struct usbip_class_device) {
- if (!strncmp(cdev->dev_path, idev->udev.path,
- strlen(idev->udev.path))) {
- struct usbip_class_device *new_cdev;
- /*
- * alloc and copy because dlist is linked
- * from only one list
- */
- new_cdev = calloc(1, sizeof(*new_cdev));
- if (!new_cdev)
- goto err;
-
- memcpy(new_cdev, cdev, sizeof(*new_cdev));
- dlist_unshift(idev->cdev_list, (void *) new_cdev);
- }
- }
+ udev_device_unref(sudev);
return idev;
@@ -53,7 +37,7 @@ err:
-static int parse_status(char *value)
+static int parse_status(const char *value)
{
int ret = 0;
char *c;
@@ -100,12 +84,6 @@ static int parse_status(char *value)
idev->busnum = (devid >> 16);
idev->devnum = (devid & 0x0000ffff);
- idev->cdev_list = dlist_new(sizeof(struct usbip_class_device));
- if (!idev->cdev_list) {
- dbg("dlist_new failed");
- return -1;
- }
-
if (idev->status != VDEV_ST_NULL
&& idev->status != VDEV_ST_NOTASSIGNED) {
idev = imported_device_init(idev, lbusid);
@@ -129,156 +107,35 @@ static int parse_status(char *value)
return 0;
}
-
-static int check_usbip_device(struct sysfs_class_device *cdev)
-{
- /* /sys/class/video4linux/video0/device */
- char class_path[SYSFS_PATH_MAX];
- /* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1 */
- char dev_path[SYSFS_PATH_MAX];
- int ret;
- struct usbip_class_device *usbip_cdev;
-
- snprintf(class_path, sizeof(class_path), "%s/device", cdev->path);
-
- ret = sysfs_get_link(class_path, dev_path, sizeof(dev_path));
- if (ret == 0) {
- if (!strncmp(dev_path, vhci_driver->hc_device->path,
- strlen(vhci_driver->hc_device->path))) {
- /* found usbip device */
- usbip_cdev = calloc(1, sizeof(*usbip_cdev));
- if (!usbip_cdev) {
- dbg("calloc failed");
- return -1;
- }
- dlist_unshift(vhci_driver->cdev_list, usbip_cdev);
- strncpy(usbip_cdev->class_path, class_path,
- sizeof(usbip_cdev->class_path));
- strncpy(usbip_cdev->dev_path, dev_path,
- sizeof(usbip_cdev->dev_path));
- dbg("found: %s %s", class_path, dev_path);
- }
- }
-
- return 0;
-}
-
-
-static int search_class_for_usbip_device(char *cname)
-{
- struct sysfs_class *class;
- struct dlist *cdev_list;
- struct sysfs_class_device *cdev;
- int ret = 0;
-
- class = sysfs_open_class(cname);
- if (!class) {
- dbg("sysfs_open_class failed");
- return -1;
- }
-
- dbg("class: %s", class->name);
-
- cdev_list = sysfs_get_class_devices(class);
- if (!cdev_list)
- /* nothing */
- goto out;
-
- dlist_for_each_data(cdev_list, cdev, struct sysfs_class_device) {
- dbg("cdev: %s", cdev->name);
- ret = check_usbip_device(cdev);
- if (ret < 0)
- goto out;
- }
-
-out:
- sysfs_close_class(class);
-
- return ret;
-}
-
-
-static int refresh_class_device_list(void)
-{
- int ret;
- struct dlist *cname_list;
- char *cname;
- char sysfs_mntpath[SYSFS_PATH_MAX];
- char class_path[SYSFS_PATH_MAX];
-
- ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
- if (ret < 0) {
- dbg("sysfs_get_mnt_path failed");
- return -1;
- }
-
- snprintf(class_path, sizeof(class_path), "%s/%s", sysfs_mntpath,
- SYSFS_CLASS_NAME);
-
- /* search under /sys/class */
- cname_list = sysfs_open_directory_list(class_path);
- if (!cname_list) {
- dbg("sysfs_open_directory failed");
- return -1;
- }
-
- dlist_for_each_data(cname_list, cname, char) {
- ret = search_class_for_usbip_device(cname);
- if (ret < 0) {
- sysfs_close_list(cname_list);
- return -1;
- }
- }
-
- sysfs_close_list(cname_list);
-
- /* search under /sys/block */
- ret = search_class_for_usbip_device(SYSFS_BLOCK_NAME);
- if (ret < 0)
- return -1;
-
- return 0;
-}
-
-
static int refresh_imported_device_list(void)
{
- struct sysfs_attribute *attr_status;
-
+ const char *attr_status;
- attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status");
+ attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device,
+ "status");
if (!attr_status) {
- dbg("sysfs_get_device_attr(\"status\") failed: %s",
- vhci_driver->hc_device->name);
+ err("udev_device_get_sysattr_value failed");
return -1;
}
- dbg("name: %s path: %s len: %d method: %d value: %s",
- attr_status->name, attr_status->path, attr_status->len,
- attr_status->method, attr_status->value);
-
- return parse_status(attr_status->value);
+ return parse_status(attr_status);
}
static int get_nports(void)
{
char *c;
int nports = 0;
- struct sysfs_attribute *attr_status;
+ const char *attr_status;
- attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status");
+ attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device,
+ "status");
if (!attr_status) {
- dbg("sysfs_get_device_attr(\"status\") failed: %s",
- vhci_driver->hc_device->name);
+ err("udev_device_get_sysattr_value failed");
return -1;
}
- dbg("name: %s path: %s len: %d method: %d value: %s",
- attr_status->name, attr_status->path, attr_status->len,
- attr_status->method, attr_status->value);
-
/* skip a header line */
- c = strchr(attr_status->value, '\n');
+ c = strchr(attr_status, '\n');
if (!c)
return 0;
c++;
@@ -295,71 +152,66 @@ static int get_nports(void)
return nports;
}
-static int get_hc_busid(char *sysfs_mntpath, char *hc_busid)
-{
- struct sysfs_driver *sdriver;
- char sdriver_path[SYSFS_PATH_MAX];
-
- struct sysfs_device *hc_dev;
- struct dlist *hc_devs;
-
- int found = 0;
-
- snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/%s/%s/%s", sysfs_mntpath,
- SYSFS_BUS_NAME, USBIP_VHCI_BUS_TYPE, SYSFS_DRIVERS_NAME,
- USBIP_VHCI_DRV_NAME);
-
- sdriver = sysfs_open_driver_path(sdriver_path);
- if (!sdriver) {
- dbg("sysfs_open_driver_path failed: %s", sdriver_path);
- dbg("make sure " USBIP_CORE_MOD_NAME ".ko and "
- USBIP_VHCI_DRV_NAME ".ko are loaded!");
- return -1;
- }
-
- hc_devs = sysfs_get_driver_devices(sdriver);
- if (!hc_devs) {
- dbg("sysfs_get_driver failed");
- goto err;
- }
-
- /* assume only one vhci_hcd */
- dlist_for_each_data(hc_devs, hc_dev, struct sysfs_device) {
- strncpy(hc_busid, hc_dev->bus_id, SYSFS_BUS_ID_SIZE);
- found = 1;
- }
-
-err:
- sysfs_close_driver(sdriver);
-
- if (found)
- return 0;
-
- dbg("%s not found", hc_busid);
- return -1;
-}
-
-static int read_record(int rhport, char *host, char *port, char *busid)
+/*
+ * 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)
{
+ 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 (fscanf(file, "%s %s %s\n", host, port, busid) != 3) {
- err("fscanf");
+ if (fgets(buffer, buffer_len, file) == NULL) {
+ err("fgets");
+ free(buffer);
fclose(file);
return -1;
}
-
fclose(file);
+ /* validate the length of each of the 3 parts */
+ start = buffer;
+ for (part = 0; part < 3; part++) {
+ end = strchr(start, delim[part]);
+ if (end == NULL || (end - start) > max_len[part]) {
+ free(buffer);
+ return -1;
+ }
+ start = end + 1;
+ }
+
+ if (sscanf(buffer, "%s %s %s\n", host, port, busid) != 3) {
+ err("sscanf");
+ free(buffer);
+ return -1;
+ }
+
+ free(buffer);
+
return 0;
}
@@ -367,30 +219,21 @@ static int read_record(int rhport, char *host, char *port, char *busid)
int usbip_vhci_driver_open(void)
{
- int ret;
- char hc_busid[SYSFS_BUS_ID_SIZE];
-
- vhci_driver = (struct usbip_vhci_driver *) calloc(1, sizeof(*vhci_driver));
- if (!vhci_driver) {
- dbg("calloc failed");
+ udev_context = udev_new();
+ if (!udev_context) {
+ err("udev_new failed");
return -1;
}
- ret = sysfs_get_mnt_path(vhci_driver->sysfs_mntpath, SYSFS_PATH_MAX);
- if (ret < 0) {
- dbg("sysfs_get_mnt_path failed");
- goto err;
- }
-
- ret = get_hc_busid(vhci_driver->sysfs_mntpath, hc_busid);
- if (ret < 0)
- goto err;
+ vhci_driver = calloc(1, sizeof(struct usbip_vhci_driver));
/* will be freed in usbip_driver_close() */
- vhci_driver->hc_device = sysfs_open_device(USBIP_VHCI_BUS_TYPE,
- hc_busid);
+ 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) {
- dbg("sysfs_open_device failed");
+ err("udev_device_new_from_subsystem_sysname failed");
goto err;
}
@@ -398,29 +241,21 @@ int usbip_vhci_driver_open(void)
dbg("available ports: %d", vhci_driver->nports);
- vhci_driver->cdev_list = dlist_new(sizeof(struct usbip_class_device));
- if (!vhci_driver->cdev_list)
- goto err;
-
- if (refresh_class_device_list())
- goto err;
-
if (refresh_imported_device_list())
goto err;
-
return 0;
-
err:
- if (vhci_driver->cdev_list)
- dlist_destroy(vhci_driver->cdev_list);
- if (vhci_driver->hc_device)
- sysfs_close_device(vhci_driver->hc_device);
+ udev_device_unref(vhci_driver->hc_device);
+
if (vhci_driver)
free(vhci_driver);
vhci_driver = NULL;
+
+ udev_unref(udev_context);
+
return -1;
}
@@ -430,53 +265,24 @@ void usbip_vhci_driver_close()
if (!vhci_driver)
return;
- if (vhci_driver->cdev_list)
- dlist_destroy(vhci_driver->cdev_list);
-
- for (int i = 0; i < vhci_driver->nports; i++) {
- if (vhci_driver->idev[i].cdev_list)
- dlist_destroy(vhci_driver->idev[i].cdev_list);
- }
+ udev_device_unref(vhci_driver->hc_device);
- if (vhci_driver->hc_device)
- sysfs_close_device(vhci_driver->hc_device);
free(vhci_driver);
vhci_driver = NULL;
+
+ udev_unref(udev_context);
}
int usbip_vhci_refresh_device_list(void)
{
- if (vhci_driver->cdev_list)
- dlist_destroy(vhci_driver->cdev_list);
-
-
- for (int i = 0; i < vhci_driver->nports; i++) {
- if (vhci_driver->idev[i].cdev_list)
- dlist_destroy(vhci_driver->idev[i].cdev_list);
- }
-
- vhci_driver->cdev_list = dlist_new(sizeof(struct usbip_class_device));
- if (!vhci_driver->cdev_list)
- goto err;
-
- if (refresh_class_device_list())
- goto err;
if (refresh_imported_device_list())
goto err;
return 0;
err:
- if (vhci_driver->cdev_list)
- dlist_destroy(vhci_driver->cdev_list);
-
- for (int i = 0; i < vhci_driver->nports; i++) {
- if (vhci_driver->idev[i].cdev_list)
- dlist_destroy(vhci_driver->idev[i].cdev_list);
- }
-
dbg("failed to refresh device list");
return -1;
}
@@ -494,24 +300,24 @@ int usbip_vhci_get_free_port(void)
int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid,
uint32_t speed) {
- struct sysfs_attribute *attr_attach;
char buff[200]; /* what size should be ? */
+ char attach_attr_path[SYSFS_PATH_MAX];
+ char attr_attach[] = "attach";
+ const char *path;
int ret;
- attr_attach = sysfs_get_device_attr(vhci_driver->hc_device, "attach");
- if (!attr_attach) {
- dbg("sysfs_get_device_attr(\"attach\") failed: %s",
- vhci_driver->hc_device->name);
- return -1;
- }
-
- snprintf(buff, sizeof(buff), "%u %u %u %u",
+ snprintf(buff, sizeof(buff), "%u %d %u %u",
port, sockfd, devid, speed);
dbg("writing: %s", buff);
- ret = sysfs_write_attribute(attr_attach, buff, strlen(buff));
+ path = udev_device_get_syspath(vhci_driver->hc_device);
+ snprintf(attach_attr_path, sizeof(attach_attr_path), "%s/%s",
+ path, attr_attach);
+ dbg("attach attribute path: %s", attach_attr_path);
+
+ ret = write_sysfs_attribute(attach_attr_path, buff, strlen(buff));
if (ret < 0) {
- dbg("sysfs_write_attribute failed");
+ dbg("write_sysfs_attribute failed");
return -1;
}
@@ -536,23 +342,23 @@ int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum,
int usbip_vhci_detach_device(uint8_t port)
{
- struct sysfs_attribute *attr_detach;
+ char detach_attr_path[SYSFS_PATH_MAX];
+ char attr_detach[] = "detach";
char buff[200]; /* what size should be ? */
+ const char *path;
int ret;
- attr_detach = sysfs_get_device_attr(vhci_driver->hc_device, "detach");
- if (!attr_detach) {
- dbg("sysfs_get_device_attr(\"detach\") failed: %s",
- vhci_driver->hc_device->name);
- return -1;
- }
-
snprintf(buff, sizeof(buff), "%u", port);
dbg("writing: %s", buff);
- ret = sysfs_write_attribute(attr_detach, buff, strlen(buff));
+ path = udev_device_get_syspath(vhci_driver->hc_device);
+ snprintf(detach_attr_path, sizeof(detach_attr_path), "%s/%s",
+ path, attr_detach);
+ dbg("detach attribute path: %s", detach_attr_path);
+
+ ret = write_sysfs_attribute(detach_attr_path, buff, strlen(buff));
if (ret < 0) {
- dbg("sysfs_write_attribute failed");
+ dbg("write_sysfs_attribute failed");
return -1;
}
@@ -573,7 +379,8 @@ int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev)
if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED)
return 0;
- ret = read_record(idev->port, host, serv, remote_busid);
+ ret = read_record(idev->port, host, sizeof(host), serv, sizeof(serv),
+ remote_busid);
if (ret) {
err("read_record");
read_record_error = 1;
diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
index e071f80..fa2316c 100644
--- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
+++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
@@ -5,7 +5,7 @@
#ifndef __VHCI_DRIVER_H
#define __VHCI_DRIVER_H
-#include <sysfs/libsysfs.h>
+#include <libudev.h>
#include <stdint.h>
#include "usbip_common.h"
@@ -13,11 +13,6 @@
#define USBIP_VHCI_BUS_TYPE "platform"
#define MAXNPORT 128
-struct usbip_class_device {
- char class_path[SYSFS_PATH_MAX];
- char dev_path[SYSFS_PATH_MAX];
-};
-
struct usbip_imported_device {
uint8_t port;
uint32_t status;
@@ -28,18 +23,13 @@ struct usbip_imported_device {
uint8_t devnum;
/* usbip_class_device list */
- struct dlist *cdev_list;
struct usbip_usb_device udev;
};
struct usbip_vhci_driver {
- char sysfs_mntpath[SYSFS_PATH_MAX];
/* /sys/devices/platform/vhci_hcd */
- struct sysfs_device *hc_device;
-
- /* usbip_class_device list */
- struct dlist *cdev_list;
+ struct udev_device *hc_device;
int nports;
struct usbip_imported_device idev[MAXNPORT];
diff --git a/drivers/staging/usbip/userspace/src/Makefile.am b/drivers/staging/usbip/userspace/src/Makefile.am
index b4f8c4b0..e81a4eb 100644
--- a/drivers/staging/usbip/userspace/src/Makefile.am
+++ b/drivers/staging/usbip/userspace/src/Makefile.am
@@ -8,5 +8,4 @@ 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
-
usbipd_SOURCES := usbip_network.h usbipd.c usbip_network.c
diff --git a/drivers/staging/usbip/userspace/src/usbip_attach.c b/drivers/staging/usbip/userspace/src/usbip_attach.c
index 0858411..716a79e 100644
--- a/drivers/staging/usbip/userspace/src/usbip_attach.c
+++ b/drivers/staging/usbip/userspace/src/usbip_attach.c
@@ -17,7 +17,6 @@
*/
#include <sys/stat.h>
-#include <sysfs/libsysfs.h>
#include <limits.h>
#include <stdint.h>
diff --git a/drivers/staging/usbip/userspace/src/usbip_bind.c b/drivers/staging/usbip/userspace/src/usbip_bind.c
index 9ecaf6e..fa46141 100644
--- a/drivers/staging/usbip/userspace/src/usbip_bind.c
+++ b/drivers/staging/usbip/userspace/src/usbip_bind.c
@@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sysfs/libsysfs.h>
+#include <libudev.h>
#include <errno.h>
#include <stdio.h>
@@ -28,6 +28,7 @@
#include "usbip_common.h"
#include "utils.h"
#include "usbip.h"
+#include "sysfs_utils.h"
enum unbind_status {
UNBIND_ST_OK,
@@ -48,167 +49,92 @@ void usbip_bind_usage(void)
/* call at unbound state */
static int bind_usbip(char *busid)
{
- char bus_type[] = "usb";
char attr_name[] = "bind";
- char sysfs_mntpath[SYSFS_PATH_MAX];
char bind_attr_path[SYSFS_PATH_MAX];
- char intf_busid[SYSFS_BUS_ID_SIZE];
- struct sysfs_device *busid_dev;
- struct sysfs_attribute *bind_attr;
- struct sysfs_attribute *bConfValue;
- struct sysfs_attribute *bNumIntfs;
- int i, failed = 0;
- int rc, ret = -1;
-
- rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
- if (rc < 0) {
- err("sysfs must be mounted: %s", strerror(errno));
- return -1;
- }
+ int rc = -1;
snprintf(bind_attr_path, sizeof(bind_attr_path), "%s/%s/%s/%s/%s/%s",
- sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
- USBIP_HOST_DRV_NAME, attr_name);
-
- bind_attr = sysfs_open_attribute(bind_attr_path);
- if (!bind_attr) {
- dbg("problem getting bind attribute: %s", strerror(errno));
- return -1;
- }
+ SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE,
+ SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name);
- busid_dev = sysfs_open_device(bus_type, busid);
- if (!busid_dev) {
- dbg("sysfs_open_device %s failed: %s", busid, strerror(errno));
- goto err_close_bind_attr;
- }
-
- bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue");
- bNumIntfs = sysfs_get_device_attr(busid_dev, "bNumInterfaces");
-
- if (!bConfValue || !bNumIntfs) {
- dbg("problem getting device attributes: %s",
+ rc = write_sysfs_attribute(bind_attr_path, busid, strlen(busid));
+ if (rc < 0) {
+ err("error binding device %s to driver: %s", busid,
strerror(errno));
- goto err_close_busid_dev;
- }
-
- for (i = 0; i < atoi(bNumIntfs->value); i++) {
- snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid,
- bConfValue->value, i);
-
- rc = sysfs_write_attribute(bind_attr, intf_busid,
- SYSFS_BUS_ID_SIZE);
- if (rc < 0) {
- dbg("bind driver at %s failed", intf_busid);
- failed = 1;
- }
+ return -1;
}
- if (!failed)
- ret = 0;
-
-err_close_busid_dev:
- sysfs_close_device(busid_dev);
-err_close_bind_attr:
- sysfs_close_attribute(bind_attr);
-
- return ret;
+ return 0;
}
/* buggy driver may cause dead lock */
static int unbind_other(char *busid)
{
- char bus_type[] = "usb";
- char intf_busid[SYSFS_BUS_ID_SIZE];
- struct sysfs_device *busid_dev;
- struct sysfs_device *intf_dev;
- struct sysfs_driver *intf_drv;
- struct sysfs_attribute *unbind_attr;
- struct sysfs_attribute *bConfValue;
- struct sysfs_attribute *bDevClass;
- struct sysfs_attribute *bNumIntfs;
- int i, rc;
enum unbind_status status = UNBIND_ST_OK;
- busid_dev = sysfs_open_device(bus_type, busid);
- if (!busid_dev) {
- dbg("sysfs_open_device %s failed: %s", busid, strerror(errno));
- return -1;
+ char attr_name[] = "unbind";
+ char unbind_attr_path[SYSFS_PATH_MAX];
+ int rc = -1;
+
+ struct udev *udev;
+ struct udev_device *dev;
+ const char *driver;
+ const char *bDevClass;
+
+ /* Create libudev context. */
+ udev = udev_new();
+
+ /* Get the device. */
+ dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid);
+ if (!dev) {
+ dbg("unable to find device with bus ID %s", busid);
+ goto err_close_busid_dev;
}
- bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue");
- bDevClass = sysfs_get_device_attr(busid_dev, "bDeviceClass");
- bNumIntfs = sysfs_get_device_attr(busid_dev, "bNumInterfaces");
- if (!bConfValue || !bDevClass || !bNumIntfs) {
- dbg("problem getting device attributes: %s",
- strerror(errno));
+ /* Check what kind of device it is. */
+ bDevClass = udev_device_get_sysattr_value(dev, "bDeviceClass");
+ if (!bDevClass) {
+ dbg("unable to get bDevClass device attribute");
goto err_close_busid_dev;
}
- if (!strncmp(bDevClass->value, "09", bDevClass->len)) {
+ if (!strncmp(bDevClass, "09", strlen(bDevClass))) {
dbg("skip unbinding of hub");
goto err_close_busid_dev;
}
- for (i = 0; i < atoi(bNumIntfs->value); i++) {
- snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid,
- bConfValue->value, i);
- intf_dev = sysfs_open_device(bus_type, intf_busid);
- if (!intf_dev) {
- dbg("could not open interface device: %s",
- strerror(errno));
- goto err_close_busid_dev;
- }
-
- dbg("%s -> %s", intf_dev->name, intf_dev->driver_name);
-
- if (!strncmp("unknown", intf_dev->driver_name, SYSFS_NAME_LEN))
- /* unbound interface */
- continue;
-
- if (!strncmp(USBIP_HOST_DRV_NAME, intf_dev->driver_name,
- SYSFS_NAME_LEN)) {
- /* already bound to usbip-host */
- status = UNBIND_ST_USBIP_HOST;
- continue;
- }
-
- /* unbinding */
- intf_drv = sysfs_open_driver(bus_type, intf_dev->driver_name);
- if (!intf_drv) {
- dbg("could not open interface driver on %s: %s",
- intf_dev->name, strerror(errno));
- goto err_close_intf_dev;
- }
+ /* Get the device driver. */
+ driver = udev_device_get_driver(dev);
+ if (!driver) {
+ /* No driver bound to this device. */
+ goto out;
+ }
- unbind_attr = sysfs_get_driver_attr(intf_drv, "unbind");
- if (!unbind_attr) {
- dbg("problem getting interface driver attribute: %s",
- strerror(errno));
- goto err_close_intf_drv;
- }
+ if (!strncmp(USBIP_HOST_DRV_NAME, driver,
+ strlen(USBIP_HOST_DRV_NAME))) {
+ /* Already bound to usbip-host. */
+ status = UNBIND_ST_USBIP_HOST;
+ goto out;
+ }
- rc = sysfs_write_attribute(unbind_attr, intf_dev->bus_id,
- SYSFS_BUS_ID_SIZE);
- if (rc < 0) {
- /* NOTE: why keep unbinding other interfaces? */
- dbg("unbind driver at %s failed", intf_dev->bus_id);
- status = UNBIND_ST_FAILED;
- }
+ /* Unbind device from driver. */
+ snprintf(unbind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s",
+ SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE,
+ SYSFS_DRIVERS_NAME, driver, attr_name);
- sysfs_close_driver(intf_drv);
- sysfs_close_device(intf_dev);
+ rc = write_sysfs_attribute(unbind_attr_path, busid, strlen(busid));
+ if (rc < 0) {
+ err("error unbinding device %s from driver", busid);
+ goto err_close_busid_dev;
}
goto out;
-err_close_intf_drv:
- sysfs_close_driver(intf_drv);
-err_close_intf_dev:
- sysfs_close_device(intf_dev);
err_close_busid_dev:
status = UNBIND_ST_FAILED;
out:
- sysfs_close_device(busid_dev);
+ udev_device_unref(dev);
+ udev_unref(udev);
return status;
}
@@ -216,6 +142,17 @@ out:
static int bind_device(char *busid)
{
int rc;
+ struct udev *udev;
+ struct udev_device *dev;
+
+ /* Check whether the device with this bus ID exists. */
+ udev = udev_new();
+ dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid);
+ if (!dev) {
+ err("device with the specified bus ID does not exist");
+ return -1;
+ }
+ udev_unref(udev);
rc = unbind_other(busid);
if (rc == UNBIND_ST_FAILED) {
@@ -240,7 +177,7 @@ static int bind_device(char *busid)
return -1;
}
- printf("bind device on busid %s: complete\n", busid);
+ info("bind device on busid %s: complete", busid);
return 0;
}
diff --git a/drivers/staging/usbip/userspace/src/usbip_detach.c b/drivers/staging/usbip/userspace/src/usbip_detach.c
index 13308df..05c6d15 100644
--- a/drivers/staging/usbip/userspace/src/usbip_detach.c
+++ b/drivers/staging/usbip/userspace/src/usbip_detach.c
@@ -16,8 +16,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sysfs/libsysfs.h>
-
#include <ctype.h>
#include <limits.h>
#include <stdint.h>
diff --git a/drivers/staging/usbip/userspace/src/usbip_list.c b/drivers/staging/usbip/userspace/src/usbip_list.c
index 237e099..d5ce34a 100644
--- a/drivers/staging/usbip/userspace/src/usbip_list.c
+++ b/drivers/staging/usbip/userspace/src/usbip_list.c
@@ -17,7 +17,7 @@
*/
#include <sys/types.h>
-#include <sysfs/libsysfs.h>
+#include <libudev.h>
#include <errno.h>
#include <stdbool.h>
@@ -54,7 +54,7 @@ static int get_exported_devices(char *host, int sockfd)
struct usbip_usb_device udev;
struct usbip_usb_interface uintf;
unsigned int i;
- int j, rc;
+ int rc, j;
rc = usbip_net_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
if (rc < 0) {
@@ -107,19 +107,20 @@ static int get_exported_devices(char *host, int sockfd)
for (j = 0; j < udev.bNumInterfaces; j++) {
rc = usbip_net_recv(sockfd, &uintf, sizeof(uintf));
if (rc < 0) {
- dbg("usbip_net_recv failed: usbip_usb_intf[%d]",
- j);
+ err("usbip_net_recv failed: usbip_usb_intf[%d]",
+ j);
return -1;
}
usbip_net_pack_usb_interface(0, &uintf);
usbip_names_get_class(class_name, sizeof(class_name),
- uintf.bInterfaceClass,
- uintf.bInterfaceSubClass,
- uintf.bInterfaceProtocol);
+ uintf.bInterfaceClass,
+ uintf.bInterfaceSubClass,
+ uintf.bInterfaceProtocol);
printf("%11s: %2d - %s\n", "", j, class_name);
}
+
printf("\n");
}
@@ -150,8 +151,8 @@ static int list_exported_devices(char *host)
return 0;
}
-static void print_device(char *busid, char *vendor, char *product,
- bool parsable)
+static void print_device(const char *busid, const char *vendor,
+ const char *product, bool parsable)
{
if (parsable)
printf("busid=%s#usbid=%.4s:%.4s#", busid, vendor, product);
@@ -165,106 +166,73 @@ static void print_product_name(char *product_name, bool parsable)
printf(" %s\n", product_name);
}
-static void print_interface(char *busid, char *driver, bool parsable)
-{
- if (parsable)
- printf("%s=%s#", busid, driver);
- else
- printf("%9s%s -> %s\n", "", busid, driver);
-}
-
-static int is_device(void *x)
-{
- struct sysfs_attribute *devpath;
- struct sysfs_device *dev = x;
- int ret = 0;
-
- devpath = sysfs_get_device_attr(dev, "devpath");
- if (devpath && *devpath->value != '0')
- ret = 1;
-
- return ret;
-}
-
-static int devcmp(void *a, void *b)
-{
- return strcmp(a, b);
-}
-
static int list_devices(bool parsable)
{
- char bus_type[] = "usb";
- char busid[SYSFS_BUS_ID_SIZE];
+ struct udev *udev;
+ struct udev_enumerate *enumerate;
+ struct udev_list_entry *devices, *dev_list_entry;
+ struct udev_device *dev;
+ const char *path;
+ const char *idVendor;
+ const char *idProduct;
+ const char *bConfValue;
+ const char *bNumIntfs;
+ const char *busid;
char product_name[128];
- struct sysfs_bus *ubus;
- struct sysfs_device *dev;
- struct sysfs_device *intf;
- struct sysfs_attribute *idVendor;
- struct sysfs_attribute *idProduct;
- struct sysfs_attribute *bConfValue;
- struct sysfs_attribute *bNumIntfs;
- struct dlist *devlist;
- int i;
int ret = -1;
- ubus = sysfs_open_bus(bus_type);
- if (!ubus) {
- err("could not open %s bus: %s", bus_type, strerror(errno));
- return -1;
- }
-
- devlist = sysfs_get_bus_devices(ubus);
- if (!devlist) {
- err("could not get %s bus devices: %s", bus_type,
- strerror(errno));
- goto err_out;
- }
-
- /* remove interfaces and root hubs from device list */
- dlist_filter_sort(devlist, is_device, devcmp);
-
- if (!parsable) {
- printf("Local USB devices\n");
- printf("=================\n");
- }
- dlist_for_each_data(devlist, dev, struct sysfs_device) {
- idVendor = sysfs_get_device_attr(dev, "idVendor");
- idProduct = sysfs_get_device_attr(dev, "idProduct");
- bConfValue = sysfs_get_device_attr(dev, "bConfigurationValue");
- bNumIntfs = sysfs_get_device_attr(dev, "bNumInterfaces");
+ /* Create libudev context. */
+ udev = udev_new();
+
+ /* Create libudev device enumeration. */
+ enumerate = udev_enumerate_new(udev);
+
+ /* Take only USB devices that are not hubs and do not have
+ * the bInterfaceNumber attribute, i.e. are not interfaces.
+ */
+ udev_enumerate_add_match_subsystem(enumerate, "usb");
+ udev_enumerate_add_nomatch_sysattr(enumerate, "bDeviceClass", "09");
+ udev_enumerate_add_nomatch_sysattr(enumerate, "bInterfaceNumber", NULL);
+ udev_enumerate_scan_devices(enumerate);
+
+ devices = udev_enumerate_get_list_entry(enumerate);
+
+ /* Show information about each device. */
+ udev_list_entry_foreach(dev_list_entry, devices) {
+ path = udev_list_entry_get_name(dev_list_entry);
+ dev = udev_device_new_from_syspath(udev, path);
+
+ /* Get device information. */
+ idVendor = udev_device_get_sysattr_value(dev, "idVendor");
+ idProduct = udev_device_get_sysattr_value(dev, "idProduct");
+ bConfValue = udev_device_get_sysattr_value(dev, "bConfigurationValue");
+ bNumIntfs = udev_device_get_sysattr_value(dev, "bNumInterfaces");
+ busid = udev_device_get_sysname(dev);
if (!idVendor || !idProduct || !bConfValue || !bNumIntfs) {
err("problem getting device attributes: %s",
strerror(errno));
goto err_out;
}
- /* get product name */
+ /* Get product name. */
usbip_names_get_product(product_name, sizeof(product_name),
- strtol(idVendor->value, NULL, 16),
- strtol(idProduct->value, NULL, 16));
- print_device(dev->bus_id, idVendor->value, idProduct->value,
- parsable);
+ strtol(idVendor, NULL, 16),
+ strtol(idProduct, NULL, 16));
+
+ /* Print information. */
+ print_device(busid, idVendor, idProduct, parsable);
print_product_name(product_name, parsable);
- for (i = 0; i < atoi(bNumIntfs->value); i++) {
- snprintf(busid, sizeof(busid), "%s:%.1s.%d",
- dev->bus_id, bConfValue->value, i);
- intf = sysfs_open_device(bus_type, busid);
- if (!intf) {
- err("could not open device interface: %s",
- strerror(errno));
- goto err_out;
- }
- print_interface(busid, intf->driver_name, parsable);
- sysfs_close_device(intf);
- }
printf("\n");
+
+ udev_device_unref(dev);
}
ret = 0;
err_out:
- sysfs_close_bus(ubus);
+ udev_enumerate_unref(enumerate);
+ udev_unref(udev);
return ret;
}
diff --git a/drivers/staging/usbip/userspace/src/usbip_network.h b/drivers/staging/usbip/userspace/src/usbip_network.h
index f19ae19..c1e875c 100644
--- a/drivers/staging/usbip/userspace/src/usbip_network.h
+++ b/drivers/staging/usbip/userspace/src/usbip_network.h
@@ -10,7 +10,6 @@
#endif
#include <sys/types.h>
-#include <sysfs/libsysfs.h>
#include <stdint.h>
diff --git a/drivers/staging/usbip/userspace/src/usbip_unbind.c b/drivers/staging/usbip/userspace/src/usbip_unbind.c
index d5a9ab6..a4a496c 100644
--- a/drivers/staging/usbip/userspace/src/usbip_unbind.c
+++ b/drivers/staging/usbip/userspace/src/usbip_unbind.c
@@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sysfs/libsysfs.h>
+#include <libudev.h>
#include <errno.h>
#include <stdio.h>
@@ -27,6 +27,7 @@
#include "usbip_common.h"
#include "utils.h"
#include "usbip.h"
+#include "sysfs_utils.h"
static const char usbip_unbind_usage_string[] =
"usbip unbind <args>\n"
@@ -41,115 +42,69 @@ void usbip_unbind_usage(void)
static int unbind_device(char *busid)
{
char bus_type[] = "usb";
- struct sysfs_driver *usbip_host_drv;
- struct sysfs_device *dev;
- struct dlist *devlist;
- int verified = 0;
int rc, ret = -1;
- char attr_name[] = "bConfigurationValue";
- char sysfs_mntpath[SYSFS_PATH_MAX];
- char busid_attr_path[SYSFS_PATH_MAX];
- struct sysfs_attribute *busid_attr;
- char *val = NULL;
- int len;
-
- /* verify the busid device is using usbip-host */
- usbip_host_drv = sysfs_open_driver(bus_type, USBIP_HOST_DRV_NAME);
- if (!usbip_host_drv) {
- err("could not open %s driver: %s", USBIP_HOST_DRV_NAME,
- strerror(errno));
- return -1;
- }
+ char unbind_attr_name[] = "unbind";
+ char unbind_attr_path[SYSFS_PATH_MAX];
+ char rebind_attr_name[] = "rebind";
+ char rebind_attr_path[SYSFS_PATH_MAX];
- devlist = sysfs_get_driver_devices(usbip_host_drv);
- if (!devlist) {
- err("%s is not in use by any devices", USBIP_HOST_DRV_NAME);
- goto err_close_usbip_host_drv;
- }
+ struct udev *udev;
+ struct udev_device *dev;
+ const char *driver;
- dlist_for_each_data(devlist, dev, struct sysfs_device) {
- if (!strncmp(busid, dev->name, strlen(busid)) &&
- !strncmp(dev->driver_name, USBIP_HOST_DRV_NAME,
- strlen(USBIP_HOST_DRV_NAME))) {
- verified = 1;
- break;
- }
- }
+ /* Create libudev context. */
+ udev = udev_new();
- if (!verified) {
- err("device on busid %s is not using %s", busid,
- USBIP_HOST_DRV_NAME);
- goto err_close_usbip_host_drv;
+ /* Check whether the device with this bus ID exists. */
+ dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid);
+ if (!dev) {
+ err("device with the specified bus ID does not exist");
+ goto err_close_udev;
}
- /*
- * NOTE: A read and write of an attribute value of the device busid
- * refers to must be done to start probing. That way a rebind of the
- * default driver for the device occurs.
- *
- * This seems very hackish and adds a lot of pointless code. I think it
- * should be done in the kernel by the driver after del_match_busid is
- * finished!
- */
-
- rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
- if (rc < 0) {
- err("sysfs must be mounted: %s", strerror(errno));
- return -1;
+ /* Check whether the device is using usbip-host driver. */
+ driver = udev_device_get_driver(dev);
+ if (!driver || strcmp(driver, "usbip-host")) {
+ err("device is not bound to usbip-host driver");
+ goto err_close_udev;
}
- snprintf(busid_attr_path, sizeof(busid_attr_path), "%s/%s/%s/%s/%s/%s",
- sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DEVICES_NAME,
- busid, attr_name);
+ /* Unbind device from driver. */
+ snprintf(unbind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s",
+ SYSFS_MNT_PATH, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
+ USBIP_HOST_DRV_NAME, unbind_attr_name);
- /* read a device attribute */
- busid_attr = sysfs_open_attribute(busid_attr_path);
- if (!busid_attr) {
- err("could not open %s/%s: %s", busid, attr_name,
- strerror(errno));
- return -1;
- }
-
- if (sysfs_read_attribute(busid_attr) < 0) {
- err("problem reading attribute: %s", strerror(errno));
- goto err_out;
+ rc = write_sysfs_attribute(unbind_attr_path, busid, strlen(busid));
+ if (rc < 0) {
+ err("error unbinding device %s from driver", busid);
+ goto err_close_udev;
}
- len = busid_attr->len;
- val = malloc(len);
- *val = *busid_attr->value;
- sysfs_close_attribute(busid_attr);
-
- /* notify driver of unbind */
+ /* Notify driver of unbind. */
rc = modify_match_busid(busid, 0);
if (rc < 0) {
err("unable to unbind device on %s", busid);
- goto err_out;
+ goto err_close_udev;
}
- /* write the device attribute */
- busid_attr = sysfs_open_attribute(busid_attr_path);
- if (!busid_attr) {
- err("could not open %s/%s: %s", busid, attr_name,
- strerror(errno));
- return -1;
- }
+ /* Trigger new probing. */
+ snprintf(rebind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s",
+ SYSFS_MNT_PATH, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
+ USBIP_HOST_DRV_NAME, rebind_attr_name);
- rc = sysfs_write_attribute(busid_attr, val, len);
+ rc = write_sysfs_attribute(rebind_attr_path, busid, strlen(busid));
if (rc < 0) {
- err("problem writing attribute: %s", strerror(errno));
- goto err_out;
+ err("error rebinding");
+ goto err_close_udev;
}
- sysfs_close_attribute(busid_attr);
ret = 0;
- printf("unbind device on busid %s: complete\n", busid);
+ info("unbind device on busid %s: complete", busid);
-err_out:
- free(val);
-err_close_usbip_host_drv:
- sysfs_close_driver(usbip_host_drv);
+err_close_udev:
+ udev_device_unref(dev);
+ udev_unref(udev);
return ret;
}
diff --git a/drivers/staging/usbip/userspace/src/usbipd.c b/drivers/staging/usbip/userspace/src/usbipd.c
index 7980f8b..2cae4ce 100644
--- a/drivers/staging/usbip/userspace/src/usbipd.c
+++ b/drivers/staging/usbip/userspace/src/usbipd.c
@@ -43,6 +43,7 @@
#include "usbip_host_driver.h"
#include "usbip_common.h"
#include "usbip_network.h"
+#include "list.h"
#undef PROGNAME
#define PROGNAME "usbipd"
@@ -93,6 +94,7 @@ static int recv_request_import(int sockfd)
struct op_common reply;
struct usbip_exported_device *edev;
struct usbip_usb_device pdu_udev;
+ struct list_head *i;
int found = 0;
int error = 0;
int rc;
@@ -107,8 +109,8 @@ static int recv_request_import(int sockfd)
}
PACK_OP_IMPORT_REQUEST(0, &req);
- dlist_for_each_data(host_driver->edev_list, edev,
- struct usbip_exported_device) {
+ list_for_each(i, &host_driver->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;
@@ -161,13 +163,12 @@ static int send_reply_devlist(int connfd)
struct usbip_usb_device pdu_udev;
struct usbip_usb_interface pdu_uinf;
struct op_devlist_reply reply;
- int i;
- int rc;
+ struct list_head *j;
+ int rc, i;
reply.ndev = 0;
/* number of exported devices */
- dlist_for_each_data(host_driver->edev_list, edev,
- struct usbip_exported_device) {
+ list_for_each(j, &host_driver->edev_list) {
reply.ndev += 1;
}
info("exportable devices: %d", reply.ndev);
@@ -185,8 +186,8 @@ static int send_reply_devlist(int connfd)
return -1;
}
- dlist_for_each_data(host_driver->edev_list, edev,
- struct usbip_exported_device) {
+ list_for_each(j, &host_driver->edev_list) {
+ edev = list_entry(j, struct usbip_exported_device, node);
dump_usb_device(&edev->udev);
memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
usbip_net_pack_usb_device(1, &pdu_udev);
@@ -203,9 +204,9 @@ static int send_reply_devlist(int connfd)
usbip_net_pack_usb_interface(1, &pdu_uinf);
rc = usbip_net_send(connfd, &pdu_uinf,
- sizeof(pdu_uinf));
+ sizeof(pdu_uinf));
if (rc < 0) {
- dbg("usbip_net_send failed: pdu_uinf");
+ err("usbip_net_send failed: pdu_uinf");
return -1;
}
}
diff --git a/drivers/staging/usbip/userspace/src/utils.c b/drivers/staging/usbip/userspace/src/utils.c
index 2d4966e..2b3d6d2 100644
--- a/drivers/staging/usbip/userspace/src/utils.c
+++ b/drivers/staging/usbip/userspace/src/utils.c
@@ -16,61 +16,37 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sysfs/libsysfs.h>
-
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "usbip_common.h"
#include "utils.h"
+#include "sysfs_utils.h"
int modify_match_busid(char *busid, int add)
{
- char bus_type[] = "usb";
char attr_name[] = "match_busid";
- char buff[SYSFS_BUS_ID_SIZE + 4];
- char sysfs_mntpath[SYSFS_PATH_MAX];
+ char command[SYSFS_BUS_ID_SIZE + 4];
char match_busid_attr_path[SYSFS_PATH_MAX];
- struct sysfs_attribute *match_busid_attr;
- int rc, ret = 0;
-
- if (strnlen(busid, SYSFS_BUS_ID_SIZE) > SYSFS_BUS_ID_SIZE - 1) {
- dbg("busid is too long");
- return -1;
- }
-
- rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
- if (rc < 0) {
- err("sysfs must be mounted: %s", strerror(errno));
- return -1;
- }
+ int rc;
snprintf(match_busid_attr_path, sizeof(match_busid_attr_path),
- "%s/%s/%s/%s/%s/%s", sysfs_mntpath, SYSFS_BUS_NAME, bus_type,
- SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name);
-
- match_busid_attr = sysfs_open_attribute(match_busid_attr_path);
- if (!match_busid_attr) {
- dbg("problem getting match_busid attribute: %s",
- strerror(errno));
- return -1;
- }
+ "%s/%s/%s/%s/%s/%s", SYSFS_MNT_PATH, SYSFS_BUS_NAME,
+ SYSFS_BUS_TYPE, SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME,
+ attr_name);
if (add)
- snprintf(buff, SYSFS_BUS_ID_SIZE + 4, "add %s", busid);
+ snprintf(command, SYSFS_BUS_ID_SIZE + 4, "add %s", busid);
else
- snprintf(buff, SYSFS_BUS_ID_SIZE + 4, "del %s", busid);
+ snprintf(command, SYSFS_BUS_ID_SIZE + 4, "del %s", busid);
- dbg("write \"%s\" to %s", buff, match_busid_attr->path);
-
- rc = sysfs_write_attribute(match_busid_attr, buff, sizeof(buff));
+ rc = write_sysfs_attribute(match_busid_attr_path, command,
+ sizeof(command));
if (rc < 0) {
dbg("failed to write match_busid: %s", strerror(errno));
- ret = -1;
+ return -1;
}
- sysfs_close_attribute(match_busid_attr);
-
- return ret;
+ return 0;
}
OpenPOWER on IntegriCloud