diff -Naur old/vp7045.c new/vp7045.c --- old/vp7045.c 2007-11-04 22:19:39.000000000 +0200 +++ new/vp7045.c 2007-11-04 22:20:40.000000000 +0200 @@ -21,6 +21,7 @@ int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec) { + int usbResult, idx; /* Hack fix to usb went wrong */ int ret = 0; u8 inbuf[12] = { 0 }, outbuf[20] = { 0 }; @@ -52,10 +53,28 @@ msleep(msec); +/* Hack fix: Removed code below and replaced with re-try looping if (usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, inbuf, 12, 2000) != 12) { +*/ + + /* Hack fix: If usb-in fails in timeout error then try to recover from it */ + /* by re-sending the command. This seem to fix the problem with some hardware */ + for (idx = 0; idx < 3; idx++) { + usbResult = usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev,0), + TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, + inbuf, 12, 2000 + (idx * 1000)); + + /* If usb-in succeeded (12 bytes) or not timed out error then do not re-try */ + if(usbResult == 12 || usbResult != -ETIMEDOUT) break; + + err("USB control message 'in' went wrong. Trying to recover (retry idx=%d).", idx); + } + + if (usbResult != 12) { err("USB control message 'in' went wrong."); ret = -EIO; goto unlock;