Commit cdf4d80f authored by Jaroslav Kysela's avatar Jaroslav Kysela

[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: default avatarTakashi Iwai <tiwai@suse.de>
parent caae3a9f
...@@ -380,6 +380,7 @@ typedef struct { ...@@ -380,6 +380,7 @@ typedef struct {
unsigned int ali_slot; /* ALI DMA slot */ unsigned int ali_slot; /* ALI DMA slot */
struct ac97_pcm *pcm; struct ac97_pcm *pcm;
int pcm_open_flag; int pcm_open_flag;
unsigned int page_attr_changed: 1;
} ichdev_t; } ichdev_t;
typedef struct _snd_intel8x0 intel8x0_t; typedef struct _snd_intel8x0 intel8x0_t;
...@@ -946,13 +947,19 @@ static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream, ...@@ -946,13 +947,19 @@ static int snd_intel8x0_hw_params(snd_pcm_substream_t * substream,
int dbl = params_rate(hw_params) > 48000; int dbl = params_rate(hw_params) > 48000;
int err; 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 */ 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)); err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
if (err < 0) if (err < 0)
return err; return err;
if (chip->fix_nocache && err > 0) if (chip->fix_nocache) {
if (runtime->dma_area && ! ichdev->page_attr_changed) {
fill_nocache(runtime->dma_area, runtime->dma_bytes, 1); fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
ichdev->page_attr_changed = 1;
}
}
if (ichdev->pcm_open_flag) { if (ichdev->pcm_open_flag) {
snd_ac97_pcm_close(ichdev->pcm); snd_ac97_pcm_close(ichdev->pcm);
ichdev->pcm_open_flag = 0; ichdev->pcm_open_flag = 0;
...@@ -978,8 +985,10 @@ static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream) ...@@ -978,8 +985,10 @@ static int snd_intel8x0_hw_free(snd_pcm_substream_t * substream)
snd_ac97_pcm_close(ichdev->pcm); snd_ac97_pcm_close(ichdev->pcm);
ichdev->pcm_open_flag = 0; 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); fill_nocache(substream->runtime->dma_area, substream->runtime->dma_bytes, 0);
ichdev->page_attr_changed = 0;
}
return snd_pcm_lib_free_pages(substream); return snd_pcm_lib_free_pages(substream);
} }
...@@ -2291,6 +2300,17 @@ static int intel8x0_suspend(snd_card_t *card, unsigned int state) ...@@ -2291,6 +2300,17 @@ static int intel8x0_suspend(snd_card_t *card, unsigned int state)
for (i = 0; i < chip->pcm_devs; i++) for (i = 0; i < chip->pcm_devs; i++)
snd_pcm_suspend_all(chip->pcm[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++) for (i = 0; i < 3; i++)
if (chip->ac97[i]) if (chip->ac97[i])
snd_ac97_suspend(chip->ac97[i]); snd_ac97_suspend(chip->ac97[i]);
...@@ -2320,7 +2340,7 @@ static int intel8x0_resume(snd_card_t *card, unsigned int state) ...@@ -2320,7 +2340,7 @@ static int intel8x0_resume(snd_card_t *card, unsigned int state)
if (chip->fix_nocache) { if (chip->fix_nocache) {
for (i = 0; i < chip->bdbars_count; i++) { for (i = 0; i < chip->bdbars_count; i++) {
ichdev_t *ichdev = &chip->ichd[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; snd_pcm_runtime_t *runtime = ichdev->substream->runtime;
if (runtime->dma_area) if (runtime->dma_area)
fill_nocache(runtime->dma_area, runtime->dma_bytes, 1); fill_nocache(runtime->dma_area, runtime->dma_bytes, 1);
......
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