From dfdbf3f6e2d279f2a46ed95614cb4bf07657394d Mon Sep 17 00:00:00 2001 From: Ian Wisbon Date: Tue, 15 Feb 2011 15:53:51 -0500 Subject: Digi del-5.6 Complete --- drivers/usb/class/usbtmc.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'drivers/usb/class/usbtmc.c') diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index b09a527f7341..aa145f7b4e25 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -367,13 +367,13 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, { struct usbtmc_device_data *data; struct device *dev; - unsigned long int n_characters; + u32 n_characters; u8 *buffer; int actual; - int done; - int remaining; + size_t done; + size_t remaining; int retval; - int this_part; + size_t this_part; /* Get pointer to private data structure */ data = filp->private_data; @@ -455,6 +455,18 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, (buffer[6] << 16) + (buffer[7] << 24); + /* Ensure the instrument doesn't lie about it */ + if(n_characters > actual - 12) { + dev_err(dev, "Device lies about message size: %zu > %zu\n", n_characters, actual - 12); + n_characters = actual - 12; + } + + /* Ensure the instrument doesn't send more back than requested */ + if(n_characters > this_part) { + dev_err(dev, "Device returns more than requested: %zu > %zu\n", done + n_characters, done + this_part); + n_characters = this_part; + } + /* Copy buffer to user space */ if (copy_to_user(buf + done, &buffer[12], n_characters)) { /* There must have been an addressing problem */ @@ -465,6 +477,8 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, done += n_characters; if (n_characters < USBTMC_SIZE_IOBUFFER) remaining = 0; + else + remaining -= n_characters; } /* Update file position value */ @@ -531,10 +545,16 @@ static ssize_t usbtmc_write(struct file *filp, const char __user *buf, n_bytes = roundup(12 + this_part, 4); memset(buffer + 12 + this_part, 0, n_bytes - (12 + this_part)); - retval = usb_bulk_msg(data->usb_dev, - usb_sndbulkpipe(data->usb_dev, - data->bulk_out), - buffer, n_bytes, &actual, USBTMC_TIMEOUT); + do { + retval = usb_bulk_msg(data->usb_dev, + usb_sndbulkpipe(data->usb_dev, + data->bulk_out), + buffer, n_bytes, + &actual, USBTMC_TIMEOUT); + if (retval != 0) + break; + n_bytes -= actual; + } while (n_bytes); data->bTag_last_write = data->bTag; data->bTag++; -- cgit v1.2.3