static int use_device_by_usbip(char *busid) { int ret; ret = unbind(busid); if (ret < 0) { g_warning("unbind drivers of %s, failed", busid); return -1; } ret = modify_match_busid(busid, 1); if (ret < 0) { g_warning("add %s to match_busid, failed", busid); return -1; } ret = bind_to_usbip(busid); if (ret < 0) { g_warning("bind usbip to %s, failed", busid); modify_match_busid(busid, 0); return -1; } g_message("bind %s to usbip, complete!", busid); return 0; }
static int use_device_by_other(char *busid) { int ret; int config; /* read and write the same config value to kick probing */ config = read_bConfigurationValue(busid); if (config < 0) { g_warning("read bConfigurationValue of %s, failed", busid); return -1; } ret = modify_match_busid(busid, 0); if (ret < 0) { g_warning("del %s to match_busid, failed", busid); return -1; } ret = write_bConfigurationValue(busid, config); if (ret < 0) { g_warning("read bConfigurationValue of %s, failed", busid); return -1; } g_message("bind %s to other drivers than usbip, complete!", busid); return 0; }
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) { err("could not unbind driver from device on busid %s", busid); return -1; } else if (rc == UNBIND_ST_USBIP_HOST) { err("device on busid %s is already bound to %s", busid, USBIP_HOST_DRV_NAME); return -1; } rc = modify_match_busid(busid, 1); if (rc < 0) { err("unable to bind device on %s", busid); return -1; } rc = bind_usbip(busid); if (rc < 0) { err("could not bind device to %s", USBIP_HOST_DRV_NAME); modify_match_busid(busid, 0); return -1; } info("bind device on busid %s: complete", busid); return 0; }
static int unbind_device(char *busid) { char bus_type[] = "usb"; int rc, ret = -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]; struct udev *udev; struct udev_device *dev; const char *driver; /* Create libudev context. */ udev = udev_new(); /* 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; } /* 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; } /* 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); 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; } /* Notify driver of unbind. */ rc = modify_match_busid(busid, 0); if (rc < 0) { err("unable to unbind device on %s", busid); goto err_close_udev; } /* 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 = write_sysfs_attribute(rebind_attr_path, busid, strlen(busid)); if (rc < 0) { err("error rebinding"); goto err_close_udev; } ret = 0; info("unbind device on busid %s: complete", busid); err_close_udev: udev_device_unref(dev); udev_unref(udev); return ret; }