staging: usbip: convert usbip-host driver to usb_device_driver
authorValentina Manea <valentina.manea.m@gmail.com>
Thu, 23 Jan 2014 21:12:29 +0000 (23:12 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Feb 2014 18:54:30 +0000 (10:54 -0800)
This driver was previously an interface driver. Since USB/IP
exports a whole device, not just an interface, it would make
sense to be a device driver.

This patch also modifies the way userspace sees and uses a
shared device:

* the usbip_status file is no longer created for interface 0, but for
the whole device (such as
/sys/devices/pci0000:00/0000:00:01.2/usb1/1-1/usbip_status).
* per interface information, such as interface class or protocol, is
no longer sent/received; only device specific information is
transmitted.
* since the driver was moved one level below in the USB architecture,
there is no need to bind/unbind each interface, just the device as a
whole.

Signed-off-by: Valentina Manea <valentina.manea.m@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
12 files changed:
drivers/staging/usbip/stub.h
drivers/staging/usbip/stub_dev.c
drivers/staging/usbip/stub_main.c
drivers/staging/usbip/stub_rx.c
drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
drivers/staging/usbip/userspace/src/usbip_bind.c
drivers/staging/usbip/userspace/src/usbip_list.c
drivers/staging/usbip/userspace/src/usbip_unbind.c
drivers/staging/usbip/userspace/src/usbipd.c
drivers/usb/core/generic.c
drivers/usb/core/message.c
include/linux/usb.h

index a73e437..82e539a 100644 (file)
@@ -93,7 +93,7 @@ struct bus_id_priv {
 extern struct kmem_cache *stub_priv_cache;
 
 /* stub_dev.c */
-extern struct usb_driver stub_driver;
+extern struct usb_device_driver stub_driver;
 
 /* stub_main.c */
 struct bus_id_priv *get_busid_priv(const char *busid);
index 76a1ff0..b0bfd34 100644 (file)
@@ -279,21 +279,19 @@ static void stub_device_unusable(struct usbip_device *ud)
  *
  * Allocates and initializes a new stub_device struct.
  */
-static struct stub_device *stub_device_alloc(struct usb_device *udev,
-                                            struct usb_interface *interface)
+static struct stub_device *stub_device_alloc(struct usb_device *udev)
 {
        struct stub_device *sdev;
-       int busnum = interface_to_busnum(interface);
-       int devnum = interface_to_devnum(interface);
+       int busnum = udev->bus->busnum;
+       int devnum = udev->devnum;
 
-       dev_dbg(&interface->dev, "allocating stub device");
+       dev_dbg(&udev->dev, "allocating stub device");
 
        /* yes, it's a new device */
        sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL);
        if (!sdev)
                return NULL;
 
-       sdev->interface = usb_get_intf(interface);
        sdev->udev = usb_get_dev(udev);
 
        /*
@@ -322,7 +320,7 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev,
 
        usbip_start_eh(&sdev->ud);
 
-       dev_dbg(&interface->dev, "register new interface\n");
+       dev_dbg(&udev->dev, "register new device\n");
 
        return sdev;
 }
@@ -332,32 +330,20 @@ static void stub_device_free(struct stub_device *sdev)
        kfree(sdev);
 }
 
-/*
- * If a usb device has multiple active interfaces, this driver is bound to all
- * the active interfaces. However, usbip exports *a* usb device (i.e., not *an*
- * active interface). Currently, a userland program must ensure that it
- * looks at the usbip's sysfs entries of only the first active interface.
- *
- * TODO: use "struct usb_device_driver" to bind a usb device.
- * However, it seems it is not fully supported in mainline kernel yet
- * (2.6.19.2).
- */
-static int stub_probe(struct usb_interface *interface,
-                     const struct usb_device_id *id)
+static int stub_probe(struct usb_device *udev)
 {
-       struct usb_device *udev = interface_to_usbdev(interface);
        struct stub_device *sdev = NULL;
-       const char *udev_busid = dev_name(interface->dev.parent);
-       int err = 0;
+       const char *udev_busid = dev_name(&udev->dev);
+       int err = 0, config;
        struct bus_id_priv *busid_priv;
 
-       dev_dbg(&interface->dev, "Enter\n");
+       dev_dbg(&udev->dev, "Enter\n");
 
        /* check we should claim or not by busid_table */
        busid_priv = get_busid_priv(udev_busid);
        if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) ||
            (busid_priv->status == STUB_BUSID_OTHER)) {
-               dev_info(&interface->dev,
+               dev_info(&udev->dev,
                        "%s is not in match_busid table... skip!\n",
                        udev_busid);
 
@@ -383,60 +369,36 @@ static int stub_probe(struct usb_interface *interface,
                return -ENODEV;
        }
 
-       if (busid_priv->status == STUB_BUSID_ALLOC) {
-               sdev = busid_priv->sdev;
-               if (!sdev)
-                       return -ENODEV;
-
-               busid_priv->interf_count++;
-               dev_info(&interface->dev,
-                       "usbip-host: register new interface (bus %u dev %u ifn %u)\n",
-                       udev->bus->busnum, udev->devnum,
-                       interface->cur_altsetting->desc.bInterfaceNumber);
-
-               /* set private data to usb_interface */
-               usb_set_intfdata(interface, sdev);
-
-               err = stub_add_files(&interface->dev);
-               if (err) {
-                       dev_err(&interface->dev, "stub_add_files for %s\n",
-                               udev_busid);
-                       usb_set_intfdata(interface, NULL);
-                       busid_priv->interf_count--;
-                       return err;
-               }
-
-               usb_get_intf(interface);
-               return 0;
-       }
-
        /* ok, this is my device */
-       sdev = stub_device_alloc(udev, interface);
+       sdev = stub_device_alloc(udev);
        if (!sdev)
                return -ENOMEM;
 
-       dev_info(&interface->dev,
-               "usbip-host: register new device (bus %u dev %u ifn %u)\n",
-               udev->bus->busnum, udev->devnum,
-               interface->cur_altsetting->desc.bInterfaceNumber);
+       dev_info(&udev->dev,
+               "usbip-host: register new device (bus %u dev %u)\n",
+               udev->bus->busnum, udev->devnum);
 
-       busid_priv->interf_count = 0;
        busid_priv->shutdown_busid = 0;
 
-       /* set private data to usb_interface */
-       usb_set_intfdata(interface, sdev);
-       busid_priv->interf_count++;
+       config = usb_choose_configuration(udev);
+       if (config >= 0) {
+               err = usb_set_configuration(udev, config);
+               if (err && err != -ENODEV)
+                       dev_err(&udev->dev, "can't set config #%d, error %d\n",
+                               config, err);
+       }
+
+       /* set private data to usb_device */
+       dev_set_drvdata(&udev->dev, sdev);
        busid_priv->sdev = sdev;
 
-       err = stub_add_files(&interface->dev);
+       err = stub_add_files(&udev->dev);
        if (err) {
-               dev_err(&interface->dev, "stub_add_files for %s\n", udev_busid);
-               usb_set_intfdata(interface, NULL);
-               usb_put_intf(interface);
+               dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid);
+               dev_set_drvdata(&udev->dev, NULL);
                usb_put_dev(udev);
                kthread_stop_put(sdev->ud.eh);
 
-               busid_priv->interf_count = 0;
                busid_priv->sdev = NULL;
                stub_device_free(sdev);
                return err;
@@ -461,13 +423,13 @@ static void shutdown_busid(struct bus_id_priv *busid_priv)
  * called in usb_disconnect() or usb_deregister()
  * but only if actconfig(active configuration) exists
  */
-static void stub_disconnect(struct usb_interface *interface)
+static void stub_disconnect(struct usb_device *udev)
 {
        struct stub_device *sdev;
-       const char *udev_busid = dev_name(interface->dev.parent);
+       const char *udev_busid = dev_name(&udev->dev);
        struct bus_id_priv *busid_priv;
 
-       dev_dbg(&interface->dev, "Enter\n");
+       dev_dbg(&udev->dev, "Enter\n");
 
        busid_priv = get_busid_priv(udev_busid);
        if (!busid_priv) {
@@ -475,41 +437,29 @@ static void stub_disconnect(struct usb_interface *interface)
                return;
        }
 
-       sdev = usb_get_intfdata(interface);
+       sdev = dev_get_drvdata(&udev->dev);
 
        /* get stub_device */
        if (!sdev) {
-               dev_err(&interface->dev, "could not get device");
+               dev_err(&udev->dev, "could not get device");
                return;
        }
 
-       usb_set_intfdata(interface, NULL);
+       dev_set_drvdata(&udev->dev, NULL);
 
        /*
         * NOTE: rx/tx threads are invoked for each usb_device.
         */
-       stub_remove_files(&interface->dev);
+       stub_remove_files(&udev->dev);
 
        /* If usb reset is called from event handler */
-       if (busid_priv->sdev->ud.eh == current) {
-               busid_priv->interf_count--;
+       if (busid_priv->sdev->ud.eh == current)
                return;
-       }
-
-       if (busid_priv->interf_count > 1) {
-               busid_priv->interf_count--;
-               shutdown_busid(busid_priv);
-               usb_put_intf(interface);
-               return;
-       }
-
-       busid_priv->interf_count = 0;
 
        /* shutdown the current connection */
        shutdown_busid(busid_priv);
 
        usb_put_dev(sdev->udev);
-       usb_put_intf(interface);
 
        /* free sdev */
        busid_priv->sdev = NULL;
@@ -523,28 +473,34 @@ static void stub_disconnect(struct usb_interface *interface)
        }
 }
 
-/*
- * Presence of pre_reset and post_reset prevents the driver from being unbound
- * when the device is being reset
- */
+#ifdef CONFIG_PM
 
-static int stub_pre_reset(struct usb_interface *interface)
+/* These functions need usb_port_suspend and usb_port_resume,
+ * which reside in drivers/usb/core/usb.h. Skip for now. */
+
+static int stub_suspend(struct usb_device *udev, pm_message_t message)
 {
-       dev_dbg(&interface->dev, "pre_reset\n");
+       dev_dbg(&udev->dev, "stub_suspend\n");
+
        return 0;
 }
 
-static int stub_post_reset(struct usb_interface *interface)
+static int stub_resume(struct usb_device *udev, pm_message_t message)
 {
-       dev_dbg(&interface->dev, "post_reset\n");
+       dev_dbg(&udev->dev, "stub_resume\n");
+
        return 0;
 }
 
-struct usb_driver stub_driver = {
+#endif /* CONFIG_PM */
+
+struct usb_device_driver stub_driver = {
        .name           = "usbip-host",
        .probe          = stub_probe,
        .disconnect     = stub_disconnect,
-       .id_table       = stub_table,
-       .pre_reset      = stub_pre_reset,
-       .post_reset     = stub_post_reset,
+#ifdef CONFIG_PM
+       .suspend        = stub_suspend,
+       .resume         = stub_resume,
+#endif
+       .supports_autosuspend   =       0,
 };
index baf857f..bd7b83a 100644 (file)
@@ -254,7 +254,7 @@ static int __init usbip_host_init(void)
                return -ENOMEM;
        }
 
-       ret = usb_register(&stub_driver);
+       ret = usb_register_device_driver(&stub_driver, THIS_MODULE);
        if (ret) {
                pr_err("usb_register failed %d\n", ret);
                goto err_usb_register;
@@ -271,7 +271,7 @@ static int __init usbip_host_init(void)
        return ret;
 
 err_create_file:
-       usb_deregister(&stub_driver);
+       usb_deregister_device_driver(&stub_driver);
 err_usb_register:
        kmem_cache_destroy(stub_priv_cache);
        return ret;
@@ -286,7 +286,7 @@ static void __exit usbip_host_exit(void)
         * deregister() calls stub_disconnect() for all devices. Device
         * specific data is cleared in stub_disconnect().
         */
-       usb_deregister(&stub_driver);
+       usb_deregister_device_driver(&stub_driver);
 
        kmem_cache_destroy(stub_priv_cache);
 }
index 5d1d4a1..76e44d9 100644 (file)
@@ -550,7 +550,7 @@ static void stub_rx_pdu(struct usbip_device *ud)
        int ret;
        struct usbip_header pdu;
        struct stub_device *sdev = container_of(ud, struct stub_device, ud);
-       struct device *dev = &sdev->interface->dev;
+       struct device *dev = &sdev->udev->dev;
 
        usbip_dbg_stub_rx("Enter\n");
 
index 71a449c..86a8675 100644 (file)
@@ -32,7 +32,6 @@ struct usbip_host_driver *host_driver;
 
 #define SYSFS_OPEN_RETRIES 100
 
-/* only the first interface value is true! */
 static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
 {
        char attrpath[SYSFS_PATH_MAX];
@@ -56,8 +55,8 @@ static int32_t read_attr_usbip_status(struct usbip_usb_device *udev)
         * usbip_status to reappear.
         */
 
-       snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status",
-                udev->path, udev->busid, udev->bConfigurationValue, 0);
+       snprintf(attrpath, SYSFS_PATH_MAX, "%s/usbip_status",
+                udev->path);
 
        while (retries > 0) {
                if (stat(attrpath, &s) == 0)
@@ -168,19 +167,18 @@ static void delete_nothing(void *unused_data)
 
 static int refresh_exported_devices(void)
 {
-       /* sysfs_device of usb_interface */
-       struct sysfs_device     *suintf;
-       struct dlist            *suintf_list;
        /* sysfs_device of usb_device */
        struct sysfs_device     *sudev;
        struct dlist            *sudev_list;
+       struct dlist            *sudev_unique_list;
        struct usbip_exported_device *edev;
 
-       sudev_list = dlist_new_with_delete(sizeof(struct sysfs_device),
-                                          delete_nothing);
+       sudev_unique_list = dlist_new_with_delete(sizeof(struct sysfs_device),
+                                                 delete_nothing);
 
-       suintf_list = sysfs_get_driver_devices(host_driver->sysfs_driver);
-       if (!suintf_list) {
+       sudev_list = sysfs_get_driver_devices(host_driver->sysfs_driver);
+
+       if (!sudev_list) {
                /*
                 * Not an error condition. There are simply no devices bound to
                 * the driver yet.
@@ -190,23 +188,13 @@ static int refresh_exported_devices(void)
                return 0;
        }
 
-       /* collect unique USB devices (not interfaces) */
-       dlist_for_each_data(suintf_list, suintf, struct sysfs_device) {
-               /* get usb device of this usb interface */
-               sudev = sysfs_get_device_parent(suintf);
-               if (!sudev) {
-                       dbg("sysfs_get_device_parent failed: %s", suintf->name);
-                       continue;
-               }
+       dlist_for_each_data(sudev_list, sudev, struct sysfs_device)
+               if (check_new(sudev_unique_list, sudev))
+                       dlist_unshift(sudev_unique_list, sudev);
 
-               if (check_new(sudev_list, sudev)) {
-                       /* insert item at head of list */
-                       dlist_unshift(sudev_list, sudev);
-               }
-       }
-
-       dlist_for_each_data(sudev_list, sudev, struct sysfs_device) {
+       dlist_for_each_data(sudev_unique_list, sudev, struct sysfs_device) {
                edev = usbip_exported_device_new(sudev->path);
+
                if (!edev) {
                        dbg("usbip_exported_device_new failed");
                        continue;
@@ -216,7 +204,7 @@ static int refresh_exported_devices(void)
                host_driver->ndevs++;
        }
 
-       dlist_destroy(sudev_list);
+       dlist_destroy(sudev_unique_list);
 
        return 0;
 }
@@ -356,9 +344,8 @@ int usbip_host_export_device(struct usbip_exported_device *edev, int sockfd)
        }
 
        /* only the first interface is true */
-       snprintf(attr_path, sizeof(attr_path), "%s/%s:%d.%d/%s",
-                edev->udev.path, edev->udev.busid,
-                edev->udev.bConfigurationValue, 0, attr_name);
+       snprintf(attr_path, sizeof(attr_path), "%s/%s",
+                edev->udev.path, attr_name);
 
        attr = sysfs_open_attribute(attr_path);
        if (!attr) {
index 9ecaf6e..8cfd2db 100644 (file)
@@ -52,12 +52,8 @@ static int bind_usbip(char *busid)
        char attr_name[] = "bind";
        char sysfs_mntpath[SYSFS_PATH_MAX];
        char bind_attr_path[SYSFS_PATH_MAX];
-       char intf_busid[SYSFS_BUS_ID_SIZE];
-       struct sysfs_device *busid_dev;
        struct sysfs_attribute *bind_attr;
-       struct sysfs_attribute *bConfValue;
-       struct sysfs_attribute *bNumIntfs;
-       int i, failed = 0;
+       int failed = 0;
        int rc, ret = -1;
 
        rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
@@ -76,39 +72,15 @@ static int bind_usbip(char *busid)
                return -1;
        }
 
-       busid_dev = sysfs_open_device(bus_type, busid);
-       if (!busid_dev) {
-               dbg("sysfs_open_device %s failed: %s", busid, strerror(errno));
-               goto err_close_bind_attr;
-       }
-
-       bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue");
-       bNumIntfs  = sysfs_get_device_attr(busid_dev, "bNumInterfaces");
-
-       if (!bConfValue || !bNumIntfs) {
-               dbg("problem getting device attributes: %s",
-                   strerror(errno));
-               goto err_close_busid_dev;
-       }
-
-       for (i = 0; i < atoi(bNumIntfs->value); i++) {
-               snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid,
-                        bConfValue->value, i);
-
-               rc = sysfs_write_attribute(bind_attr, intf_busid,
-                                          SYSFS_BUS_ID_SIZE);
-               if (rc < 0) {
-                       dbg("bind driver at %s failed", intf_busid);
-                       failed = 1;
-               }
+       rc = sysfs_write_attribute(bind_attr, busid, SYSFS_BUS_ID_SIZE);
+       if (rc < 0) {
+               dbg("bind driver at %s failed", busid);
+               failed = 1;
        }
 
        if (!failed)
                ret = 0;
 
-err_close_busid_dev:
-       sysfs_close_device(busid_dev);
-err_close_bind_attr:
        sysfs_close_attribute(bind_attr);
 
        return ret;
@@ -118,15 +90,12 @@ err_close_bind_attr:
 static int unbind_other(char *busid)
 {
        char bus_type[] = "usb";
-       char intf_busid[SYSFS_BUS_ID_SIZE];
        struct sysfs_device *busid_dev;
-       struct sysfs_device *intf_dev;
-       struct sysfs_driver *intf_drv;
+       struct sysfs_device *dev;
+       struct sysfs_driver *drv;
        struct sysfs_attribute *unbind_attr;
-       struct sysfs_attribute *bConfValue;
        struct sysfs_attribute *bDevClass;
-       struct sysfs_attribute *bNumIntfs;
-       int i, rc;
+       int rc;
        enum unbind_status status = UNBIND_ST_OK;
 
        busid_dev = sysfs_open_device(bus_type, busid);
@@ -134,12 +103,11 @@ static int unbind_other(char *busid)
                dbg("sysfs_open_device %s failed: %s", busid, strerror(errno));
                return -1;
        }
+       dbg("busid path: %s", busid_dev->path);
 
-       bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue");
        bDevClass  = sysfs_get_device_attr(busid_dev, "bDeviceClass");
-       bNumIntfs  = sysfs_get_device_attr(busid_dev, "bNumInterfaces");
-       if (!bConfValue || !bDevClass || !bNumIntfs) {
-               dbg("problem getting device attributes: %s",
+       if (!bDevClass) {
+               dbg("problem getting device attribute: %s",
                    strerror(errno));
                goto err_close_busid_dev;
        }
@@ -149,62 +117,62 @@ static int unbind_other(char *busid)
                goto err_close_busid_dev;
        }
 
-       for (i = 0; i < atoi(bNumIntfs->value); i++) {
-               snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid,
-                        bConfValue->value, i);
-               intf_dev = sysfs_open_device(bus_type, intf_busid);
-               if (!intf_dev) {
-                       dbg("could not open interface device: %s",
-                           strerror(errno));
-                       goto err_close_busid_dev;
-               }
-
-               dbg("%s -> %s", intf_dev->name,  intf_dev->driver_name);
+       dev = sysfs_open_device(bus_type, busid);
+       if (!dev) {
+               dbg("could not open device: %s",
+                               strerror(errno));
+               goto err_close_busid_dev;
+       }
 
-               if (!strncmp("unknown", intf_dev->driver_name, SYSFS_NAME_LEN))
-                       /* unbound interface */
-                       continue;
+       dbg("%s -> %s", dev->name,  dev->driver_name);
 
-               if (!strncmp(USBIP_HOST_DRV_NAME, intf_dev->driver_name,
-                            SYSFS_NAME_LEN)) {
-                       /* already bound to usbip-host */
-                       status = UNBIND_ST_USBIP_HOST;
-                       continue;
-               }
+       if (!strncmp("unknown", dev->driver_name, SYSFS_NAME_LEN)) {
+               /* unbound interface */
+               sysfs_close_device(dev);
+               goto out;
+       }
 
-               /* unbinding */
-               intf_drv = sysfs_open_driver(bus_type, intf_dev->driver_name);
-               if (!intf_drv) {
-                       dbg("could not open interface driver on %s: %s",
-                           intf_dev->name, strerror(errno));
-                       goto err_close_intf_dev;
-               }
+       if (!strncmp(USBIP_HOST_DRV_NAME, dev->driver_name,
+                               SYSFS_NAME_LEN)) {
+               /* already bound to usbip-host */
+               status = UNBIND_ST_USBIP_HOST;
+               sysfs_close_device(dev);
+               goto out;
+       }
 
-               unbind_attr = sysfs_get_driver_attr(intf_drv, "unbind");
-               if (!unbind_attr) {
-                       dbg("problem getting interface driver attribute: %s",
-                           strerror(errno));
-                       goto err_close_intf_drv;
-               }
+       /* unbinding */
+       drv = sysfs_open_driver(bus_type, dev->driver_name);
+       if (!drv) {
+               dbg("could not open device driver on %s: %s",
+                               dev->name, strerror(errno));
+               goto err_close_intf_dev;
+       }
+       dbg("device driver: %s", drv->path);
 
-               rc = sysfs_write_attribute(unbind_attr, intf_dev->bus_id,
-                                          SYSFS_BUS_ID_SIZE);
-               if (rc < 0) {
-                       /* NOTE: why keep unbinding other interfaces? */
-                       dbg("unbind driver at %s failed", intf_dev->bus_id);
-                       status = UNBIND_ST_FAILED;
-               }
+       unbind_attr = sysfs_get_driver_attr(drv, "unbind");
+       if (!unbind_attr) {
+               dbg("problem getting device driver attribute: %s",
+                               strerror(errno));
+               goto err_close_intf_drv;
+       }
 
-               sysfs_close_driver(intf_drv);
-               sysfs_close_device(intf_dev);
+       rc = sysfs_write_attribute(unbind_attr, dev->bus_id,
+                       SYSFS_BUS_ID_SIZE);
+       if (rc < 0) {
+               /* NOTE: why keep unbinding other interfaces? */
+               dbg("unbind driver at %s failed", dev->bus_id);
+               status = UNBIND_ST_FAILED;
        }
 
+       sysfs_close_driver(drv);
+       sysfs_close_device(dev);
+
        goto out;
 
 err_close_intf_drv:
-       sysfs_close_driver(intf_drv);
+       sysfs_close_driver(drv);
 err_close_intf_dev:
-       sysfs_close_device(intf_dev);
+       sysfs_close_device(dev);
 err_close_busid_dev:
        status = UNBIND_ST_FAILED;
 out:
index 237e099..8864fa2 100644 (file)
@@ -52,9 +52,8 @@ static int get_exported_devices(char *host, int sockfd)
        struct op_devlist_reply reply;
        uint16_t code = OP_REP_DEVLIST;
        struct usbip_usb_device udev;
-       struct usbip_usb_interface uintf;
        unsigned int i;
-       int j, rc;
+       int rc;
 
        rc = usbip_net_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
        if (rc < 0) {
@@ -104,22 +103,6 @@ static int get_exported_devices(char *host, int sockfd)
                printf("%11s: %s\n", "", udev.path);
                printf("%11s: %s\n", "", class_name);
 
-               for (j = 0; j < udev.bNumInterfaces; j++) {
-                       rc = usbip_net_recv(sockfd, &uintf, sizeof(uintf));
-                       if (rc < 0) {
-                               dbg("usbip_net_recv failed: usbip_usb_intf[%d]",
-                                   j);
-
-                               return -1;
-                       }
-                       usbip_net_pack_usb_interface(0, &uintf);
-
-                       usbip_names_get_class(class_name, sizeof(class_name),
-                                             uintf.bInterfaceClass,
-                                             uintf.bInterfaceSubClass,
-                                             uintf.bInterfaceProtocol);
-                       printf("%11s: %2d - %s\n", "", j, class_name);
-               }
                printf("\n");
        }
 
index d5a9ab6..cace878 100644 (file)
@@ -47,12 +47,10 @@ static int unbind_device(char *busid)
        int verified = 0;
        int rc, ret = -1;
 
-       char attr_name[] = "bConfigurationValue";
+       char attr_name[] = "unbind";
        char sysfs_mntpath[SYSFS_PATH_MAX];
-       char busid_attr_path[SYSFS_PATH_MAX];
-       struct sysfs_attribute *busid_attr;
-       char *val = NULL;
-       int len;
+       char unbind_attr_path[SYSFS_PATH_MAX];
+       struct sysfs_attribute *unbind_attr;
 
        /* verify the busid device is using usbip-host */
        usbip_host_drv = sysfs_open_driver(bus_type, USBIP_HOST_DRV_NAME);
@@ -99,55 +97,34 @@ static int unbind_device(char *busid)
                return -1;
        }
 
-       snprintf(busid_attr_path, sizeof(busid_attr_path), "%s/%s/%s/%s/%s/%s",
-                sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DEVICES_NAME,
-                busid, attr_name);
+       snprintf(unbind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s",
+                sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME,
+                USBIP_HOST_DRV_NAME, attr_name);
 
        /* read a device attribute */
-       busid_attr = sysfs_open_attribute(busid_attr_path);
-       if (!busid_attr) {
+       unbind_attr = sysfs_open_attribute(unbind_attr_path);
+       if (!unbind_attr) {
                err("could not open %s/%s: %s", busid, attr_name,
                    strerror(errno));
                return -1;
        }
 
-       if (sysfs_read_attribute(busid_attr) < 0) {
-               err("problem reading attribute: %s", strerror(errno));
-               goto err_out;
-       }
-
-       len = busid_attr->len;
-       val = malloc(len);
-       *val = *busid_attr->value;
-       sysfs_close_attribute(busid_attr);
-
        /* notify driver of unbind */
        rc = modify_match_busid(busid, 0);
        if (rc < 0) {
                err("unable to unbind device on %s", busid);
-               goto err_out;
-       }
-
-       /* write the device attribute */
-       busid_attr = sysfs_open_attribute(busid_attr_path);
-       if (!busid_attr) {
-               err("could not open %s/%s: %s", busid, attr_name,
-                   strerror(errno));
-               return -1;
        }
 
-       rc = sysfs_write_attribute(busid_attr, val, len);
-       if (rc < 0) {
-               err("problem writing attribute: %s", strerror(errno));
-               goto err_out;
-       }
-       sysfs_close_attribute(busid_attr);
+       rc = sysfs_write_attribute(unbind_attr, busid,
+                                  SYSFS_BUS_ID_SIZE);
+               if (rc < 0) {
+                       dbg("bind driver at %s failed", busid);
+               }
+       sysfs_close_attribute(unbind_attr);
 
        ret = 0;
        printf("unbind device on busid %s: complete\n", busid);
 
-err_out:
-       free(val);
 err_close_usbip_host_drv:
        sysfs_close_driver(usbip_host_drv);
 
index 7980f8b..c2b3ced 100644 (file)
@@ -159,9 +159,7 @@ static int send_reply_devlist(int connfd)
 {
        struct usbip_exported_device *edev;
        struct usbip_usb_device pdu_udev;
-       struct usbip_usb_interface pdu_uinf;
        struct op_devlist_reply reply;
-       int i;
        int rc;
 
        reply.ndev = 0;
@@ -196,19 +194,6 @@ static int send_reply_devlist(int connfd)
                        dbg("usbip_net_send failed: pdu_udev");
                        return -1;
                }
-
-               for (i = 0; i < edev->udev.bNumInterfaces; i++) {
-                       dump_usb_interface(&edev->uinf[i]);
-                       memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf));
-                       usbip_net_pack_usb_interface(1, &pdu_uinf);
-
-                       rc = usbip_net_send(connfd, &pdu_uinf,
-                                           sizeof(pdu_uinf));
-                       if (rc < 0) {
-                               dbg("usbip_net_send failed: pdu_uinf");
-                               return -1;
-                       }
-               }
        }
 
        return 0;
index acbfeb0..358ca8d 100644 (file)
@@ -155,6 +155,7 @@ int usb_choose_configuration(struct usb_device *udev)
        }
        return i;
 }
+EXPORT_SYMBOL_GPL(usb_choose_configuration);
 
 static int generic_probe(struct usb_device *udev)
 {
index f829a1a..08d95e9 100644 (file)
@@ -1920,6 +1920,7 @@ free_interfaces:
        usb_autosuspend_device(dev);
        return 0;
 }
+EXPORT_SYMBOL_GPL(usb_set_configuration);
 
 static LIST_HEAD(set_config_list);
 static DEFINE_SPINLOCK(set_config_lock);
index c716da1..f434619 100644 (file)
@@ -1668,6 +1668,10 @@ extern void usb_reset_endpoint(struct usb_device *dev, unsigned int epaddr);
 /* this request isn't really synchronous, but it belongs with the others */
 extern int usb_driver_set_configuration(struct usb_device *udev, int config);
 
+/* choose and set configuration for device */
+extern int usb_choose_configuration(struct usb_device *udev);
+extern int usb_set_configuration(struct usb_device *dev, int configuration);
+
 /*
  * timeouts, in milliseconds, used for sending/receiving control messages
  * they typically complete within a few frames (msec) after they're issued