aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@suse.cz>2005-01-03 13:09:59 +0100
committerJaroslav Kysela <perex@suse.cz>2005-01-03 13:09:59 +0100
commitcdf4d80f336c84fce5a4de0fe8701aacca9f12df (patch)
treecff83bc13e074944a3c52b9e09afde38f5f7f6df /sound
parentcaae3a9f91adc5be104d5b9be679dc213bce432d (diff)
downloadhistory-cdf4d80f336c84fce5a4de0fe8701aacca9f12df.tar.gz
[ALSA] Fix non-symmetrical page_attr changes
Intel8x0 driver Fixed non-symmetrical calls of change_page_attr() which may cause BUG(). This bug happens only on 440MX. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/intel8x0.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index f2bd304a46c28d..3206f39b6df080 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -380,6 +380,7 @@ typedef struct {
unsigned int ali_slot; /* ALI DMA slot */
struct ac97_pcm *pcm;
int pcm_open_flag;
+ unsigned int page_attr_changed: 1;
} ichdev_t;
typedef struct _snd_intel8x0 intel8x0_t;
@@ -946,13 +947,19 @@ static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream,
int dbl = params_rate(hw_params) > 48000;
int err;
- if (chip->fix_nocache && runtime->dma_area && runtime->dma_bytes < size)
+ if (chip->fix_nocache && ichdev->page_attr_changed) {
fill_nocache(runtime->dma_area, runtime->dma_bytes, 0); /* clear */
+ ichdev->page_attr_changed = 0;
+ }
err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
if (err < 0)
return err;
- if (chip->fix_nocache && err > 0)
- fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
+ if (chip->fix_nocache) {
+ if (runtime->dma_area && ! ichdev->page_attr_changed) {
+ fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
+ ichdev->page_attr_changed = 1;
+ }
+ }
if (ichdev->pcm_open_flag) {
snd_ac97_pcm_close(ichdev->pcm);
ichdev->pcm_open_flag = 0;
@@ -978,8 +985,10 @@ static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream)
snd_ac97_pcm_close(ichdev->pcm);
ichdev->pcm_open_flag = 0;
}
- if (chip->fix_nocache && substream->runtime->dma_area)
+ if (chip->fix_nocache && ichdev->page_attr_changed) {
fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);
+ ichdev->page_attr_changed = 0;
+ }
return snd_pcm_lib_free_pages(substream);
}
@@ -2291,6 +2300,17 @@ static int intel8x0_suspend(snd_card_t *card, unsigned int state)
for (i = 0; i < chip->pcm_devs; i++)
snd_pcm_suspend_all(chip->pcm[i]);
+ /* clear nocache */
+ if (chip->fix_nocache) {
+ for (i = 0; i < chip->bdbars_count; i++) {
+ ichdev_t *ichdev = &chip->ichd[i];
+ if (ichdev->substream && ichdev->page_attr_changed) {
+ snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
+ if (runtime->dma_area)
+ fill_nocache(runtime->dma_area, runtime->dma_bytes, 0);
+ }
+ }
+ }
for (i = 0; i < 3; i++)
if (chip->ac97[i])
snd_ac97_suspend(chip->ac97[i]);
@@ -2320,7 +2340,7 @@ static int intel8x0_resume(snd_card_t *card, unsigned int state)
if (chip->fix_nocache) {
for (i = 0; i < chip->bdbars_count; i++) {
ichdev_t *ichdev = &chip->ichd[i];
- if (ichdev->substream) {
+ if (ichdev->substream && ichdev->page_attr_changed) {
snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
if (runtime->dma_area)
fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);