From mboxrd@z Thu Jan 1 00:00:00 1970 From: Takashi Iwai Subject: Re: via82xx calc_linear_pos bug Date: Tue, 27 Jul 2004 15:39:12 +0200 Sender: alsa-devel-admin@lists.sourceforge.net Message-ID: References: <1090597651.3258.3.camel@onion.home.net> Mime-Version: 1.0 (generated by SEMI 1.14.5 - "Awara-Onsen") Content-Type: multipart/mixed; boundary="Multipart_Tue_Jul_27_15:39:12_2004-1" Return-path: In-Reply-To: <1090597651.3258.3.camel@onion.home.net> Errors-To: alsa-devel-admin@lists.sourceforge.net List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , List-Archive: To: alsa-devel@lists.sourceforge.net List-Id: alsa-devel@alsa-project.org --Multipart_Tue_Jul_27_15:39:12_2004-1 Content-Type: text/plain; charset=US-ASCII At Fri, 23 Jul 2004 18:47:30 +0300, Timo Hirvonen wrote: > > After playing about 10-20 seconds snd_pcm_status_get_avail returns too > large value (1972895704, 1972895664 ..). Grrr, the empire strikes again. The change in the recent version was a workaround to fix the similar bug on many buggy mobos. Could you try the attached patch? Takashi --Multipart_Tue_Jul_27_15:39:12_2004-1 Content-Type: text/plain; charset=US-ASCII Index: alsa-kernel/pci/via82xx.c =================================================================== RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/via82xx.c,v retrieving revision 1.122 diff -u -r1.122 via82xx.c --- alsa-kernel/pci/via82xx.c 15 Jul 2004 14:55:29 -0000 1.122 +++ alsa-kernel/pci/via82xx.c 27 Jul 2004 13:37:25 -0000 @@ -707,29 +707,36 @@ /* * calculate the linear position at the given sg-buffer index and the rest count */ + +#define check_invalid_pos(viadev,pos) \ + ((pos) < viadev->lastpos && ((pos) >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2)) + static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count) { unsigned int size, res; size = viadev->idx_table[idx].size; - /* FIXME: is this always true? */ - if (count) - res = viadev->idx_table[idx].offset + size - count; - else - res = viadev->idx_table[idx].offset; + res = viadev->idx_table[idx].offset + size - count; /* check the validity of the calculated position */ - if (size < count || (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))) { + if (size < count) { + snd_printd(KERN_ERR "invalid via82xx_cur_ptr (size = %d, count = %d)\n", (int)size, (int)count); + res = viadev->lastpos; + } else if (check_invalid_pos(viadev, res)) { #ifdef POINTER_DEBUG printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count); #endif - /* count register returns full size when end of buffer is reached */ - if (size != count) { + if (count && size < count) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n"); res = viadev->lastpos; } else { - res = viadev->idx_table[idx].offset + size; - if (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2)) { + if (! count) + /* bogus count 0 on the DMA boundary? */ + res = viadev->idx_table[idx].offset; + else + /* count register returns full size when end of buffer is reached */ + res = viadev->idx_table[idx].offset + size; + if (check_invalid_pos(viadev, res)) { snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n"); res = viadev->lastpos; } --Multipart_Tue_Jul_27_15:39:12_2004-1-- ------------------------------------------------------- This SF.Net email is sponsored by BEA Weblogic Workshop FREE Java Enterprise J2EE developer tools! Get your free copy of BEA WebLogic Workshop 8.1 today. http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click