主题 : WM8960声卡移植:playback write error (DMA or IRQ trouble?) 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 123066
精华: 0
发帖: 4
金钱: 20 两
威望: 4 点
综合积分: 8 分
注册时间: 2016-03-01
最后登录: 2016-08-20
楼主  发表于: 2016-05-01 15:07

 WM8960声卡移植:playback write error (DMA or IRQ trouble?)

内核版本: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操作是否有关?