Commit 25ac563a authored by Daniel Scheller's avatar Daniel Scheller Committed by Mauro Carvalho Chehab

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: default avatarDaniel Scheller <d.scheller@gmx.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
parent fac37bb1
...@@ -1032,7 +1032,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype) ...@@ -1032,7 +1032,7 @@ static int tuner_attach_tda18212(struct ddb_input *input, u32 porttype)
return 0; return 0;
err: 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; return -ENODEV;
} }
...@@ -1425,7 +1425,7 @@ static int dvb_input_attach(struct ddb_input *input) ...@@ -1425,7 +1425,7 @@ static int dvb_input_attach(struct ddb_input *input)
dvb->dmxdev.demux = &dvbdemux->dmx; dvb->dmxdev.demux = &dvbdemux->dmx;
ret = dvb_dmxdev_init(&dvb->dmxdev, adap); ret = dvb_dmxdev_init(&dvb->dmxdev, adap);
if (ret < 0) if (ret < 0)
return ret; goto err_detach;
dvb->attached = 0x11; dvb->attached = 0x11;
dvb->mem_frontend.source = DMX_MEMORY_FE; dvb->mem_frontend.source = DMX_MEMORY_FE;
...@@ -1434,12 +1434,12 @@ static int dvb_input_attach(struct ddb_input *input) ...@@ -1434,12 +1434,12 @@ static int dvb_input_attach(struct ddb_input *input)
dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend); dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend);
ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend); ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend);
if (ret < 0) if (ret < 0)
return ret; goto err_detach;
dvb->attached = 0x12; dvb->attached = 0x12;
ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux); ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux);
if (ret < 0) if (ret < 0)
return ret; goto err_detach;
dvb->attached = 0x20; dvb->attached = 0x20;
dvb->fe = NULL; dvb->fe = NULL;
...@@ -1447,47 +1447,47 @@ static int dvb_input_attach(struct ddb_input *input) ...@@ -1447,47 +1447,47 @@ static int dvb_input_attach(struct ddb_input *input)
switch (port->type) { switch (port->type) {
case DDB_TUNER_MXL5XX: case DDB_TUNER_MXL5XX:
if (ddb_fe_attach_mxl5xx(input) < 0) if (ddb_fe_attach_mxl5xx(input) < 0)
return -ENODEV; goto err_detach;
break; break;
case DDB_TUNER_DVBS_ST: case DDB_TUNER_DVBS_ST:
if (demod_attach_stv0900(input, 0) < 0) if (demod_attach_stv0900(input, 0) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_stv6110(input, 0) < 0) if (tuner_attach_stv6110(input, 0) < 0)
goto err_tuner; goto err_tuner;
break; break;
case DDB_TUNER_DVBS_ST_AA: case DDB_TUNER_DVBS_ST_AA:
if (demod_attach_stv0900(input, 1) < 0) if (demod_attach_stv0900(input, 1) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_stv6110(input, 1) < 0) if (tuner_attach_stv6110(input, 1) < 0)
goto err_tuner; goto err_tuner;
break; break;
case DDB_TUNER_DVBS_STV0910: case DDB_TUNER_DVBS_STV0910:
if (demod_attach_stv0910(input, 0) < 0) if (demod_attach_stv0910(input, 0) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_stv6111(input, 0) < 0) if (tuner_attach_stv6111(input, 0) < 0)
goto err_tuner; goto err_tuner;
break; break;
case DDB_TUNER_DVBS_STV0910_PR: case DDB_TUNER_DVBS_STV0910_PR:
if (demod_attach_stv0910(input, 1) < 0) if (demod_attach_stv0910(input, 1) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_stv6111(input, 1) < 0) if (tuner_attach_stv6111(input, 1) < 0)
goto err_tuner; goto err_tuner;
break; break;
case DDB_TUNER_DVBS_STV0910_P: case DDB_TUNER_DVBS_STV0910_P:
if (demod_attach_stv0910(input, 0) < 0) if (demod_attach_stv0910(input, 0) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_stv6111(input, 1) < 0) if (tuner_attach_stv6111(input, 1) < 0)
goto err_tuner; goto err_tuner;
break; break;
case DDB_TUNER_DVBCT_TR: case DDB_TUNER_DVBCT_TR:
if (demod_attach_drxk(input) < 0) if (demod_attach_drxk(input) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_tda18271(input) < 0) if (tuner_attach_tda18271(input) < 0)
goto err_tuner; goto err_tuner;
break; break;
case DDB_TUNER_DVBCT_ST: case DDB_TUNER_DVBCT_ST:
if (demod_attach_stv0367(input) < 0) if (demod_attach_stv0367(input) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_tda18212(input, port->type) < 0) if (tuner_attach_tda18212(input, port->type) < 0)
goto err_tuner; goto err_tuner;
break; break;
...@@ -1507,7 +1507,7 @@ static int dvb_input_attach(struct ddb_input *input) ...@@ -1507,7 +1507,7 @@ static int dvb_input_attach(struct ddb_input *input)
else else
par = 1; par = 1;
if (demod_attach_cxd28xx(input, par, osc24) < 0) if (demod_attach_cxd28xx(input, par, osc24) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_tda18212(input, port->type) < 0) if (tuner_attach_tda18212(input, port->type) < 0)
goto err_tuner; goto err_tuner;
break; break;
...@@ -1518,7 +1518,7 @@ static int dvb_input_attach(struct ddb_input *input) ...@@ -1518,7 +1518,7 @@ static int dvb_input_attach(struct ddb_input *input)
case DDB_TUNER_DVBC2T2_SONY: case DDB_TUNER_DVBC2T2_SONY:
case DDB_TUNER_ISDBT_SONY: case DDB_TUNER_ISDBT_SONY:
if (demod_attach_cxd28xx(input, 0, osc24) < 0) if (demod_attach_cxd28xx(input, 0, osc24) < 0)
return -ENODEV; goto err_detach;
if (tuner_attach_tda18212(input, port->type) < 0) if (tuner_attach_tda18212(input, port->type) < 0)
goto err_tuner; goto err_tuner;
break; break;
...@@ -1529,11 +1529,13 @@ static int dvb_input_attach(struct ddb_input *input) ...@@ -1529,11 +1529,13 @@ static int dvb_input_attach(struct ddb_input *input)
if (dvb->fe) { if (dvb->fe) {
if (dvb_register_frontend(adap, dvb->fe) < 0) if (dvb_register_frontend(adap, dvb->fe) < 0)
return -ENODEV; goto err_detach;
if (dvb->fe2) { if (dvb->fe2) {
if (dvb_register_frontend(adap, dvb->fe2) < 0) if (dvb_register_frontend(adap, dvb->fe2) < 0) {
return -ENODEV; dvb_unregister_frontend(dvb->fe);
goto err_detach;
}
dvb->fe2->tuner_priv = dvb->fe->tuner_priv; dvb->fe2->tuner_priv = dvb->fe->tuner_priv;
memcpy(&dvb->fe2->ops.tuner_ops, memcpy(&dvb->fe2->ops.tuner_ops,
&dvb->fe->ops.tuner_ops, &dvb->fe->ops.tuner_ops,
...@@ -1545,12 +1547,18 @@ static int dvb_input_attach(struct ddb_input *input) ...@@ -1545,12 +1547,18 @@ static int dvb_input_attach(struct ddb_input *input)
return 0; return 0;
err_tuner: err_tuner:
dev_warn(port->dev->dev, "tuner attach failed!\n"); dev_err(port->dev->dev, "tuner attach failed!\n");
if (dvb->fe2) if (dvb->fe2)
dvb_frontend_detach(dvb->fe2); dvb_frontend_detach(dvb->fe2);
if (dvb->fe) if (dvb->fe)
dvb_frontend_detach(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; return -ENODEV;
} }
...@@ -1981,8 +1989,8 @@ void ddb_ports_detach(struct ddb *dev) ...@@ -1981,8 +1989,8 @@ void ddb_ports_detach(struct ddb *dev)
switch (port->class) { switch (port->class) {
case DDB_PORT_TUNER: case DDB_PORT_TUNER:
dvb_input_detach(port->input[0]);
dvb_input_detach(port->input[1]); dvb_input_detach(port->input[1]);
dvb_input_detach(port->input[0]);
break; break;
case DDB_PORT_CI: case DDB_PORT_CI:
case DDB_PORT_LOOP: case DDB_PORT_LOOP:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment