diff options
author | Mike Isely <devnull@localhost> | 2006-01-09 06:54:46 +0000 |
---|---|---|
committer | Mike Isely <devnull@localhost> | 2006-01-09 06:54:46 +0000 |
commit | 2f999c230688131f47f938e3184982d425d19637 (patch) | |
tree | f6b041fd9c4f9f4b6ae3f32e2d4a9a418b99a077 | |
parent | 4c4fffc05ca33429a5927f46a66e4569a11c9ad8 (diff) | |
download | mediapointer-dvb-s2-2f999c230688131f47f938e3184982d425d19637.tar.gz mediapointer-dvb-s2-2f999c230688131f47f938e3184982d425d19637.tar.bz2 |
Make the pvrusb2 driver more tolerant of USB streaming errors
From: Mike Isely <isely@pobox.com>
Signed-off-by: Mike Isely <isely@pobox.com>
-rw-r--r-- | v4l/ChangeLog | 18 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-debug.h | 3 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-hdw.c | 27 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-io.c | 30 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-io.h | 5 | ||||
-rw-r--r-- | v4l_experimental/pvrusb2/pvrusb2-main.c | 3 |
6 files changed, 76 insertions, 10 deletions
diff --git a/v4l/ChangeLog b/v4l/ChangeLog index 2626d66cb..ca7e23ba9 100644 --- a/v4l/ChangeLog +++ b/v4l/ChangeLog @@ -1,3 +1,21 @@ +2006-01-09 06:50 mcisely + + * v4l_experimental/pvrusb2/pvrusb2-debug.h: + * v4l_experimental/pvrusb2/pvrusb2-hdw.c: + (get_default_error_tolerance), (pvr2_hdw_setup_low), + (pvr2_hdw_render_useless_unlocked): + * v4l_experimental/pvrusb2/pvrusb2-io.c: (buffer_complete), + (pvr2_stream_setup): + * v4l_experimental/pvrusb2/pvrusb2-io.h: + * v4l_experimental/pvrusb2/pvrusb2-main.c: + + - Implement new feature in pvrusb2 (which must be enabled via a + module option) that permits the streaming logic to tolerate a + specified level of USB errors. This change makes it possible to + still function in environments with flakey USB hardware. + + Signed-off-by: Mike Isely <isely@pobox.com> + 2006-01-09 06:42 mcisely * v4l_experimental/pvrusb2/pvrusb2-hdw.c: diff --git a/v4l_experimental/pvrusb2/pvrusb2-debug.h b/v4l_experimental/pvrusb2/pvrusb2-debug.h index 3f58eef94..b0616e6f4 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-debug.h +++ b/v4l_experimental/pvrusb2/pvrusb2-debug.h @@ -1,5 +1,5 @@ /* - * $Id: pvrusb2-debug.h,v 1.3 2006/01/09 06:24:23 mcisely Exp $ + * $Id: pvrusb2-debug.h,v 1.4 2006/01/09 06:54:46 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -28,6 +28,7 @@ extern int debug; increasing noise level. */ #define PVR2_TRACE_INFO (1 << 0) // Normal messages #define PVR2_TRACE_ERROR_LEGS (1 << 1) // error messages +#define PVR2_TRACE_TOLERANCE (1 << 2) // track tolerance-affected errors #define PVR2_TRACE_TRAP (1 << 3) // Trap & report misbehavior from app #define PVR2_TRACE_INIT (1 << 4) // misc initialization steps #define PVR2_TRACE_START_STOP (1 << 5) // Streaming start / stop diff --git a/v4l_experimental/pvrusb2/pvrusb2-hdw.c b/v4l_experimental/pvrusb2/pvrusb2-hdw.c index 15969ac46..2c6bfc949 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-hdw.c +++ b/v4l_experimental/pvrusb2/pvrusb2-hdw.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-hdw.c,v 1.9 2006/01/09 06:45:51 mcisely Exp $ + * $Id: pvrusb2-hdw.c,v 1.10 2006/01/09 06:54:46 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -44,6 +44,7 @@ static int ctlchg = 0; static int initusbreset = 1; static int procreload = 0; static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 }; +static int tolerance[PVR_NUM] = { [0 ... PVR_NUM-1] = 0 }; module_param(ctlchg, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(ctlchg, "0=optimize ctl change 1=always accept new ctl value"); @@ -58,6 +59,8 @@ module_param(width, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(width, "video width : 720,480,352"); module_param_array(tuner, int, NULL, 0444); MODULE_PARM_DESC(tuner,"specify installed tuner type"); +module_param_array(tolerance, int, NULL, 0444); +MODULE_PARM_DESC(tolerance,"specify stream error tolerance"); #define PVR2_CTL_WRITE_ENDPOINT 0x01 #define PVR2_CTL_READ_ENDPOINT 0x81 @@ -944,6 +947,17 @@ static int get_default_tuner_type(struct pvr2_hdw *hdw) } +static unsigned int get_default_error_tolerance(struct pvr2_hdw *hdw) +{ + int unit_number = hdw->unit_number; + int tp = 0; + if ((unit_number >= 0) && (unit_number < PVR_NUM)) { + tp = tolerance[unit_number]; + } + return tp; +} + + static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) { unsigned int idx; @@ -1005,8 +1019,15 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) pvr2_trace(PVR2_TRACE_INIT, "pvr2_hdw_setup: video stream is %p",hdw->vid_stream); if (hdw->vid_stream) { + idx = get_default_error_tolerance(hdw); + if (idx) { + pvr2_trace(PVR2_TRACE_INIT, + "pvr2_hdw_setup: video stream %p" + " setting tolerance %u", + hdw->vid_stream,idx); + } pvr2_stream_setup(hdw->vid_stream,hdw->usb_dev, - PVR2_VID_ENDPOINT); + PVR2_VID_ENDPOINT,idx); } if (!pvr2_hdw_dev_ok(hdw)) return; @@ -2129,7 +2150,7 @@ void pvr2_hdw_render_useless_unlocked(struct pvr2_hdw *hdw) pvr2_trace(PVR2_TRACE_INIT,"render_useless"); hdw->flag_ok = 0; if (hdw->vid_stream) { - pvr2_stream_setup(hdw->vid_stream,0,0); + pvr2_stream_setup(hdw->vid_stream,0,0,0); } hdw->flag_streaming_enabled = 0; hdw->subsys_enabled_mask = 0; diff --git a/v4l_experimental/pvrusb2/pvrusb2-io.c b/v4l_experimental/pvrusb2/pvrusb2-io.c index 935978a14..c170bede0 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-io.c +++ b/v4l_experimental/pvrusb2/pvrusb2-io.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-io.c,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-io.c,v 1.2 2006/01/09 06:54:46 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -86,6 +86,9 @@ struct pvr2_stream { /* Overhead for mutex enforcement */ spinlock_t list_lock; struct semaphore sem; + /* Tracking state for tolerating errors */ + unsigned int fail_count; + unsigned int fail_tolerance; }; struct pvr2_buffer { @@ -437,19 +440,38 @@ static void buffer_complete(struct urb *urb, struct pt_regs *regs) { struct pvr2_buffer *bp = urb->context; struct pvr2_stream *sp; + unsigned long irq_flags; BUFFER_CHECK(bp); sp = bp->stream; bp->used_count = 0; + bp->status = 0; pvr2_trace(PVR2_TRACE_BUF_FLOW, "/*---TRACE_FLOW---*/ bufferComplete %p stat=%d cnt=%d", bp,urb->status,urb->actual_length); + spin_lock_irqsave(&sp->list_lock,irq_flags); if ((!(urb->status)) || (urb->status == -ENOENT) || (urb->status == -ECONNRESET) || (urb->status == -ESHUTDOWN)) { bp->used_count = urb->actual_length; + if (sp->fail_count) { + pvr2_trace(PVR2_TRACE_TOLERANCE, + "stream %p transfer ok" + " - fail count reset",sp); + sp->fail_count = 0; + } + } else if (sp->fail_count < sp->fail_tolerance) { + // We can tolerate this error, because we're below the + // threshold... + (sp->fail_count)++; + pvr2_trace(PVR2_TRACE_TOLERANCE, + "stream %p ignoring error %d" + " - fail count increased to %u", + sp,urb->status,sp->fail_count); + } else { + bp->status = urb->status; } - bp->status = urb->status; + spin_unlock_irqrestore(&sp->list_lock,irq_flags); pvr2_buffer_set_ready(bp); if (sp && sp->callback_func) { sp->callback_func(sp->callback_data); @@ -477,12 +499,14 @@ void pvr2_stream_destroy(struct pvr2_stream *sp) void pvr2_stream_setup(struct pvr2_stream *sp, struct usb_device *dev, - int endpoint) + int endpoint, + unsigned int tolerance) { down(&sp->sem); do { pvr2_stream_internal_flush(sp); sp->dev = dev; sp->endpoint = endpoint; + sp->fail_tolerance = tolerance; } while(0); up(&sp->sem); } diff --git a/v4l_experimental/pvrusb2/pvrusb2-io.h b/v4l_experimental/pvrusb2/pvrusb2-io.h index 17e01345b..5dc72b1ef 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-io.h +++ b/v4l_experimental/pvrusb2/pvrusb2-io.h @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-io.h,v 1.1 2005/11/14 13:31:24 mchehab Exp $ + * $Id: pvrusb2-io.h,v 1.2 2006/01/09 06:54:46 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * @@ -42,7 +42,8 @@ const char *pvr2_buffer_state_decode(enum pvr2_buffer_state); struct pvr2_stream *pvr2_stream_create(void); void pvr2_stream_destroy(struct pvr2_stream *); void pvr2_stream_setup(struct pvr2_stream *, - struct usb_device *dev,int endpoint); + struct usb_device *dev,int endpoint, + unsigned int tolerance); void pvr2_stream_set_callback(struct pvr2_stream *, pvr2_stream_callback func, void *data); diff --git a/v4l_experimental/pvrusb2/pvrusb2-main.c b/v4l_experimental/pvrusb2/pvrusb2-main.c index ffaaa4409..aa6fa7c9d 100644 --- a/v4l_experimental/pvrusb2/pvrusb2-main.c +++ b/v4l_experimental/pvrusb2/pvrusb2-main.c @@ -1,6 +1,6 @@ /* * - * $Id: pvrusb2-main.c,v 1.3 2006/01/01 08:26:03 mcisely Exp $ + * $Id: pvrusb2-main.c,v 1.4 2006/01/09 06:54:46 mcisely Exp $ * * Copyright (C) 2005 Mike Isely <isely@pobox.com> * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr> @@ -43,6 +43,7 @@ #define DEFAULT_DEBUG_MASK (PVR2_TRACE_ERROR_LEGS| \ PVR2_TRACE_INFO| \ + PVR2_TRACE_TOLERANCE| \ PVR2_TRACE_TRAP| \ PVR2_TRACE_FIRMWARE| \ PVR2_TRACE_EEPROM | \ |