Commit 99b5c5bb authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Remove the use of set_fs()

set_fs() is used in HD-audio vmaster code to retrieve the TLV data of
each slave kctl.  Since the slave is supposed to be a standard amp
kctl, we can call directly the supposed tlv callback instead of the
indirect call, so that we can remove the set_fs() hack.
Reviewed-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 3db9e970
...@@ -1477,18 +1477,8 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, ...@@ -1477,18 +1477,8 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
} }
EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put); EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put);
/** /* inquiry the amp caps and convert to TLV */
* snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume static void get_ctl_amp_tlv(struct snd_kcontrol *kcontrol, unsigned int *tlv)
* @kcontrol: ctl element
* @op_flag: operation flag
* @size: byte size of input TLV
* @_tlv: TLV data
*
* The control element is supposed to have the private_value field
* set up via HDA_COMPOSE_AMP_VAL*() or related macros.
*/
int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
unsigned int size, unsigned int __user *_tlv)
{ {
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = get_amp_nid(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol);
...@@ -1497,8 +1487,6 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, ...@@ -1497,8 +1487,6 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
bool min_mute = get_amp_min_mute(kcontrol); bool min_mute = get_amp_min_mute(kcontrol);
u32 caps, val1, val2; u32 caps, val1, val2;
if (size < 4 * sizeof(unsigned int))
return -ENOMEM;
caps = query_amp_caps(codec, nid, dir); caps = query_amp_caps(codec, nid, dir);
val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
val2 = (val2 + 1) * 25; val2 = (val2 + 1) * 25;
...@@ -1507,13 +1495,31 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, ...@@ -1507,13 +1495,31 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
val1 = ((int)val1) * ((int)val2); val1 = ((int)val1) * ((int)val2);
if (min_mute || (caps & AC_AMPCAP_MIN_MUTE)) if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
val2 |= TLV_DB_SCALE_MUTE; val2 |= TLV_DB_SCALE_MUTE;
if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) tlv[0] = SNDRV_CTL_TLVT_DB_SCALE;
return -EFAULT; tlv[1] = 2 * sizeof(unsigned int);
if (put_user(2 * sizeof(unsigned int), _tlv + 1)) tlv[2] = val1;
return -EFAULT; tlv[3] = val2;
if (put_user(val1, _tlv + 2)) }
return -EFAULT;
if (put_user(val2, _tlv + 3)) /**
* snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume
* @kcontrol: ctl element
* @op_flag: operation flag
* @size: byte size of input TLV
* @_tlv: TLV data
*
* The control element is supposed to have the private_value field
* set up via HDA_COMPOSE_AMP_VAL*() or related macros.
*/
int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
unsigned int size, unsigned int __user *_tlv)
{
unsigned int tlv[4];
if (size < 4 * sizeof(unsigned int))
return -ENOMEM;
get_ctl_amp_tlv(kcontrol, tlv);
if (copy_to_user(_tlv, tlv, sizeof(tlv)))
return -EFAULT; return -EFAULT;
return 0; return 0;
} }
...@@ -1807,13 +1813,10 @@ static int get_kctl_0dB_offset(struct hda_codec *codec, ...@@ -1807,13 +1813,10 @@ static int get_kctl_0dB_offset(struct hda_codec *codec,
const int *tlv = NULL; const int *tlv = NULL;
int val = -1; int val = -1;
if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { if ((kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) &&
/* FIXME: set_fs() hack for obtaining user-space TLV data */ kctl->tlv.c == snd_hda_mixer_amp_tlv) {
mm_segment_t fs = get_fs(); get_ctl_amp_tlv(kctl, _tlv);
set_fs(get_ds()); tlv = _tlv;
if (!kctl->tlv.c(kctl, 0, sizeof(_tlv), _tlv))
tlv = _tlv;
set_fs(fs);
} else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ) } else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
tlv = kctl->tlv.p; tlv = kctl->tlv.p;
if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) { if (tlv && tlv[0] == SNDRV_CTL_TLVT_DB_SCALE) {
......
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