From a46034ca57ed6bdbb574a46ca3453061946b62f9 Mon Sep 17 00:00:00 2001 From: Valentina Manea Date: Sat, 8 Mar 2014 14:53:33 +0200 Subject: staging: usbip: trigger driver probing after unbinding from usbip-host A sysfs attribute is used to announce kernel space that a new driver probing session should be triggered for the just unbinded device. In order to have the address of struct device associated to this USB device, a new member has been added to struct bus_id_priv. Signed-off-by: Valentina Manea Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/stub_main.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers/staging/usbip/stub_main.c') diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index bd7b83a..9c5832a 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -19,6 +19,7 @@ #include #include +#include #include "usbip_common.h" #include "stub.h" @@ -187,6 +188,34 @@ static ssize_t store_match_busid(struct device_driver *dev, const char *buf, static DRIVER_ATTR(match_busid, S_IRUSR | S_IWUSR, show_match_busid, store_match_busid); +static ssize_t rebind_store(struct device_driver *dev, const char *buf, + size_t count) +{ + int ret; + int len; + struct bus_id_priv *bid; + + /* buf length should be less that BUSID_SIZE */ + len = strnlen(buf, BUSID_SIZE); + + if (!(len < BUSID_SIZE)) + return -EINVAL; + + bid = get_busid_priv(buf); + if (!bid) + return -ENODEV; + + ret = device_attach(&bid->udev->dev); + if (ret < 0) { + dev_err(&bid->udev->dev, "rebind failed\n"); + return ret; + } + + return count; +} + +static DRIVER_ATTR_WO(rebind); + static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead) { struct stub_priv *priv, *tmp; @@ -267,6 +296,13 @@ static int __init usbip_host_init(void) goto err_create_file; } + ret = driver_create_file(&stub_driver.drvwrap.driver, + &driver_attr_rebind); + if (ret) { + pr_err("driver_create_file failed\n"); + goto err_create_file; + } + pr_info(DRIVER_DESC " v" USBIP_VERSION "\n"); return ret; @@ -282,6 +318,9 @@ static void __exit usbip_host_exit(void) driver_remove_file(&stub_driver.drvwrap.driver, &driver_attr_match_busid); + driver_remove_file(&stub_driver.drvwrap.driver, + &driver_attr_rebind); + /* * deregister() calls stub_disconnect() for all devices. Device * specific data is cleared in stub_disconnect(). -- cgit v1.1