diff options
Diffstat (limited to 'sound/usb/line6')
-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 | } |