diff options
author | Daniel Scheller <d.scheller@gmx.net> | 2017-12-17 10:40:46 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2017-12-19 07:16:53 -0500 |
commit | 25ac563abf3453339ca1db2bd35d42e47d9993b1 (patch) | |
tree | ad286f2105ec15fb3593ded6f3d0603bde68d00f /drivers/media/pci | |
parent | fac37bb124c221bde55ae77fbf8c7eff84881bda (diff) |
media: ddbridge: completely tear down input resources on failure
In dvb_input_attach(), whenever a demod driver fails to initialise, or if
frontend registration fails, perform a full input/frontend teardown using
dvb_input_detach() (which can safely be done since the current init state
is tracked in the 'attached' struct member). Claimed resources thus are
freed which aren't needed when an input or a port is not functional.
While at it, in ddb_ports_detach(), detach the secondary input first. Also
increase the kernlog severity of TDA18212 errors and tuner failures in
general.
Signed-off-by: Daniel Scheller <d.scheller@gmx.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'drivers/media/pci')
-rw-r--r-- | drivers/media/pci/ddbridge/ddbridge-core.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/drivers/media/pci/ddbridge/ddbridge-core.c b/drivers/media/pci/ddbridge/ddbridge-core.c index a81125d492ff..c2013d170c99 100644 --- a/drivers/media/pci/ddbridge/ddbridge-core.c +++ b/drivers/media/pci/ddbridge/ddbridge-core.c @@ -1032,7 +1032,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype) return 0; err: - dev_notice(dev, "TDA18212 tuner not found. Device is not fully operational.\n"); + dev_err(dev, "TDA18212 tuner not found. Device is not fully operational.\n"); return -ENODEV; } @@ -1425,7 +1425,7 @@ static int dvb_input_attach(struct ddb_input *input) dvb->dmxdev.demux = &dvbdemux->dmx; ret = dvb_dmxdev_init(&dvb->dmxdev, adap); if (ret < 0) - return ret; + goto err_detach; dvb->attached = 0x11; dvb->mem_frontend.source = DMX_MEMORY_FE; @@ -1434,12 +1434,12 @@ static int dvb_input_attach(struct ddb_input *input) dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend); ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend); if (ret < 0) - return ret; + goto err_detach; dvb->attached = 0x12; ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux); if (ret < 0) - return ret; + goto err_detach; dvb->attached = 0x20; dvb->fe = NULL; @@ -1447,47 +1447,47 @@ static int dvb_input_attach(struct ddb_input *input) switch (port->type) { case DDB_TUNER_MXL5XX: if (ddb_fe_attach_mxl5xx(input) < 0) - return -ENODEV; + goto err_detach; break; case DDB_TUNER_DVBS_ST: if (demod_attach_stv0900(input, 0) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_stv6110(input, 0) < 0) goto err_tuner; break; case DDB_TUNER_DVBS_ST_AA: if (demod_attach_stv0900(input, 1) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_stv6110(input, 1) < 0) goto err_tuner; break; case DDB_TUNER_DVBS_STV0910: if (demod_attach_stv0910(input, 0) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_stv6111(input, 0) < 0) goto err_tuner; break; case DDB_TUNER_DVBS_STV0910_PR: if (demod_attach_stv0910(input, 1) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_stv6111(input, 1) < 0) goto err_tuner; break; case DDB_TUNER_DVBS_STV0910_P: if (demod_attach_stv0910(input, 0) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_stv6111(input, 1) < 0) goto err_tuner; break; case DDB_TUNER_DVBCT_TR: if (demod_attach_drxk(input) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_tda18271(input) < 0) goto err_tuner; break; case DDB_TUNER_DVBCT_ST: if (demod_attach_stv0367(input) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_tda18212(input, port->type) < 0) goto err_tuner; break; @@ -1507,7 +1507,7 @@ static int dvb_input_attach(struct ddb_input *input) else par = 1; if (demod_attach_cxd28xx(input, par, osc24) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_tda18212(input, port->type) < 0) goto err_tuner; break; @@ -1518,7 +1518,7 @@ static int dvb_input_attach(struct ddb_input *input) case DDB_TUNER_DVBC2T2_SONY: case DDB_TUNER_ISDBT_SONY: if (demod_attach_cxd28xx(input, 0, osc24) < 0) - return -ENODEV; + goto err_detach; if (tuner_attach_tda18212(input, port->type) < 0) goto err_tuner; break; @@ -1529,11 +1529,13 @@ static int dvb_input_attach(struct ddb_input *input) if (dvb->fe) { if (dvb_register_frontend(adap, dvb->fe) < 0) - return -ENODEV; + goto err_detach; if (dvb->fe2) { - if (dvb_register_frontend(adap, dvb->fe2) < 0) - return -ENODEV; + if (dvb_register_frontend(adap, dvb->fe2) < 0) { + dvb_unregister_frontend(dvb->fe); + goto err_detach; + } dvb->fe2->tuner_priv = dvb->fe->tuner_priv; memcpy(&dvb->fe2->ops.tuner_ops, &dvb->fe->ops.tuner_ops, @@ -1545,12 +1547,18 @@ static int dvb_input_attach(struct ddb_input *input) return 0; err_tuner: - dev_warn(port->dev->dev, "tuner attach failed!\n"); + dev_err(port->dev->dev, "tuner attach failed!\n"); if (dvb->fe2) dvb_frontend_detach(dvb->fe2); if (dvb->fe) dvb_frontend_detach(dvb->fe); +err_detach: + dvb_input_detach(input); + + /* return error from ret if set */ + if (ret < 0) + return ret; return -ENODEV; } @@ -1981,8 +1989,8 @@ void ddb_ports_detach(struct ddb *dev) switch (port->class) { case DDB_PORT_TUNER: - dvb_input_detach(port->input[0]); dvb_input_detach(port->input[1]); + dvb_input_detach(port->input[0]); break; case DDB_PORT_CI: case DDB_PORT_LOOP: |