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; } _