diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-04-10 21:34:56 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-04-10 21:34:56 +0200 |
commit | 27762b2ce16d5c6f7bc8ab1aad1b9179076f997a (patch) | |
tree | 04108617a1ccc18e3cef39e780c67460da9d5a0d /sound/pci/cmipci.c | |
parent | 7b7b9042263f5cafb6ce85b3764375a8de7e22da (diff) | |
parent | 29aac005ff4dc8a5f50b80f4e5c4f59b21c0fb50 (diff) | |
download | kernel_replicant_linux-27762b2ce16d5c6f7bc8ab1aad1b9179076f997a.tar.gz kernel_replicant_linux-27762b2ce16d5c6f7bc8ab1aad1b9179076f997a.tar.bz2 kernel_replicant_linux-27762b2ce16d5c6f7bc8ab1aad1b9179076f997a.zip |
Merge branch 'fix/misc' into topic/usb
Diffstat (limited to 'sound/pci/cmipci.c')
-rw-r--r-- | sound/pci/cmipci.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 1ded64e05643..329968edca9b 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci struct snd_pcm_substream *substream) { size_t ptr; - unsigned int reg; + unsigned int reg, rem, tries; + if (!rec->running) return 0; #if 1 // this seems better.. reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; - ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1); - ptr >>= rec->shift; + for (tries = 0; tries < 3; tries++) { + rem = snd_cmipci_read_w(cm, reg); + if (rem < rec->dma_size) + goto ok; + } + printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem); + return SNDRV_PCM_POS_XRUN; +ok: + ptr = (rec->dma_size - (rem + 1)) >> rec->shift; #else reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; ptr = snd_cmipci_read(cm, reg) - rec->offset; |