Skip to content

Commit

Permalink
ALSA: line6: Return error if device not responding
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
  • Loading branch information
crorvick authored and tiwai committed Feb 11, 2015
1 parent e64e94d commit f3dfd1b
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions sound/usb/line6/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ static void line6_data_received(struct urb *urb)
}

#define LINE6_READ_WRITE_STATUS_DELAY 2 /* milliseconds */
#define LINE6_READ_WRITE_MAX_RETRIES 50

/*
Read data from device.
Expand All @@ -307,6 +308,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data,
struct usb_device *usbdev = line6->usbdev;
int ret;
unsigned char len;
unsigned count;

/* query the serial number: */
ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
Expand All @@ -320,7 +322,7 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data,
}

/* Wait for data length. We'll get 0xff until length arrives. */
do {
for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) {
mdelay(LINE6_READ_WRITE_STATUS_DELAY);

ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
Expand All @@ -333,9 +335,16 @@ int line6_read_data(struct usb_line6 *line6, int address, void *data,
"receive length failed (error %d)\n", ret);
return ret;
}
} while (len == 0xff);

if (len != datalen) {
if (len != 0xff)
break;
}

if (len == 0xff) {
dev_err(line6->ifcdev, "read failed after %d retries\n",
count);
return -EIO;
} else if (len != datalen) {
/* should be equal or something went wrong */
dev_err(line6->ifcdev,
"length mismatch (expected %d, got %d)\n",
Expand Down Expand Up @@ -367,6 +376,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
struct usb_device *usbdev = line6->usbdev;
int ret;
unsigned char status;
int count;

ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
Expand All @@ -379,7 +389,7 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
return ret;
}

do {
for (count = 0; count < LINE6_READ_WRITE_MAX_RETRIES; count++) {
mdelay(LINE6_READ_WRITE_STATUS_DELAY);

ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
Expand All @@ -394,9 +404,16 @@ int line6_write_data(struct usb_line6 *line6, int address, void *data,
"receiving status failed (error %d)\n", ret);
return ret;
}
} while (status == 0xff);

if (status != 0) {
if (status != 0xff)
break;
}

if (status == 0xff) {
dev_err(line6->ifcdev, "write failed after %d retries\n",
count);
return -EIO;
} else if (status != 0) {
dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
return -EINVAL;
}
Expand Down

0 comments on commit f3dfd1b

Please sign in to comment.