|
@@ -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;
|