diff options
author | Johan Hovold <johan@kernel.org> | 2017-01-12 14:56:14 +0100 |
---|---|---|
committer | Johan Hovold <johan@kernel.org> | 2017-01-16 16:38:56 +0100 |
commit | 3c0e25d883d06a1fbd1ad35257e8abaa57befb37 (patch) | |
tree | b501418076edfddb14c8637e044e1abda9c7bea5 /drivers | |
parent | e4457d9798adb96272468e93da663de9bd0a4198 (diff) | |
download | linux-3c0e25d883d06a1fbd1ad35257e8abaa57befb37.tar.bz2 |
USB: serial: io_edgeport: fix descriptor error handling
Make sure to detect short control-message transfers and log an error
when reading incomplete manufacturer and boot descriptors.
Note that the default all-zero descriptors will now be used after a
short transfer is detected instead of partially initialised ones.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/serial/io_edgeport.c | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 993a36a3e557..8ab5f5b49ef3 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -2102,8 +2102,7 @@ static int rom_write(struct usb_serial *serial, __u16 extAddr, __u16 addr, * rom_read * reads a number of bytes from the Edgeport device starting at the given * address. - * If successful returns the number of bytes read, otherwise it returns - * a negative error number of the problem. + * Returns zero on success or a negative error number. ****************************************************************************/ static int rom_read(struct usb_serial *serial, __u16 extAddr, __u16 addr, __u16 length, __u8 *data) @@ -2128,12 +2127,17 @@ static int rom_read(struct usb_serial *serial, __u16 extAddr, USB_REQUEST_ION_READ_ROM, 0xC0, addr, extAddr, transfer_buffer, current_length, 300); - if (result < 0) + if (result < current_length) { + if (result >= 0) + result = -EIO; break; + } memcpy(data, transfer_buffer, current_length); length -= current_length; addr += current_length; data += current_length; + + result = 0; } kfree(transfer_buffer); @@ -2587,9 +2591,10 @@ static void get_manufacturing_desc(struct edgeport_serial *edge_serial) EDGE_MANUF_DESC_LEN, (__u8 *)(&edge_serial->manuf_descriptor)); - if (response < 1) - dev_err(dev, "error in getting manufacturer descriptor\n"); - else { + if (response < 0) { + dev_err(dev, "error in getting manufacturer descriptor: %d\n", + response); + } else { char string[30]; dev_dbg(dev, "**Manufacturer Descriptor\n"); dev_dbg(dev, " RomSize: %dK\n", @@ -2646,9 +2651,10 @@ static void get_boot_desc(struct edgeport_serial *edge_serial) EDGE_BOOT_DESC_LEN, (__u8 *)(&edge_serial->boot_descriptor)); - if (response < 1) - dev_err(dev, "error in getting boot descriptor\n"); - else { + if (response < 0) { + dev_err(dev, "error in getting boot descriptor: %d\n", + response); + } else { dev_dbg(dev, "**Boot Descriptor:\n"); dev_dbg(dev, " BootCodeLength: %d\n", le16_to_cpu(edge_serial->boot_descriptor.BootCodeLength)); |