Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 143381
b: refs/heads/master
c: 83b2086
h: refs/heads/master
i:
  143379: 91fe78f
v: v3
  • Loading branch information
Justin Mattock authored and Takashi Iwai committed Apr 15, 2009
1 parent 9c49e4f commit b97485e
Show file tree
Hide file tree
Showing 30 changed files with 268 additions and 266 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f4723b224d21ff546ac1fea4483094548d529479
refs/heads/master: 83b2086ce2a1458168dc8b9d624060b2d7a82d4c
4 changes: 2 additions & 2 deletions trunk/Documentation/sound/alsa/HD-Audio.txt
Original file line number Diff line number Diff line change
Expand Up @@ -169,15 +169,15 @@ PCI SSID look-up.
What `model` option values are available depends on the codec chip.
Check your codec chip from the codec proc file (see "Codec Proc-File"
section below). It will show the vendor/product name of your codec
chip. Then, see Documentation/sound/alsa/HD-Audio-Modelstxt file,
chip. Then, see Documentation/sound/alsa/HD-Audio-Models.txt file,
the section of HD-audio driver. You can find a list of codecs
and `model` options belonging to each codec. For example, for Realtek
ALC262 codec chip, pass `model=ultra` for devices that are compatible
with Samsung Q1 Ultra.

Thus, the first thing you can do for any brand-new, unsupported and
non-working HD-audio hardware is to check HD-audio codec and several
different `model` option values. If you have a luck, some of them
different `model` option values. If you have any luck, some of them
might suit with your device well.

Some codecs such as ALC880 have a special model option `model=test`.
Expand Down
3 changes: 1 addition & 2 deletions trunk/include/sound/pcm.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,7 @@ struct snd_pcm_runtime {
int overrange;
snd_pcm_uframes_t avail_max;
snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time*/

/* -- HW params -- */
snd_pcm_access_t access; /* access mode */
Expand Down
35 changes: 22 additions & 13 deletions trunk/sound/core/control.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,11 +723,14 @@ static int snd_ctl_elem_read_user(struct snd_card *card,
{
struct snd_ctl_elem_value *control;
int result;

control = memdup_user(_control, sizeof(*control));
if (IS_ERR(control))
return PTR_ERR(control);


control = kmalloc(sizeof(*control), GFP_KERNEL);
if (control == NULL)
return -ENOMEM;
if (copy_from_user(control, _control, sizeof(*control))) {
kfree(control);
return -EFAULT;
}
snd_power_lock(card);
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
if (result >= 0)
Expand Down Expand Up @@ -781,10 +784,13 @@ static int snd_ctl_elem_write_user(struct snd_ctl_file *file,
struct snd_card *card;
int result;

control = memdup_user(_control, sizeof(*control));
if (IS_ERR(control))
return PTR_ERR(control);

control = kmalloc(sizeof(*control), GFP_KERNEL);
if (control == NULL)
return -ENOMEM;
if (copy_from_user(control, _control, sizeof(*control))) {
kfree(control);
return -EFAULT;
}
card = file->card;
snd_power_lock(card);
result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
Expand Down Expand Up @@ -910,10 +916,13 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol,
if (op_flag > 0) {
if (size > 1024 * 128) /* sane value */
return -EINVAL;

new_data = memdup_user(tlv, size);
if (IS_ERR(new_data))
return PTR_ERR(new_data);
new_data = kmalloc(size, GFP_KERNEL);
if (new_data == NULL)
return -ENOMEM;
if (copy_from_user(new_data, tlv, size)) {
kfree(new_data);
return -EFAULT;
}
change = ue->tlv_data_size != size;
if (!change)
change = memcmp(ue->tlv_data, new_data, size);
Expand Down
11 changes: 7 additions & 4 deletions trunk/sound/core/pcm_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,14 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
if (! (runtime = substream->runtime))
return -ENOTTY;

data = kmalloc(sizeof(*data), GFP_KERNEL);
if (data == NULL)
return -ENOMEM;
/* only fifo_size is different, so just copy all */
data = memdup_user(data32, sizeof(*data32));
if (IS_ERR(data))
return PTR_ERR(data);

if (copy_from_user(data, data32, sizeof(*data32))) {
err = -EFAULT;
goto error;
}
if (refine)
err = snd_pcm_hw_refine(substream, data);
else
Expand Down
47 changes: 8 additions & 39 deletions trunk/sound/core/pcm_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,9 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_uframes_t pos;
snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_ptr_interrupt, hw_base;
snd_pcm_sframes_t hdelta, delta;
unsigned long jdelta;
snd_pcm_uframes_t new_hw_ptr, hw_ptr_interrupt, hw_base;
snd_pcm_sframes_t delta;

old_hw_ptr = runtime->status->hw_ptr;
pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
if (pos == SNDRV_PCM_POS_XRUN) {
xrun(substream);
Expand Down Expand Up @@ -249,30 +247,7 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)
new_hw_ptr = hw_base + pos;
}
}
hdelta = new_hw_ptr - old_hw_ptr;
jdelta = jiffies - runtime->hw_ptr_jiffies;
if (((hdelta * HZ) / runtime->rate) > jdelta + HZ/100) {
delta = jdelta /
(((runtime->period_size * HZ) / runtime->rate)
+ HZ/100);
hw_ptr_error(substream,
"hw_ptr skipping! [Q] "
"(pos=%ld, delta=%ld, period=%ld, "
"jdelta=%lu/%lu/%lu)\n",
(long)pos, (long)hdelta,
(long)runtime->period_size, jdelta,
((hdelta * HZ) / runtime->rate), delta);
hw_ptr_interrupt = runtime->hw_ptr_interrupt +
runtime->period_size * delta;
if (hw_ptr_interrupt >= runtime->boundary)
hw_ptr_interrupt -= runtime->boundary;
/* rebase to interrupt position */
hw_base = new_hw_ptr = hw_ptr_interrupt;
/* align hw_base to buffer_size */
hw_base -= hw_base % runtime->buffer_size;
delta = 0;
}
if (delta > runtime->period_size + runtime->period_size / 2) {
if (delta > runtime->period_size) {
hw_ptr_error(substream,
"Lost interrupts? "
"(stream=%i, delta=%ld, intr_ptr=%ld)\n",
Expand All @@ -288,7 +263,6 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream)

runtime->hw_ptr_base = hw_base;
runtime->status->hw_ptr = new_hw_ptr;
runtime->hw_ptr_jiffies = jiffies;
runtime->hw_ptr_interrupt = hw_ptr_interrupt;

return snd_pcm_update_hw_ptr_post(substream, runtime);
Expand All @@ -301,7 +275,6 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
snd_pcm_uframes_t pos;
snd_pcm_uframes_t old_hw_ptr, new_hw_ptr, hw_base;
snd_pcm_sframes_t delta;
unsigned long jdelta;

old_hw_ptr = runtime->status->hw_ptr;
pos = snd_pcm_update_hw_ptr_pos(substream, runtime);
Expand All @@ -313,29 +286,27 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
new_hw_ptr = hw_base + pos;

delta = new_hw_ptr - old_hw_ptr;
jdelta = jiffies - runtime->hw_ptr_jiffies;
if (delta < 0) {
delta += runtime->buffer_size;
if (delta < 0) {
hw_ptr_error(substream,
"Unexpected hw_pointer value [2] "
"(stream=%i, pos=%ld, old_ptr=%ld, jdelta=%li)\n",
"(stream=%i, pos=%ld, old_ptr=%ld)\n",
substream->stream, (long)pos,
(long)old_hw_ptr, jdelta);
(long)old_hw_ptr);
return 0;
}
hw_base += runtime->buffer_size;
if (hw_base >= runtime->boundary)
hw_base = 0;
new_hw_ptr = hw_base + pos;
}
if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) {
if (delta > runtime->period_size && runtime->periods > 1) {
hw_ptr_error(substream,
"hw_ptr skipping! "
"(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n",
"(pos=%ld, delta=%ld, period=%ld)\n",
(long)pos, (long)delta,
(long)runtime->period_size, jdelta,
((delta * HZ) / runtime->rate));
(long)runtime->period_size);
return 0;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
Expand All @@ -344,7 +315,6 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)

runtime->hw_ptr_base = hw_base;
runtime->status->hw_ptr = new_hw_ptr;
runtime->hw_ptr_jiffies = jiffies;

return snd_pcm_update_hw_ptr_post(substream, runtime);
}
Expand Down Expand Up @@ -1471,7 +1441,6 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream,
runtime->status->hw_ptr %= runtime->buffer_size;
else
runtime->status->hw_ptr = 0;
runtime->hw_ptr_jiffies = jiffies;
snd_pcm_stream_unlock_irqrestore(substream, flags);
return 0;
}
Expand Down
93 changes: 58 additions & 35 deletions trunk/sound/core/pcm_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,16 +327,21 @@ static int snd_pcm_hw_refine_user(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params;
int err;

params = memdup_user(_params, sizeof(*params));
if (IS_ERR(params))
return PTR_ERR(params);

params = kmalloc(sizeof(*params), GFP_KERNEL);
if (!params) {
err = -ENOMEM;
goto out;
}
if (copy_from_user(params, _params, sizeof(*params))) {
err = -EFAULT;
goto out;
}
err = snd_pcm_hw_refine(substream, params);
if (copy_to_user(_params, params, sizeof(*params))) {
if (!err)
err = -EFAULT;
}

out:
kfree(params);
return err;
}
Expand Down Expand Up @@ -460,16 +465,21 @@ static int snd_pcm_hw_params_user(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params;
int err;

params = memdup_user(_params, sizeof(*params));
if (IS_ERR(params))
return PTR_ERR(params);

params = kmalloc(sizeof(*params), GFP_KERNEL);
if (!params) {
err = -ENOMEM;
goto out;
}
if (copy_from_user(params, _params, sizeof(*params))) {
err = -EFAULT;
goto out;
}
err = snd_pcm_hw_params(substream, params);
if (copy_to_user(_params, params, sizeof(*params))) {
if (!err)
err = -EFAULT;
}

out:
kfree(params);
return err;
}
Expand Down Expand Up @@ -2583,11 +2593,13 @@ static int snd_pcm_playback_ioctl1(struct file *file,
return -EFAULT;
if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
return -EFAULT;

bufs = memdup_user(xfern.bufs,
sizeof(void *) * runtime->channels);
if (IS_ERR(bufs))
return PTR_ERR(bufs);
bufs = kmalloc(sizeof(void *) * runtime->channels, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
if (copy_from_user(bufs, xfern.bufs, sizeof(void *) * runtime->channels)) {
kfree(bufs);
return -EFAULT;
}
result = snd_pcm_lib_writev(substream, bufs, xfern.frames);
kfree(bufs);
__put_user(result, &_xfern->result);
Expand Down Expand Up @@ -2663,11 +2675,13 @@ static int snd_pcm_capture_ioctl1(struct file *file,
return -EFAULT;
if (copy_from_user(&xfern, _xfern, sizeof(xfern)))
return -EFAULT;

bufs = memdup_user(xfern.bufs,
sizeof(void *) * runtime->channels);
if (IS_ERR(bufs))
return PTR_ERR(bufs);
bufs = kmalloc(sizeof(void *) * runtime->channels, GFP_KERNEL);
if (bufs == NULL)
return -ENOMEM;
if (copy_from_user(bufs, xfern.bufs, sizeof(void *) * runtime->channels)) {
kfree(bufs);
return -EFAULT;
}
result = snd_pcm_lib_readv(substream, bufs, xfern.frames);
kfree(bufs);
__put_user(result, &_xfern->result);
Expand Down Expand Up @@ -3298,12 +3312,18 @@ static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
int err;

params = kmalloc(sizeof(*params), GFP_KERNEL);
if (!params)
return -ENOMEM;
if (!params) {
err = -ENOMEM;
goto out;
}
oparams = kmalloc(sizeof(*oparams), GFP_KERNEL);
if (!oparams) {
err = -ENOMEM;
goto out;
}

oparams = memdup_user(_oparams, sizeof(*oparams));
if (IS_ERR(oparams)) {
err = PTR_ERR(oparams);
if (copy_from_user(oparams, _oparams, sizeof(*oparams))) {
err = -EFAULT;
goto out;
}
snd_pcm_hw_convert_from_old_params(params, oparams);
Expand All @@ -3313,10 +3333,9 @@ static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream,
if (!err)
err = -EFAULT;
}

kfree(oparams);
out:
kfree(params);
kfree(oparams);
return err;
}

Expand All @@ -3328,12 +3347,17 @@ static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
int err;

params = kmalloc(sizeof(*params), GFP_KERNEL);
if (!params)
return -ENOMEM;

oparams = memdup_user(_oparams, sizeof(*oparams));
if (IS_ERR(oparams)) {
err = PTR_ERR(oparams);
if (!params) {
err = -ENOMEM;
goto out;
}
oparams = kmalloc(sizeof(*oparams), GFP_KERNEL);
if (!oparams) {
err = -ENOMEM;
goto out;
}
if (copy_from_user(oparams, _oparams, sizeof(*oparams))) {
err = -EFAULT;
goto out;
}
snd_pcm_hw_convert_from_old_params(params, oparams);
Expand All @@ -3343,10 +3367,9 @@ static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream,
if (!err)
err = -EFAULT;
}

kfree(oparams);
out:
kfree(params);
kfree(oparams);
return err;
}
#endif /* CONFIG_SND_SUPPORT_OLD_API */
Expand Down
Loading

0 comments on commit b97485e

Please sign in to comment.