diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:25:16 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-23 12:25:16 -0400 |
| commit | be90a49ca22a95f184d9f32d35b5247b44032849 (patch) | |
| tree | d3c2edc18c003c384366f57901616ac29c80bc27 /drivers/usb/class | |
| parent | 1f0918d03ff4b5c94540c71ce889672abdbc2f4a (diff) | |
| parent | a87371b477774b290c27bc5cb7f4ccc5379574a9 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (142 commits)
USB: Fix sysfs paths in documentation
USB: skeleton: fix coding style issues.
USB: O_NONBLOCK in read path of skeleton
USB: make usb-skeleton honor O_NONBLOCK in write path
USB: skel_read really sucks royally
USB: Add hub descriptor update hook for xHCI
USB: xhci: Support USB hubs.
USB: xhci: Set multi-TT field for LS/FS devices under hubs.
USB: xhci: Set route string for all devices.
USB: xhci: Fix command wait list handling.
USB: xhci: Change how xHCI commands are handled.
USB: xhci: Refactor input device context setup.
USB: xhci: Endpoint representation refactoring.
USB: gadget: ether needs to select CRC32
USB: fix USBTMC get_capabilities success handling
USB: fix missing error check in probing
USB: usbfs: add USBDEVFS_URB_BULK_CONTINUATION flag
USB: support for autosuspend in sierra while online
USB: ehci-dbgp,ehci: Allow dbpg to work with suspend/resume
USB: ehci-dbgp,documentation: Documentation updates for ehci-dbgp
...
Diffstat (limited to 'drivers/usb/class')
| -rw-r--r-- | drivers/usb/class/cdc-acm.c | 2 | ||||
| -rw-r--r-- | drivers/usb/class/cdc-wdm.c | 30 | ||||
| -rw-r--r-- | drivers/usb/class/usbtmc.c | 84 |
3 files changed, 95 insertions, 21 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 85a1a55815cf..e3861b21e776 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
| @@ -59,6 +59,7 @@ | |||
| 59 | #include <linux/init.h> | 59 | #include <linux/init.h> |
| 60 | #include <linux/slab.h> | 60 | #include <linux/slab.h> |
| 61 | #include <linux/tty.h> | 61 | #include <linux/tty.h> |
| 62 | #include <linux/serial.h> | ||
| 62 | #include <linux/tty_driver.h> | 63 | #include <linux/tty_driver.h> |
| 63 | #include <linux/tty_flip.h> | 64 | #include <linux/tty_flip.h> |
| 64 | #include <linux/module.h> | 65 | #include <linux/module.h> |
| @@ -609,6 +610,7 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) | |||
| 609 | acm->throttle = 0; | 610 | acm->throttle = 0; |
| 610 | 611 | ||
| 611 | tasklet_schedule(&acm->urb_task); | 612 | tasklet_schedule(&acm->urb_task); |
| 613 | set_bit(ASYNCB_INITIALIZED, &acm->port.flags); | ||
| 612 | rv = tty_port_block_til_ready(&acm->port, tty, filp); | 614 | rv = tty_port_block_til_ready(&acm->port, tty, filp); |
| 613 | done: | 615 | done: |
| 614 | mutex_unlock(&acm->mutex); | 616 | mutex_unlock(&acm->mutex); |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8c64c018b676..3e564bfe17d1 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
| @@ -313,8 +313,13 @@ static ssize_t wdm_write | |||
| 313 | r = usb_autopm_get_interface(desc->intf); | 313 | r = usb_autopm_get_interface(desc->intf); |
| 314 | if (r < 0) | 314 | if (r < 0) |
| 315 | goto outnp; | 315 | goto outnp; |
| 316 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, | 316 | |
| 317 | &desc->flags)); | 317 | if (!file->f_flags && O_NONBLOCK) |
| 318 | r = wait_event_interruptible(desc->wait, !test_bit(WDM_IN_USE, | ||
| 319 | &desc->flags)); | ||
| 320 | else | ||
| 321 | if (test_bit(WDM_IN_USE, &desc->flags)) | ||
| 322 | r = -EAGAIN; | ||
| 318 | if (r < 0) | 323 | if (r < 0) |
| 319 | goto out; | 324 | goto out; |
| 320 | 325 | ||
| @@ -377,7 +382,7 @@ outnl: | |||
| 377 | static ssize_t wdm_read | 382 | static ssize_t wdm_read |
| 378 | (struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 383 | (struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
| 379 | { | 384 | { |
| 380 | int rv, cntr; | 385 | int rv, cntr = 0; |
| 381 | int i = 0; | 386 | int i = 0; |
| 382 | struct wdm_device *desc = file->private_data; | 387 | struct wdm_device *desc = file->private_data; |
| 383 | 388 | ||
| @@ -389,10 +394,23 @@ static ssize_t wdm_read | |||
| 389 | if (desc->length == 0) { | 394 | if (desc->length == 0) { |
| 390 | desc->read = 0; | 395 | desc->read = 0; |
| 391 | retry: | 396 | retry: |
| 397 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | ||
| 398 | rv = -ENODEV; | ||
| 399 | goto err; | ||
| 400 | } | ||
| 392 | i++; | 401 | i++; |
| 393 | rv = wait_event_interruptible(desc->wait, | 402 | if (file->f_flags & O_NONBLOCK) { |
| 394 | test_bit(WDM_READ, &desc->flags)); | 403 | if (!test_bit(WDM_READ, &desc->flags)) { |
| 404 | rv = cntr ? cntr : -EAGAIN; | ||
| 405 | goto err; | ||
| 406 | } | ||
| 407 | rv = 0; | ||
| 408 | } else { | ||
| 409 | rv = wait_event_interruptible(desc->wait, | ||
| 410 | test_bit(WDM_READ, &desc->flags)); | ||
| 411 | } | ||
| 395 | 412 | ||
| 413 | /* may have happened while we slept */ | ||
| 396 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { | 414 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) { |
| 397 | rv = -ENODEV; | 415 | rv = -ENODEV; |
| 398 | goto err; | 416 | goto err; |
| @@ -448,7 +466,7 @@ retry: | |||
| 448 | 466 | ||
| 449 | err: | 467 | err: |
| 450 | mutex_unlock(&desc->rlock); | 468 | mutex_unlock(&desc->rlock); |
| 451 | if (rv < 0) | 469 | if (rv < 0 && rv != -EAGAIN) |
| 452 | dev_err(&desc->intf->dev, "wdm_read: exit error\n"); | 470 | dev_err(&desc->intf->dev, "wdm_read: exit error\n"); |
| 453 | return rv; | 471 | return rv; |
| 454 | } | 472 | } |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index b09a527f7341..333ee02e7b2b 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
| @@ -57,7 +57,9 @@ MODULE_DEVICE_TABLE(usb, usbtmc_devices); | |||
| 57 | 57 | ||
| 58 | /* | 58 | /* |
| 59 | * This structure is the capabilities for the device | 59 | * This structure is the capabilities for the device |
| 60 | * See section 4.2.1.8 of the USBTMC specification for details. | 60 | * See section 4.2.1.8 of the USBTMC specification, |
| 61 | * and section 4.2.2 of the USBTMC usb488 subclass | ||
| 62 | * specification for details. | ||
| 61 | */ | 63 | */ |
| 62 | struct usbtmc_dev_capabilities { | 64 | struct usbtmc_dev_capabilities { |
| 63 | __u8 interface_capabilities; | 65 | __u8 interface_capabilities; |
| @@ -86,6 +88,8 @@ struct usbtmc_device_data { | |||
| 86 | bool TermCharEnabled; | 88 | bool TermCharEnabled; |
| 87 | bool auto_abort; | 89 | bool auto_abort; |
| 88 | 90 | ||
| 91 | bool zombie; /* fd of disconnected device */ | ||
| 92 | |||
| 89 | struct usbtmc_dev_capabilities capabilities; | 93 | struct usbtmc_dev_capabilities capabilities; |
| 90 | struct kref kref; | 94 | struct kref kref; |
| 91 | struct mutex io_mutex; /* only one i/o function running at a time */ | 95 | struct mutex io_mutex; /* only one i/o function running at a time */ |
| @@ -367,13 +371,13 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
| 367 | { | 371 | { |
| 368 | struct usbtmc_device_data *data; | 372 | struct usbtmc_device_data *data; |
| 369 | struct device *dev; | 373 | struct device *dev; |
| 370 | unsigned long int n_characters; | 374 | u32 n_characters; |
| 371 | u8 *buffer; | 375 | u8 *buffer; |
| 372 | int actual; | 376 | int actual; |
| 373 | int done; | 377 | size_t done; |
| 374 | int remaining; | 378 | size_t remaining; |
| 375 | int retval; | 379 | int retval; |
| 376 | int this_part; | 380 | size_t this_part; |
| 377 | 381 | ||
| 378 | /* Get pointer to private data structure */ | 382 | /* Get pointer to private data structure */ |
| 379 | data = filp->private_data; | 383 | data = filp->private_data; |
| @@ -384,6 +388,10 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
| 384 | return -ENOMEM; | 388 | return -ENOMEM; |
| 385 | 389 | ||
| 386 | mutex_lock(&data->io_mutex); | 390 | mutex_lock(&data->io_mutex); |
| 391 | if (data->zombie) { | ||
| 392 | retval = -ENODEV; | ||
| 393 | goto exit; | ||
| 394 | } | ||
| 387 | 395 | ||
| 388 | remaining = count; | 396 | remaining = count; |
| 389 | done = 0; | 397 | done = 0; |
| @@ -401,10 +409,10 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
| 401 | buffer[1] = data->bTag; | 409 | buffer[1] = data->bTag; |
| 402 | buffer[2] = ~(data->bTag); | 410 | buffer[2] = ~(data->bTag); |
| 403 | buffer[3] = 0; /* Reserved */ | 411 | buffer[3] = 0; /* Reserved */ |
| 404 | buffer[4] = (this_part - 12 - 3) & 255; | 412 | buffer[4] = (this_part) & 255; |
| 405 | buffer[5] = ((this_part - 12 - 3) >> 8) & 255; | 413 | buffer[5] = ((this_part) >> 8) & 255; |
| 406 | buffer[6] = ((this_part - 12 - 3) >> 16) & 255; | 414 | buffer[6] = ((this_part) >> 16) & 255; |
| 407 | buffer[7] = ((this_part - 12 - 3) >> 24) & 255; | 415 | buffer[7] = ((this_part) >> 24) & 255; |
| 408 | buffer[8] = data->TermCharEnabled * 2; | 416 | buffer[8] = data->TermCharEnabled * 2; |
| 409 | /* Use term character? */ | 417 | /* Use term character? */ |
| 410 | buffer[9] = data->TermChar; | 418 | buffer[9] = data->TermChar; |
| @@ -455,6 +463,22 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
| 455 | (buffer[6] << 16) + | 463 | (buffer[6] << 16) + |
| 456 | (buffer[7] << 24); | 464 | (buffer[7] << 24); |
| 457 | 465 | ||
| 466 | /* Ensure the instrument doesn't lie about it */ | ||
| 467 | if(n_characters > actual - 12) { | ||
| 468 | dev_err(dev, "Device lies about message size: %u > %d\n", n_characters, actual - 12); | ||
| 469 | n_characters = actual - 12; | ||
| 470 | } | ||
| 471 | |||
| 472 | /* Ensure the instrument doesn't send more back than requested */ | ||
| 473 | if(n_characters > this_part) { | ||
| 474 | dev_err(dev, "Device returns more than requested: %zu > %zu\n", done + n_characters, done + this_part); | ||
| 475 | n_characters = this_part; | ||
| 476 | } | ||
| 477 | |||
| 478 | /* Bound amount of data received by amount of data requested */ | ||
| 479 | if (n_characters > this_part) | ||
| 480 | n_characters = this_part; | ||
| 481 | |||
| 458 | /* Copy buffer to user space */ | 482 | /* Copy buffer to user space */ |
| 459 | if (copy_to_user(buf + done, &buffer[12], n_characters)) { | 483 | if (copy_to_user(buf + done, &buffer[12], n_characters)) { |
| 460 | /* There must have been an addressing problem */ | 484 | /* There must have been an addressing problem */ |
| @@ -463,8 +487,11 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, | |||
| 463 | } | 487 | } |
| 464 | 488 | ||
| 465 | done += n_characters; | 489 | done += n_characters; |
| 466 | if (n_characters < USBTMC_SIZE_IOBUFFER) | 490 | /* Terminate if end-of-message bit recieved from device */ |
| 491 | if ((buffer[8] & 0x01) && (actual >= n_characters + 12)) | ||
| 467 | remaining = 0; | 492 | remaining = 0; |
| 493 | else | ||
| 494 | remaining -= n_characters; | ||
| 468 | } | 495 | } |
| 469 | 496 | ||
| 470 | /* Update file position value */ | 497 | /* Update file position value */ |
| @@ -496,6 +523,10 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf, | |||
| 496 | return -ENOMEM; | 523 | return -ENOMEM; |
| 497 | 524 | ||
| 498 | mutex_lock(&data->io_mutex); | 525 | mutex_lock(&data->io_mutex); |
| 526 | if (data->zombie) { | ||
| 527 | retval = -ENODEV; | ||
| 528 | goto exit; | ||
| 529 | } | ||
| 499 | 530 | ||
| 500 | remaining = count; | 531 | remaining = count; |
| 501 | done = 0; | 532 | done = 0; |
| @@ -767,20 +798,21 @@ static int get_capabilities(struct usbtmc_device_data *data) | |||
| 767 | } | 798 | } |
| 768 | 799 | ||
| 769 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 800 | dev_dbg(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
| 770 | dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]); | ||
| 771 | dev_dbg(dev, "Device capabilities are %x\n", buffer[5]); | ||
| 772 | dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]); | ||
| 773 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); | ||
| 774 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { | 801 | if (buffer[0] != USBTMC_STATUS_SUCCESS) { |
| 775 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); | 802 | dev_err(dev, "GET_CAPABILITIES returned %x\n", buffer[0]); |
| 776 | rv = -EPERM; | 803 | rv = -EPERM; |
| 777 | goto err_out; | 804 | goto err_out; |
| 778 | } | 805 | } |
| 806 | dev_dbg(dev, "Interface capabilities are %x\n", buffer[4]); | ||
| 807 | dev_dbg(dev, "Device capabilities are %x\n", buffer[5]); | ||
| 808 | dev_dbg(dev, "USB488 interface capabilities are %x\n", buffer[14]); | ||
| 809 | dev_dbg(dev, "USB488 device capabilities are %x\n", buffer[15]); | ||
| 779 | 810 | ||
| 780 | data->capabilities.interface_capabilities = buffer[4]; | 811 | data->capabilities.interface_capabilities = buffer[4]; |
| 781 | data->capabilities.device_capabilities = buffer[5]; | 812 | data->capabilities.device_capabilities = buffer[5]; |
| 782 | data->capabilities.usb488_interface_capabilities = buffer[14]; | 813 | data->capabilities.usb488_interface_capabilities = buffer[14]; |
| 783 | data->capabilities.usb488_device_capabilities = buffer[15]; | 814 | data->capabilities.usb488_device_capabilities = buffer[15]; |
| 815 | rv = 0; | ||
| 784 | 816 | ||
| 785 | err_out: | 817 | err_out: |
| 786 | kfree(buffer); | 818 | kfree(buffer); |
| @@ -925,6 +957,10 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 925 | 957 | ||
| 926 | data = file->private_data; | 958 | data = file->private_data; |
| 927 | mutex_lock(&data->io_mutex); | 959 | mutex_lock(&data->io_mutex); |
| 960 | if (data->zombie) { | ||
| 961 | retval = -ENODEV; | ||
| 962 | goto skip_io_on_zombie; | ||
| 963 | } | ||
| 928 | 964 | ||
| 929 | switch (cmd) { | 965 | switch (cmd) { |
| 930 | case USBTMC_IOCTL_CLEAR_OUT_HALT: | 966 | case USBTMC_IOCTL_CLEAR_OUT_HALT: |
| @@ -952,6 +988,7 @@ static long usbtmc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 952 | break; | 988 | break; |
| 953 | } | 989 | } |
| 954 | 990 | ||
| 991 | skip_io_on_zombie: | ||
| 955 | mutex_unlock(&data->io_mutex); | 992 | mutex_unlock(&data->io_mutex); |
| 956 | return retval; | 993 | return retval; |
| 957 | } | 994 | } |
| @@ -995,6 +1032,7 @@ static int usbtmc_probe(struct usb_interface *intf, | |||
| 995 | usb_set_intfdata(intf, data); | 1032 | usb_set_intfdata(intf, data); |
| 996 | kref_init(&data->kref); | 1033 | kref_init(&data->kref); |
| 997 | mutex_init(&data->io_mutex); | 1034 | mutex_init(&data->io_mutex); |
| 1035 | data->zombie = 0; | ||
| 998 | 1036 | ||
| 999 | /* Initialize USBTMC bTag and other fields */ | 1037 | /* Initialize USBTMC bTag and other fields */ |
| 1000 | data->bTag = 1; | 1038 | data->bTag = 1; |
| @@ -1065,14 +1103,30 @@ static void usbtmc_disconnect(struct usb_interface *intf) | |||
| 1065 | usb_deregister_dev(intf, &usbtmc_class); | 1103 | usb_deregister_dev(intf, &usbtmc_class); |
| 1066 | sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); | 1104 | sysfs_remove_group(&intf->dev.kobj, &capability_attr_grp); |
| 1067 | sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); | 1105 | sysfs_remove_group(&intf->dev.kobj, &data_attr_grp); |
| 1106 | mutex_lock(&data->io_mutex); | ||
| 1107 | data->zombie = 1; | ||
| 1108 | mutex_unlock(&data->io_mutex); | ||
| 1068 | kref_put(&data->kref, usbtmc_delete); | 1109 | kref_put(&data->kref, usbtmc_delete); |
| 1069 | } | 1110 | } |
| 1070 | 1111 | ||
| 1112 | static int usbtmc_suspend (struct usb_interface *intf, pm_message_t message) | ||
| 1113 | { | ||
| 1114 | /* this driver does not have pending URBs */ | ||
| 1115 | return 0; | ||
| 1116 | } | ||
| 1117 | |||
| 1118 | static int usbtmc_resume (struct usb_interface *intf) | ||
| 1119 | { | ||
| 1120 | return 0; | ||
| 1121 | } | ||
| 1122 | |||
| 1071 | static struct usb_driver usbtmc_driver = { | 1123 | static struct usb_driver usbtmc_driver = { |
| 1072 | .name = "usbtmc", | 1124 | .name = "usbtmc", |
| 1073 | .id_table = usbtmc_devices, | 1125 | .id_table = usbtmc_devices, |
| 1074 | .probe = usbtmc_probe, | 1126 | .probe = usbtmc_probe, |
| 1075 | .disconnect = usbtmc_disconnect | 1127 | .disconnect = usbtmc_disconnect, |
| 1128 | .suspend = usbtmc_suspend, | ||
| 1129 | .resume = usbtmc_resume, | ||
| 1076 | }; | 1130 | }; |
| 1077 | 1131 | ||
| 1078 | static int __init usbtmc_init(void) | 1132 | static int __init usbtmc_init(void) |
