case -ESHUTDOWN:
return;
default: /* error */
- cx231xx_isocdbg("urb completition error %d.\n", urb->status);
+ cx231xx_isocdbg("urb completion error %d.\n", urb->status);
break;
}
case -ENOENT:
case -ESHUTDOWN:
return;
+ case -EPIPE: /* stall */
+ cx231xx_isocdbg("urb completion error - device is stalled.\n");
+ return;
default: /* error */
- cx231xx_isocdbg("urb completition error %d.\n", urb->status);
+ cx231xx_isocdbg("urb completion error %d.\n", urb->status);
break;
}
struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
struct urb *urb;
int i;
+ bool broken_pipe = false;
cx231xx_isocdbg("cx231xx: called cx231xx_uninit_isoc\n");
transfer_buffer[i],
urb->transfer_dma);
}
+ if (urb->status == -EPIPE) {
+ broken_pipe = true;
+ }
usb_free_urb(urb);
dev->video_mode.isoc_ctl.urb[i] = NULL;
}
dev->video_mode.isoc_ctl.transfer_buffer[i] = NULL;
}
+ if (broken_pipe) {
+ cx231xx_isocdbg("Reset endpoint to recover broken pipe.");
+ usb_reset_endpoint(dev->udev, dev->video_mode.end_point_addr);
+ }
kfree(dev->video_mode.isoc_ctl.urb);
kfree(dev->video_mode.isoc_ctl.transfer_buffer);
kfree(dma_q->p_left_data);
struct cx231xx_dmaqueue *dma_q = &dev->video_mode.vidq;
struct urb *urb;
int i;
+ bool broken_pipe = false;
cx231xx_isocdbg("cx231xx: called cx231xx_uninit_bulk\n");
transfer_buffer[i],
urb->transfer_dma);
}
+ if (urb->status == -EPIPE) {
+ broken_pipe = true;
+ }
usb_free_urb(urb);
dev->video_mode.bulk_ctl.urb[i] = NULL;
}
dev->video_mode.bulk_ctl.transfer_buffer[i] = NULL;
}
+ if (broken_pipe) {
+ cx231xx_isocdbg("Reset endpoint to recover broken pipe.");
+ usb_reset_endpoint(dev->udev, dev->video_mode.end_point_addr);
+ }
kfree(dev->video_mode.bulk_ctl.urb);
kfree(dev->video_mode.bulk_ctl.transfer_buffer);
kfree(dma_q->p_left_data);