aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/class/usbtmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/class/usbtmc.c')
-rw-r--r--drivers/usb/class/usbtmc.c84
1 files changed, 69 insertions, 15 deletions
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 */
62struct usbtmc_dev_capabilities { 64struct 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
785err_out: 817err_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
991skip_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
1112static 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
1118static int usbtmc_resume (struct usb_interface *intf)
1119{
1120 return 0;
1121}
1122
1071static struct usb_driver usbtmc_driver = { 1123static 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
1078static int __init usbtmc_init(void) 1132static int __init usbtmc_init(void)