diff options
author | Luca Olivetti <luca@ventoso.org> | 2007-07-27 09:27:47 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-07-30 15:26:36 -0400 |
commit | 639ffd2d9038d34725b752147a0f1a8536146851 (patch) | |
tree | f091a555d5d675a2f3b9a6269ee9ac6d8df0688a /drivers/media/dvb/dvb-usb | |
parent | be9a5c7d9a04349c137610c72e3a74a5352dccf5 (diff) |
V4L/DVB (5932): Af9005 fix tuner module unload
This patch removes the useless tuner field and avoids a double free of
the tuner (either mt2060 or qt1010).
Signed-off-by: Luca Olivetti <luca@ventoso.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9005-fe.c | 37 |
1 files changed, 12 insertions, 25 deletions
diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c index 7195c9461524..6809c6024d46 100644 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c | |||
@@ -29,8 +29,6 @@ | |||
29 | 29 | ||
30 | struct af9005_fe_state { | 30 | struct af9005_fe_state { |
31 | struct dvb_usb_device *d; | 31 | struct dvb_usb_device *d; |
32 | struct dvb_frontend *tuner; | ||
33 | |||
34 | fe_status_t stat; | 32 | fe_status_t stat; |
35 | 33 | ||
36 | /* retraining parameters */ | 34 | /* retraining parameters */ |
@@ -447,7 +445,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) | |||
447 | u8 temp; | 445 | u8 temp; |
448 | int ret; | 446 | int ret; |
449 | 447 | ||
450 | if (state->tuner == NULL) | 448 | if (fe->ops.tuner_ops.release == NULL) |
451 | return -ENODEV; | 449 | return -ENODEV; |
452 | 450 | ||
453 | *stat = 0; | 451 | *stat = 0; |
@@ -493,7 +491,7 @@ static int af9005_fe_read_status(struct dvb_frontend *fe, fe_status_t * stat) | |||
493 | static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) | 491 | static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) |
494 | { | 492 | { |
495 | struct af9005_fe_state *state = fe->demodulator_priv; | 493 | struct af9005_fe_state *state = fe->demodulator_priv; |
496 | if (state->tuner == NULL) | 494 | if (fe->ops.tuner_ops.release == NULL) |
497 | return -ENODEV; | 495 | return -ENODEV; |
498 | af9005_fe_refresh_state(fe); | 496 | af9005_fe_refresh_state(fe); |
499 | *ber = state->ber; | 497 | *ber = state->ber; |
@@ -503,7 +501,7 @@ static int af9005_fe_read_ber(struct dvb_frontend *fe, u32 * ber) | |||
503 | static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) | 501 | static int af9005_fe_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) |
504 | { | 502 | { |
505 | struct af9005_fe_state *state = fe->demodulator_priv; | 503 | struct af9005_fe_state *state = fe->demodulator_priv; |
506 | if (state->tuner == NULL) | 504 | if (fe->ops.tuner_ops.release == NULL) |
507 | return -ENODEV; | 505 | return -ENODEV; |
508 | af9005_fe_refresh_state(fe); | 506 | af9005_fe_refresh_state(fe); |
509 | *unc = state->unc; | 507 | *unc = state->unc; |
@@ -517,7 +515,7 @@ static int af9005_fe_read_signal_strength(struct dvb_frontend *fe, | |||
517 | int ret; | 515 | int ret; |
518 | u8 if_gain, rf_gain; | 516 | u8 if_gain, rf_gain; |
519 | 517 | ||
520 | if (state->tuner == NULL) | 518 | if (fe->ops.tuner_ops.release == NULL) |
521 | return -ENODEV; | 519 | return -ENODEV; |
522 | ret = | 520 | ret = |
523 | af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain, | 521 | af9005_read_ofdm_register(state->d, xd_r_reg_aagc_rf_gain, |
@@ -1041,7 +1039,7 @@ static int af9005_fe_init(struct dvb_frontend *fe) | |||
1041 | return ret; | 1039 | return ret; |
1042 | 1040 | ||
1043 | /* attach tuner and init */ | 1041 | /* attach tuner and init */ |
1044 | if (state->tuner == NULL) { | 1042 | if (fe->ops.tuner_ops.release == NULL) { |
1045 | /* read tuner and board id from eeprom */ | 1043 | /* read tuner and board id from eeprom */ |
1046 | ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); | 1044 | ret = af9005_read_eeprom(adap->dev, 0xc6, buf, 2); |
1047 | if (ret) { | 1045 | if (ret) { |
@@ -1058,20 +1056,16 @@ static int af9005_fe_init(struct dvb_frontend *fe) | |||
1058 | return ret; | 1056 | return ret; |
1059 | } | 1057 | } |
1060 | if1 = (u16) (buf[0] << 8) + buf[1]; | 1058 | if1 = (u16) (buf[0] << 8) + buf[1]; |
1061 | state->tuner = | 1059 | if (dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, |
1062 | dvb_attach(mt2060_attach, fe, &adap->dev->i2c_adap, | 1060 | &af9005_mt2060_config, if1) == NULL) { |
1063 | &af9005_mt2060_config, if1); | ||
1064 | if (state->tuner == NULL) { | ||
1065 | deb_info("MT2060 attach failed\n"); | 1061 | deb_info("MT2060 attach failed\n"); |
1066 | return -ENODEV; | 1062 | return -ENODEV; |
1067 | } | 1063 | } |
1068 | break; | 1064 | break; |
1069 | case 3: /* QT1010 */ | 1065 | case 3: /* QT1010 */ |
1070 | case 9: /* QT1010B */ | 1066 | case 9: /* QT1010B */ |
1071 | state->tuner = | 1067 | if (dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, |
1072 | dvb_attach(qt1010_attach, fe, &adap->dev->i2c_adap, | 1068 | &af9005_qt1010_config) ==NULL) { |
1073 | &af9005_qt1010_config); | ||
1074 | if (state->tuner == NULL) { | ||
1075 | deb_info("QT1010 attach failed\n"); | 1069 | deb_info("QT1010 attach failed\n"); |
1076 | return -ENODEV; | 1070 | return -ENODEV; |
1077 | } | 1071 | } |
@@ -1080,7 +1074,7 @@ static int af9005_fe_init(struct dvb_frontend *fe) | |||
1080 | err("Unsupported tuner type %d", buf[0]); | 1074 | err("Unsupported tuner type %d", buf[0]); |
1081 | return -ENODEV; | 1075 | return -ENODEV; |
1082 | } | 1076 | } |
1083 | ret = state->tuner->ops.tuner_ops.init(state->tuner); | 1077 | ret = fe->ops.tuner_ops.init(fe); |
1084 | if (ret) | 1078 | if (ret) |
1085 | return ret; | 1079 | return ret; |
1086 | } | 1080 | } |
@@ -1118,7 +1112,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, | |||
1118 | 1112 | ||
1119 | deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, | 1113 | deb_info("af9005_fe_set_frontend freq %d bw %d\n", fep->frequency, |
1120 | fep->u.ofdm.bandwidth); | 1114 | fep->u.ofdm.bandwidth); |
1121 | if (state->tuner == NULL) { | 1115 | if (fe->ops.tuner_ops.release == NULL) { |
1122 | err("Tuner not attached"); | 1116 | err("Tuner not attached"); |
1123 | return -ENODEV; | 1117 | return -ENODEV; |
1124 | } | 1118 | } |
@@ -1199,7 +1193,7 @@ static int af9005_fe_set_frontend(struct dvb_frontend *fe, | |||
1199 | return ret; | 1193 | return ret; |
1200 | /* set tuner */ | 1194 | /* set tuner */ |
1201 | deb_info("set tuner\n"); | 1195 | deb_info("set tuner\n"); |
1202 | ret = state->tuner->ops.tuner_ops.set_params(state->tuner, fep); | 1196 | ret = fe->ops.tuner_ops.set_params(fe, fep); |
1203 | if (ret) | 1197 | if (ret) |
1204 | return ret; | 1198 | return ret; |
1205 | 1199 | ||
@@ -1435,12 +1429,6 @@ static void af9005_fe_release(struct dvb_frontend *fe) | |||
1435 | { | 1429 | { |
1436 | struct af9005_fe_state *state = | 1430 | struct af9005_fe_state *state = |
1437 | (struct af9005_fe_state *)fe->demodulator_priv; | 1431 | (struct af9005_fe_state *)fe->demodulator_priv; |
1438 | if (state->tuner != NULL && state->tuner->ops.tuner_ops.release != NULL) { | ||
1439 | state->tuner->ops.tuner_ops.release(state->tuner); | ||
1440 | #ifdef CONFIG_DVB_CORE_ATTACH | ||
1441 | symbol_put_addr(state->tuner->ops.tuner_ops.release); | ||
1442 | #endif | ||
1443 | } | ||
1444 | kfree(state); | 1432 | kfree(state); |
1445 | } | 1433 | } |
1446 | 1434 | ||
@@ -1458,7 +1446,6 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) | |||
1458 | deb_info("attaching frontend af9005\n"); | 1446 | deb_info("attaching frontend af9005\n"); |
1459 | 1447 | ||
1460 | state->d = d; | 1448 | state->d = d; |
1461 | state->tuner = NULL; | ||
1462 | state->opened = 0; | 1449 | state->opened = 0; |
1463 | 1450 | ||
1464 | memcpy(&state->frontend.ops, &af9005_fe_ops, | 1451 | memcpy(&state->frontend.ops, &af9005_fe_ops, |