From mboxrd@z Thu Jan 1 00:00:00 1970 From: Takashi Iwai Subject: Re: Oops in snd_emu10k1_efx_playback_prepare Date: Wed, 23 Mar 2005 12:35:56 +0100 Message-ID: References: <1110347780.7123.21.camel@mindpipe> <1110490545.14297.9.camel@mindpipe> <1111203050.12740.7.camel@mindpipe> <1111203432.12740.13.camel@mindpipe> Mime-Version: 1.0 (generated by SEMI 1.14.5 - "Awara-Onsen") Content-Type: multipart/mixed; boundary="Multipart_Wed_Mar_23_12:35:56_2005-1" In-Reply-To: <1111203432.12740.13.camel@mindpipe> Sender: alsa-devel-admin@lists.sourceforge.net Errors-To: alsa-devel-admin@lists.sourceforge.net List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , List-Archive: To: Lee Revell Cc: alsa-devel List-Id: alsa-devel@alsa-project.org --Multipart_Wed_Mar_23_12:35:56_2005-1 Content-Type: text/plain; charset=US-ASCII At Fri, 18 Mar 2005 22:37:12 -0500, Lee Revell wrote: > > On Fri, 2005-03-18 at 22:30 -0500, Lee Revell wrote: > > Unable to handle kernel paging request at virtual address 936e4158 > > Sorry, ksymoops is really useless. The oops from dmesg is a lot better: > > Unable to handle kernel paging request at virtual address 936e4158 > printing eip: > c01d3d63 > *pde = 00000000 > Oops: 0000 [#1] > PREEMPT > Modules linked in: snd_usb_audio snd_usb_lib snd_emu10k1_synth > snd_emux_synth snd_seq_virmidi snd_seq_midi_emul snd_seq_oss > snd_seq_midi snd_seq_midi_event snd_seq snd_emu10k1 snd_rawmidi > snd_seq_device snd_ac97_codec snd_pcm_oss snd_mixer_oss snd_pcm > snd_timer snd_page_alloc snd_util_mem snd_hwdep snd realtime commoncap > af_packet e100 mii uhci_hcd agpgart evdev psmouse usbhid ehci_hcd > usbcore > CPU: 0 > EIP: 0060:[] Not tainted VLI > EFLAGS: 00210012 (2.6.12-rc1) > EIP is at memcpy+0x23/0x60 > eax: 00000008 ebx: 936e4170 ecx: 00000002 edx: d0b9fe3c > esi: 936e4158 edi: d0b9fe3c ebp: d0b9fe0c esp: d0b9fdf8 > ds: 007b es: 007b ss: 0068 > Process jackd (pid: 13176, threadinfo=d0b9e000 task=d2d4f580) > Stack: 00200046 def60000 0779dfff 03020100 00000001 d0b9fe50 e08e2178 > d0b9fe3c > 936e4158 00000008 00000000 00200216 00000001 00000000 de61e000 > 00000005 > 00000000 00000002 00000005 00001780 00001780 0000000f d0b9fe88 > e08e2597 > Call Trace: > [] show_stack+0x7f/0xa0 > [] show_registers+0x15a/0x1c0 > [] die+0xf0/0x190 > [] do_page_fault+0x31b/0x670 > [] error_code+0x2b/0x30 > [] snd_emu10k1_pcm_init_voice+0x5c8/0x610 [snd_emu10k1] > [] snd_emu10k1_efx_playback_prepare+0xd7/0xf0 [snd_emu10k1] > [] snd_pcm_do_prepare+0x15/0x40 [snd_pcm] > [] snd_pcm_action_single+0x34/0x70 [snd_pcm] > [] snd_pcm_action_nonatomic+0x73/0x80 [snd_pcm] > [] snd_pcm_prepare+0x21/0x30 [snd_pcm] > [] snd_pcm_playback_ioctl1+0x47/0x2d0 [snd_pcm] > [] snd_pcm_playback_ioctl_old+0x27/0x40 [snd_pcm] > [] do_ioctl+0x63/0x90 > [] vfs_ioctl+0x62/0x1c0 > [] sys_ioctl+0x61/0x80 > [] syscall_call+0x7/0xb > Code: 90 90 90 90 90 90 90 90 55 89 e5 83 ec 14 8b 45 10 89 75 f8 89 7d > fc 8b 55 08 8b 75 0c 3d ff 01 00 00 77 24 89 c1 89 d7 c1 e9 02 a5 > a8 02 74 02 66 a5 a8 01 74 01 a4 89 d0 8b 75 f8 8b 7d fc > <6>note: jackd[13176] exited with preempt_count 1 > > Now, the only memcpy's in snd_emu10k1_pcm_init_voice are these: > > 311 /* volume parameters */ > 312 if (extra) { > 313 attn = 0; > 314 memset(send_routing, 0, sizeof(send_routing)); > 315 send_routing[0] = 0; > 316 send_routing[1] = 1; > 317 send_routing[2] = 2; > 318 send_routing[3] = 3; > 319 memset(send_amount, 0, sizeof(send_amount)); > 320 } else { > 321 /* mono, left, right (master voice = left) */ > 322 tmp = stereo ? (master ? 1 : 2) : 0; > 323 memcpy(send_routing, &mix->send_routing[tmp][0], 8); > 324 memcpy(send_amount, &mix->send_volume[tmp][0], 8); > 325 } > 326 > > It looks like this is related to the change I made to the send routing > controls for the multichannel device. The calculation of mix pointer seems wrong when the voices are allocated from the tail of voice table and back to 0 (e.g. voice 30, 31, 0, 1, 2, ...) Could you try the patch below? Takashi --Multipart_Wed_Mar_23_12:35:56_2005-1 Content-Type: text/plain; charset=US-ASCII Index: alsa-kernel/pci/emu10k1/emupcm.c =================================================================== RCS file: /home/iwai/cvs/alsa/alsa-kernel/pci/emu10k1/emupcm.c,v retrieving revision 1.47 diff -u -r1.47 emupcm.c --- alsa-kernel/pci/emu10k1/emupcm.c 14 Mar 2005 14:56:17 -0000 1.47 +++ alsa-kernel/pci/emu10k1/emupcm.c 23 Mar 2005 11:33:01 -0000 @@ -275,11 +275,11 @@ int master, int extra, emu10k1_voice_t *evoice, unsigned int start_addr, - unsigned int end_addr) + unsigned int end_addr, + emu10k1_pcm_mixer_t *mix) { snd_pcm_substream_t *substream = evoice->epcm->substream; snd_pcm_runtime_t *runtime = substream->runtime; - emu10k1_pcm_mixer_t *mix; unsigned int silent_page, tmp; int voice, stereo, w_16; unsigned char attn, send_amount[8]; @@ -289,11 +289,6 @@ unsigned int ccis; voice = evoice->number; - if (evoice->epcm->type == PLAYBACK_EFX) - mix = &emu->efx_pcm_mixer[voice - evoice->epcm->voices[0]->number]; - else - mix = &emu->pcm_mixer[substream->number]; - stereo = runtime->channels == 2; w_16 = snd_pcm_format_width(runtime->format) == 16; @@ -497,14 +492,16 @@ } end_addr += start_addr; snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra, - start_addr, end_addr); + start_addr, end_addr, NULL); start_addr = epcm->start_addr; end_addr = epcm->start_addr + snd_pcm_lib_buffer_bytes(substream); snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], - start_addr, end_addr); + start_addr, end_addr, + &emu->pcm_mixer[substream->number]); if (epcm->voices[1]) snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[1], - start_addr, end_addr); + start_addr, end_addr, + &emu->pcm_mixer[substream->number]); return 0; } @@ -526,16 +523,18 @@ channel_size = ( end_addr - start_addr ) / NUM_EFX_PLAYBACK; snd_emu10k1_pcm_init_voice(emu, 1, 1, epcm->extra, - start_addr, start_addr + (channel_size / 2)); + start_addr, start_addr + (channel_size / 2), NULL); /* only difference with the master voice is we use it for the pointer */ snd_emu10k1_pcm_init_voice(emu, 1, 0, epcm->voices[0], - start_addr, start_addr + channel_size); + start_addr, start_addr + channel_size, + &emu->efx_pcm_mixer[0]); start_addr += channel_size; for (i = 1; i < NUM_EFX_PLAYBACK; i++) { snd_emu10k1_pcm_init_voice(emu, 0, 0, epcm->voices[i], - start_addr, start_addr+channel_size); + start_addr, start_addr + channel_size, + &emu->efx_pcm_mixer[i]); start_addr += channel_size; } @@ -654,12 +653,13 @@ } } -static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, int master, int extra) +static void snd_emu10k1_playback_prepare_voice(emu10k1_t *emu, emu10k1_voice_t *evoice, + int master, int extra, + emu10k1_pcm_mixer_t *mix) { snd_pcm_substream_t *substream; snd_pcm_runtime_t *runtime; - emu10k1_pcm_mixer_t *mix; - unsigned int attn; + unsigned int attn, vattn; unsigned int voice, tmp; if (evoice == NULL) /* skip second voice for mono */ @@ -668,15 +668,12 @@ runtime = substream->runtime; voice = evoice->number; - mix = evoice->epcm->type == PLAYBACK_EFX - ? &emu->efx_pcm_mixer[voice - evoice->epcm->voices[0]->number] - : &emu->pcm_mixer[substream->number]; - attn = extra ? 0 : 0x00ff; tmp = runtime->channels == 2 ? (master ? 1 : 2) : 0; + vattn = mix != NULL ? (mix->attn[tmp] << 16) : 0; snd_emu10k1_ptr_write(emu, IFATN, voice, attn); - snd_emu10k1_ptr_write(emu, VTFT, voice, (mix->attn[tmp] << 16) | 0xffff); - snd_emu10k1_ptr_write(emu, CVCF, voice, (mix->attn[tmp] << 16) | 0xffff); + snd_emu10k1_ptr_write(emu, VTFT, voice, vattn | 0xffff); + snd_emu10k1_ptr_write(emu, CVCF, voice, vattn | 0xffff); snd_emu10k1_ptr_write(emu, DCYSUSV, voice, 0x7f7f); snd_emu10k1_voice_clear_loop_stop(emu, voice); } @@ -725,7 +722,9 @@ emu10k1_t *emu = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; emu10k1_pcm_t *epcm = runtime->private_data; + emu10k1_pcm_mixer_t *mix; int result = 0; + // printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); spin_lock(&emu->reg_lock); switch (cmd) { @@ -734,9 +733,10 @@ snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]); /* follow thru */ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0); - snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0); - snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1); + mix = &emu->pcm_mixer[substream->number]; + snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 1, 0, mix); + snd_emu10k1_playback_prepare_voice(emu, epcm->voices[1], 0, 0, mix); + snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL); snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 1, 0); snd_emu10k1_playback_trigger_voice(emu, epcm->voices[1], 0, 0); snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1); @@ -851,7 +851,7 @@ emu10k1_t *emu = snd_pcm_substream_chip(substream); snd_pcm_runtime_t *runtime = substream->runtime; emu10k1_pcm_t *epcm = runtime->private_data; - int i = 0; + int i; int result = 0; spin_lock(&emu->reg_lock); @@ -865,16 +865,16 @@ /* follow thru */ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0); - snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1); - for (i = 1; i < NUM_EFX_PLAYBACK; i++) { - snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0); - } + snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL); + snd_emu10k1_playback_prepare_voice(emu, epcm->voices[0], 0, 0, + &emu->efx_pcm_mixer[0]); + for (i = 1; i < NUM_EFX_PLAYBACK; i++) + snd_emu10k1_playback_prepare_voice(emu, epcm->voices[i], 0, 0, + &emu->efx_pcm_mixer[i]); snd_emu10k1_playback_trigger_voice(emu, epcm->voices[0], 0, 0); snd_emu10k1_playback_trigger_voice(emu, epcm->extra, 1, 1); - for (i = 1; i < NUM_EFX_PLAYBACK; i++) { + for (i = 1; i < NUM_EFX_PLAYBACK; i++) snd_emu10k1_playback_trigger_voice(emu, epcm->voices[i], 0, 0); - } epcm->running = 1; break; case SNDRV_PCM_TRIGGER_STOP: Index: alsa-kernel/pci/emu10k1/voice.c =================================================================== RCS file: /home/iwai/cvs/alsa/alsa-kernel/pci/emu10k1/voice.c,v retrieving revision 1.6 diff -u -r1.6 voice.c --- alsa-kernel/pci/emu10k1/voice.c 14 Mar 2005 14:55:56 -0000 1.6 +++ alsa-kernel/pci/emu10k1/voice.c 23 Mar 2005 11:33:01 -0000 @@ -62,15 +62,13 @@ continue; } - /* make sure the block of voices does not cross the 32 voice boundary */ - //if (((i % 32) + number) > 32) - // continue; - skip = 0; for (k = 0; k < number; k++) { voice = &emu->voices[(i+k) % NUM_G]; - if (voice->use) + if (voice->use) { skip = 1; + break; + } } if (!skip) { // printk("allocated voice %d\n", i); --Multipart_Wed_Mar_23_12:35:56_2005-1-- ------------------------------------------------------- This SF.net email is sponsored by: 2005 Windows Mobile Application Contest Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones for the chance to win $25,000 and application distribution. Enter today at http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click