patch-1.3.74 linux/drivers/sound/dmabuf.c

Next file: linux/drivers/sound/gus_card.c
Previous file: linux/drivers/sound/dev_table.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.73/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c
@@ -234,6 +234,7 @@
     dmap->dma_mode = DMODE_NONE;
   dmap->flags &= ~DMA_BUSY;
 
+  disable_dma (chan);
   sound_free_dmap (dev, dmap);
 }
 
@@ -1303,35 +1304,41 @@
 polish_buffers (struct dma_buffparms *dmap)
 {
   int             i;
+  int             p, l;
 
-  if (dmap->cfrag < 0)
+  i = dmap->qhead;
+
+  p = dmap->fragment_size * i;
+
+  if (i == dmap->cfrag)
     {
-      memset (dmap->raw_buf,
-	      dmap->neutral_byte,
-	      dmap->bytes_in_use);
-      return;
+      l = dmap->fragment_size - dmap->counts[i];
     }
+  else
+    l = dmap->fragment_size;
 
-  for (i = 0; i < dmap->nbufs; i++)
+  if (l)
     {
-      int             p, l;
-
-      p = dmap->fragment_size * i;
+      memset (dmap->raw_buf + p,
+	      dmap->neutral_byte,
+	      l);
+    }
+}
 
-      if (i == dmap->cfrag)
-	{
-	  l = dmap->fragment_size - dmap->counts[i];
-	}
-      else
-	l = dmap->fragment_size;
+static void
+force_restart (int dev, struct dma_buffparms *dmap)
+{
+  if ((audio_devs[dev]->flags & DMA_DUPLEX) &&
+      audio_devs[dev]->halt_output)
+    audio_devs[dev]->halt_output (dev);
+  else
+    audio_devs[dev]->halt_xfer (dev);
 
-      if (l)
-	{
-	  memset (dmap->raw_buf + p,
-		  dmap->neutral_byte,
-		  l);
-	}
-    }
+  dmap->flags &= ~DMA_ACTIVE;
+  if (audio_devs[dev]->flags & DMA_AUTOMODE)
+    dmap->flags |= DMA_RESTART;
+  else
+    dmap->flags &= ~DMA_RESTART;
 }
 
 void
@@ -1393,7 +1400,14 @@
       if (event_type == 1 && dmap->qlen < 1)
 	{
 	  dmap->underrun_count++;
-	  /* Ignore underrun. Just move the tail pointer forward and go */
+
+	  if (dmap->underrun_count > 5 || dmap->flags & DMA_EMPTY)
+	    {
+	      dmap->qlen = 0;
+	      force_restart (dev, dmap);
+	    }
+	  else
+	    /* Ignore underrun. Just move the tail pointer forward and go */
 	  if (dmap->closing)
 	    {
 	      polish_buffers (dmap);
@@ -1482,7 +1496,7 @@
 
       if (audio_devs[dev]->flags & DMA_AUTOMODE)
 	{
-	  /* Force restart on next write */
+	  /* Force restart on next read */
 	  if ((audio_devs[dev]->flags & DMA_DUPLEX) &&
 	      audio_devs[dev]->halt_input)
 	    audio_devs[dev]->halt_input (dev);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this