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 | |
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>
-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 | } |