diff options
author | Chris Rorvick <chris@rorvick.com> | 2015-02-11 00:03:14 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-02-11 04:37:30 -0500 |
commit | f3dfd1be08cc55f930f32e714fb1967630c47991 (patch) | |
tree | d150f709d2a8d9ad4015db521e1ae376c36cf18b /sound/usb | |
parent | e64e94df9916a1db6c85a3677e20926c99a1d0b3 (diff) |
ALSA: line6: Return error if device not responding
Put an upper bound on how long we will wait for the device to respond to
a read/write request (i.e., 100 milliseconds) and return an error if
this is reached.
Signed-off-by: Chris Rorvick <chris@rorvick.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/line6/driver.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index 2f9b74e7accb..f2ee8046271a 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c | |||
@@ -297,6 +297,7 @@ static void line6_data_received(struct urb *urb) | |||
297 | } | 297 | } |
298 | 298 | ||
299 | #define LINE6_READ_WRITE_STATUS_DELAY 2 /* milliseconds */ | 299 | #define LINE6_READ_WRITE_STATUS_DELAY 2 /* milliseconds */ |
300 | #define LINE6_READ_WRITE_MAX_RETRIES 50 | ||
300 | 301 | ||
301 | /* | 302 | /* |
302 | Read data from device. | 303 | Read data from device. |
@@ -307,6 +308,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, | |||
307 | struct usb_device *usbdev = line6->usbdev; | 308 | struct usb_device *usbdev = line6->usbdev; |
308 | int ret; | 309 | int ret; |
309 | unsigned char len; | 310 | unsigned char len; |
311 | unsigned count; | ||
310 | 312 | ||
311 | /* query the serial number: */ | 313 | /* query the serial number: */ |
312 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, | 314 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, |
@@ -320,7 +322,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, | |||
320 | } | 322 | } |
321 | 323 | ||
322 | /* Wait for data length. We'll get 0xff until length arrives. */ | 324 | /* Wait for data length. We'll get 0xff until length arrives. */ |
323 | do { | 325 | for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { |
324 | mdelay(LINE6_READ_WRITE_STATUS_DELAY); | 326 | mdelay(LINE6_READ_WRITE_STATUS_DELAY); |
325 | 327 | ||
326 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, | 328 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67, |
@@ -333,9 +335,16 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data, | |||
333 | "receive length failed (error %d)\n", ret); | 335 | "receive length failed (error %d)\n", ret); |
334 | return ret; | 336 | return ret; |
335 | } | 337 | } |
336 | } while (len == 0xff); | ||
337 | 338 | ||
338 | if (len != datalen) { | 339 | if (len != 0xff) |
340 | break; | ||
341 | } | ||
342 | |||
343 | if (len == 0xff) { | ||
344 | dev_err(line6->ifcdev, "read failed after %d retries\n", | ||
345 | count); | ||
346 | return -EIO; | ||
347 | } else if (len != datalen) { | ||
339 | /* should be equal or something went wrong */ | 348 | /* should be equal or something went wrong */ |
340 | dev_err(line6->ifcdev, | 349 | dev_err(line6->ifcdev, |
341 | "length mismatch (expected %d, got %d)\n", | 350 | "length mismatch (expected %d, got %d)\n", |
@@ -367,6 +376,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, | |||
367 | struct usb_device *usbdev = line6->usbdev; | 376 | struct usb_device *usbdev = line6->usbdev; |
368 | int ret; | 377 | int ret; |
369 | unsigned char status; | 378 | unsigned char status; |
379 | int count; | ||
370 | 380 | ||
371 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, | 381 | ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67, |
372 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | 382 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
@@ -379,7 +389,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, | |||
379 | return ret; | 389 | return ret; |
380 | } | 390 | } |
381 | 391 | ||
382 | do { | 392 | for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) { |
383 | mdelay(LINE6_READ_WRITE_STATUS_DELAY); | 393 | mdelay(LINE6_READ_WRITE_STATUS_DELAY); |
384 | 394 | ||
385 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), | 395 | ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), |
@@ -394,9 +404,16 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data, | |||
394 | "receiving status failed (error %d)\n", ret); | 404 | "receiving status failed (error %d)\n", ret); |
395 | return ret; | 405 | return ret; |
396 | } | 406 | } |
397 | } while (status == 0xff); | ||
398 | 407 | ||
399 | if (status != 0) { | 408 | if (status != 0xff) |
409 | break; | ||
410 | } | ||
411 | |||
412 | if (status == 0xff) { | ||
413 | dev_err(line6->ifcdev, "write failed after %d retries\n", | ||
414 | count); | ||
415 | return -EIO; | ||
416 | } else if (status != 0) { | ||
400 | dev_err(line6->ifcdev, "write failed (error %d)\n", ret); | 417 | dev_err(line6->ifcdev, "write failed (error %d)\n", ret); |
401 | return -EINVAL; | 418 | return -EINVAL; |
402 | } | 419 | } |