[linux-dvb] [patch 2.6.12-rc4-dvb-cvs 9/14] dvb: error checking in __av7110_budget_register/av7110_register

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Error checking in __av7110_budget_register/av7110_register

No comment.

Signed-off-by: Francois Romieu <romieu@xxxxxxxxxxxxx>

diff -puN drivers/media/dvb/ttpci/av7110.c~dvb-200 drivers/media/dvb/ttpci/av7110.c
--- a/drivers/media/dvb/ttpci/av7110.c~dvb-200	2005-05-20 19:32:10.393115676 +0200
+++ b/drivers/media/dvb/ttpci/av7110.c	2005-05-20 19:36:19.562386480 +0200
@@ -27,6 +27,9 @@
  *
  *
  * the project's page is at http://www.linuxtv.org/dvb/
+ *
+ * TODO:
+ *  20050502 - audit dmx->disconnect_frontend() failure.
  */
 
 
@@ -1262,6 +1265,7 @@ static int __av7110_budget_register(stru
 	struct dvb_demux *dvbdemux = &av7110->demux1;
 	struct dmxdev *dmxdev = &av7110->dmxdev1;
 	struct dmx_demux *dmx = &dvbdemux->dmx;
+	int ret = 0;
 
 	if (!budgetpatch)
 		goto out;
@@ -1280,28 +1284,52 @@ static int __av7110_budget_register(stru
 	dmx->capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
 			      DMX_MEMORY_BASED_FILTERING);
 
-	dvb_dmx_init(dvbdemux);
+	ret = dvb_dmx_init(dvbdemux);
+	if (ret < 0)
+		goto out;
 
 	av7110_dmxdev_init(dmxdev, dmx, 256, 0);
 
-	dvb_dmxdev_init(dmxdev, &av7110->dvb_adapter);
+	ret = dvb_dmxdev_init(dmxdev, &av7110->dvb_adapter);
+	if (ret < 0)
+		goto err_dvb_dmx_release_0;
+
+	ret = dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, dmx);
+	if (ret < 0)
+		goto err_dvb_dmxdev_release_1;
 
-	dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, dmx);
 	printk("dvb-ttpci: additional demux1 for budget-patch registered\n");
 out:
+	return ret;
+
+err_dvb_dmxdev_release_1:
+	dvb_dmxdev_release(dmxdev);
+err_dvb_dmx_release_0:
+	dvb_dmx_release(dvbdemux);
+	goto out;
+}
+
+static int av7110_osd_register(struct av7110 *av7110)
+{
+#ifdef CONFIG_DVB_AV7110_OSD
+	return dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
+				   &dvbdev_osd, av7110, DVB_DEVICE_OSD);
+#else
 	return 0;
+#endif
 }
 
 static int av7110_register(struct av7110 *av7110)
 {
-	int ret, i;
 	struct dvb_demux *dvbdemux = &av7110->demux;
 	struct dmx_demux *dmx = &dvbdemux->dmx;
+	int i, ret = -1;
 
 	dprintk(4, "%p\n", av7110);
 
+	/* FIXME: smells like race */
 	if (av7110->registered)
-		return -1;
+		goto out;
 
 	av7110->registered = 1;
 
@@ -1318,44 +1346,75 @@ static int av7110_register(struct av7110
 	dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING |
 				      DMX_MEMORY_BASED_FILTERING);
 
-	dvb_dmx_init(dvbdemux);
+	ret = dvb_dmx_init(dvbdemux);
+	if (ret < 0)
+		goto out;
+
 	dmx->get_stc = dvb_get_stc;
 
 	av7110_dmxdev_init(&av7110->dmxdev, dmx, 32, 0);
 
-	dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
+	ret = dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter);
+	if (ret < 0)
+		goto err_dvb_dmx_release_0;
 
 	av7110->hw_frontend.source = DMX_FRONTEND_0;
 
 	ret = dmx->add_frontend(dmx, &av7110->hw_frontend);
-
 	if (ret < 0)
-		return ret;
+		goto err_dvb_dmxdev_release_1;
 
 	av7110->mem_frontend.source = DMX_MEMORY_FE;
 
 	ret = dmx->add_frontend(dmx, &av7110->mem_frontend);
-
 	if (ret < 0)
-		return ret;
+		goto err_dmx_remove_frontend_hw_2;
 
 	ret = dmx->connect_frontend(dmx, &av7110->hw_frontend);
 	if (ret < 0)
-		return ret;
+		goto err_dmx_remove_frontend_mem_3;
 
-	av7110_av_register(av7110);
-	av7110_ca_register(av7110);
+	ret = av7110_av_register(av7110);
+	if (ret < 0)
+		goto err_dmx_disconnect_frontend_hw_4;
 
-#ifdef CONFIG_DVB_AV7110_OSD
-	dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev,
-			    &dvbdev_osd, av7110, DVB_DEVICE_OSD);
-#endif
+	ret = av7110_ca_register(av7110);
+	if (ret < 0)
+		goto err_av_unregister_5;
+
+	ret = av7110_osd_register(av7110);
+	if (ret < 0)
+		goto err_av7110_ca_unregiter_6;
 
-	dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, dmx);
+	ret = dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, dmx);
+	if (ret < 0)
+		goto err_osd_unregister_7;
 
 	ret = __av7110_budget_register(av7110);
-
+	if (ret < 0)
+		goto err_dvb_net_release_8;
+out:
 	return ret;
+
+err_dvb_net_release_8:
+	dvb_net_release(&av7110->dvb_net);
+err_osd_unregister_7:
+	dvb_unregister_device(av7110->osd_dev);
+err_av7110_ca_unregiter_6:
+	av7110_ca_unregister(av7110);
+err_av_unregister_5:
+	av7110_av_unregister(av7110);
+err_dmx_disconnect_frontend_hw_4:
+	dmx->disconnect_frontend(dmx);
+err_dmx_remove_frontend_mem_3:
+	dmx->remove_frontend(dmx, &av7110->mem_frontend);
+err_dmx_remove_frontend_hw_2:
+	dmx->remove_frontend(dmx, &av7110->hw_frontend);
+err_dvb_dmxdev_release_1:
+	dvb_dmxdev_release(&av7110->dmxdev);
+err_dvb_dmx_release_0:
+	dvb_dmx_release(dvbdemux);
+	goto out;
 }
 
 

_



[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux