[alsa-devel] [PATCH 3/3] ALSA: hda - hdmi: Notify userspace when ELD control changes
Takashi Iwai
tiwai at suse.de
Mon Feb 18 17:21:24 CET 2013
At Mon, 18 Feb 2013 17:08:36 +0100,
David Henningsson wrote:
>
> On 02/18/2013 04:14 PM, Takashi Iwai wrote:
> > At Mon, 18 Feb 2013 16:09:37 +0100,
> > David Henningsson wrote:
> >>
> >> On 02/18/2013 03:55 PM, Takashi Iwai wrote:
> >>> At Mon, 18 Feb 2013 15:46:04 +0100,
> >>> David Henningsson wrote:
> >>>>
> >>>> On 02/18/2013 03:41 PM, Takashi Iwai wrote:
> >>>>> At Mon, 18 Feb 2013 14:11:13 +0100,
> >>>>> David Henningsson wrote:
> >>>>>>
> >>>>>> Since ELD sometimes becomes available a while after we have detected
> >>>>>> presence, we need to be able to listen for changes on the ELD control.
> >>>>>>
> >>>>>> Signed-off-by: David Henningsson <david.henningsson at canonical.com>
> >>>>>> ---
> >>>>>> sound/pci/hda/patch_hdmi.c | 10 ++++++++++
> >>>>>> 1 file changed, 10 insertions(+)
> >>>>>>
> >>>>>> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> >>>>>> index 9236cdb..d3b1a93 100644
> >>>>>> --- a/sound/pci/hda/patch_hdmi.c
> >>>>>> +++ b/sound/pci/hda/patch_hdmi.c
> >>>>>> @@ -74,6 +74,7 @@ struct hdmi_spec_per_pin {
> >>>>>>
> >>>>>> struct hda_codec *codec;
> >>>>>> struct hdmi_eld sink_eld;
> >>>>>> + struct snd_kcontrol *eld_ctl;
> >>>>>> struct delayed_work work;
> >>>>>> int repoll_count;
> >>>>>> bool non_pcm;
> >>>>>> @@ -406,6 +407,7 @@ static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
> >>>>>> if (err < 0)
> >>>>>> return err;
> >>>>>>
> >>>>>> + spec->pins[pin_idx].eld_ctl = kctl;
> >>>>>> return 0;
> >>>>>> }
> >>>>>>
> >>>>>> @@ -1175,6 +1177,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
> >>>>>> */
> >>>>>> int present = snd_hda_pin_sense(codec, pin_nid);
> >>>>>> bool eld_valid = false;
> >>>>>> + bool old_eld_valid = eld->eld_valid;
> >>>>>>
> >>>>>> memset(eld, 0, offsetof(struct hdmi_eld, eld_buffer));
> >>>>>>
> >>>>>> @@ -1196,6 +1199,13 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
> >>>>>> msecs_to_jiffies(300));
> >>>>>> }
> >>>>>> }
> >>>>>> +
> >>>>>> + if (eld->eld_valid != old_eld_valid && per_pin->eld_ctl) {
> >>>>>> + snd_ctl_notify(codec->bus->card,
> >>>>>> + SNDRV_CTL_EVENT_MASK_VALUE | SNDRV_CTL_EVENT_MASK_INFO,
> >>>>>> + &per_pin->eld_ctl->id);
> >>>>>> + }
> >>>>>
> >>>>> This notification should be skipped when the pin sensing is requeued.
> >>>>
> >>>> I don't understand this comment. Are you referring to repolling the ELD?
> >>>
> >>> Yes.
> >>>
> >>>> eld->eld_valid is never set to TRUE when repoll happens.
> >>>
> >>> But old_eld_valid might be TRUE, and you cleared eld->eld_valid to
> >>> FALSE now before the actual probe result. Thus the check above passes
> >>> and sends a notification although the actual probe isn't done.
> >>
> >> If old_eld_valid is true, then we're talking about an unplug event. Why
> >> would there be a repoll when the monitor has disappeared?
> >>
> >> But yes, the patch is based on the fact that ELD info never actually
> >> changes from one valid state to another valid state, without being
> >> invalid in between. If you think that could actually happen, maybe I
> >> need to add a memory compare of the old and new ELDs?
> >
> > It'd be more robust, yes. We should take it into account that some
> > unsol events might be missing or wrongly delivered.
>
> The problem here is that there is no copy of the eld buffer. If we're
> talking about the - very hypothetical, I believe - case where we
> currently have valid eld data, and suddenly go into a repoll for some
> reason, the eld buffer might still have changed, e g if the mnl byte is
> wrong. Even if the lack of snd_ctl_notify makes it more unlikely that
> the temporary invalid ELD data will be read, there is still a chance
> that it will be.
>
> Do you think we should allocate a temporary struct hdmi_eld, and only
> copy over if successful? (And if so, on the stack or through kalloc?)
> That seems to me like the only choice if we want total consistency on
> the ELD bytes kcontrol.
This would be one option. Or, if sending the notification early
doesn't matter much for user-space, we should implement some locks
against the race, at least. Sending a notification before finishing
the whole read may trigger a race pretty easily.
Takashi
More information about the Alsa-devel
mailing list