diff options
Diffstat (limited to 'drivers/usb/misc/ldusb.c')
| -rw-r--r-- | drivers/usb/misc/ldusb.c | 36 | 
1 files changed, 19 insertions, 17 deletions
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index f3108d85e768..8f86b4ebca89 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -380,10 +380,7 @@ static int ld_usb_release(struct inode *inode, struct file *file)  		goto exit;  	} -	if (mutex_lock_interruptible(&dev->mutex)) { -		retval = -ERESTARTSYS; -		goto exit; -	} +	mutex_lock(&dev->mutex);  	if (dev->open_count != 1) {  		retval = -ENODEV; @@ -467,7 +464,7 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,  	/* wait for data */  	spin_lock_irq(&dev->rbsl); -	if (dev->ring_head == dev->ring_tail) { +	while (dev->ring_head == dev->ring_tail) {  		dev->interrupt_in_done = 0;  		spin_unlock_irq(&dev->rbsl);  		if (file->f_flags & O_NONBLOCK) { @@ -477,15 +474,20 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,  		retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);  		if (retval < 0)  			goto unlock_exit; -	} else { -		spin_unlock_irq(&dev->rbsl); + +		spin_lock_irq(&dev->rbsl);  	} +	spin_unlock_irq(&dev->rbsl);  	/* actual_buffer contains actual_length + interrupt_in_buffer */  	actual_buffer = (size_t *)(dev->ring_buffer + dev->ring_tail * (sizeof(size_t)+dev->interrupt_in_endpoint_size)); +	if (*actual_buffer > dev->interrupt_in_endpoint_size) { +		retval = -EIO; +		goto unlock_exit; +	}  	bytes_to_read = min(count, *actual_buffer);  	if (bytes_to_read < *actual_buffer) -		dev_warn(&dev->intf->dev, "Read buffer overflow, %zd bytes dropped\n", +		dev_warn(&dev->intf->dev, "Read buffer overflow, %zu bytes dropped\n",  			 *actual_buffer-bytes_to_read);  	/* copy one interrupt_in_buffer from ring_buffer into userspace */ @@ -493,11 +495,11 @@ static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count,  		retval = -EFAULT;  		goto unlock_exit;  	} -	dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; -  	retval = bytes_to_read;  	spin_lock_irq(&dev->rbsl); +	dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size; +  	if (dev->buffer_overflow) {  		dev->buffer_overflow = 0;  		spin_unlock_irq(&dev->rbsl); @@ -560,8 +562,9 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,  	/* write the data into interrupt_out_buffer from userspace */  	bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);  	if (bytes_to_write < count) -		dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n", count-bytes_to_write); -	dev_dbg(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", +		dev_warn(&dev->intf->dev, "Write buffer overflow, %zu bytes dropped\n", +			count - bytes_to_write); +	dev_dbg(&dev->intf->dev, "%s: count = %zu, bytes_to_write = %zu\n",  		__func__, count, bytes_to_write);  	if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { @@ -578,7 +581,7 @@ static ssize_t ld_usb_write(struct file *file, const char __user *buffer,  					 1 << 8, 0,  					 dev->interrupt_out_buffer,  					 bytes_to_write, -					 USB_CTRL_SET_TIMEOUT * HZ); +					 USB_CTRL_SET_TIMEOUT);  		if (retval < 0)  			dev_err(&dev->intf->dev,  				"Couldn't submit HID_REQ_SET_REPORT %d\n", @@ -693,10 +696,9 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *  		dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");  	dev->interrupt_in_endpoint_size = usb_endpoint_maxp(dev->interrupt_in_endpoint); -	dev->ring_buffer = -		kmalloc_array(ring_buffer_size, -			      sizeof(size_t) + dev->interrupt_in_endpoint_size, -			      GFP_KERNEL); +	dev->ring_buffer = kcalloc(ring_buffer_size, +			sizeof(size_t) + dev->interrupt_in_endpoint_size, +			GFP_KERNEL);  	if (!dev->ring_buffer)  		goto error;  	dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);  | 
