19 #include <sysfs/libsysfs.h>
28 #include "usbip_common.h"
38 static const char usbip_bind_usage_string[] =
45 printf(
"usage: %s", usbip_bind_usage_string);
49 static int bind_usbip(
char *
busid)
55 char intf_busid[SYSFS_BUS_ID_SIZE];
56 struct sysfs_device *busid_dev;
57 struct sysfs_attribute *bind_attr;
58 struct sysfs_attribute *bConfValue;
59 struct sysfs_attribute *bNumIntfs;
69 snprintf(bind_attr_path,
sizeof(bind_attr_path),
"%s/%s/%s/%s/%s/%s",
70 sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
73 bind_attr = sysfs_open_attribute(bind_attr_path);
75 dbg(
"problem getting bind attribute: %s",
strerror(errno));
79 busid_dev = sysfs_open_device(bus_type, busid);
81 dbg(
"sysfs_open_device %s failed: %s", busid,
strerror(errno));
82 goto err_close_bind_attr;
85 bConfValue = sysfs_get_device_attr(busid_dev,
"bConfigurationValue");
86 bNumIntfs = sysfs_get_device_attr(busid_dev,
"bNumInterfaces");
88 if (!bConfValue || !bNumIntfs) {
89 dbg(
"problem getting device attributes: %s",
91 goto err_close_busid_dev;
94 for (i = 0; i < atoi(bNumIntfs->value); i++) {
95 snprintf(intf_busid, SYSFS_BUS_ID_SIZE,
"%s:%.1s.%d", busid,
96 bConfValue->value, i);
98 rc = sysfs_write_attribute(bind_attr, intf_busid,
101 dbg(
"bind driver at %s failed", intf_busid);
110 sysfs_close_device(busid_dev);
112 sysfs_close_attribute(bind_attr);
118 static int unbind_other(
char *busid)
120 char bus_type[] =
"usb";
121 char intf_busid[SYSFS_BUS_ID_SIZE];
122 struct sysfs_device *busid_dev;
123 struct sysfs_device *intf_dev;
124 struct sysfs_driver *intf_drv;
125 struct sysfs_attribute *unbind_attr;
126 struct sysfs_attribute *bConfValue;
127 struct sysfs_attribute *bDevClass;
128 struct sysfs_attribute *bNumIntfs;
132 busid_dev = sysfs_open_device(bus_type, busid);
134 dbg(
"sysfs_open_device %s failed: %s", busid,
strerror(errno));
138 bConfValue = sysfs_get_device_attr(busid_dev,
"bConfigurationValue");
139 bDevClass = sysfs_get_device_attr(busid_dev,
"bDeviceClass");
140 bNumIntfs = sysfs_get_device_attr(busid_dev,
"bNumInterfaces");
141 if (!bConfValue || !bDevClass || !bNumIntfs) {
142 dbg(
"problem getting device attributes: %s",
144 goto err_close_busid_dev;
147 if (!
strncmp(bDevClass->value,
"09", bDevClass->len)) {
148 dbg(
"skip unbinding of hub");
149 goto err_close_busid_dev;
152 for (i = 0; i < atoi(bNumIntfs->value); i++) {
153 snprintf(intf_busid, SYSFS_BUS_ID_SIZE,
"%s:%.1s.%d", busid,
154 bConfValue->value, i);
155 intf_dev = sysfs_open_device(bus_type, intf_busid);
157 dbg(
"could not open interface device: %s",
159 goto err_close_busid_dev;
162 dbg(
"%s -> %s", intf_dev->name, intf_dev->driver_name);
164 if (!
strncmp(
"unknown", intf_dev->driver_name, SYSFS_NAME_LEN))
176 intf_drv = sysfs_open_driver(bus_type, intf_dev->driver_name);
178 dbg(
"could not open interface driver on %s: %s",
180 goto err_close_intf_dev;
183 unbind_attr = sysfs_get_driver_attr(intf_drv,
"unbind");
185 dbg(
"problem getting interface driver attribute: %s",
187 goto err_close_intf_drv;
190 rc = sysfs_write_attribute(unbind_attr, intf_dev->bus_id,
194 dbg(
"unbind driver at %s failed", intf_dev->bus_id);
198 sysfs_close_driver(intf_drv);
199 sysfs_close_device(intf_dev);
205 sysfs_close_driver(intf_drv);
207 sysfs_close_device(intf_dev);
211 sysfs_close_device(busid_dev);
216 static int bind_device(
char *busid)
220 rc = unbind_other(busid);
222 err(
"could not unbind driver from device on busid %s", busid);
225 err(
"device on busid %s is already bound to %s", busid,
232 err(
"unable to bind device on %s", busid);
236 rc = bind_usbip(busid);
243 printf(
"bind device on busid %s: complete\n", busid);
250 static const struct option opts[] = {
251 {
"busid", required_argument,
NULL,
'b' },
259 opt = getopt_long(argc, argv,
"b:", opts,
NULL);
266 ret = bind_device(optarg);