Title: [3990] trunk/sound/soc/blackfin: Bug[#3727] use dummy ring to avoid potential conflict between loading descriptor while changing it 's content
Revision
3990
Author
cliff
Date
2007-12-05 17:54:57 -0600 (Wed, 05 Dec 2007)

Log Message

Bug[#3727]use dummy ring to avoid potential conflict between loading descriptor while changing it's content 

Diffstat

 bf5xx-ac97.c  |    2 +-
 bf5xx-sport.c |   28 ++++++++++++++++------------
 bf5xx-sport.h |    2 +-
 3 files changed, 18 insertions(+), 14 deletions(-)

Modified Paths

Diff

Modified: trunk/sound/soc/blackfin/bf5xx-ac97.c (3989 => 3990)


--- trunk/sound/soc/blackfin/bf5xx-ac97.c	2007-12-05 20:37:59 UTC (rev 3989)
+++ trunk/sound/soc/blackfin/bf5xx-ac97.c	2007-12-05 23:54:57 UTC (rev 3990)
@@ -309,7 +309,7 @@
 	gpio_set_value(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
 #endif
 	sport_handle = sport_init(&sport_params[sport_num], 2, \
-			sizeof(struct ac97_frame), NULL);
+			10*sizeof(struct ac97_frame), NULL);
 	if (!sport_handle) {
 		peripheral_free_list(&sport_req[sport_num][0]);
 #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET

Modified: trunk/sound/soc/blackfin/bf5xx-sport.c (3989 => 3990)


--- trunk/sound/soc/blackfin/bf5xx-sport.c	2007-12-05 20:37:59 UTC (rev 3989)
+++ trunk/sound/soc/blackfin/bf5xx-sport.c	2007-12-05 23:54:57 UTC (rev 3990)
@@ -181,7 +181,7 @@
 
 	/* Maybe the dummy buffer descriptor ring is damaged */
 	sport->dummy_rx_desc->next_desc_addr = \
-			(unsigned long)sport->dummy_rx_desc;
+			(unsigned long)(sport->dummy_rx_desc+1);
 
 	local_irq_save(flags);
 	desc = (struct dmasg *)get_dma_next_desc_ptr(sport->dma_rx_chan);
@@ -256,6 +256,9 @@
 		BUG_ON(sport->dma_rx_desc == NULL);
 		BUG_ON(sport->curr_rx_desc != sport->dummy_rx_desc);
 		local_irq_save(flags);
+		while ((get_dma_curr_desc_ptr(sport->dma_rx_chan) - \
+			sizeof(struct dmasg)) != \
+			(unsigned long)sport->dummy_rx_desc) {}
 		sport->dummy_rx_desc->next_desc_addr = \
 				(unsigned long)(sport->dma_rx_desc);
 		local_irq_restore(flags);
@@ -303,7 +306,7 @@
 	BUG_ON(sport->curr_tx_desc == sport->dummy_tx_desc);
 
 	sport->dummy_tx_desc->next_desc_addr = \
-			(unsigned long)sport->dummy_tx_desc;
+			(unsigned long)(sport->dummy_tx_desc+1);
 
 	/* Shorten the time on last normal descriptor */
 	local_irq_save(flags);
@@ -338,6 +341,9 @@
 		BUG_ON(sport->curr_tx_desc != sport->dummy_tx_desc);
 		/* Hook the normal buffer descriptor */
 		local_irq_save(flags);
+		while ((get_dma_curr_desc_ptr(sport->dma_tx_chan) - \
+			sizeof(struct dmasg)) != \
+			(unsigned long)sport->dummy_tx_desc) {}
 		sport->dummy_tx_desc->next_desc_addr = \
 				(unsigned long)(sport->dma_tx_desc);
 		local_irq_restore(flags);
@@ -537,19 +543,18 @@
 		printk(KERN_ERR "Failed to allocate memory for dummy rx desc\n");
 		return -ENOMEM;
 	}
-
 	memset(desc, 0, 2 * sizeof(*desc));
 	sport->dummy_rx_desc = desc;
-
-	desc->next_desc_addr = (unsigned long)desc;
 	desc->start_addr = (unsigned long)sport->dummy_buf;
 	config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize) | WNR | DMAEN;
 	desc->cfg = config;
 	desc->x_count = sport->dummy_count;
-	desc->x_modify = 0;
+	desc->x_modify = sport->wdsize;
 	desc->y_count = 0;
 	desc->y_modify = 0;
-
+	memcpy(desc+1, desc, sizeof(*desc));
+	desc->next_desc_addr = (unsigned long)(desc+1);
+	desc[1].next_desc_addr = (unsigned long)desc;
 	return 0;
 }
 
@@ -572,11 +577,8 @@
 		printk(KERN_ERR "Failed to allocate memory for dummy tx desc\n");
 		return -ENOMEM;
 	}
-
 	memset(desc, 0, 2 * sizeof(*desc));
 	sport->dummy_tx_desc = desc;
-
-	desc->next_desc_addr = (unsigned long)desc;
 	desc->start_addr = (unsigned long)sport->dummy_buf + \
 		sizeof(struct ac97_frame);
 	config = DMAFLOW_LARGE | NDSIZE_9 | compute_wdsize(sport->wdsize) | DMAEN;
@@ -585,7 +587,9 @@
 	desc->x_modify = sport->wdsize;
 	desc->y_count = 0;
 	desc->y_modify = 0;
-
+	memcpy(desc+1, desc, sizeof(*desc));
+	desc->next_desc_addr = (unsigned long)(desc+1);
+	desc[1].next_desc_addr = (unsigned long)desc;
 	return 0;
 }
 
@@ -715,6 +719,7 @@
 		printk(KERN_ERR "tx dma is already stopped\n");
 		return IRQ_HANDLED;
 	}
+	sport->tx_next_desc = get_dma_next_desc_ptr(sport->dma_tx_chan);
 	if (sport->tx_callback) {
 		sport->tx_callback(sport->tx_data);
 		return IRQ_HANDLED;
@@ -748,7 +753,6 @@
 			disable_dma(sport->dma_rx_chan);
 			sport_rx_dma_start(sport, 0);
 			enable_dma(sport->dma_rx_chan);
-
 		}
 	}
 	status = sport->regs->stat;

Modified: trunk/sound/soc/blackfin/bf5xx-sport.h (3989 => 3990)


--- trunk/sound/soc/blackfin/bf5xx-sport.h	2007-12-05 20:37:59 UTC (rev 3989)
+++ trunk/sound/soc/blackfin/bf5xx-sport.h	2007-12-05 23:54:57 UTC (rev 3990)
@@ -114,7 +114,7 @@
 	void *tx_data;
 	void (*err_callback)(void *data);
 	void *err_data;
-
+	unsigned long tx_next_desc;
 	void *private_data;
 };
 
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
http://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to