On 2 Jan 2015, at 4:15 pm, David Gwynne <da...@gwynne.id.au> wrote:

> can someone test this?
> 
> it allocates storage for the volume change details rather than cast
> arguments to a single global task.
> 
> adds some safety while there if audio0 is a hotplug device.
> 
> ok?

The keyboard audio controls on my X120e following -current work
same as before with this diff applied.

> 
> Index: audio.c
> ===================================================================
> RCS file: /cvs/src/sys/dev/audio.c,v
> retrieving revision 1.125
> diff -u -p -r1.125 audio.c
> --- audio.c   19 Dec 2014 22:44:58 -0000      1.125
> +++ audio.c   2 Jan 2015 06:08:39 -0000
> @@ -465,11 +465,6 @@ audioattach(struct device *parent, struc
>       }
>       DPRINTF(("audio_attach: inputs ports=0x%x, output ports=0x%x\n",
>                sc->sc_inports.allports, sc->sc_outports.allports));
> -
> -#if NWSKBD > 0
> -     task_set(&sc->sc_mixer_task, wskbd_set_mixervolume_callback, NULL,
> -         NULL);
> -#endif /* NWSKBD > 0 */
> }
> 
> int
> @@ -3432,27 +3427,39 @@ filt_audiowrite(struct knote *kn, long h
> }
> 
> #if NWSKBD > 0
> +struct wskbd_vol_change {
> +     struct task t;
> +     long dir;
> +     long out;
> +};
> +
> int
> wskbd_set_mixervolume(long dir, long out)
> {
>       struct audio_softc *sc;
> +     struct wskbd_vol_change *ch;
> 
>       if (audio_cd.cd_ndevs == 0 || (sc = audio_cd.cd_devs[0]) == NULL) {
>               DPRINTF(("wskbd_set_mixervolume: audio_cd\n"));
>               return (ENXIO);
>       }
> 
> -     task_del(systq, &sc->sc_mixer_task);
> -     task_set(&sc->sc_mixer_task, wskbd_set_mixervolume_callback,
> -         (void *)dir, (void *)out);
> -     task_add(systq, &sc->sc_mixer_task);
> +     ch = malloc(sizeof(*ch), M_TEMP, M_NOWAIT);
> +     if (ch == NULL)
> +             return (ENOMEM);
> +
> +     task_set(&ch->t, wskbd_set_mixervolume_callback, ch, NULL);
> +     ch->dir = dir;
> +     ch->out = out;
> +     task_add(systq, &ch->t);
> 
>       return (0);
> }
> 
> void
> -wskbd_set_mixervolume_callback(void *arg1, void *arg2)
> +wskbd_set_mixervolume_callback(void *xch, void *null)
> {
> +     struct wskbd_vol_change *ch = xch;
>       struct audio_softc *sc;
>       struct au_mixer_ports *ports;
>       mixer_devinfo_t mi;
> @@ -3461,19 +3468,19 @@ wskbd_set_mixervolume_callback(void *arg
>       u_int gain;
>       int error;
> 
> -     if (audio_cd.cd_ndevs == 0 || (sc = audio_cd.cd_devs[0]) == NULL) {
> -             DPRINTF(("%s: audio_cd\n", __func__));
> -             return;
> -     }
> +     dir = ch->dir;
> +     out = ch->out;
> +     free(ch, M_TEMP, sizeof(*ch));
> 
> -     dir = (long)arg1;
> -     out = (long)arg2;
> +     sc = (struct audio_softc *)device_lookup(&audio_cd, 0);
> +     if (sc == NULL)
> +             return;
> 
>       ports = out ? &sc->sc_outports : &sc->sc_inports;
> 
>       if (ports->master == -1) {
>               DPRINTF(("%s: master == -1\n", __func__));
> -             return;
> +             goto done;
>       }
> 
>       if (dir == 0) {
> @@ -3482,7 +3489,7 @@ wskbd_set_mixervolume_callback(void *arg
>               error = au_get_mute(sc, ports, &mute);
>               if (error != 0) {
>                       DPRINTF(("%s: au_get_mute: %d\n", __func__, error));
> -                     return;
> +                     goto done;
>               }
> 
>               mute = !mute;
> @@ -3490,7 +3497,7 @@ wskbd_set_mixervolume_callback(void *arg
>               error = au_set_mute(sc, ports, mute);
>               if (error != 0) {
>                       DPRINTF(("%s: au_set_mute: %d\n", __func__, error));
> -                     return;
> +                     goto done;
>               }
>       } else {
>               /* Raise or lower volume */
> @@ -3499,7 +3506,7 @@ wskbd_set_mixervolume_callback(void *arg
>               error = sc->hw_if->query_devinfo(sc->hw_hdl, &mi);
>               if (error != 0) {
>                       DPRINTF(("%s: query_devinfo: %d\n", __func__, error));
> -                     return;
> +                     goto done;
>               }
> 
>               au_get_gain(sc, ports, &gain, &balance);
> @@ -3512,8 +3519,11 @@ wskbd_set_mixervolume_callback(void *arg
>               error = au_set_gain(sc, ports, gain, balance);
>               if (error != 0) {
>                       DPRINTF(("%s: au_set_gain: %d\n", __func__, error));
> -                     return;
> +                     goto done;
>               }
>       }
> +
> +done:
> +     device_unref(&sc->dev);
> }
> #endif /* NWSKBD > 0 */


Reply via email to