diff options
| -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 | |||
| 941 | struct snd_pcm_substream *substream) | 941 | struct snd_pcm_substream *substream) |
| 942 | { | 942 | { |
| 943 | size_t ptr; | 943 | size_t ptr; |
| 944 | unsigned int reg; | 944 | unsigned int reg, rem, tries; |
| 945 | |||
| 945 | if (!rec->running) | 946 | if (!rec->running) |
| 946 | return 0; | 947 | return 0; |
| 947 | #if 1 // this seems better.. | 948 | #if 1 // this seems better.. |
| 948 | reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; | 949 | reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; |
| 949 | ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1); | 950 | for (tries = 0; tries < 3; tries++) { |
| 950 | ptr >>= rec->shift; | 951 | rem = snd_cmipci_read_w(cm, reg); |
| 952 | if (rem < rec->dma_size) | ||
| 953 | goto ok; | ||
| 954 | } | ||
| 955 | printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem); | ||
| 956 | return SNDRV_PCM_POS_XRUN; | ||
| 957 | ok: | ||
| 958 | ptr = (rec->dma_size - (rem + 1)) >> rec->shift; | ||
| 951 | #else | 959 | #else |
| 952 | reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; | 960 | reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; |
| 953 | ptr = snd_cmipci_read(cm, reg) - rec->offset; | 961 | ptr = snd_cmipci_read(cm, reg) - rec->offset; |
