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

Next file: linux/drivers/sound/mad16.c
Previous file: linux/drivers/sound/audio.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.17/linux/drivers/sound/dmabuf.c linux/drivers/sound/dmabuf.c
@@ -489,14 +489,46 @@
     case SNDCTL_DSP_GETOSPACE:
       if (!local)
 	return RET_ERROR (EINVAL);
+      else
+	{
+	  audio_buf_info *info = (audio_buf_info *) arg;
+
+	  if (!(dmap->flags & DMA_ALLOC_DONE))
+	    reorganize_buffers (dev);
+
+	  if (cmd == SNDCTL_DSP_GETISPACE)
+	    info->fragments = dmap->qlen;
+	  else
+	    {
+	      if (!space_in_queue (dev))
+		info->fragments = 0;
+	      else
+		{
+		  info->fragments = dmap->nbufs - dmap->qlen;
+		  if (audio_devs[dev]->local_qlen)
+		    {
+		      int             tmp = audio_devs[dev]->local_qlen (dev);
+
+		      if (tmp & info->fragments)
+			tmp--;	/*
+				   * This buffer has been counted twice
+				 */
+		      info->fragments -= tmp;
+		    }
+		}
+	    }
+
+	  if (info->fragments < 0)
+	    info->fragments = 0;
+	  else if (info->fragments > dmap->nbufs)
+	    info->fragments = dmap->nbufs;
 
-      {
-	audio_buf_info *info = (audio_buf_info *) arg;
+	  info->fragsize = dmap->fragment_size;
+	  info->bytes = info->fragments * dmap->fragment_size;
 
-	info->fragments = dmap->qlen;
-	info->fragsize = dmap->fragment_size;
-	info->bytes = dmap->qlen * dmap->fragment_size;
-      }
+	  if (cmd == SNDCTL_DSP_GETISPACE && dmap->qlen)
+	    info->bytes -= dmap->counts[dmap->qhead];
+	}
       return 0;
 
     default:
@@ -511,7 +543,7 @@
   int             len, max, tmp;
   struct dma_buffparms *dmap = audio_devs[dev]->dmap;
 
-  if (dmap->qlen == dmap->nbufs)	/* No space at all */
+  if (dmap->qlen >= dmap->nbufs)	/* No space at all */
     return 0;
 
   /*
@@ -929,6 +961,7 @@
   switch (sel_type)
     {
     case SEL_IN:
+
       if (dmap->dma_mode != DMODE_INPUT)
 	return 0;
 
@@ -945,10 +978,14 @@
 
     case SEL_OUT:
       if (dmap->dma_mode == DMODE_INPUT)
-	return 0;
+	{
+	  return 0;
+	}
 
       if (dmap->dma_mode == DMODE_NONE)
-	return 1;
+	{
+	  return 1;
+	}
 
       if (!space_in_queue (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