diff options
| author | Johan Hovold <johan@kernel.org> | 2017-01-12 08:56:22 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-14 08:00:18 -0400 |
| commit | 4d32e36d62627ad9730338e6f603c8b996aaf7eb (patch) | |
| tree | cecb8c10a9ef5a49a64d4c8e0a5aeae3c464c99f /drivers/usb | |
| parent | 9ca3010675025a512db998b1421ad0b60963c790 (diff) | |
USB: serial: ssu100: fix control-message error handling
commit 1eac5c244f705182d1552a53e2f74e2775ed95d6 upstream.
Make sure to detect short control-message transfers rather than continue
with zero-initialised data when retrieving modem status and during
device initialisation.
Fixes: 52af95459939 ("USB: add USB serial ssu100 driver")
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/serial/ssu100.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 70a098de429f..886e1294b120 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
| @@ -80,9 +80,17 @@ static inline int ssu100_setdevice(struct usb_device *dev, u8 *data) | |||
| 80 | 80 | ||
| 81 | static inline int ssu100_getdevice(struct usb_device *dev, u8 *data) | 81 | static inline int ssu100_getdevice(struct usb_device *dev, u8 *data) |
| 82 | { | 82 | { |
| 83 | return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 83 | int ret; |
| 84 | QT_SET_GET_DEVICE, 0xc0, 0, 0, | 84 | |
| 85 | data, 3, 300); | 85 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
| 86 | QT_SET_GET_DEVICE, 0xc0, 0, 0, | ||
| 87 | data, 3, 300); | ||
| 88 | if (ret < 3) { | ||
| 89 | if (ret >= 0) | ||
| 90 | ret = -EIO; | ||
| 91 | } | ||
| 92 | |||
| 93 | return ret; | ||
| 86 | } | 94 | } |
| 87 | 95 | ||
| 88 | static inline int ssu100_getregister(struct usb_device *dev, | 96 | static inline int ssu100_getregister(struct usb_device *dev, |
| @@ -90,10 +98,17 @@ static inline int ssu100_getregister(struct usb_device *dev, | |||
| 90 | unsigned short reg, | 98 | unsigned short reg, |
| 91 | u8 *data) | 99 | u8 *data) |
| 92 | { | 100 | { |
| 93 | return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 101 | int ret; |
| 94 | QT_SET_GET_REGISTER, 0xc0, reg, | 102 | |
| 95 | uart, data, sizeof(*data), 300); | 103 | ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
| 104 | QT_SET_GET_REGISTER, 0xc0, reg, | ||
| 105 | uart, data, sizeof(*data), 300); | ||
| 106 | if (ret < sizeof(*data)) { | ||
| 107 | if (ret >= 0) | ||
| 108 | ret = -EIO; | ||
| 109 | } | ||
| 96 | 110 | ||
| 111 | return ret; | ||
| 97 | } | 112 | } |
| 98 | 113 | ||
| 99 | 114 | ||
| @@ -289,8 +304,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
| 289 | QT_OPEN_CLOSE_CHANNEL, | 304 | QT_OPEN_CLOSE_CHANNEL, |
| 290 | QT_TRANSFER_IN, 0x01, | 305 | QT_TRANSFER_IN, 0x01, |
| 291 | 0, data, 2, 300); | 306 | 0, data, 2, 300); |
| 292 | if (result < 0) { | 307 | if (result < 2) { |
| 293 | dev_dbg(&port->dev, "%s - open failed %i\n", __func__, result); | 308 | dev_dbg(&port->dev, "%s - open failed %i\n", __func__, result); |
| 309 | if (result >= 0) | ||
| 310 | result = -EIO; | ||
| 294 | kfree(data); | 311 | kfree(data); |
| 295 | return result; | 312 | return result; |
| 296 | } | 313 | } |
