patch-2.4.27 linux-2.4.27/drivers/sound/pss.c
Next file: linux-2.4.27/drivers/usb/audio.c
Previous file: linux-2.4.27/drivers/sound/msnd_pinnacle.c
Back to the patch index
Back to the overall index
- Lines: 173
- Date:
2004-08-07 16:26:05.562384087 -0700
- Orig file:
linux-2.4.26/drivers/sound/pss.c
- Orig date:
2002-11-28 15:53:14.000000000 -0800
diff -urN linux-2.4.26/drivers/sound/pss.c linux-2.4.27/drivers/sound/pss.c
@@ -450,20 +450,36 @@
}
}
-static void arg_to_volume_mono(unsigned int volume, int *aleft)
+static int set_volume_mono(caddr_t p, int *aleft)
{
int left;
+ unsigned volume;
+ if (get_user(volume, (unsigned *)p))
+ return -EFAULT;
- left = volume & 0x00ff;
+ left = volume & 0xff;
if (left > 100)
left = 100;
*aleft = left;
+ return 0;
}
-static void arg_to_volume_stereo(unsigned int volume, int *aleft, int *aright)
+static int set_volume_stereo(caddr_t p, int *aleft, int *aright)
{
- arg_to_volume_mono(volume, aleft);
- arg_to_volume_mono(volume >> 8, aright);
+ int left, right;
+ unsigned volume;
+ if (get_user(volume, (unsigned *)p))
+ return -EFAULT;
+
+ left = volume & 0xff;
+ if (left > 100)
+ left = 100;
+ right = (volume >> 8) & 0xff;
+ if (right > 100)
+ right = 100;
+ *aleft = left;
+ *aright = right;
+ return 0;
}
static int ret_vol_mono(int left)
@@ -510,33 +526,38 @@
return call_ad_mixer(devc, cmd, arg);
else
{
- if (*(int *)arg != 0)
+ int v;
+ if (get_user(v, (int *)arg))
+ return -EFAULT;
+ if (v != 0)
return -EINVAL;
return 0;
}
case SOUND_MIXER_VOLUME:
- arg_to_volume_stereo(*(unsigned int *)arg, &devc->mixer.volume_l,
- &devc->mixer.volume_r);
+ if (set_volume_stereo(arg,
+ &devc->mixer.volume_l,
+ &devc->mixer.volume_r))
+ return -EFAULT;
set_master_volume(devc, devc->mixer.volume_l,
devc->mixer.volume_r);
return ret_vol_stereo(devc->mixer.volume_l,
devc->mixer.volume_r);
case SOUND_MIXER_BASS:
- arg_to_volume_mono(*(unsigned int *)arg,
- &devc->mixer.bass);
+ if (set_volume_mono(arg, &devc->mixer.bass))
+ return -EFAULT;
set_bass(devc, devc->mixer.bass);
return ret_vol_mono(devc->mixer.bass);
case SOUND_MIXER_TREBLE:
- arg_to_volume_mono(*(unsigned int *)arg,
- &devc->mixer.treble);
+ if (set_volume_mono(arg, &devc->mixer.treble))
+ return -EFAULT;
set_treble(devc, devc->mixer.treble);
return ret_vol_mono(devc->mixer.treble);
case SOUND_MIXER_SYNTH:
- arg_to_volume_mono(*(unsigned int *)arg,
- &devc->mixer.synth);
+ if (set_volume_mono(arg, &devc->mixer.synth))
+ return -EFAULT;
set_synth_volume(devc, devc->mixer.synth);
return ret_vol_mono(devc->mixer.synth);
@@ -546,54 +567,67 @@
}
else
{
+ int val, and_mask = 0, or_mask = 0;
/*
* Return parameters
*/
switch (cmdf)
{
-
case SOUND_MIXER_DEVMASK:
if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
- *(int *)arg = 0; /* no mixer devices */
- return (*(int *)arg |= SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH);
+ break;
+ and_mask = ~0;
+ or_mask = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE | SOUND_MASK_SYNTH;
+ break;
case SOUND_MIXER_STEREODEVS:
if (call_ad_mixer(devc, cmd, arg) == -EINVAL)
- *(int *)arg = 0; /* no stereo devices */
- return (*(int *)arg |= SOUND_MASK_VOLUME);
+ break;
+ and_mask = ~0;
+ or_mask = SOUND_MASK_VOLUME;
+ break;
case SOUND_MIXER_RECMASK:
if (devc->ad_mixer_dev != NO_WSS_MIXER)
return call_ad_mixer(devc, cmd, arg);
- else
- return (*(int *)arg = 0); /* no record devices */
+ break;
case SOUND_MIXER_CAPS:
if (devc->ad_mixer_dev != NO_WSS_MIXER)
return call_ad_mixer(devc, cmd, arg);
- else
- return (*(int *)arg = SOUND_CAP_EXCL_INPUT);
+ or_mask = SOUND_CAP_EXCL_INPUT;
+ break;
case SOUND_MIXER_RECSRC:
if (devc->ad_mixer_dev != NO_WSS_MIXER)
return call_ad_mixer(devc, cmd, arg);
- else
- return (*(int *)arg = 0); /* no record source */
+ break;
case SOUND_MIXER_VOLUME:
- return (*(int *)arg = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r));
+ or_mask = ret_vol_stereo(devc->mixer.volume_l, devc->mixer.volume_r);
+ break;
case SOUND_MIXER_BASS:
- return (*(int *)arg = ret_vol_mono(devc->mixer.bass));
+ or_mask = ret_vol_mono(devc->mixer.bass);
+ break;
case SOUND_MIXER_TREBLE:
- return (*(int *)arg = ret_vol_mono(devc->mixer.treble));
+ or_mask = ret_vol_mono(devc->mixer.treble);
+ break;
case SOUND_MIXER_SYNTH:
- return (*(int *)arg = ret_vol_mono(devc->mixer.synth));
+ or_mask = ret_vol_mono(devc->mixer.synth);
+ break;
default:
return -EINVAL;
}
+ if (get_user(val, (int *)arg))
+ return -EFAULT;
+ val &= and_mask;
+ val |= or_mask;
+ if (put_user(val, (int *)arg))
+ return -EFAULT;
+ return val;
}
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)