diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-24 16:22:33 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-09-24 16:22:33 -0400 |
commit | baea7b946f00a291b166ccae7fcfed6c01530cc6 (patch) | |
tree | 4aa275fbdbec9c7b9b4629e8bee2bbecd3c6a6af /drivers/usb/class | |
parent | ae19ffbadc1b2100285a5b5b3d0a4e0a11390904 (diff) | |
parent | 94e0fb086fc5663c38bbc0fe86d698be8314f82f (diff) |
Merge branch 'origin' into for-linus
Conflicts:
MAINTAINERS
Diffstat (limited to 'drivers/usb/class')
-rw-r--r-- | drivers/usb/class/cdc-acm.c | 7 | ||||
-rw-r--r-- | drivers/usb/class/cdc-wdm.c | 32 | ||||
-rw-r--r-- | drivers/usb/class/usblp.c | 4 | ||||
-rw-r--r-- | drivers/usb/class/usbtmc.c | 84 |
4 files changed, 98 insertions, 29 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 2bfc41ece0e1..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); |
@@ -858,10 +860,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, | |||
858 | if (!ACM_READY(acm)) | 860 | if (!ACM_READY(acm)) |
859 | return; | 861 | return; |
860 | 862 | ||
861 | /* FIXME: Needs to support the tty_baud interface */ | 863 | newline.dwDTERate = cpu_to_le32(tty_get_baud_rate(tty)); |
862 | /* FIXME: Broken on sparc */ | ||
863 | newline.dwDTERate = cpu_to_le32p(acm_tty_speed + | ||
864 | (termios->c_cflag & CBAUD & ~CBAUDEX) + (termios->c_cflag & CBAUDEX ? 15 : 0)); | ||
865 | newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0; | 864 | newline.bCharFormat = termios->c_cflag & CSTOPB ? 2 : 0; |
866 | newline.bParityType = termios->c_cflag & PARENB ? | 865 | newline.bParityType = termios->c_cflag & PARENB ? |
867 | (termios->c_cflag & PARODD ? 1 : 2) + | 866 | (termios->c_cflag & PARODD ? 1 : 2) + |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index ba589d4ca8bc..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 | } |
@@ -506,8 +524,6 @@ static int wdm_open(struct inode *inode, struct file *file) | |||
506 | desc = usb_get_intfdata(intf); | 524 | desc = usb_get_intfdata(intf); |
507 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) | 525 | if (test_bit(WDM_DISCONNECTING, &desc->flags)) |
508 | goto out; | 526 | goto out; |
509 | |||
510 | ; | ||
511 | file->private_data = desc; | 527 | file->private_data = desc; |
512 | 528 | ||
513 | rv = usb_autopm_get_interface(desc->intf); | 529 | rv = usb_autopm_get_interface(desc->intf); |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 26c09f0257db..9bc112ee7803 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -1057,14 +1057,14 @@ static const struct file_operations usblp_fops = { | |||
1057 | .release = usblp_release, | 1057 | .release = usblp_release, |
1058 | }; | 1058 | }; |
1059 | 1059 | ||
1060 | static char *usblp_nodename(struct device *dev) | 1060 | static char *usblp_devnode(struct device *dev, mode_t *mode) |
1061 | { | 1061 | { |
1062 | return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); | 1062 | return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev)); |
1063 | } | 1063 | } |
1064 | 1064 | ||
1065 | static struct usb_class_driver usblp_class = { | 1065 | static struct usb_class_driver usblp_class = { |
1066 | .name = "lp%d", | 1066 | .name = "lp%d", |
1067 | .nodename = usblp_nodename, | 1067 | .devnode = usblp_devnode, |
1068 | .fops = &usblp_fops, | 1068 | .fops = &usblp_fops, |
1069 | .minor_base = USBLP_MINOR_BASE, | 1069 | .minor_base = USBLP_MINOR_BASE, |
1070 | }; | 1070 | }; |
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) |