At Wed, 20 Dec 2006 14:06:37 -0500, David Cullen wrote: > > >> >> Also, could you give me some pointers regarding my previous e-mails > >> >> regarding this issue: > >> >> > >> >> Takashi Iwai wrote: > >> >> > At Mon, 27 Nov 2006 17:01:52 -0500, > >> >> > David Cullen wrote: > >> >> >> > >> >> >> I am trying to get ALSA version 1.0.13 working on an AMCC PowerPC > >> >> >> PPC405EP Taihu board with a Sound Blaster Live! 24-bit 7.1 PCI > >> >> >> card. I am using a patched 2.6.13 kernel that comes with the > >> >> >> board. I built the kernel with the sound core built in and I > >> >> >> used the cross-compiler tools to build the ALSA driver, library, > >> >> >> and utils. When I run "speaker-test", it crashes in the ALSA > >> >> >> library. The problem is that the call to mmap in > >> >> >> > >> >> >> alsa-lib-1.0.13/src/pcm/pcm_mmap.c line 367 > >> >> >> > >> >> >> which looks like > >> >> >> > >> >> >> ptr = mmap(NULL, size, PROT_READ|PROT_WRITE, > >> >> >> MAP_FILE|MAP_SHARED, i->u.mmap.fd, i->u.mmap.offset); > >> >> >> > >> >> >> returns a pointer that appears to be valid (0x3001E000) but > >> >> >> causes a kernel OOPS when accessed. > >> >> >> > >> >> >> Previous calls to mmap in pcm_hw.c on lines 822 and 854 both > >> >> >> succeed, and the pointers returned can be successfully accessed, > >> >> >> but they use the status and control offsets as parameters to > >> >> >> mmap. > >> >> >> > >> >> >> I haved traced the problem on the target into the ALSA library > >> >> >> using gdb and into the kernel using kgdb and everything looks > >> >> >> like it works properly. If I disable the semaphore acquisition > >> >> >> in do_mmap2, I can print the contents of the address in kgdb > >> >> >> using > >> >> >> > >> >> >> (gdb) print ((char *)vma->vm_start)[0] > >> >> >> > >> >> >> after the call to vm_link in do_mmap_pgoff. However, the board > >> >> >> locks up after the print command. > >> >> >> > >> >> >> Anyone have any experience with this type of problem on PowerPC > >> >> >> systems? > >> >> > > >> >> > Possibly a memory coherency problem. The memory allocated via > >> >> > dma_alloc_coherent() isn't simply mmappable. > >> >> > > >> >> > An essential fix would be to add dma_mmap_coherent() to all > >> >> > architectures and use it for ALSA mmap. I made some patches quite > >> >> > ago, but left it rotten for the time being... > >> >> > > >> >> > >> >> How do I "add dma_mmap_coherent() to all architectures and use it > >> >> for ALSA mmap"? > >> > > >> > Well, for that, we need to patch the kernel itself and add > >> > dma_mmap_coherent() call. The problem is that the memory returned > >> > from dma_alloc_coherent() isn't the address of the really allocated > >> > pages in your case. Since the ALSA mmap mode obtains the page via > >> > virt_to_page(), this doesn't work. Thus, a new function, > >> > dma_mmap_coherent() is required to calculate the real page address and > >> > do the rest of low-level mmap jobs. > >> > >> Where would dma_mmap_coherent be placed? Which specific file? > > > > It's somewhere in arch/*/* directory. > > > >> Would I replace all calls to mmap with dma_mmap_coherent? I can > >> probably figure out how to implement it if you can give me an > >> example for another architecture. I tried looking at old patches on > >> the web, but I had difficulty understanding them. I think they were > >> for the ARM architecture. > > > > Yes, ARM has already it. > > > > In arch/arm/mm/consistent.c I find the following lines: > > int dma_mmap_coherent(struct device *dev, > struct vm_area_struct *vma, void *cpu_addr, > dma_addr_t dma_addr, size_t size) > { > vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); > return dma_mmap(dev, vma, cpu_addr, dma_addr, size); > } > EXPORT_SYMBOL(dma_mmap_coherent); > > Can I add this code verbatim to a file in arch/ppc/mm? For example, > could I add it to 4xx_mmu.c? Or do I need to make a copy of > consistent.c in arch/ppc/mm? I apologize for all the questions, but > when I look at this code I am reminded of the quote from ADVENT: > "You are in a maze of twisty little passages, all alike." The implementation depends pretty much on the architecture. (Also, dma_mmap() is no global function but specific only for ARM.) Since the vm_region struct is different between ppc and arm (the page pointer is missing in ppc version), it cannot be copied as it is. A simple (but totally untested) version would be like below: int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, void *cpu_addr, dma_addr_t dma_addr, size_t size) { unsigned long pfn; pfn = page_to_pfn(virt_to_page(bus_to_virt(dma_addr))); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_pgprot); } (This might not work for some ppc models, though...) Then either add .mmap callback to each of snd_pcm_ops table in ca0106 that calls dma_mmap_coherent() above, or change snd_pcm_default_mmap to call dma_mmap_coherent() directly instead of nopage method. For the former way, take a look at sound/arm/aaci.c (and devdma.c) as a reference. > > >> > A simple solution would be simply disable mmap. > >> > In pci/ca0106/ca0106_main.c, remove SNDRV_PCM_INFO_MMAP and > >> > SNDRV_PCM_INFO_MMAP_VALID from snd_ca0106_playback_hw and > >> > snd_ca0106_capture_hw structs. > >> > > >> > Also, disable #if defined(CONFIG_PPC) around > >> > snd_pcm_mmap_status_*() in core/pcm_native.c. > >> > > >> > This will reduce the sound system functionality (e.g. no dmix is > >> > available), though. > >> > >> At this point, if we can get speaker-test to work, we will be happy. > >> So dmix is not necessary (I believe...). However, I do not know > >> the complete details of the end user's application, so dmix may be > >> needed eventually. If you can give me a few pointers on how to > >> implement dma_mmap_coherent and sew it into ALSA, that would really > >> help. > > > > When mmap is disabled in the driver, change the default alsa-lib > > configuration, too. Either edit alsa-lib/src/conf/cards/CA0106.conf > > or override the default PCM configuration in /etc/asound.conf, such as > > pcm.!default plughw > > > > > > Currently, /etc/asound.conf is > > pcm.ca0106 { > type hw > card 0 > } > > ctl.ca0106 { > type hw > card 0 > } > > I am confused about where is the right place to put > > pcm.!default plughw > > Do I just add another section that looks like this > > pcm.!default { > type plughw > card 0 > } > > or do I just add the line to asound.conf? The above (using aliasing) might work possibly only with the recent alsa-lib. With the older alsa-lib, you'd need to define the following in /etc/asound.conf: pcm.!default { type plug slave.pcm { type hw card 0 } } This will override the default PCM. Takashi ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.sourceforge.net/lists/listinfo/alsa-devel