aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-05-30 03:49:41 -0400
committerTakashi Iwai <tiwai@suse.de>2008-05-30 05:37:41 -0400
commita5003fc04113c217370409beac812831cbf6e0ac (patch)
treeabf148b548a089f08240a21c77c80db2c5a0691d /sound/pci
parent2621f0338ce4e3e57cc32a967f5a3d2999390fe3 (diff)
[ALSA] emu10k1 - simplify page allocation for synth
Simplify the page allocation of emu10k1 driver for emux synth support. Since these pages aren't be necessarily coherent, we can avoid expensive DMA-coherent routines. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/emu10k1/memory.c66
1 files changed, 28 insertions, 38 deletions
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c
index 916c1dbcd53c..128eaca17a61 100644
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -437,43 +437,46 @@ static void get_single_page_range(struct snd_util_memhdr *hdr,
437 *last_page_ret = last_page; 437 *last_page_ret = last_page;
438} 438}
439 439
440/* release allocated pages */
441static void __synth_free_pages(struct snd_emu10k1 *emu, int first_page,
442 int last_page)
443{
444 int page;
445
446 for (page = first_page; page <= last_page; page++) {
447 free_page((unsigned long)emu->page_ptr_table[page]);
448 emu->page_addr_table[page] = 0;
449 emu->page_ptr_table[page] = NULL;
450 }
451}
452
440/* 453/*
441 * allocate kernel pages 454 * allocate kernel pages
442 */ 455 */
443static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) 456static int synth_alloc_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
444{ 457{
445 int page, first_page, last_page; 458 int page, first_page, last_page;
446 struct snd_dma_buffer dmab;
447 459
448 emu10k1_memblk_init(blk); 460 emu10k1_memblk_init(blk);
449 get_single_page_range(emu->memhdr, blk, &first_page, &last_page); 461 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
450 /* allocate kernel pages */ 462 /* allocate kernel pages */
451 for (page = first_page; page <= last_page; page++) { 463 for (page = first_page; page <= last_page; page++) {
452 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(emu->pci), 464 /* first try to allocate from <4GB zone */
453 PAGE_SIZE, &dmab) < 0) 465 struct page *p = alloc_page(GFP_KERNEL | GFP_DMA32 |
454 goto __fail; 466 __GFP_NOWARN);
455 if (! is_valid_page(emu, dmab.addr)) { 467 if (!p || (page_to_pfn(p) & ~(emu->dma_mask >> PAGE_SHIFT)))
456 snd_dma_free_pages(&dmab); 468 /* try to allocate from <16MB zone */
457 goto __fail; 469 p = alloc_page(GFP_DMA |
470 __GFP_NORETRY | /* no OOM-killer */
471 __GFP_NOWARN);
472 if (!p) {
473 __synth_free_pages(emu, first_page, page - 1);
474 return -ENOMEM;
458 } 475 }
459 emu->page_addr_table[page] = dmab.addr; 476 emu->page_addr_table[page] = page_to_phys(p);
460 emu->page_ptr_table[page] = dmab.area; 477 emu->page_ptr_table[page] = page_address(p);
461 } 478 }
462 return 0; 479 return 0;
463
464__fail:
465 /* release allocated pages */
466 last_page = page - 1;
467 for (page = first_page; page <= last_page; page++) {
468 dmab.area = emu->page_ptr_table[page];
469 dmab.addr = emu->page_addr_table[page];
470 dmab.bytes = PAGE_SIZE;
471 snd_dma_free_pages(&dmab);
472 emu->page_addr_table[page] = 0;
473 emu->page_ptr_table[page] = NULL;
474 }
475
476 return -ENOMEM;
477} 480}
478 481
479/* 482/*
@@ -481,23 +484,10 @@ __fail:
481 */ 484 */
482static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) 485static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
483{ 486{
484 int page, first_page, last_page; 487 int first_page, last_page;
485 struct snd_dma_buffer dmab;
486 488
487 get_single_page_range(emu->memhdr, blk, &first_page, &last_page); 489 get_single_page_range(emu->memhdr, blk, &first_page, &last_page);
488 dmab.dev.type = SNDRV_DMA_TYPE_DEV; 490 __synth_free_pages(emu, first_page, last_page);
489 dmab.dev.dev = snd_dma_pci_data(emu->pci);
490 for (page = first_page; page <= last_page; page++) {
491 if (emu->page_ptr_table[page] == NULL)
492 continue;
493 dmab.area = emu->page_ptr_table[page];
494 dmab.addr = emu->page_addr_table[page];
495 dmab.bytes = PAGE_SIZE;
496 snd_dma_free_pages(&dmab);
497 emu->page_addr_table[page] = 0;
498 emu->page_ptr_table[page] = NULL;
499 }
500
501 return 0; 491 return 0;
502} 492}
503 493