diff options
author | Takashi Iwai <tiwai@suse.de> | 2014-04-08 10:58:34 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-04-08 10:58:34 -0400 |
commit | 4f8e940095536bc002a81666a4107a581c84e9b9 (patch) | |
tree | ac00fa04d730f553a397a1aa93e9b035cd01da47 /sound | |
parent | dcb32ecd9a533f47ab652c5c5680bc50a7a822cd (diff) |
ALSA: ice1712: Fix boundary checks in PCM pointer ops
PCM pointer callbacks in ice1712 driver check the buffer size boundary
wrongly between bytes and frames. This leads to PCM core warnings
like:
snd_pcm_update_hw_ptr0: 105 callbacks suppressed
ALSA pcm_lib.c:352 BUG: pcmC3D0c:0, pos = 5461, buffer size = 5461, period size = 2730
This patch fixes these checks to be placed after the proper unit
conversions.
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/ice1712/ice1712.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index da005493f060..d9b9e4595f17 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -685,9 +685,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pointer(struct snd_pcm_substream * | |||
685 | if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1)) | 685 | if (!(snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL) & 1)) |
686 | return 0; | 686 | return 0; |
687 | ptr = runtime->buffer_size - inw(ice->ddma_port + 4); | 687 | ptr = runtime->buffer_size - inw(ice->ddma_port + 4); |
688 | ptr = bytes_to_frames(substream->runtime, ptr); | ||
688 | if (ptr == runtime->buffer_size) | 689 | if (ptr == runtime->buffer_size) |
689 | ptr = 0; | 690 | ptr = 0; |
690 | return bytes_to_frames(substream->runtime, ptr); | 691 | return ptr; |
691 | } | 692 | } |
692 | 693 | ||
693 | static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream) | 694 | static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substream *substream) |
@@ -704,9 +705,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_ds_pointer(struct snd_pcm_substrea | |||
704 | addr = ICE1712_DSC_ADDR0; | 705 | addr = ICE1712_DSC_ADDR0; |
705 | ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) - | 706 | ptr = snd_ice1712_ds_read(ice, substream->number * 2, addr) - |
706 | ice->playback_con_virt_addr[substream->number]; | 707 | ice->playback_con_virt_addr[substream->number]; |
708 | ptr = bytes_to_frames(substream->runtime, ptr); | ||
707 | if (ptr == substream->runtime->buffer_size) | 709 | if (ptr == substream->runtime->buffer_size) |
708 | ptr = 0; | 710 | ptr = 0; |
709 | return bytes_to_frames(substream->runtime, ptr); | 711 | return ptr; |
710 | } | 712 | } |
711 | 713 | ||
712 | static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream) | 714 | static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *substream) |
@@ -717,9 +719,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s | |||
717 | if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1)) | 719 | if (!(snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL) & 1)) |
718 | return 0; | 720 | return 0; |
719 | ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr; | 721 | ptr = inl(ICEREG(ice, CONCAP_ADDR)) - ice->capture_con_virt_addr; |
722 | ptr = bytes_to_frames(substream->runtime, ptr); | ||
720 | if (ptr == substream->runtime->buffer_size) | 723 | if (ptr == substream->runtime->buffer_size) |
721 | ptr = 0; | 724 | ptr = 0; |
722 | return bytes_to_frames(substream->runtime, ptr); | 725 | return ptr; |
723 | } | 726 | } |
724 | 727 | ||
725 | static const struct snd_pcm_hardware snd_ice1712_playback = { | 728 | static const struct snd_pcm_hardware snd_ice1712_playback = { |
@@ -1116,9 +1119,10 @@ static snd_pcm_uframes_t snd_ice1712_playback_pro_pointer(struct snd_pcm_substre | |||
1116 | if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START)) | 1119 | if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_PLAYBACK_START)) |
1117 | return 0; | 1120 | return 0; |
1118 | ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2); | 1121 | ptr = ice->playback_pro_size - (inw(ICEMT(ice, PLAYBACK_SIZE)) << 2); |
1122 | ptr = bytes_to_frames(substream->runtime, ptr); | ||
1119 | if (ptr == substream->runtime->buffer_size) | 1123 | if (ptr == substream->runtime->buffer_size) |
1120 | ptr = 0; | 1124 | ptr = 0; |
1121 | return bytes_to_frames(substream->runtime, ptr); | 1125 | return ptr; |
1122 | } | 1126 | } |
1123 | 1127 | ||
1124 | static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream) | 1128 | static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substream *substream) |
@@ -1129,9 +1133,10 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea | |||
1129 | if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW)) | 1133 | if (!(inl(ICEMT(ice, PLAYBACK_CONTROL)) & ICE1712_CAPTURE_START_SHADOW)) |
1130 | return 0; | 1134 | return 0; |
1131 | ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2); | 1135 | ptr = ice->capture_pro_size - (inw(ICEMT(ice, CAPTURE_SIZE)) << 2); |
1136 | ptr = bytes_to_frames(substream->runtime, ptr); | ||
1132 | if (ptr == substream->runtime->buffer_size) | 1137 | if (ptr == substream->runtime->buffer_size) |
1133 | ptr = 0; | 1138 | ptr = 0; |
1134 | return bytes_to_frames(substream->runtime, ptr); | 1139 | return ptr; |
1135 | } | 1140 | } |
1136 | 1141 | ||
1137 | static const struct snd_pcm_hardware snd_ice1712_playback_pro = { | 1142 | static const struct snd_pcm_hardware snd_ice1712_playback_pro = { |