Blob Blame History Raw
From a4463c92db0805581f4dfb700f72533cf25ebd48 Mon Sep 17 00:00:00 2001
From: "Maciej S. Szmigiero" <mail@maciej.szmigiero.name>
Date: Wed, 14 Feb 2018 00:04:58 +0100
Subject: [PATCH] ALSA: emu10k1: remove reserved_page
Git-commit: a4463c92db0805581f4dfb700f72533cf25ebd48
Patch-mainline: v4.17-rc1
References: bsc#1093027

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: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Takashi Iwai <tiwai@suse.de>

---
 include/sound/emu10k1.h          |    1 -
 sound/pci/emu10k1/emu10k1_main.c |   11 -----------
 sound/pci/emu10k1/memory.c       |    8 ++++++--
 3 files changed, 6 insertions(+), 14 deletions(-)

--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -1718,7 +1718,6 @@ struct snd_emu10k1 {
 	struct snd_dma_buffer p16v_buffer;
 
 	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_order_link_head;
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -1272,12 +1272,6 @@ static int snd_emu10k1_free(struct snd_e
 	release_firmware(emu->dock_fw);
 	if (emu->irq >= 0)
 		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);
 	if (emu->silent_page.area)
 		snd_dma_free_pages(&emu->silent_page);
@@ -1993,11 +1987,6 @@ int snd_emu10k1_create(struct snd_card *
 		SPCS_GENERATIONSTATUS | 0x00001200 |
 		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 */
 	memset(emu->silent_page.area, 0, PAGE_SIZE);
 	silent_page = emu->silent_page.addr << emu->address_mode;
--- a/sound/pci/emu10k1/memory.c
+++ b/sound/pci/emu10k1/memory.c
@@ -102,7 +102,7 @@ static void emu10k1_memblk_init(struct s
  */
 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 size;
 	struct list_head *candidate = &emu->mapped_link_head;
@@ -147,6 +147,10 @@ static int map_memblk(struct snd_emu10k1
 	page = search_empty_map_area(emu, blk->pages, &next);
 	if (page < 0) /* not found */
 		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 */
 	list_add_tail(&blk->mapped_link, next);
 	/* append this as a newest block in order list */
@@ -177,7 +181,7 @@ static int unmap_memblk(struct snd_emu10
 		q = get_emu10k1_memblk(p, mapped_link);
 		start_page = q->mapped_page + q->pages;
 	} else
-		start_page = 0;
+		start_page = 1;
 	if ((p = blk->mapped_link.next) != &emu->mapped_link_head) {
 		q = get_emu10k1_memblk(p, mapped_link);
 		end_page = q->mapped_page;