Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: usbip: convert usbip-host driver to usb_device_driver

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>

authored by

Valentina Manea and committed by
Greg Kroah-Hartman
b7945b77 a6646ea6

+156 -294
+1 -1
drivers/staging/usbip/stub.h
··· 93 93 extern struct kmem_cache *stub_priv_cache; 94 94 95 95 /* stub_dev.c */ 96 - extern struct usb_driver stub_driver; 96 + extern struct usb_device_driver stub_driver; 97 97 98 98 /* stub_main.c */ 99 99 struct bus_id_priv *get_busid_priv(const char *busid);
+53 -97
drivers/staging/usbip/stub_dev.c
··· 279 279 * 280 280 * Allocates and initializes a new stub_device struct. 281 281 */ 282 - static struct stub_device *stub_device_alloc(struct usb_device *udev, 283 - struct usb_interface *interface) 282 + static struct stub_device *stub_device_alloc(struct usb_device *udev) 284 283 { 285 284 struct stub_device *sdev; 286 - int busnum = interface_to_busnum(interface); 287 - int devnum = interface_to_devnum(interface); 285 + int busnum = udev->bus->busnum; 286 + int devnum = udev->devnum; 288 287 289 - dev_dbg(&interface->dev, "allocating stub device"); 288 + dev_dbg(&udev->dev, "allocating stub device"); 290 289 291 290 /* yes, it's a new device */ 292 291 sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL); 293 292 if (!sdev) 294 293 return NULL; 295 294 296 - sdev->interface = usb_get_intf(interface); 297 295 sdev->udev = usb_get_dev(udev); 298 296 299 297 /* ··· 320 322 321 323 usbip_start_eh(&sdev->ud); 322 324 323 - dev_dbg(&interface->dev, "register new interface\n"); 325 + dev_dbg(&udev->dev, "register new device\n"); 324 326 325 327 return sdev; 326 328 } ··· 330 332 kfree(sdev); 331 333 } 332 334 333 - /* 334 - * If a usb device has multiple active interfaces, this driver is bound to all 335 - * the active interfaces. However, usbip exports *a* usb device (i.e., not *an* 336 - * active interface). Currently, a userland program must ensure that it 337 - * looks at the usbip's sysfs entries of only the first active interface. 338 - * 339 - * TODO: use "struct usb_device_driver" to bind a usb device. 340 - * However, it seems it is not fully supported in mainline kernel yet 341 - * (2.6.19.2). 342 - */ 343 - static int stub_probe(struct usb_interface *interface, 344 - const struct usb_device_id *id) 335 + static int stub_probe(struct usb_device *udev) 345 336 { 346 - struct usb_device *udev = interface_to_usbdev(interface); 347 337 struct stub_device *sdev = NULL; 348 - const char *udev_busid = dev_name(interface->dev.parent); 349 - int err = 0; 338 + const char *udev_busid = dev_name(&udev->dev); 339 + int err = 0, config; 350 340 struct bus_id_priv *busid_priv; 351 341 352 - dev_dbg(&interface->dev, "Enter\n"); 342 + dev_dbg(&udev->dev, "Enter\n"); 353 343 354 344 /* check we should claim or not by busid_table */ 355 345 busid_priv = get_busid_priv(udev_busid); 356 346 if (!busid_priv || (busid_priv->status == STUB_BUSID_REMOV) || 357 347 (busid_priv->status == STUB_BUSID_OTHER)) { 358 - dev_info(&interface->dev, 348 + dev_info(&udev->dev, 359 349 "%s is not in match_busid table... skip!\n", 360 350 udev_busid); 361 351 ··· 369 383 return -ENODEV; 370 384 } 371 385 372 - if (busid_priv->status == STUB_BUSID_ALLOC) { 373 - sdev = busid_priv->sdev; 374 - if (!sdev) 375 - return -ENODEV; 376 - 377 - busid_priv->interf_count++; 378 - dev_info(&interface->dev, 379 - "usbip-host: register new interface (bus %u dev %u ifn %u)\n", 380 - udev->bus->busnum, udev->devnum, 381 - interface->cur_altsetting->desc.bInterfaceNumber); 382 - 383 - /* set private data to usb_interface */ 384 - usb_set_intfdata(interface, sdev); 385 - 386 - err = stub_add_files(&interface->dev); 387 - if (err) { 388 - dev_err(&interface->dev, "stub_add_files for %s\n", 389 - udev_busid); 390 - usb_set_intfdata(interface, NULL); 391 - busid_priv->interf_count--; 392 - return err; 393 - } 394 - 395 - usb_get_intf(interface); 396 - return 0; 397 - } 398 - 399 386 /* ok, this is my device */ 400 - sdev = stub_device_alloc(udev, interface); 387 + sdev = stub_device_alloc(udev); 401 388 if (!sdev) 402 389 return -ENOMEM; 403 390 404 - dev_info(&interface->dev, 405 - "usbip-host: register new device (bus %u dev %u ifn %u)\n", 406 - udev->bus->busnum, udev->devnum, 407 - interface->cur_altsetting->desc.bInterfaceNumber); 391 + dev_info(&udev->dev, 392 + "usbip-host: register new device (bus %u dev %u)\n", 393 + udev->bus->busnum, udev->devnum); 408 394 409 - busid_priv->interf_count = 0; 410 395 busid_priv->shutdown_busid = 0; 411 396 412 - /* set private data to usb_interface */ 413 - usb_set_intfdata(interface, sdev); 414 - busid_priv->interf_count++; 397 + config = usb_choose_configuration(udev); 398 + if (config >= 0) { 399 + err = usb_set_configuration(udev, config); 400 + if (err && err != -ENODEV) 401 + dev_err(&udev->dev, "can't set config #%d, error %d\n", 402 + config, err); 403 + } 404 + 405 + /* set private data to usb_device */ 406 + dev_set_drvdata(&udev->dev, sdev); 415 407 busid_priv->sdev = sdev; 416 408 417 - err = stub_add_files(&interface->dev); 409 + err = stub_add_files(&udev->dev); 418 410 if (err) { 419 - dev_err(&interface->dev, "stub_add_files for %s\n", udev_busid); 420 - usb_set_intfdata(interface, NULL); 421 - usb_put_intf(interface); 411 + dev_err(&udev->dev, "stub_add_files for %s\n", udev_busid); 412 + dev_set_drvdata(&udev->dev, NULL); 422 413 usb_put_dev(udev); 423 414 kthread_stop_put(sdev->ud.eh); 424 415 425 - busid_priv->interf_count = 0; 426 416 busid_priv->sdev = NULL; 427 417 stub_device_free(sdev); 428 418 return err; ··· 423 461 * called in usb_disconnect() or usb_deregister() 424 462 * but only if actconfig(active configuration) exists 425 463 */ 426 - static void stub_disconnect(struct usb_interface *interface) 464 + static void stub_disconnect(struct usb_device *udev) 427 465 { 428 466 struct stub_device *sdev; 429 - const char *udev_busid = dev_name(interface->dev.parent); 467 + const char *udev_busid = dev_name(&udev->dev); 430 468 struct bus_id_priv *busid_priv; 431 469 432 - dev_dbg(&interface->dev, "Enter\n"); 470 + dev_dbg(&udev->dev, "Enter\n"); 433 471 434 472 busid_priv = get_busid_priv(udev_busid); 435 473 if (!busid_priv) { ··· 437 475 return; 438 476 } 439 477 440 - sdev = usb_get_intfdata(interface); 478 + sdev = dev_get_drvdata(&udev->dev); 441 479 442 480 /* get stub_device */ 443 481 if (!sdev) { 444 - dev_err(&interface->dev, "could not get device"); 482 + dev_err(&udev->dev, "could not get device"); 445 483 return; 446 484 } 447 485 448 - usb_set_intfdata(interface, NULL); 486 + dev_set_drvdata(&udev->dev, NULL); 449 487 450 488 /* 451 489 * NOTE: rx/tx threads are invoked for each usb_device. 452 490 */ 453 - stub_remove_files(&interface->dev); 491 + stub_remove_files(&udev->dev); 454 492 455 493 /* If usb reset is called from event handler */ 456 - if (busid_priv->sdev->ud.eh == current) { 457 - busid_priv->interf_count--; 494 + if (busid_priv->sdev->ud.eh == current) 458 495 return; 459 - } 460 - 461 - if (busid_priv->interf_count > 1) { 462 - busid_priv->interf_count--; 463 - shutdown_busid(busid_priv); 464 - usb_put_intf(interface); 465 - return; 466 - } 467 - 468 - busid_priv->interf_count = 0; 469 496 470 497 /* shutdown the current connection */ 471 498 shutdown_busid(busid_priv); 472 499 473 500 usb_put_dev(sdev->udev); 474 - usb_put_intf(interface); 475 501 476 502 /* free sdev */ 477 503 busid_priv->sdev = NULL; ··· 473 523 } 474 524 } 475 525 476 - /* 477 - * Presence of pre_reset and post_reset prevents the driver from being unbound 478 - * when the device is being reset 479 - */ 526 + #ifdef CONFIG_PM 480 527 481 - static int stub_pre_reset(struct usb_interface *interface) 528 + /* These functions need usb_port_suspend and usb_port_resume, 529 + * which reside in drivers/usb/core/usb.h. Skip for now. */ 530 + 531 + static int stub_suspend(struct usb_device *udev, pm_message_t message) 482 532 { 483 - dev_dbg(&interface->dev, "pre_reset\n"); 533 + dev_dbg(&udev->dev, "stub_suspend\n"); 534 + 484 535 return 0; 485 536 } 486 537 487 - static int stub_post_reset(struct usb_interface *interface) 538 + static int stub_resume(struct usb_device *udev, pm_message_t message) 488 539 { 489 - dev_dbg(&interface->dev, "post_reset\n"); 540 + dev_dbg(&udev->dev, "stub_resume\n"); 541 + 490 542 return 0; 491 543 } 492 544 493 - struct usb_driver stub_driver = { 545 + #endif /* CONFIG_PM */ 546 + 547 + struct usb_device_driver stub_driver = { 494 548 .name = "usbip-host", 495 549 .probe = stub_probe, 496 550 .disconnect = stub_disconnect, 497 - .id_table = stub_table, 498 - .pre_reset = stub_pre_reset, 499 - .post_reset = stub_post_reset, 551 + #ifdef CONFIG_PM 552 + .suspend = stub_suspend, 553 + .resume = stub_resume, 554 + #endif 555 + .supports_autosuspend = 0, 500 556 };
+3 -3
drivers/staging/usbip/stub_main.c
··· 254 254 return -ENOMEM; 255 255 } 256 256 257 - ret = usb_register(&stub_driver); 257 + ret = usb_register_device_driver(&stub_driver, THIS_MODULE); 258 258 if (ret) { 259 259 pr_err("usb_register failed %d\n", ret); 260 260 goto err_usb_register; ··· 271 271 return ret; 272 272 273 273 err_create_file: 274 - usb_deregister(&stub_driver); 274 + usb_deregister_device_driver(&stub_driver); 275 275 err_usb_register: 276 276 kmem_cache_destroy(stub_priv_cache); 277 277 return ret; ··· 286 286 * deregister() calls stub_disconnect() for all devices. Device 287 287 * specific data is cleared in stub_disconnect(). 288 288 */ 289 - usb_deregister(&stub_driver); 289 + usb_deregister_device_driver(&stub_driver); 290 290 291 291 kmem_cache_destroy(stub_priv_cache); 292 292 }
+1 -1
drivers/staging/usbip/stub_rx.c
··· 550 550 int ret; 551 551 struct usbip_header pdu; 552 552 struct stub_device *sdev = container_of(ud, struct stub_device, ud); 553 - struct device *dev = &sdev->interface->dev; 553 + struct device *dev = &sdev->udev->dev; 554 554 555 555 usbip_dbg_stub_rx("Enter\n"); 556 556
+16 -29
drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
··· 32 32 33 33 #define SYSFS_OPEN_RETRIES 100 34 34 35 - /* only the first interface value is true! */ 36 35 static int32_t read_attr_usbip_status(struct usbip_usb_device *udev) 37 36 { 38 37 char attrpath[SYSFS_PATH_MAX]; ··· 55 56 * usbip_status to reappear. 56 57 */ 57 58 58 - snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status", 59 - udev->path, udev->busid, udev->bConfigurationValue, 0); 59 + snprintf(attrpath, SYSFS_PATH_MAX, "%s/usbip_status", 60 + udev->path); 60 61 61 62 while (retries > 0) { 62 63 if (stat(attrpath, &s) == 0) ··· 167 168 168 169 static int refresh_exported_devices(void) 169 170 { 170 - /* sysfs_device of usb_interface */ 171 - struct sysfs_device *suintf; 172 - struct dlist *suintf_list; 173 171 /* sysfs_device of usb_device */ 174 172 struct sysfs_device *sudev; 175 173 struct dlist *sudev_list; 174 + struct dlist *sudev_unique_list; 176 175 struct usbip_exported_device *edev; 177 176 178 - sudev_list = dlist_new_with_delete(sizeof(struct sysfs_device), 179 - delete_nothing); 177 + sudev_unique_list = dlist_new_with_delete(sizeof(struct sysfs_device), 178 + delete_nothing); 180 179 181 - suintf_list = sysfs_get_driver_devices(host_driver->sysfs_driver); 182 - if (!suintf_list) { 180 + sudev_list = sysfs_get_driver_devices(host_driver->sysfs_driver); 181 + 182 + if (!sudev_list) { 183 183 /* 184 184 * Not an error condition. There are simply no devices bound to 185 185 * the driver yet. ··· 188 190 return 0; 189 191 } 190 192 191 - /* collect unique USB devices (not interfaces) */ 192 - dlist_for_each_data(suintf_list, suintf, struct sysfs_device) { 193 - /* get usb device of this usb interface */ 194 - sudev = sysfs_get_device_parent(suintf); 195 - if (!sudev) { 196 - dbg("sysfs_get_device_parent failed: %s", suintf->name); 197 - continue; 198 - } 193 + dlist_for_each_data(sudev_list, sudev, struct sysfs_device) 194 + if (check_new(sudev_unique_list, sudev)) 195 + dlist_unshift(sudev_unique_list, sudev); 199 196 200 - if (check_new(sudev_list, sudev)) { 201 - /* insert item at head of list */ 202 - dlist_unshift(sudev_list, sudev); 203 - } 204 - } 205 - 206 - dlist_for_each_data(sudev_list, sudev, struct sysfs_device) { 197 + dlist_for_each_data(sudev_unique_list, sudev, struct sysfs_device) { 207 198 edev = usbip_exported_device_new(sudev->path); 199 + 208 200 if (!edev) { 209 201 dbg("usbip_exported_device_new failed"); 210 202 continue; ··· 204 216 host_driver->ndevs++; 205 217 } 206 218 207 - dlist_destroy(sudev_list); 219 + dlist_destroy(sudev_unique_list); 208 220 209 221 return 0; 210 222 } ··· 344 356 } 345 357 346 358 /* only the first interface is true */ 347 - snprintf(attr_path, sizeof(attr_path), "%s/%s:%d.%d/%s", 348 - edev->udev.path, edev->udev.busid, 349 - edev->udev.bConfigurationValue, 0, attr_name); 359 + snprintf(attr_path, sizeof(attr_path), "%s/%s", 360 + edev->udev.path, attr_name); 350 361 351 362 attr = sysfs_open_attribute(attr_path); 352 363 if (!attr) {
+61 -93
drivers/staging/usbip/userspace/src/usbip_bind.c
··· 52 52 char attr_name[] = "bind"; 53 53 char sysfs_mntpath[SYSFS_PATH_MAX]; 54 54 char bind_attr_path[SYSFS_PATH_MAX]; 55 - char intf_busid[SYSFS_BUS_ID_SIZE]; 56 - struct sysfs_device *busid_dev; 57 55 struct sysfs_attribute *bind_attr; 58 - struct sysfs_attribute *bConfValue; 59 - struct sysfs_attribute *bNumIntfs; 60 - int i, failed = 0; 56 + int failed = 0; 61 57 int rc, ret = -1; 62 58 63 59 rc = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX); ··· 72 76 return -1; 73 77 } 74 78 75 - busid_dev = sysfs_open_device(bus_type, busid); 76 - if (!busid_dev) { 77 - dbg("sysfs_open_device %s failed: %s", busid, strerror(errno)); 78 - goto err_close_bind_attr; 79 - } 80 - 81 - bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue"); 82 - bNumIntfs = sysfs_get_device_attr(busid_dev, "bNumInterfaces"); 83 - 84 - if (!bConfValue || !bNumIntfs) { 85 - dbg("problem getting device attributes: %s", 86 - strerror(errno)); 87 - goto err_close_busid_dev; 88 - } 89 - 90 - for (i = 0; i < atoi(bNumIntfs->value); i++) { 91 - snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid, 92 - bConfValue->value, i); 93 - 94 - rc = sysfs_write_attribute(bind_attr, intf_busid, 95 - SYSFS_BUS_ID_SIZE); 96 - if (rc < 0) { 97 - dbg("bind driver at %s failed", intf_busid); 98 - failed = 1; 99 - } 79 + rc = sysfs_write_attribute(bind_attr, busid, SYSFS_BUS_ID_SIZE); 80 + if (rc < 0) { 81 + dbg("bind driver at %s failed", busid); 82 + failed = 1; 100 83 } 101 84 102 85 if (!failed) 103 86 ret = 0; 104 87 105 - err_close_busid_dev: 106 - sysfs_close_device(busid_dev); 107 - err_close_bind_attr: 108 88 sysfs_close_attribute(bind_attr); 109 89 110 90 return ret; ··· 90 118 static int unbind_other(char *busid) 91 119 { 92 120 char bus_type[] = "usb"; 93 - char intf_busid[SYSFS_BUS_ID_SIZE]; 94 121 struct sysfs_device *busid_dev; 95 - struct sysfs_device *intf_dev; 96 - struct sysfs_driver *intf_drv; 122 + struct sysfs_device *dev; 123 + struct sysfs_driver *drv; 97 124 struct sysfs_attribute *unbind_attr; 98 - struct sysfs_attribute *bConfValue; 99 125 struct sysfs_attribute *bDevClass; 100 - struct sysfs_attribute *bNumIntfs; 101 - int i, rc; 126 + int rc; 102 127 enum unbind_status status = UNBIND_ST_OK; 103 128 104 129 busid_dev = sysfs_open_device(bus_type, busid); ··· 103 134 dbg("sysfs_open_device %s failed: %s", busid, strerror(errno)); 104 135 return -1; 105 136 } 137 + dbg("busid path: %s", busid_dev->path); 106 138 107 - bConfValue = sysfs_get_device_attr(busid_dev, "bConfigurationValue"); 108 139 bDevClass = sysfs_get_device_attr(busid_dev, "bDeviceClass"); 109 - bNumIntfs = sysfs_get_device_attr(busid_dev, "bNumInterfaces"); 110 - if (!bConfValue || !bDevClass || !bNumIntfs) { 111 - dbg("problem getting device attributes: %s", 140 + if (!bDevClass) { 141 + dbg("problem getting device attribute: %s", 112 142 strerror(errno)); 113 143 goto err_close_busid_dev; 114 144 } ··· 117 149 goto err_close_busid_dev; 118 150 } 119 151 120 - for (i = 0; i < atoi(bNumIntfs->value); i++) { 121 - snprintf(intf_busid, SYSFS_BUS_ID_SIZE, "%s:%.1s.%d", busid, 122 - bConfValue->value, i); 123 - intf_dev = sysfs_open_device(bus_type, intf_busid); 124 - if (!intf_dev) { 125 - dbg("could not open interface device: %s", 126 - strerror(errno)); 127 - goto err_close_busid_dev; 128 - } 129 - 130 - dbg("%s -> %s", intf_dev->name, intf_dev->driver_name); 131 - 132 - if (!strncmp("unknown", intf_dev->driver_name, SYSFS_NAME_LEN)) 133 - /* unbound interface */ 134 - continue; 135 - 136 - if (!strncmp(USBIP_HOST_DRV_NAME, intf_dev->driver_name, 137 - SYSFS_NAME_LEN)) { 138 - /* already bound to usbip-host */ 139 - status = UNBIND_ST_USBIP_HOST; 140 - continue; 141 - } 142 - 143 - /* unbinding */ 144 - intf_drv = sysfs_open_driver(bus_type, intf_dev->driver_name); 145 - if (!intf_drv) { 146 - dbg("could not open interface driver on %s: %s", 147 - intf_dev->name, strerror(errno)); 148 - goto err_close_intf_dev; 149 - } 150 - 151 - unbind_attr = sysfs_get_driver_attr(intf_drv, "unbind"); 152 - if (!unbind_attr) { 153 - dbg("problem getting interface driver attribute: %s", 154 - strerror(errno)); 155 - goto err_close_intf_drv; 156 - } 157 - 158 - rc = sysfs_write_attribute(unbind_attr, intf_dev->bus_id, 159 - SYSFS_BUS_ID_SIZE); 160 - if (rc < 0) { 161 - /* NOTE: why keep unbinding other interfaces? */ 162 - dbg("unbind driver at %s failed", intf_dev->bus_id); 163 - status = UNBIND_ST_FAILED; 164 - } 165 - 166 - sysfs_close_driver(intf_drv); 167 - sysfs_close_device(intf_dev); 152 + dev = sysfs_open_device(bus_type, busid); 153 + if (!dev) { 154 + dbg("could not open device: %s", 155 + strerror(errno)); 156 + goto err_close_busid_dev; 168 157 } 158 + 159 + dbg("%s -> %s", dev->name, dev->driver_name); 160 + 161 + if (!strncmp("unknown", dev->driver_name, SYSFS_NAME_LEN)) { 162 + /* unbound interface */ 163 + sysfs_close_device(dev); 164 + goto out; 165 + } 166 + 167 + if (!strncmp(USBIP_HOST_DRV_NAME, dev->driver_name, 168 + SYSFS_NAME_LEN)) { 169 + /* already bound to usbip-host */ 170 + status = UNBIND_ST_USBIP_HOST; 171 + sysfs_close_device(dev); 172 + goto out; 173 + } 174 + 175 + /* unbinding */ 176 + drv = sysfs_open_driver(bus_type, dev->driver_name); 177 + if (!drv) { 178 + dbg("could not open device driver on %s: %s", 179 + dev->name, strerror(errno)); 180 + goto err_close_intf_dev; 181 + } 182 + dbg("device driver: %s", drv->path); 183 + 184 + unbind_attr = sysfs_get_driver_attr(drv, "unbind"); 185 + if (!unbind_attr) { 186 + dbg("problem getting device driver attribute: %s", 187 + strerror(errno)); 188 + goto err_close_intf_drv; 189 + } 190 + 191 + rc = sysfs_write_attribute(unbind_attr, dev->bus_id, 192 + SYSFS_BUS_ID_SIZE); 193 + if (rc < 0) { 194 + /* NOTE: why keep unbinding other interfaces? */ 195 + dbg("unbind driver at %s failed", dev->bus_id); 196 + status = UNBIND_ST_FAILED; 197 + } 198 + 199 + sysfs_close_driver(drv); 200 + sysfs_close_device(dev); 169 201 170 202 goto out; 171 203 172 204 err_close_intf_drv: 173 - sysfs_close_driver(intf_drv); 205 + sysfs_close_driver(drv); 174 206 err_close_intf_dev: 175 - sysfs_close_device(intf_dev); 207 + sysfs_close_device(dev); 176 208 err_close_busid_dev: 177 209 status = UNBIND_ST_FAILED; 178 210 out:
+1 -18
drivers/staging/usbip/userspace/src/usbip_list.c
··· 52 52 struct op_devlist_reply reply; 53 53 uint16_t code = OP_REP_DEVLIST; 54 54 struct usbip_usb_device udev; 55 - struct usbip_usb_interface uintf; 56 55 unsigned int i; 57 - int j, rc; 56 + int rc; 58 57 59 58 rc = usbip_net_send_op_common(sockfd, OP_REQ_DEVLIST, 0); 60 59 if (rc < 0) { ··· 103 104 printf("%11s: %s\n", "", udev.path); 104 105 printf("%11s: %s\n", "", class_name); 105 106 106 - for (j = 0; j < udev.bNumInterfaces; j++) { 107 - rc = usbip_net_recv(sockfd, &uintf, sizeof(uintf)); 108 - if (rc < 0) { 109 - dbg("usbip_net_recv failed: usbip_usb_intf[%d]", 110 - j); 111 - 112 - return -1; 113 - } 114 - usbip_net_pack_usb_interface(0, &uintf); 115 - 116 - usbip_names_get_class(class_name, sizeof(class_name), 117 - uintf.bInterfaceClass, 118 - uintf.bInterfaceSubClass, 119 - uintf.bInterfaceProtocol); 120 - printf("%11s: %2d - %s\n", "", j, class_name); 121 - } 122 107 printf("\n"); 123 108 } 124 109
+14 -37
drivers/staging/usbip/userspace/src/usbip_unbind.c
··· 47 47 int verified = 0; 48 48 int rc, ret = -1; 49 49 50 - char attr_name[] = "bConfigurationValue"; 50 + char attr_name[] = "unbind"; 51 51 char sysfs_mntpath[SYSFS_PATH_MAX]; 52 - char busid_attr_path[SYSFS_PATH_MAX]; 53 - struct sysfs_attribute *busid_attr; 54 - char *val = NULL; 55 - int len; 52 + char unbind_attr_path[SYSFS_PATH_MAX]; 53 + struct sysfs_attribute *unbind_attr; 56 54 57 55 /* verify the busid device is using usbip-host */ 58 56 usbip_host_drv = sysfs_open_driver(bus_type, USBIP_HOST_DRV_NAME); ··· 97 99 return -1; 98 100 } 99 101 100 - snprintf(busid_attr_path, sizeof(busid_attr_path), "%s/%s/%s/%s/%s/%s", 101 - sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DEVICES_NAME, 102 - busid, attr_name); 102 + snprintf(unbind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s", 103 + sysfs_mntpath, SYSFS_BUS_NAME, bus_type, SYSFS_DRIVERS_NAME, 104 + USBIP_HOST_DRV_NAME, attr_name); 103 105 104 106 /* read a device attribute */ 105 - busid_attr = sysfs_open_attribute(busid_attr_path); 106 - if (!busid_attr) { 107 + unbind_attr = sysfs_open_attribute(unbind_attr_path); 108 + if (!unbind_attr) { 107 109 err("could not open %s/%s: %s", busid, attr_name, 108 110 strerror(errno)); 109 111 return -1; 110 112 } 111 - 112 - if (sysfs_read_attribute(busid_attr) < 0) { 113 - err("problem reading attribute: %s", strerror(errno)); 114 - goto err_out; 115 - } 116 - 117 - len = busid_attr->len; 118 - val = malloc(len); 119 - *val = *busid_attr->value; 120 - sysfs_close_attribute(busid_attr); 121 113 122 114 /* notify driver of unbind */ 123 115 rc = modify_match_busid(busid, 0); 124 116 if (rc < 0) { 125 117 err("unable to unbind device on %s", busid); 126 - goto err_out; 127 118 } 128 119 129 - /* write the device attribute */ 130 - busid_attr = sysfs_open_attribute(busid_attr_path); 131 - if (!busid_attr) { 132 - err("could not open %s/%s: %s", busid, attr_name, 133 - strerror(errno)); 134 - return -1; 135 - } 136 - 137 - rc = sysfs_write_attribute(busid_attr, val, len); 138 - if (rc < 0) { 139 - err("problem writing attribute: %s", strerror(errno)); 140 - goto err_out; 141 - } 142 - sysfs_close_attribute(busid_attr); 120 + rc = sysfs_write_attribute(unbind_attr, busid, 121 + SYSFS_BUS_ID_SIZE); 122 + if (rc < 0) { 123 + dbg("bind driver at %s failed", busid); 124 + } 125 + sysfs_close_attribute(unbind_attr); 143 126 144 127 ret = 0; 145 128 printf("unbind device on busid %s: complete\n", busid); 146 129 147 - err_out: 148 - free(val); 149 130 err_close_usbip_host_drv: 150 131 sysfs_close_driver(usbip_host_drv); 151 132
-15
drivers/staging/usbip/userspace/src/usbipd.c
··· 159 159 { 160 160 struct usbip_exported_device *edev; 161 161 struct usbip_usb_device pdu_udev; 162 - struct usbip_usb_interface pdu_uinf; 163 162 struct op_devlist_reply reply; 164 - int i; 165 163 int rc; 166 164 167 165 reply.ndev = 0; ··· 193 195 if (rc < 0) { 194 196 dbg("usbip_net_send failed: pdu_udev"); 195 197 return -1; 196 - } 197 - 198 - for (i = 0; i < edev->udev.bNumInterfaces; i++) { 199 - dump_usb_interface(&edev->uinf[i]); 200 - memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf)); 201 - usbip_net_pack_usb_interface(1, &pdu_uinf); 202 - 203 - rc = usbip_net_send(connfd, &pdu_uinf, 204 - sizeof(pdu_uinf)); 205 - if (rc < 0) { 206 - dbg("usbip_net_send failed: pdu_uinf"); 207 - return -1; 208 - } 209 198 } 210 199 } 211 200
+1
drivers/usb/core/generic.c
··· 155 155 } 156 156 return i; 157 157 } 158 + EXPORT_SYMBOL_GPL(usb_choose_configuration); 158 159 159 160 static int generic_probe(struct usb_device *udev) 160 161 {
+1
drivers/usb/core/message.c
··· 1920 1920 usb_autosuspend_device(dev); 1921 1921 return 0; 1922 1922 } 1923 + EXPORT_SYMBOL_GPL(usb_set_configuration); 1923 1924 1924 1925 static LIST_HEAD(set_config_list); 1925 1926 static DEFINE_SPINLOCK(set_config_lock);
+4
include/linux/usb.h
··· 1668 1668 /* this request isn't really synchronous, but it belongs with the others */ 1669 1669 extern int usb_driver_set_configuration(struct usb_device *udev, int config); 1670 1670 1671 + /* choose and set configuration for device */ 1672 + extern int usb_choose_configuration(struct usb_device *udev); 1673 + extern int usb_set_configuration(struct usb_device *dev, int configuration); 1674 + 1671 1675 /* 1672 1676 * timeouts, in milliseconds, used for sending/receiving control messages 1673 1677 * they typically complete within a few frames (msec) after they're issued