Commit a4463c92 authored by Maciej S. Szmigiero's avatar Maciej S. Szmigiero Committed by Takashi Iwai

ALSA: emu10k1: remove reserved_page

The emu10k1-family chips need the first page (index 0) reserved in their
page tables for some reason (every emu10k1 driver I've checked does this
without much of an explanation).
Using the first page for normal samples results in a broken playback.

However, we already have a dummy page allocated - so called "silent page"
and, in fact, had always been setting it as the first page in the chip page
table because an initialization of every entry of the page table to point
to a silent page happens after and overwrites the reserved_page allocation.

So the only thing remaining to remove the reserved_page allocation is a
trivial change to the page allocation logic to ignore the first page entry
and start its allocations from the second entry (index 1).
Signed-off-by: default avatarMaciej S. Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent bafeca67
...@@ -1718,7 +1718,6 @@ struct snd_emu10k1 { ...@@ -1718,7 +1718,6 @@ struct snd_emu10k1 {
struct snd_dma_buffer p16v_buffer; struct snd_dma_buffer p16v_buffer;
struct snd_util_memhdr *memhdr; /* page allocation list */ struct snd_util_memhdr *memhdr; /* page allocation list */
struct snd_emu10k1_memblk *reserved_page; /* reserved page */
struct list_head mapped_link_head; struct list_head mapped_link_head;
struct list_head mapped_order_link_head; struct list_head mapped_order_link_head;
......
...@@ -1272,12 +1272,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu) ...@@ -1272,12 +1272,6 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
release_firmware(emu->dock_fw); release_firmware(emu->dock_fw);
if (emu->irq >= 0) if (emu->irq >= 0)
free_irq(emu->irq, emu); free_irq(emu->irq, emu);
/* remove reserved page */
if (emu->reserved_page) {
snd_emu10k1_synth_free(emu,
(struct snd_util_memblk *)emu->reserved_page);
emu->reserved_page = NULL;
}
snd_util_memhdr_free(emu->memhdr); snd_util_memhdr_free(emu->memhdr);
if (emu->silent_page.area) if (emu->silent_page.area)
snd_dma_free_pages(&emu->silent_page); snd_dma_free_pages(&emu->silent_page);
...@@ -1993,11 +1987,6 @@ int snd_emu10k1_create(struct snd_card *card, ...@@ -1993,11 +1987,6 @@ int snd_emu10k1_create(struct snd_card *card,
SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_GENERATIONSTATUS | 0x00001200 |
0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT; 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
emu->reserved_page = (struct snd_emu10k1_memblk *)
snd_emu10k1_synth_alloc(emu, 4096);
if (emu->reserved_page)
emu->reserved_page->map_locked = 1;
/* Clear silent pages and set up pointers */ /* Clear silent pages and set up pointers */
memset(emu->silent_page.area, 0, PAGE_SIZE); memset(emu->silent_page.area, 0, PAGE_SIZE);
silent_page = emu->silent_page.addr << emu->address_mode; silent_page = emu->silent_page.addr << emu->address_mode;
......
...@@ -102,7 +102,7 @@ static void emu10k1_memblk_init(struct snd_emu10k1_memblk *blk) ...@@ -102,7 +102,7 @@ static void emu10k1_memblk_init(struct snd_emu10k1_memblk *blk)
*/ */
static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct list_head **nextp) static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct list_head **nextp)
{ {
int page = 0, found_page = -ENOMEM; int page = 1, found_page = -ENOMEM;
int max_size = npages; int max_size = npages;
int size; int size;
struct list_head *candidate = &emu->mapped_link_head; struct list_head *candidate = &emu->mapped_link_head;
...@@ -147,6 +147,10 @@ static int map_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) ...@@ -147,6 +147,10 @@ static int map_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
page = search_empty_map_area(emu, blk->pages, &next); page = search_empty_map_area(emu, blk->pages, &next);
if (page < 0) /* not found */ if (page < 0) /* not found */
return page; return page;
if (page == 0) {
dev_err(emu->card->dev, "trying to map zero (reserved) page\n");
return -EINVAL;
}
/* insert this block in the proper position of mapped list */ /* insert this block in the proper position of mapped list */
list_add_tail(&blk->mapped_link, next); list_add_tail(&blk->mapped_link, next);
/* append this as a newest block in order list */ /* append this as a newest block in order list */
...@@ -177,7 +181,7 @@ static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk) ...@@ -177,7 +181,7 @@ static int unmap_memblk(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk *blk)
q = get_emu10k1_memblk(p, mapped_link); q = get_emu10k1_memblk(p, mapped_link);
start_page = q->mapped_page + q->pages; start_page = q->mapped_page + q->pages;
} else } else
start_page = 0; start_page = 1;
if ((p = blk->mapped_link.next) != &emu->mapped_link_head) { if ((p = blk->mapped_link.next) != &emu->mapped_link_head) {
q = get_emu10k1_memblk(p, mapped_link); q = get_emu10k1_memblk(p, mapped_link);
end_page = q->mapped_page; end_page = q->mapped_page;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment