[linux-dvb] af9005/mt2060 module unload failure

Trent Piepho xyzzy at speakeasy.org
Fri Jun 15 00:42:30 CEST 2007


On Fri, 15 Jun 2007, Luca Olivetti wrote:
> >>> In af9005_fe_set_frontend(), you do this:
> >>>         ret = state->tuner->ops.tuner_ops.set_params(state->tuner, fep);
> >>>
> >>> What you should do is:
> >>>     ret = fe->ops.tuner_ops.set_params(state->tuner, fep);
> >>>
> >>> I don't think you need the state->tuner field really.  Just replace
> >>> all the
> >>> "state->tuner->ops..." with "fe->ops...".  And change (state->tuner
> >>> != NULL)
> >>> to (fe->ops.tuner_ops.release != NULL), or add a one bit flag
> >>> state->tuner_is_attached and use that.
> >> Ok, that could be an idea, but it wouldn't explain why my
> >> symbol_put_addr messes up the reference count, while the same exact
> >> thing done in dvb_frontend_detach wouldn't.
> >>
> >> Bye
> > It does explain it -- dvb_frontend_detach is running _and_ your code
> > that calls symbol_put_addr is also running.  With both of them
> > occurring, this explains the module ref count being screwed up.
>
> dvb_frontend_detach calls fe->ops.release, which is af9005_release,
> which, before returning, does the symbol_put_addr, at the same time that
>   dvb_frontend_detach would do it if it had a fe->ops.tuner_ops.release,

But dvb_frontend_detach _does_ have fe->ops.tuner_ops.release().

> so, frankly, though at the time it cost me a lot of time to untangle the
> indirections, I don't see the difference.
> I.e:
>
> with fe->ops.tuner_ops.release not null the sequence is:
>
> -->in dvb_frontend_detach
>    symbol_put_addr(fe->ops.tuner_ops.release);
>    symbol_put_addr(ptr)  (where ptr is a copy of fe)
>
> while in my code the sequence is
>
> -->in af9005_release
>    symbol_put_addr(fe->demodulator_priv->tuner_ops.release);
> -->in dvb_frontend_detach
>    symbol_put_addr(ptr)

Nope, your code is doing it like this:

dvb_frontend_detach(fe)
     fe->ops.tuner_ops.release() -> mt2060_release()
     symbol_put_addr(fe->ops.tuner_ops.release == mt2060_release)
     fe->ops.release() -> af9005_fe_release()
         symbol_put_addr(fe->demodulator_priv->tuner_ops.release == mt2060_release)
     symbol_put_addr(fe->ops.release == af9005_fe_release)



More information about the linux-dvb mailing list