]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] DVB: Fix feed list handling bugs in demux
authorMichael Hunold <hunold@linuxtv.org>
Thu, 1 Jan 2004 03:24:56 +0000 (19:24 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Thu, 1 Jan 2004 03:24:56 +0000 (19:24 -0800)
 - corrected handling of feed lists (Andres Oberritter)

drivers/media/dvb/dvb-core/dvb_demux.c

index 41b5dab890a14505e89d804afbbcebc5a1ec50a5..ffb01c0912d648f850bdd0279eb71f6dec341ab2 100644 (file)
@@ -542,33 +542,38 @@ static struct dvb_demux_feed * dvb_dmx_feed_alloc(struct dvb_demux *demux)
        return &demux->feed[i];
 }
 
-
-static int dmx_pid_set (u16 pid, struct dvb_demux_feed *feed)
+static int dvb_demux_feed_find(struct dvb_demux_feed *feed)
 {
-       struct dvb_demux *demux = feed->demux;
-       struct list_head *pos, *n, *head=&demux->feed_list;
+       struct dvb_demux_feed *entry;
 
-       if (pid > DMX_MAX_PID)
-               return -EINVAL;
+       list_for_each_entry(entry, &feed->demux->feed_list, list_head)
+               if (entry == feed)
+                       return 1;
 
-       if (pid == feed->pid)
                return 0;
-
-       if (feed->pid <= DMX_MAX_PID) {
-               list_for_each_safe(pos, n, head) {
-                       if (DMX_FEED_ENTRY(pos)->pid == feed->pid) {
-                               list_del(pos);
-                               break;
-                       }
                }
+
+static void dvb_demux_feed_add(struct dvb_demux_feed *feed)
+{
+       if (dvb_demux_feed_find(feed)) {
+               printk(KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n",
+                               __FUNCTION__, feed->type, feed->state, feed->pid);
+               return;
        }
 
-       list_add(&feed->list_head, head);
-       feed->pid = pid;
+       list_add(&feed->list_head, &feed->demux->feed_list);
+}
 
-       return 0;
+static void dvb_demux_feed_del(struct dvb_demux_feed *feed)
+{
+       if (!(dvb_demux_feed_find(feed))) {
+               printk(KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n",
+                               __FUNCTION__, feed->type, feed->state, feed->pid);
+               return;
 }
 
+       list_del(&feed->list_head);
+}
 
 static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type, 
                     enum dmx_ts_pes pes_type, size_t callback_length, 
@@ -577,7 +582,9 @@ static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
 {
        struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
        struct dvb_demux *demux = feed->demux;
-       int ret;
+
+       if (pid > DMX_MAX_PID)
+               return -EINVAL;
        
        if (down_interruptible (&demux->mutex))
                return -ERESTARTSYS;
@@ -594,26 +601,13 @@ static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
                        return -EINVAL;
                }
 
-               if ((pes_type != DMX_TS_PES_PCR0) && 
-                   (pes_type != DMX_TS_PES_PCR1) && 
-                   (pes_type != DMX_TS_PES_PCR2) && 
-                   (pes_type != DMX_TS_PES_PCR3)) {
-                       if ((ret = dmx_pid_set(pid, feed))<0) {
-                               up(&demux->mutex);
-                               return ret;
-                       }
-               } else
-                       feed->pid = pid;
-                               
                demux->pesfilter[pes_type] = feed;
-               demux->pids[pes_type] = feed->pid;
-       } else {
-               if ((ret = dmx_pid_set(pid, feed))<0) {
-                       up(&demux->mutex);
-                       return ret;
-               }
+               demux->pids[pes_type] = pid;
        }
 
+       dvb_demux_feed_add(feed);
+
+       feed->pid = pid;
        feed->buffer_size = circular_buffer_size;
        feed->descramble = descramble;
        feed->timeout = timeout;
@@ -757,7 +751,6 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_
 {
        struct dvb_demux *demux = (struct dvb_demux *) dmx;
        struct dvb_demux_feed *feed = (struct dvb_demux_feed *) ts_feed;
-       struct list_head *pos, *n, *head=&demux->feed_list;
 
        if (down_interruptible (&demux->mutex))
                return -ERESTARTSYS;
@@ -777,14 +770,9 @@ static int dvbdmx_release_ts_feed(struct dmx_demux *dmx, struct dmx_ts_feed *ts_
        feed->state = DMX_STATE_FREE;
        feed->filter->state = DMX_STATE_FREE;
 
-       if (feed->pid <= DMX_MAX_PID) {
-               list_for_each_safe(pos, n, head)
-                       if (DMX_FEED_ENTRY(pos)->pid == feed->pid) {
-                               list_del(pos);
-                               break;
-                       }
+       dvb_demux_feed_del(feed);
+
                feed->pid = 0xffff;
-       }
        
        if (feed->ts_type & TS_DECODER)
                demux->pesfilter[feed->pes_type] = NULL;
@@ -836,7 +824,6 @@ static int dmx_section_feed_set(struct dmx_section_feed* feed,
 {
        struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
        struct dvb_demux *dvbdmx=dvbdmxfeed->demux;
-       struct list_head *pos, *n, *head=&dvbdmx->feed_list;
 
        if (pid>0x1fff)
                return -EINVAL;
@@ -844,16 +831,7 @@ static int dmx_section_feed_set(struct dmx_section_feed* feed,
        if (down_interruptible (&dvbdmx->mutex))
                return -ERESTARTSYS;
        
-       if (dvbdmxfeed->pid <= DMX_MAX_PID) {
-               list_for_each_safe(pos, n, head) {
-                       if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) {
-                               list_del(pos);
-                               break;
-                       }
-               }
-       }
-
-       list_add(&dvbdmxfeed->list_head, head);
+       dvb_demux_feed_add(dvbdmxfeed);
 
        dvbdmxfeed->pid = pid;
        dvbdmxfeed->buffer_size=circular_buffer_size;
@@ -1045,7 +1023,6 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
 {
        struct dvb_demux_feed *dvbdmxfeed=(struct dvb_demux_feed *) feed;
        struct dvb_demux *dvbdmx=(struct dvb_demux *) demux;
-       struct list_head *pos, *n, *head=&dvbdmx->feed_list;
 
        if (down_interruptible (&dvbdmx->mutex))
                return -ERESTARTSYS;
@@ -1062,15 +1039,9 @@ static int dvbdmx_release_section_feed(struct dmx_demux *demux,
 #endif
        dvbdmxfeed->state=DMX_STATE_FREE;
 
-       if (dvbdmxfeed->pid <= DMX_MAX_PID) {
-               list_for_each_safe(pos, n, head) {
-                       if (DMX_FEED_ENTRY(pos)->pid == dvbdmxfeed->pid) {
-                               list_del(pos);
-                               break;
-                       }
-               }
+       dvb_demux_feed_del(dvbdmxfeed);
+
                dvbdmxfeed->pid = 0xffff;
-       }
 
        up(&dvbdmx->mutex);
        return 0;