内核版本:kernel_3.8.13
一、执行aplay xxx.wav, 播放文件,
.open = snd_pcm_playback_open, //第一步:open 操作
.mmap = snd_pcm_mmap, //第二步:mmap 操作
跟踪了下snd_pcm_mmap()函数时:
offset = area-> vm_pgoff << PAGE_SHIFT == SNDRV_PCM_MMAP_OFFSET_STATUS;
这样就不会跑到如下链路:
==〉 snd_pcm_mmap_data(substream, file, area)
==〉 substream->ops->mmap(substream, area)
从而也不会跑platform_drvier
==〉samsung_asoc_platform -> dma_ops -> .mmap = dma_mmap
snd_pcm_mmap()函数原型:
static int snd_pcm_mmap(struct file *file, struct vm_area_struct *area)
{
struct snd_pcm_file * pcm_file;
struct snd_pcm_substream *substream;
unsigned long offset;
pcm_file = file->private_data;
substream = pcm_file->substream;
if (PCM_RUNTIME_CHECK(substream))
return -ENXIO;
offset = area-> vm_pgoff << PAGE_SHIFT;
switch (offset) {
case SNDRV_PCM_MMAP_OFFSET_STATUS:
if (pcm_file->no_compat_mmap)
return -ENXIO;
return snd_pcm_mmap_status(substream, file, area);
case SNDRV_PCM_MMAP_OFFSET_CONTROL:
if (pcm_file->no_compat_mmap)
return -ENXIO;
return snd_pcm_mmap_control(substream, file, area);
default:
return snd_pcm_mmap_data(substream, file, area);
}
return 0;
}
执行完mmap操作,再执行ioctl操作
.unlocked_ioctl = snd_pcm_playback_ioctl //第三步:ioctl操作
==> snd_pcm_playback_ioctl1
==> case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
snd_pcm_lib_write(substream, xferi.buf, xferi.frames)
==> snd_pcm_lib_write1(substream, (unsigned long)buf, size, nonblock, snd_pcm_lib_write_transfer)
==> avail = snd_pcm_playback_avail(runtime);
在这里,DMA缓存区的大小avail得到的一直是0,会报错:
logo信息:
-----------------------wm8960_mute(out), line:599
Playing WAVE 'usr/local/music/windows_xp.wav' : Signed 16 bit Little Endian, Rate 22050 Hz, Stereo
playback write error (DMA or IRQ trouble?)
-----------------------wm8960_mute(in), line:585
+wm8960_mute()
+wm8960_mute(): mute 1
-wm8960_mute()
-----------------------wm8960_mute(out), line:599
二、请教各位大侠,这个错误与mmap操作是否有关?