int usbip_vhci_detach_device(uint8_t port) { char detach_attr_path[SYSFS_PATH_MAX]; char attr_detach[] = "detach"; 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); dbg("detach attribute path: %s", detach_attr_path); ret = write_sysfs_attribute(detach_attr_path, buff, strlen(buff)); if (ret < 0) { dbg("write_sysfs_attribute failed"); return -1; } dbg("detached port: %d", port); return 0; }
int modify_match_busid(char *busid, int add) { char attr_name[] = "match_busid"; char command[SYSFS_BUS_ID_SIZE + 4]; char match_busid_attr_path[SYSFS_PATH_MAX]; int rc; snprintf(match_busid_attr_path, sizeof(match_busid_attr_path), "%s/%s/%s/%s/%s/%s", SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE, SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name); dbg("match_busid attribute path: %s", match_busid_attr_path); if (add) snprintf(command, SYSFS_BUS_ID_SIZE + 4, "add %s", busid); else snprintf(command, SYSFS_BUS_ID_SIZE + 4, "del %s", busid); dbg("write \"%s\" to %s", command, match_busid_attr_path); rc = write_sysfs_attribute(match_busid_attr_path, command, sizeof(command)); if (rc < 0) { dbg("Failed to write match_busid: %s", strerror(errno)); return -1; } return 0; }
int mempool_add_block(int argc, char *argv[]) { int opt = 0; char *blknum = NULL; int ret = ERR_SUCCESS; char path[SYSFS_PATH_MAX]; struct MsgSerOp *pSer = (struct MsgSerOp *)malloc(sizeof(struct MsgSerOp)); memset(pSer, 0, sizeof(struct MsgSerOp)); memset(path, 0, SYSFS_PATH_MAX); //option parse for(;;) { opt = getopt_long(argc, argv, "n:", addblk_opt, NULL); if(-1 == opt) { break; } switch(opt) { case 'n': DEBUG_INFO("block num:%s", optarg); blknum = optarg; break; default: PRINT_INFO("option error:invalid option\n"); } } if(NULL == blknum) { PRINT_INFO("argument error: block number missing\n"); ret = ERR_SER_ARG_MISSING; goto err_args; } //copy to structure if((pSer->info.addblk.block_num = atoi(blknum)) == 0) { PRINT_INFO("argument error: block number illegal\n"); ret = ERR_SER_ARG_ILLEGAL; goto err_args; } pSer->op = SERHOST_OP_ADD_BLK; snprintf(path, SYSFS_PATH_MAX, "%s/%s/%s/%s", SYSFS_MNT_PATH, SYSFS_BLKDEV_PATH, SYSFS_DEV_PATH, SYSFS_MEMPOOLCFG_PATH); write_sysfs_attribute(path, (char *)pSer, sizeof(struct MsgSerOp)); err_args: free(pSer); return ret; }
/* call at unbound state */ static int bind_usbip(char *busid) { char attr_name[] = "bind"; char bind_attr_path[SYSFS_PATH_MAX]; int rc = -1; snprintf(bind_attr_path, sizeof(bind_attr_path), "%s/%s/%s/%s/%s/%s", SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE, SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name); rc = write_sysfs_attribute(bind_attr_path, busid, strlen(busid)); if (rc < 0) { err("error binding device %s to driver: %s", busid, strerror(errno)); return -1; } return 0; }
/* buggy driver may cause dead lock */ static int unbind_other(char *busid) { enum unbind_status status = UNBIND_ST_OK; 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; } /* 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, "09", strlen(bDevClass))) { dbg("skip unbinding of hub"); goto err_close_busid_dev; } /* Get the device driver. */ driver = udev_device_get_driver(dev); if (!driver) { /* No driver bound to this device. */ goto out; } if (!strncmp(USBIP_HOST_DRV_NAME, driver, strlen(USBIP_HOST_DRV_NAME))) { /* Already bound to usbip-host. */ status = UNBIND_ST_USBIP_HOST; goto out; } /* 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); 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_busid_dev: status = UNBIND_ST_FAILED; out: udev_device_unref(dev); udev_unref(udev); return status; }
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; }