Index: alsa-kernel/pci/via82xx.c =================================================================== RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/via82xx.c,v retrieving revision 1.21 diff -u -r1.21 via82xx.c --- alsa-kernel/pci/via82xx.c 22 Jan 2003 14:21:05 -0000 1.21 +++ alsa-kernel/pci/via82xx.c 23 Jan 2003 09:40:01 -0000 @@ -232,6 +232,7 @@ struct snd_via_sg_table *idx_table; /* for recovery from the unexpected pointer */ unsigned int lastpos; + unsigned int lastidx; unsigned int bufsize; unsigned int bufsize2; }; @@ -485,6 +486,7 @@ outb(0x00, port + VIA_REG_OFFSET_TYPE); /* for via686 */ outl(0, port + VIA_REG_OFFSET_CURR_PTR); viadev->lastpos = 0; + viadev->lastidx = 0; } @@ -589,17 +591,26 @@ #endif /* count register returns full size when end of buffer is reached */ if (size != count) { - snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n"); - res = viadev->lastpos; + /* assume the next index */ + idx = viadev->lastidx + 1; + if (idx >= viadev->tbl_entries) + idx = 0; + size = viadev->idx_table[idx].size; + res = viadev->idx_table[idx].offset + size - count; + if (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2)) { + snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n"); + return viadev->lastpos; + } } else { res = viadev->idx_table[idx].offset + size; if (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2)) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n"); - res = viadev->lastpos; + return viadev->lastpos; } } } viadev->lastpos = res; /* remember the last positiion */ + viadev->lastidx = idx; if (res >= viadev->bufsize) res -= viadev->bufsize; return res; @@ -648,7 +659,7 @@ return 0; spin_lock(&chip->reg_lock); count = inl(VIAREG(chip, OFFSET_CURR_COUNT) + viadev->reg_offset); - idx = count >> 24; + idx = (count >> 24) & viadev->tbl_entries; count &= 0xffffff; res = calc_linear_pos(viadev, idx, count); spin_unlock(&chip->reg_lock);