aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/misc/vstusb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/misc/vstusb.c')
-rw-r--r--drivers/usb/misc/vstusb.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c
index 5ad75e4a0323..8648470c81ca 100644
--- a/drivers/usb/misc/vstusb.c
+++ b/drivers/usb/misc/vstusb.c
@@ -59,6 +59,8 @@
59#define USB_PRODUCT_LABPRO 0x0001 59#define USB_PRODUCT_LABPRO 0x0001
60#define USB_PRODUCT_LABQUEST 0x0005 60#define USB_PRODUCT_LABQUEST 0x0005
61 61
62#define VST_MAXBUFFER (64*1024)
63
62static struct usb_device_id id_table[] = { 64static struct usb_device_id id_table[] = {
63 { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)}, 65 { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_USB2000)},
64 { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)}, 66 { USB_DEVICE(USB_VENDOR_OCEANOPTICS, USB_PRODUCT_HR4000)},
@@ -73,6 +75,7 @@ static struct usb_device_id id_table[] = {
73MODULE_DEVICE_TABLE(usb, id_table); 75MODULE_DEVICE_TABLE(usb, id_table);
74 76
75struct vstusb_device { 77struct vstusb_device {
78 struct kref kref;
76 struct mutex lock; 79 struct mutex lock;
77 struct usb_device *usb_dev; 80 struct usb_device *usb_dev;
78 char present; 81 char present;
@@ -83,9 +86,18 @@ struct vstusb_device {
83 int wr_pipe; 86 int wr_pipe;
84 int wr_timeout_ms; 87 int wr_timeout_ms;
85}; 88};
89#define to_vst_dev(d) container_of(d, struct vstusb_device, kref)
86 90
87static struct usb_driver vstusb_driver; 91static struct usb_driver vstusb_driver;
88 92
93static void vstusb_delete(struct kref *kref)
94{
95 struct vstusb_device *vstdev = to_vst_dev(kref);
96
97 usb_put_dev(vstdev->usb_dev);
98 kfree(vstdev);
99}
100
89static int vstusb_open(struct inode *inode, struct file *file) 101static int vstusb_open(struct inode *inode, struct file *file)
90{ 102{
91 struct vstusb_device *vstdev; 103 struct vstusb_device *vstdev;
@@ -114,6 +126,9 @@ static int vstusb_open(struct inode *inode, struct file *file)
114 return -EBUSY; 126 return -EBUSY;
115 } 127 }
116 128
129 /* increment our usage count */
130 kref_get(&vstdev->kref);
131
117 vstdev->isopen = 1; 132 vstdev->isopen = 1;
118 133
119 /* save device in the file's private structure */ 134 /* save device in the file's private structure */
@@ -126,7 +141,7 @@ static int vstusb_open(struct inode *inode, struct file *file)
126 return 0; 141 return 0;
127} 142}
128 143
129static int vstusb_close(struct inode *inode, struct file *file) 144static int vstusb_release(struct inode *inode, struct file *file)
130{ 145{
131 struct vstusb_device *vstdev; 146 struct vstusb_device *vstdev;
132 147
@@ -138,14 +153,12 @@ static int vstusb_close(struct inode *inode, struct file *file)
138 mutex_lock(&vstdev->lock); 153 mutex_lock(&vstdev->lock);
139 154
140 vstdev->isopen = 0; 155 vstdev->isopen = 0;
141 file->private_data = NULL;
142 156
143 /* if device is no longer present */ 157 dev_dbg(&vstdev->usb_dev->dev, "%s: released\n", __func__);
144 if (!vstdev->present) { 158
145 mutex_unlock(&vstdev->lock); 159 mutex_unlock(&vstdev->lock);
146 kfree(vstdev); 160
147 } else 161 kref_put(&vstdev->kref, vstusb_delete);
148 mutex_unlock(&vstdev->lock);
149 162
150 return 0; 163 return 0;
151} 164}
@@ -268,7 +281,7 @@ static ssize_t vstusb_read(struct file *file, char __user *buffer,
268 return -ENODEV; 281 return -ENODEV;
269 282
270 /* verify that we actually want to read some data */ 283 /* verify that we actually want to read some data */
271 if (count == 0) 284 if ((count == 0) || (count > VST_MAXBUFFER))
272 return -EINVAL; 285 return -EINVAL;
273 286
274 /* lock this object */ 287 /* lock this object */
@@ -354,7 +367,7 @@ static ssize_t vstusb_write(struct file *file, const char __user *buffer,
354 return -ENODEV; 367 return -ENODEV;
355 368
356 /* verify that we actually have some data to write */ 369 /* verify that we actually have some data to write */
357 if (count == 0) 370 if ((count == 0) || (count > VST_MAXBUFFER))
358 return retval; 371 return retval;
359 372
360 /* lock this object */ 373 /* lock this object */
@@ -498,7 +511,7 @@ static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
498 511
499 case IOCTL_VSTUSB_SEND_PIPE: 512 case IOCTL_VSTUSB_SEND_PIPE:
500 513
501 if (usb_data.count == 0) { 514 if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
502 mutex_unlock(&vstdev->lock); 515 mutex_unlock(&vstdev->lock);
503 retval = -EINVAL; 516 retval = -EINVAL;
504 goto exit; 517 goto exit;
@@ -551,7 +564,7 @@ static long vstusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
551 break; 564 break;
552 case IOCTL_VSTUSB_RECV_PIPE: 565 case IOCTL_VSTUSB_RECV_PIPE:
553 566
554 if (usb_data.count == 0) { 567 if ((usb_data.count == 0) || (usb_data.count > VST_MAXBUFFER)) {
555 mutex_unlock(&vstdev->lock); 568 mutex_unlock(&vstdev->lock);
556 retval = -EINVAL; 569 retval = -EINVAL;
557 goto exit; 570 goto exit;
@@ -633,7 +646,7 @@ static const struct file_operations vstusb_fops = {
633 .unlocked_ioctl = vstusb_ioctl, 646 .unlocked_ioctl = vstusb_ioctl,
634 .compat_ioctl = vstusb_ioctl, 647 .compat_ioctl = vstusb_ioctl,
635 .open = vstusb_open, 648 .open = vstusb_open,
636 .release = vstusb_close, 649 .release = vstusb_release,
637}; 650};
638 651
639static struct usb_class_driver usb_vstusb_class = { 652static struct usb_class_driver usb_vstusb_class = {
@@ -656,6 +669,10 @@ static int vstusb_probe(struct usb_interface *intf,
656 if (vstdev == NULL) 669 if (vstdev == NULL)
657 return -ENOMEM; 670 return -ENOMEM;
658 671
672 /* must do usb_get_dev() prior to kref_init() since the kref_put()
673 * release function will do a usb_put_dev() */
674 usb_get_dev(dev);
675 kref_init(&vstdev->kref);
659 mutex_init(&vstdev->lock); 676 mutex_init(&vstdev->lock);
660 677
661 i = dev->descriptor.bcdDevice; 678 i = dev->descriptor.bcdDevice;
@@ -676,7 +693,7 @@ static int vstusb_probe(struct usb_interface *intf,
676 "%s: Not able to get a minor for this device.\n", 693 "%s: Not able to get a minor for this device.\n",
677 __func__); 694 __func__);
678 usb_set_intfdata(intf, NULL); 695 usb_set_intfdata(intf, NULL);
679 kfree(vstdev); 696 kref_put(&vstdev->kref, vstusb_delete);
680 return retval; 697 return retval;
681 } 698 }
682 699
@@ -704,14 +721,11 @@ static void vstusb_disconnect(struct usb_interface *intf)
704 721
705 usb_kill_anchored_urbs(&vstdev->submitted); 722 usb_kill_anchored_urbs(&vstdev->submitted);
706 723
707 /* if the device is not opened, then we clean up right now */ 724 mutex_unlock(&vstdev->lock);
708 if (!vstdev->isopen) {
709 mutex_unlock(&vstdev->lock);
710 kfree(vstdev);
711 } else
712 mutex_unlock(&vstdev->lock);
713 725
726 kref_put(&vstdev->kref, vstusb_delete);
714 } 727 }
728
715} 729}
716 730
717static int vstusb_suspend(struct usb_interface *intf, pm_message_t message) 731static int vstusb_suspend(struct usb_interface *intf, pm_message_t message)