* [PATCH 0/2] usbip: Cleanup of sysfs attributes.
@ 2026-06-11 22:10 Jakub Lecki
2026-06-11 22:10 ` [PATCH 1/2] usbip: Convert usbip_debug to driver attribute Jakub Lecki
2026-06-11 22:10 ` [PATCH 2/2] usbip: Cleanup of vhci_hcd attributes Jakub Lecki
0 siblings, 2 replies; 3+ messages in thread
From: Jakub Lecki @ 2026-06-11 22:10 UTC (permalink / raw)
To: Valentina Manea, Shuah Khan, Hongren Zheng, Greg Kroah-Hartman
Cc: linux-usb, linux-kernel, Jakub Lecki
Hi!
This patchset is a prerequisite and a follow-up to my previous proposal
to parameterize the number of vhci controllers and the number of ports
[1], where Greg suggested that new parameters should be implemented in
sysfs/configfs.
Before doing that though, existing sysfs attributes must be cleaned up
as it's very unintuitive in present form.
First commit aims to align `usbip_debug` attribute that is shared
between drivers, to the expected usage. It controls the global debug
flag, therefore creating multiple instances of it in all of the driver's
devices makes no sense. At the same time it also allows to get rid of
manual attributes creation in vhci_hcd drivers in the next commit.
The second commit segregates the existing vhci_hcd sysfs attributes.
Before it, the first vhci device was used as an 'user interface' to the
driver. That required recognition of the first device and custom
handling in usb controller start function. With this change, the
driver-level attributes for attaching/detaching and getting number of
ports are defined as driver_attribute, and `status` attribute is
automatically created for each of vhci devices.
Thanks to that, future implementation of parametrized num_controllers
and ports will be much simpler as the fist device doesn't need to be
specially handled and doesn't control other devices which are now
handled by the driver.
[1] https://lore.kernel.org/linux-usb/20251104113248.223594-1-lec.jakub@gmail.com/
Signed-off-by: Jakub Lecki <lec.jakub@gmail.com>
---
Jakub Lecki (2):
usbip: Convert usbip_debug to driver attribute.
usbip: Cleanup of vhci_hcd attributes.
drivers/usb/usbip/stub_dev.c | 10 ++-
drivers/usb/usbip/usbip_common.c | 14 ++--
drivers/usb/usbip/usbip_common.h | 2 +-
drivers/usb/usbip/vhci.h | 6 +-
drivers/usb/usbip/vhci_hcd.c | 71 ++++++------------
drivers/usb/usbip/vhci_sysfs.c | 132 +++++-----------------------------
tools/usb/usbip/libsrc/sysfs_utils.c | 23 ++++++
tools/usb/usbip/libsrc/sysfs_utils.h | 1 +
tools/usb/usbip/libsrc/usbip_common.h | 2 +
tools/usb/usbip/libsrc/vhci_driver.c | 61 ++++++++++------
10 files changed, 126 insertions(+), 196 deletions(-)
---
base-commit: 9716c086c8e8b141d35aa61f2e96a2e83de212a7
change-id: 20260611-usbip-attribute-cleanup-7515b9ff2872
Best regards,
--
Jakub Lecki <lec.jakub@gmail.com>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2] usbip: Convert usbip_debug to driver attribute.
2026-06-11 22:10 [PATCH 0/2] usbip: Cleanup of sysfs attributes Jakub Lecki
@ 2026-06-11 22:10 ` Jakub Lecki
2026-06-11 22:10 ` [PATCH 2/2] usbip: Cleanup of vhci_hcd attributes Jakub Lecki
1 sibling, 0 replies; 3+ messages in thread
From: Jakub Lecki @ 2026-06-11 22:10 UTC (permalink / raw)
To: Valentina Manea, Shuah Khan, Hongren Zheng, Greg Kroah-Hartman
Cc: linux-usb, linux-kernel, Jakub Lecki
Changing configuration of the debug flag affects all of devices debug
prints. Move the attribute to a driver level to prevent duplication.
The attribute for given drivers is located under:
* /sys/bus/platform/drivers/vhci_hcd/usbip_debug
* /sys/bus/usb/drivers/usbip-host/usbip_debug
Signed-off-by: Jakub Lecki <lec.jakub@gmail.com>
---
drivers/usb/usbip/stub_dev.c | 10 +++++++++-
drivers/usb/usbip/usbip_common.c | 14 ++++++--------
drivers/usb/usbip/usbip_common.h | 2 +-
drivers/usb/usbip/vhci_hcd.c | 7 +++++++
drivers/usb/usbip/vhci_sysfs.c | 3 +--
5 files changed, 24 insertions(+), 12 deletions(-)
diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c
index abfa11d6bde7..653d582de181 100644
--- a/drivers/usb/usbip/stub_dev.c
+++ b/drivers/usb/usbip/stub_dev.c
@@ -145,11 +145,16 @@ static DEVICE_ATTR_WO(usbip_sockfd);
static struct attribute *usbip_attrs[] = {
&dev_attr_usbip_status.attr,
&dev_attr_usbip_sockfd.attr,
- &dev_attr_usbip_debug.attr,
NULL,
};
ATTRIBUTE_GROUPS(usbip);
+static struct attribute *usbip_drv_attrs[] = {
+ &driver_attr_usbip_debug.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(usbip_drv);
+
static void stub_shutdown_connection(struct usbip_device *ud)
{
struct stub_device *sdev = container_of(ud, struct stub_device, ud);
@@ -531,4 +536,7 @@ struct usb_device_driver stub_driver = {
#endif
.supports_autosuspend = 0,
.dev_groups = usbip_groups,
+ .driver = {
+ .groups = usbip_drv_groups,
+ }
};
diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c
index a5837c0feb05..6920c12f2863 100644
--- a/drivers/usb/usbip/usbip_common.c
+++ b/drivers/usb/usbip/usbip_common.c
@@ -30,24 +30,22 @@ module_param(usbip_debug_flag, ulong, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(usbip_debug_flag, "debug flags (defined in usbip_common.h)");
/* FIXME */
-struct device_attribute dev_attr_usbip_debug;
-EXPORT_SYMBOL_GPL(dev_attr_usbip_debug);
+struct driver_attribute driver_attr_usbip_debug;
+EXPORT_SYMBOL_GPL(driver_attr_usbip_debug);
-static ssize_t usbip_debug_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t usbip_debug_show(struct device_driver *driver, char *buf)
{
return sprintf(buf, "%lx\n", usbip_debug_flag);
}
-static ssize_t usbip_debug_store(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t count)
+static ssize_t usbip_debug_store(struct device_driver *driver,
+ const char *buf, size_t count)
{
if (sscanf(buf, "%lx", &usbip_debug_flag) != 1)
return -EINVAL;
return count;
}
-DEVICE_ATTR_RW(usbip_debug);
+DRIVER_ATTR_RW(usbip_debug);
static void usbip_dump_buffer(char *buff, int bufflen)
{
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
index 282efca64a01..ee4114e44935 100644
--- a/drivers/usb/usbip/usbip_common.h
+++ b/drivers/usb/usbip/usbip_common.h
@@ -57,7 +57,7 @@ enum {
#define usbip_dbg_flag_vhci_sysfs (usbip_debug_flag & usbip_debug_vhci_sysfs)
extern unsigned long usbip_debug_flag;
-extern struct device_attribute dev_attr_usbip_debug;
+extern struct driver_attribute driver_attr_usbip_debug;
#define usbip_dbg_with_flag(flag, fmt, args...) \
do { \
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index 39e8faf4c18c..bff752ac3183 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -1506,6 +1506,12 @@ static int vhci_hcd_resume(struct platform_device *pdev)
#endif
+static struct attribute *vhci_attrs[] = {
+ &driver_attr_usbip_debug.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(vhci);
+
static struct platform_driver vhci_driver = {
.probe = vhci_hcd_probe,
.remove = vhci_hcd_remove,
@@ -1513,6 +1519,7 @@ static struct platform_driver vhci_driver = {
.resume = vhci_hcd_resume,
.driver = {
.name = driver_name,
+ .groups = vhci_groups,
},
};
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index 5bc8c47788d4..2742ab12f309 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -512,9 +512,8 @@ int vhci_init_attr_group(void)
*attrs = &dev_attr_nports.attr;
*(attrs + 1) = &dev_attr_detach.attr;
*(attrs + 2) = &dev_attr_attach.attr;
- *(attrs + 3) = &dev_attr_usbip_debug.attr;
for (i = 0; i < vhci_num_controllers; i++)
- *(attrs + i + 4) = &((status_attrs + i)->attr.attr);
+ *(attrs + i + 3) = &((status_attrs + i)->attr.attr);
vhci_attr_group.attrs = attrs;
return 0;
}
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 2/2] usbip: Cleanup of vhci_hcd attributes.
2026-06-11 22:10 [PATCH 0/2] usbip: Cleanup of sysfs attributes Jakub Lecki
2026-06-11 22:10 ` [PATCH 1/2] usbip: Convert usbip_debug to driver attribute Jakub Lecki
@ 2026-06-11 22:10 ` Jakub Lecki
1 sibling, 0 replies; 3+ messages in thread
From: Jakub Lecki @ 2026-06-11 22:10 UTC (permalink / raw)
To: Valentina Manea, Shuah Khan, Hongren Zheng, Greg Kroah-Hartman
Cc: linux-usb, linux-kernel, Jakub Lecki
`nports`, `detach` and`attach` attibutes are common to all of
vhci devices, therefore should not exist in a single specific device.
Move them to the driver level. They can be found under
`/sys/bus/platform/drivers/vhci_hcd/`.
On the other hand, status attribute is specific to a device, thus it is
registered as a device attribute and created for each of vhci devices.
`status` attribute can be found under
`/sys/devices/platform/vhci_hcd.<n>/status`.
usbip userspace application sources are adjusted accordingly to the new
placement of attributes.
Signed-off-by: Jakub Lecki <lec.jakub@gmail.com>
---
drivers/usb/usbip/vhci.h | 6 +-
drivers/usb/usbip/vhci_hcd.c | 64 ++++-------------
drivers/usb/usbip/vhci_sysfs.c | 131 +++++-----------------------------
tools/usb/usbip/libsrc/sysfs_utils.c | 23 ++++++
tools/usb/usbip/libsrc/sysfs_utils.h | 1 +
tools/usb/usbip/libsrc/usbip_common.h | 2 +
tools/usb/usbip/libsrc/vhci_driver.c | 61 ++++++++++------
7 files changed, 103 insertions(+), 185 deletions(-)
diff --git a/drivers/usb/usbip/vhci.h b/drivers/usb/usbip/vhci.h
index 5659dce1526e..3bee1c0109e3 100644
--- a/drivers/usb/usbip/vhci.h
+++ b/drivers/usb/usbip/vhci.h
@@ -126,8 +126,10 @@ extern struct attribute_group vhci_attr_group;
void rh_port_connect(struct vhci_device *vdev, enum usb_device_speed speed);
/* vhci_sysfs.c */
-int vhci_init_attr_group(void);
-void vhci_finish_attr_group(void);
+extern struct device_attribute dev_attr_status;
+extern struct driver_attribute driver_attr_nports;
+extern struct driver_attribute driver_attr_detach;
+extern struct driver_attribute driver_attr_attach;
/* vhci_rx.c */
struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum);
diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c
index bff752ac3183..f1941a2b85dd 100644
--- a/drivers/usb/usbip/vhci_hcd.c
+++ b/drivers/usb/usbip/vhci_hcd.c
@@ -46,6 +46,7 @@ static const char driver_desc[] = "USB/IP Virtual Host Controller";
int vhci_num_controllers = VHCI_NR_HCS;
struct vhci *vhcis;
+static struct platform_driver vhci_driver;
static const char * const bit_desc[] = {
"CONNECTION", /*0*/
@@ -1150,23 +1151,6 @@ static void vhci_device_init(struct vhci_device *vdev)
usbip_start_eh(&vdev->ud);
}
-static int hcd_name_to_id(const char *name)
-{
- char *c;
- long val;
- int ret;
-
- c = strchr(name, '.');
- if (c == NULL)
- return 0;
-
- ret = kstrtol(c+1, 10, &val);
- if (ret < 0)
- return ret;
-
- return val;
-}
-
static int vhci_setup(struct usb_hcd *hcd)
{
struct vhci *vhci = *((void **)dev_get_platdata(hcd->self.controller));
@@ -1198,8 +1182,7 @@ static int vhci_setup(struct usb_hcd *hcd)
static int vhci_start(struct usb_hcd *hcd)
{
struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
- int id, rhport;
- int err;
+ int rhport;
usbip_dbg_vhci_hc("enter vhci_start\n");
@@ -1224,46 +1207,17 @@ static int vhci_start(struct usb_hcd *hcd)
hcd->self.otg_port = 1;
#endif
- id = hcd_name_to_id(hcd_name(hcd));
- if (id < 0) {
- dev_err(hcd_dev(hcd), "invalid vhci name %s\n", hcd_name(hcd));
- return -EINVAL;
- }
-
- /* vhci_hcd is now ready to be controlled through sysfs */
- if (id == 0 && usb_hcd_is_primary_hcd(hcd)) {
- err = vhci_init_attr_group();
- if (err) {
- dev_err(hcd_dev(hcd), "init attr group failed, err = %d\n", err);
- return err;
- }
- err = sysfs_create_group(&hcd_dev(hcd)->kobj, &vhci_attr_group);
- if (err) {
- dev_err(hcd_dev(hcd), "create sysfs files failed, err = %d\n", err);
- vhci_finish_attr_group();
- return err;
- }
- dev_info(hcd_dev(hcd), "created sysfs %s\n", hcd_name(hcd));
- }
-
return 0;
}
static void vhci_stop(struct usb_hcd *hcd)
{
struct vhci_hcd *vhci_hcd = hcd_to_vhci_hcd(hcd);
- int id, rhport;
+ int rhport;
usbip_dbg_vhci_hc("stop VHCI controller\n");
- /* 1. remove the userland interface of vhci_hcd */
- id = hcd_name_to_id(hcd_name(hcd));
- if (id == 0 && usb_hcd_is_primary_hcd(hcd)) {
- sysfs_remove_group(&hcd_dev(hcd)->kobj, &vhci_attr_group);
- vhci_finish_attr_group();
- }
-
- /* 2. shutdown all the ports of vhci_hcd */
+ /* shutdown all the ports of vhci_hcd */
for (rhport = 0; rhport < VHCI_HC_PORTS; rhport++) {
struct vhci_device *vdev = &vhci_hcd->vdev[rhport];
@@ -1507,11 +1461,20 @@ static int vhci_hcd_resume(struct platform_device *pdev)
#endif
static struct attribute *vhci_attrs[] = {
+ &driver_attr_nports.attr,
+ &driver_attr_detach.attr,
+ &driver_attr_attach.attr,
&driver_attr_usbip_debug.attr,
NULL
};
ATTRIBUTE_GROUPS(vhci);
+static struct attribute *vhci_dev_attrs[] = {
+ &dev_attr_status.attr,
+ NULL,
+};
+ATTRIBUTE_GROUPS(vhci_dev);
+
static struct platform_driver vhci_driver = {
.probe = vhci_hcd_probe,
.remove = vhci_hcd_remove,
@@ -1520,6 +1483,7 @@ static struct platform_driver vhci_driver = {
.driver = {
.name = driver_name,
.groups = vhci_groups,
+ .dev_groups = vhci_dev_groups,
},
};
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index 2742ab12f309..5baf9ccef625 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -127,23 +127,6 @@ static ssize_t status_show_not_ready(int pdev_nr, char *out)
return out - s;
}
-static int status_name_to_id(const char *name)
-{
- char *c;
- long val;
- int ret;
-
- c = strchr(name, '.');
- if (c == NULL)
- return 0;
-
- ret = kstrtol(c+1, 10, &val);
- if (ret < 0)
- return ret;
-
- return val;
-}
-
static ssize_t status_show(struct device *dev,
struct device_attribute *attr, char *out)
{
@@ -153,7 +136,7 @@ static ssize_t status_show(struct device *dev,
out += sprintf(out,
"hub port sta spd dev sockfd local_busid\n");
- pdev_nr = status_name_to_id(attr->attr.name);
+ pdev_nr = container_of(dev, struct platform_device, dev)->id;
if (pdev_nr < 0)
out += status_show_not_ready(pdev_nr, out);
else
@@ -161,9 +144,9 @@ static ssize_t status_show(struct device *dev,
return out - s;
}
+DEVICE_ATTR_RO(status);
-static ssize_t nports_show(struct device *dev, struct device_attribute *attr,
- char *out)
+static ssize_t nports_show(struct device_driver *driver, char *out)
{
char *s = out;
@@ -174,7 +157,7 @@ static ssize_t nports_show(struct device *dev, struct device_attribute *attr,
out += sprintf(out, "%d\n", VHCI_PORTS * vhci_num_controllers);
return out - s;
}
-static DEVICE_ATTR_RO(nports);
+DRIVER_ATTR_RO(nports);
/* Sysfs entry to shutdown a virtual connection */
static int vhci_port_disconnect(struct vhci_hcd *vhci_hcd, __u32 rhport)
@@ -230,7 +213,7 @@ static int valid_port(__u32 *pdev_nr, __u32 *rhport)
return 1;
}
-static ssize_t detach_store(struct device *dev, struct device_attribute *attr,
+static ssize_t detach_store(struct device_driver *driver,
const char *buf, size_t count)
{
__u32 port = 0, pdev_nr = 0, rhport = 0;
@@ -249,7 +232,7 @@ static ssize_t detach_store(struct device *dev, struct device_attribute *attr,
hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
if (hcd == NULL) {
- dev_err(dev, "port is not ready %u\n", port);
+ pr_err("port is not ready %u\n", port);
return -EAGAIN;
}
@@ -268,7 +251,7 @@ static ssize_t detach_store(struct device *dev, struct device_attribute *attr,
return count;
}
-static DEVICE_ATTR_WO(detach);
+DRIVER_ATTR_WO(detach);
static int valid_args(__u32 *pdev_nr, __u32 *rhport,
enum usb_device_speed speed)
@@ -306,7 +289,7 @@ static int valid_args(__u32 *pdev_nr, __u32 *rhport,
*
* write() returns 0 on success, else negative errno.
*/
-static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
+static ssize_t attach_store(struct device_driver *driver,
const char *buf, size_t count)
{
struct socket *socket;
@@ -343,7 +326,7 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
hcd = platform_get_drvdata(vhcis[pdev_nr].pdev);
if (hcd == NULL) {
- dev_err(dev, "port %d is not ready\n", port);
+ pr_err("port %d is not ready\n", port);
return -EAGAIN;
}
@@ -360,13 +343,13 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
/* Extract socket from fd. */
socket = sockfd_lookup(sockfd, &err);
if (!socket) {
- dev_err(dev, "failed to lookup sock");
+ pr_err("failed to lookup sock");
err = -EINVAL;
goto unlock_mutex;
}
if (socket->type != SOCK_STREAM) {
- dev_err(dev, "Expecting SOCK_STREAM - found %d",
- socket->type);
+ pr_err("Expecting SOCK_STREAM - found %d",
+ socket->type);
sockfd_put(socket);
err = -EINVAL;
goto unlock_mutex;
@@ -404,7 +387,7 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
kthread_stop_put(tcp_rx);
kthread_stop_put(tcp_tx);
- dev_err(dev, "port %d already used\n", rhport);
+ pr_err("port %d already used\n", rhport);
/*
* Will be retried from userspace
* if there's another free port.
@@ -413,10 +396,10 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
goto unlock_mutex;
}
- dev_info(dev, "pdev(%u) rhport(%u) sockfd(%d)\n",
- pdev_nr, rhport, sockfd);
- dev_info(dev, "devid(%u) speed(%u) speed_str(%s)\n",
- devid, speed, usb_speed_string(speed));
+ pr_info("pdev(%u) rhport(%u) sockfd(%d)\n",
+ pdev_nr, rhport, sockfd);
+ pr_info("devid(%u) speed(%u) speed_str(%s)\n",
+ devid, speed, usb_speed_string(speed));
vdev->devid = devid;
vdev->speed = speed;
@@ -436,7 +419,7 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
rh_port_connect(vdev, speed);
- dev_info(dev, "Device attached\n");
+ pr_info("Device attached\n");
mutex_unlock(&vdev->ud.sysfs_lock);
@@ -446,80 +429,4 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
mutex_unlock(&vdev->ud.sysfs_lock);
return err;
}
-static DEVICE_ATTR_WO(attach);
-
-#define MAX_STATUS_NAME 16
-
-struct status_attr {
- struct device_attribute attr;
- char name[MAX_STATUS_NAME+1];
-};
-
-static struct status_attr *status_attrs;
-
-static void set_status_attr(int id)
-{
- struct status_attr *status;
-
- status = status_attrs + id;
- if (id == 0)
- strscpy(status->name, "status");
- else
- snprintf(status->name, MAX_STATUS_NAME+1, "status.%d", id);
- status->attr.attr.name = status->name;
- status->attr.attr.mode = S_IRUGO;
- status->attr.show = status_show;
- sysfs_attr_init(&status->attr.attr);
-}
-
-static int init_status_attrs(void)
-{
- int id;
-
- status_attrs = kzalloc_objs(struct status_attr, vhci_num_controllers);
- if (status_attrs == NULL)
- return -ENOMEM;
-
- for (id = 0; id < vhci_num_controllers; id++)
- set_status_attr(id);
-
- return 0;
-}
-
-static void finish_status_attrs(void)
-{
- kfree(status_attrs);
-}
-
-struct attribute_group vhci_attr_group = {
- .attrs = NULL,
-};
-
-int vhci_init_attr_group(void)
-{
- struct attribute **attrs;
- int ret, i;
-
- attrs = kzalloc_objs(struct attribute *, (vhci_num_controllers + 5));
- if (attrs == NULL)
- return -ENOMEM;
-
- ret = init_status_attrs();
- if (ret) {
- kfree(attrs);
- return ret;
- }
- *attrs = &dev_attr_nports.attr;
- *(attrs + 1) = &dev_attr_detach.attr;
- *(attrs + 2) = &dev_attr_attach.attr;
- for (i = 0; i < vhci_num_controllers; i++)
- *(attrs + i + 3) = &((status_attrs + i)->attr.attr);
- vhci_attr_group.attrs = attrs;
- return 0;
-}
-
-void vhci_finish_attr_group(void)
-{
- finish_status_attrs();
- kfree(vhci_attr_group.attrs);
-}
+DRIVER_ATTR_WO(attach);
diff --git a/tools/usb/usbip/libsrc/sysfs_utils.c b/tools/usb/usbip/libsrc/sysfs_utils.c
index 14d5e67d398a..3e7bd8ee1b32 100644
--- a/tools/usb/usbip/libsrc/sysfs_utils.c
+++ b/tools/usb/usbip/libsrc/sysfs_utils.c
@@ -30,3 +30,26 @@ int write_sysfs_attribute(const char *attr_path, const char *new_value,
return 0;
}
+
+int read_sysfs_attribute(const char *attr_path, char *value, size_t len)
+{
+ int fd;
+ int length;
+
+ fd = open(attr_path, O_RDONLY);
+ if (fd < 0) {
+ dbg("error opening attribute %s", attr_path);
+ return -1;
+ }
+
+ length = read(fd, value, len - 1);
+ if (length < 0) {
+ dbg("error reading from attribute %s", attr_path);
+ close(fd);
+ return -1;
+ }
+
+ value[length] = '\0';
+ close(fd);
+ return 0;
+}
diff --git a/tools/usb/usbip/libsrc/sysfs_utils.h b/tools/usb/usbip/libsrc/sysfs_utils.h
index 0cd5f17e7eb2..6c34b0c88cf6 100644
--- a/tools/usb/usbip/libsrc/sysfs_utils.h
+++ b/tools/usb/usbip/libsrc/sysfs_utils.h
@@ -5,5 +5,6 @@
int write_sysfs_attribute(const char *attr_path, const char *new_value,
size_t len);
+int read_sysfs_attribute(const char *attr_path, char *value, size_t len);
#endif
diff --git a/tools/usb/usbip/libsrc/usbip_common.h b/tools/usb/usbip/libsrc/usbip_common.h
index 73a367a7fa10..424bd90bcd34 100644
--- a/tools/usb/usbip/libsrc/usbip_common.h
+++ b/tools/usb/usbip/libsrc/usbip_common.h
@@ -42,6 +42,8 @@
#define SYSFS_PATH_MAX 256
#define SYSFS_BUS_ID_SIZE 32
+#define SYSFS_NPORTS_SIZE 32
+#define SYSFS_DEVICE_NAME_SIZE 32
/* Defines for op_code status in server/client op_common PDUs */
#define ST_OK 0x00
diff --git a/tools/usb/usbip/libsrc/vhci_driver.c b/tools/usb/usbip/libsrc/vhci_driver.c
index 8159fd98680b..11738699fcd2 100644
--- a/tools/usb/usbip/libsrc/vhci_driver.c
+++ b/tools/usb/usbip/libsrc/vhci_driver.c
@@ -106,28 +106,38 @@ static int parse_status(const char *value)
return 0;
}
-#define MAX_STATUS_NAME 18
-
static int refresh_imported_device_list(void)
{
const char *attr_status;
- char status[MAX_STATUS_NAME+1] = "status";
+ char status[] = "status";
int i, ret;
+ struct udev_device *hc_device;
+ char hc_device_name[SYSFS_DEVICE_NAME_SIZE];
for (i = 0; i < vhci_driver->ncontrollers; i++) {
- if (i > 0)
- snprintf(status, sizeof(status), "status.%d", i);
-
- attr_status = udev_device_get_sysattr_value(vhci_driver->hc_device,
+ snprintf(hc_device_name, sizeof(hc_device_name), "%s.%d",
+ "vhci_hcd", i);
+ hc_device =
+ udev_device_new_from_subsystem_sysname(udev_context,
+ USBIP_VHCI_BUS_TYPE,
+ hc_device_name);
+ if (!hc_device) {
+ err("udev_device_new_from_subsystem_sysname failed: %s",
+ hc_device_name);
+ return -1;
+ }
+ attr_status = udev_device_get_sysattr_value(hc_device,
status);
if (!attr_status) {
err("udev_device_get_sysattr_value failed");
+ udev_device_unref(hc_device);
return -1;
}
dbg("controller %d", i);
ret = parse_status(attr_status);
+ udev_device_unref(hc_device);
if (ret != 0)
return ret;
}
@@ -135,13 +145,21 @@ static int refresh_imported_device_list(void)
return 0;
}
-static int get_nports(struct udev_device *hc_device)
+static int get_nports(void)
{
- const char *attr_nports;
+ char attr_nports[SYSFS_NPORTS_SIZE];
+ char bus_type[] = "platform";
+ char nports_attr_name[] = "nports";
+ char nports_attr_path[SYSFS_PATH_MAX];
+ int ret;
+
+ snprintf(nports_attr_path, sizeof(nports_attr_path), "%s/%s/%s/%s/%s/%s",
+ SYSFS_MNT_PATH, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
+ USBIP_VHCI_DRV_NAME, nports_attr_name);
- attr_nports = udev_device_get_sysattr_value(hc_device, "nports");
- if (!attr_nports) {
- err("udev_device_get_sysattr_value nports failed");
+ ret = read_sysfs_attribute(nports_attr_path, attr_nports, sizeof(attr_nports));
+ if (ret < 0) {
+ err("error reading nports attribute");
return -1;
}
@@ -261,7 +279,7 @@ int usbip_vhci_driver_open(void)
goto err;
}
- nports = get_nports(hc_device);
+ nports = get_nports();
if (nports <= 0) {
err("no available ports");
goto err;
@@ -359,16 +377,17 @@ int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid,
char buff[200]; /* what size should be ? */
char attach_attr_path[SYSFS_PATH_MAX];
char attr_attach[] = "attach";
- const char *path;
+ char bus_type[] = "platform";
int ret;
snprintf(buff, sizeof(buff), "%u %d %u %u",
port, sockfd, devid, speed);
dbg("writing: %s", buff);
- path = udev_device_get_syspath(vhci_driver->hc_device);
- snprintf(attach_attr_path, sizeof(attach_attr_path), "%s/%s",
- path, attr_attach);
+ snprintf(attach_attr_path, sizeof(attach_attr_path), "%s/%s/%s/%s/%s/%s",
+ SYSFS_MNT_PATH, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
+ USBIP_VHCI_DRV_NAME, attr_attach);
+
dbg("attach attribute path: %s", attach_attr_path);
ret = write_sysfs_attribute(attach_attr_path, buff, strlen(buff));
@@ -400,16 +419,16 @@ int usbip_vhci_detach_device(uint8_t port)
{
char detach_attr_path[SYSFS_PATH_MAX];
char attr_detach[] = "detach";
+ char bus_type[] = "platform";
char buff[200]; /* what size should be ? */
- const char *path;
int ret;
snprintf(buff, sizeof(buff), "%u", port);
dbg("writing: %s", buff);
- path = udev_device_get_syspath(vhci_driver->hc_device);
- snprintf(detach_attr_path, sizeof(detach_attr_path), "%s/%s",
- path, attr_detach);
+ snprintf(detach_attr_path, sizeof(detach_attr_path), "%s/%s/%s/%s/%s/%s",
+ SYSFS_MNT_PATH, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
+ USBIP_VHCI_DRV_NAME, attr_detach);
dbg("detach attribute path: %s", detach_attr_path);
ret = write_sysfs_attribute(detach_attr_path, buff, strlen(buff));
--
2.53.0
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-06-11 22:11 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-11 22:10 [PATCH 0/2] usbip: Cleanup of sysfs attributes Jakub Lecki
2026-06-11 22:10 ` [PATCH 1/2] usbip: Convert usbip_debug to driver attribute Jakub Lecki
2026-06-11 22:10 ` [PATCH 2/2] usbip: Cleanup of vhci_hcd attributes Jakub Lecki
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®