The patch number 9266 was added via [EMAIL PROTECTED]
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        [EMAIL PROTECTED]

------

From: Darron Broad  <[EMAIL PROTECTED]>
videobuf: properly handle attachment failure


This fixes attachment failure where we now unwind
attachment and skip non-attached nodes where
necessary so we can survive a fault situation
correctly.

Priority: normal

Signed-off-by: Darron Broad <[EMAIL PROTECTED]>
Signed-off-by: Steven Toth <[EMAIL PROTECTED]>


---

 linux/drivers/media/video/videobuf-dvb.c |   43 ++++++++++++++---------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff -r 118354d8c3fb -r c4ff51456d9c linux/drivers/media/video/videobuf-dvb.c
--- a/linux/drivers/media/video/videobuf-dvb.c  Wed Oct 15 17:43:41 2008 +0100
+++ b/linux/drivers/media/video/videobuf-dvb.c  Wed Oct 15 17:48:43 2008 +0100
@@ -150,19 +150,19 @@ int videobuf_dvb_register_bus(struct vid
 {
        struct list_head *list, *q;
        struct videobuf_dvb_frontend *fe;
-       int res = -EINVAL;
+       int res;
 
        fe = videobuf_dvb_get_frontend(f, 1);
        if (!fe) {
                printk(KERN_WARNING "Unable to register the adapter which has 
no frontends\n");
-               goto err;
+               return -EINVAL;
        }
 
        /* Bring up the adapter */
        res = videobuf_dvb_register_adapter(f, module, adapter_priv, device, 
fe->dvb.name, adapter_nr, mfe_shared);
        if (res < 0) {
                printk(KERN_WARNING "videobuf_dvb_register_adapter failed 
(errno = %d)\n", res);
-               goto err;
+               return res;
        }
 
        /* Attach all of the frontends to the adapter */
@@ -173,11 +173,15 @@ int videobuf_dvb_register_bus(struct vid
                if (res < 0) {
                        printk(KERN_WARNING "%s: videobuf_dvb_register_frontend 
failed (errno = %d)\n",
                                fe->dvb.name, res);
-               }
-       }
-       mutex_unlock(&f->lock);
+                       goto err;
+               }
+       }
+       mutex_unlock(&f->lock);
+       return 0;
 
 err:
+       mutex_unlock(&f->lock);
+       videobuf_dvb_unregister_bus(f);
        return res;
 }
 
@@ -269,6 +273,10 @@ int videobuf_dvb_register_frontend(struc
 
        /* register network adapter */
        dvb_net_init(adapter, &dvb->net, &dvb->demux.dmx);
+       if (dvb->net.dvbdev == NULL) {
+               result = -ENOMEM;
+               goto fail_fe_conn;
+       }
        return 0;
 
 fail_fe_conn:
@@ -283,7 +291,7 @@ fail_dmx:
        dvb_unregister_frontend(dvb->frontend);
 fail_frontend:
        dvb_frontend_detach(dvb->frontend);
-       dvb_unregister_adapter(adapter);
+       dvb->frontend = NULL;
 
        return result;
 }
@@ -296,15 +304,18 @@ void videobuf_dvb_unregister_bus(struct 
        mutex_lock(&f->lock);
        list_for_each_safe(list, q, &f->felist) {
                fe = list_entry(list, struct videobuf_dvb_frontend, felist);
-
-               dvb_net_release(&fe->dvb.net);
-               fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, 
&fe->dvb.fe_mem);
-               fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, 
&fe->dvb.fe_hw);
-               dvb_dmxdev_release(&fe->dvb.dmxdev);
-               dvb_dmx_release(&fe->dvb.demux);
-               dvb_unregister_frontend(fe->dvb.frontend);
-               dvb_frontend_detach(fe->dvb.frontend);
-
+               if(fe->dvb.net.dvbdev) {
+                       dvb_net_release(&fe->dvb.net);
+                       fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, 
&fe->dvb.fe_mem);
+                       fe->dvb.demux.dmx.remove_frontend(&fe->dvb.demux.dmx, 
&fe->dvb.fe_hw);
+                       dvb_dmxdev_release(&fe->dvb.dmxdev);
+                       dvb_dmx_release(&fe->dvb.demux);
+                       dvb_unregister_frontend(fe->dvb.frontend);
+               }
+               if(fe->dvb.frontend) {  /* always allocated, may have been 
reset */
+                       dvb_frontend_detach(fe->dvb.frontend);
+                       fe->dvb.frontend = NULL;
+               }
                list_del(list);
                kfree(fe);
        }


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/c4ff51456d9c781b30cc9ed272b5c3836c3f52cf

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to