diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c
new file mode 100644
index 0000000..baf4244
--- /dev/null
+++ b/sound/oss/dmabuf.c
@@ -0,0 +1,1298 @@
+/*
+ * sound/dmabuf.c
+ *
+ * The DMA buffer manager for digitized voice applications
+ */
+/*
+ * Copyright (C) by Hannu Savolainen 1993-1997
+ *
+ * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
+ * Version 2 (June 1991). See the "COPYING" file distributed with this software
+ * for more info.
+ *
+ * Thomas Sailer   : moved several static variables into struct audio_operations
+ *                   (which is grossly misnamed btw.) because they have the same
+ *                   lifetime as the rest in there and dynamic allocation saves
+ *                   12k or so
+ * Thomas Sailer   : remove {in,out}_sleep_flag. It was used for the sleeper to
+ *                   determine if it was woken up by the expiring timeout or by
+ *                   an explicit wake_up. The return value from schedule_timeout
+ *		     can be used instead; if 0, the wakeup was due to the timeout.
+ *
+ * Rob Riggs		Added persistent DMA buffers (1998/10/17)
+ */
+
+#define BE_CONSERVATIVE
+#define SAMPLE_ROUNDUP 0
+
+#include "sound_config.h"
+
+#define DMAP_FREE_ON_CLOSE      0
+#define DMAP_KEEP_ON_CLOSE      1
+extern int sound_dmap_flag;
+
+static void dma_reset_output(int dev);
+static void dma_reset_input(int dev);
+static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode);
+
+
+
+static int debugmem;    	/* switched off by default */
+static int dma_buffsize = DSP_BUFFSIZE;
+
+static long dmabuf_timeout(struct dma_buffparms *dmap)
+{
+	long tmout;
+
+	tmout = (dmap->fragment_size * HZ) / dmap->data_rate;
+	tmout += HZ / 5;	/* Some safety distance */
+	if (tmout < (HZ / 2))
+		tmout = HZ / 2;
+	if (tmout > 20 * HZ)
+		tmout = 20 * HZ;
+	return tmout;
+}
+
+static int sound_alloc_dmap(struct dma_buffparms *dmap)
+{
+	char *start_addr, *end_addr;
+	int dma_pagesize;
+	int sz, size;
+	struct page *page;
+
+	dmap->mapping_flags &= ~DMA_MAP_MAPPED;
+
+	if (dmap->raw_buf != NULL)
+		return 0;	/* Already done */
+	if (dma_buffsize < 4096)
+		dma_buffsize = 4096;
+	dma_pagesize = (dmap->dma < 4) ? (64 * 1024) : (128 * 1024);
+	
+	/*
+	 *	Now check for the Cyrix problem.
+	 */
+	 
+	if(isa_dma_bridge_buggy==2)
+		dma_pagesize=32768;
+	 
+	dmap->raw_buf = NULL;
+	dmap->buffsize = dma_buffsize;
+	if (dmap->buffsize > dma_pagesize)
+		dmap->buffsize = dma_pagesize;
+	start_addr = NULL;
+	/*
+	 * Now loop until we get a free buffer. Try to get smaller buffer if
+	 * it fails. Don't accept smaller than 8k buffer for performance
+	 * reasons.
+	 */
+	while (start_addr == NULL && dmap->buffsize > PAGE_SIZE) {
+		for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
+		dmap->buffsize = PAGE_SIZE * (1 << sz);
+		start_addr = (char *) __get_free_pages(GFP_ATOMIC|GFP_DMA|__GFP_NOWARN, sz);
+		if (start_addr == NULL)
+			dmap->buffsize /= 2;
+	}
+
+	if (start_addr == NULL) {
+		printk(KERN_WARNING "Sound error: Couldn't allocate DMA buffer\n");
+		return -ENOMEM;
+	} else {
+		/* make some checks */
+		end_addr = start_addr + dmap->buffsize - 1;
+
+		if (debugmem)
+			printk(KERN_DEBUG "sound: start 0x%lx, end 0x%lx\n", (long) start_addr, (long) end_addr);
+		
+		/* now check if it fits into the same dma-pagesize */
+
+		if (((long) start_addr & ~(dma_pagesize - 1)) != ((long) end_addr & ~(dma_pagesize - 1))
+		    || end_addr >= (char *) (MAX_DMA_ADDRESS)) {
+			printk(KERN_ERR "sound: Got invalid address 0x%lx for %db DMA-buffer\n", (long) start_addr, dmap->buffsize);
+			return -EFAULT;
+		}
+	}
+	dmap->raw_buf = start_addr;
+	dmap->raw_buf_phys = virt_to_bus(start_addr);
+
+	for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
+		SetPageReserved(page);
+	return 0;
+}
+
+static void sound_free_dmap(struct dma_buffparms *dmap)
+{
+	int sz, size;
+	struct page *page;
+	unsigned long start_addr, end_addr;
+
+	if (dmap->raw_buf == NULL)
+		return;
+	if (dmap->mapping_flags & DMA_MAP_MAPPED)
+		return;		/* Don't free mmapped buffer. Will use it next time */
+	for (sz = 0, size = PAGE_SIZE; size < dmap->buffsize; sz++, size <<= 1);
+
+	start_addr = (unsigned long) dmap->raw_buf;
+	end_addr = start_addr + dmap->buffsize;
+
+	for (page = virt_to_page(start_addr); page <= virt_to_page(end_addr); page++)
+		ClearPageReserved(page);
+
+	free_pages((unsigned long) dmap->raw_buf, sz);
+	dmap->raw_buf = NULL;
+}
+
+
+/* Intel version !!!!!!!!! */
+
+static int sound_start_dma(struct dma_buffparms *dmap, unsigned long physaddr, int count, int dma_mode)
+{
+	unsigned long flags;
+	int chan = dmap->dma;
+
+	/* printk( "Start DMA%d %d, %d\n",  chan,  (int)(physaddr-dmap->raw_buf_phys),  count); */
+
+	flags = claim_dma_lock();
+	disable_dma(chan);
+	clear_dma_ff(chan);
+	set_dma_mode(chan, dma_mode);
+	set_dma_addr(chan, physaddr);
+	set_dma_count(chan, count);
+	enable_dma(chan);
+	release_dma_lock(flags);
+
+	return 0;
+}
+
+static void dma_init_buffers(struct dma_buffparms *dmap)
+{
+	dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
+	dmap->byte_counter = 0;
+	dmap->max_byte_counter = 8000 * 60 * 60;
+	dmap->bytes_in_use = dmap->buffsize;
+
+	dmap->dma_mode = DMODE_NONE;
+	dmap->mapping_flags = 0;
+	dmap->neutral_byte = 0x80;
+	dmap->data_rate = 8000;
+	dmap->cfrag = -1;
+	dmap->closing = 0;
+	dmap->nbufs = 1;
+	dmap->flags = DMA_BUSY;	/* Other flags off */
+}
+
+static int open_dmap(struct audio_operations *adev, int mode, struct dma_buffparms *dmap)
+{
+	int err;
+	
+	if (dmap->flags & DMA_BUSY)
+		return -EBUSY;
+	if ((err = sound_alloc_dmap(dmap)) < 0)
+		return err;
+
+	if (dmap->raw_buf == NULL) {
+		printk(KERN_WARNING "Sound: DMA buffers not available\n");
+		return -ENOSPC;	/* Memory allocation failed during boot */
+	}
+	if (dmap->dma >= 0 && sound_open_dma(dmap->dma, adev->name)) {
+		printk(KERN_WARNING "Unable to grab(2) DMA%d for the audio driver\n", dmap->dma);
+		return -EBUSY;
+	}
+	dma_init_buffers(dmap);
+	spin_lock_init(&dmap->lock);
+	dmap->open_mode = mode;
+	dmap->subdivision = dmap->underrun_count = 0;
+	dmap->fragment_size = 0;
+	dmap->max_fragments = 65536;	/* Just a large value */
+	dmap->byte_counter = 0;
+	dmap->max_byte_counter = 8000 * 60 * 60;
+	dmap->applic_profile = APF_NORMAL;
+	dmap->needs_reorg = 1;
+	dmap->audio_callback = NULL;
+	dmap->callback_parm = 0;
+	return 0;
+}
+
+static void close_dmap(struct audio_operations *adev, struct dma_buffparms *dmap)
+{
+	unsigned long flags;
+	
+	if (dmap->dma >= 0) {
+		sound_close_dma(dmap->dma);
+		flags=claim_dma_lock();
+		disable_dma(dmap->dma);
+		release_dma_lock(flags);
+	}
+	if (dmap->flags & DMA_BUSY)
+		dmap->dma_mode = DMODE_NONE;
+	dmap->flags &= ~DMA_BUSY;
+	
+	if (sound_dmap_flag == DMAP_FREE_ON_CLOSE)
+		sound_free_dmap(dmap);
+}
+
+
+static unsigned int default_set_bits(int dev, unsigned int bits)
+{
+	mm_segment_t fs = get_fs();
+
+	set_fs(get_ds());
+	audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SETFMT, (void __user *)&bits);
+	set_fs(fs);
+	return bits;
+}
+
+static int default_set_speed(int dev, int speed)
+{
+	mm_segment_t fs = get_fs();
+
+	set_fs(get_ds());
+	audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_SPEED, (void __user *)&speed);
+	set_fs(fs);
+	return speed;
+}
+
+static short default_set_channels(int dev, short channels)
+{
+	int c = channels;
+	mm_segment_t fs = get_fs();
+
+	set_fs(get_ds());
+	audio_devs[dev]->d->ioctl(dev, SNDCTL_DSP_CHANNELS, (void __user *)&c);
+	set_fs(fs);
+	return c;
+}
+
+static void check_driver(struct audio_driver *d)
+{
+	if (d->set_speed == NULL)
+		d->set_speed = default_set_speed;
+	if (d->set_bits == NULL)
+		d->set_bits = default_set_bits;
+	if (d->set_channels == NULL)
+		d->set_channels = default_set_channels;
+}
+
+int DMAbuf_open(int dev, int mode)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	int retval;
+	struct dma_buffparms *dmap_in = NULL;
+	struct dma_buffparms *dmap_out = NULL;
+
+	if (!adev)
+		  return -ENXIO;
+	if (!(adev->flags & DMA_DUPLEX))
+		adev->dmap_in = adev->dmap_out;
+	check_driver(adev->d);
+
+	if ((retval = adev->d->open(dev, mode)) < 0)
+		return retval;
+	dmap_out = adev->dmap_out;
+	dmap_in = adev->dmap_in;
+	if (dmap_in == dmap_out)
+		adev->flags &= ~DMA_DUPLEX;
+
+	if (mode & OPEN_WRITE) {
+		if ((retval = open_dmap(adev, mode, dmap_out)) < 0) {
+			adev->d->close(dev);
+			return retval;
+		}
+	}
+	adev->enable_bits = mode;
+
+	if (mode == OPEN_READ || (mode != OPEN_WRITE && (adev->flags & DMA_DUPLEX))) {
+		if ((retval = open_dmap(adev, mode, dmap_in)) < 0) {
+			adev->d->close(dev);
+			if (mode & OPEN_WRITE)
+				close_dmap(adev, dmap_out);
+			return retval;
+		}
+	}
+	adev->open_mode = mode;
+	adev->go = 1;
+
+	adev->d->set_bits(dev, 8);
+	adev->d->set_channels(dev, 1);
+	adev->d->set_speed(dev, DSP_DEFAULT_SPEED);
+	if (adev->dmap_out->dma_mode == DMODE_OUTPUT) 
+		memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,
+		       adev->dmap_out->bytes_in_use);
+	return 0;
+}
+/* MUST not hold the spinlock */
+void DMAbuf_reset(int dev)
+{
+	if (audio_devs[dev]->open_mode & OPEN_WRITE)
+		dma_reset_output(dev);
+
+	if (audio_devs[dev]->open_mode & OPEN_READ)
+		dma_reset_input(dev);
+}
+
+static void dma_reset_output(int dev)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	unsigned long flags,f ;
+	struct dma_buffparms *dmap = adev->dmap_out;
+
+	if (!(dmap->flags & DMA_STARTED))	/* DMA is not active */
+		return;
+
+	/*
+	 *	First wait until the current fragment has been played completely
+	 */
+	spin_lock_irqsave(&dmap->lock,flags);
+	adev->dmap_out->flags |= DMA_SYNCING;
+
+	adev->dmap_out->underrun_count = 0;
+	if (!signal_pending(current) && adev->dmap_out->qlen && 
+	    adev->dmap_out->underrun_count == 0){
+		spin_unlock_irqrestore(&dmap->lock,flags);
+		interruptible_sleep_on_timeout(&adev->out_sleeper,
+					       dmabuf_timeout(dmap));
+		spin_lock_irqsave(&dmap->lock,flags);
+	}
+	adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
+
+	/*
+	 *	Finally shut the device off
+	 */
+	if (!(adev->flags & DMA_DUPLEX) || !adev->d->halt_output)
+		adev->d->halt_io(dev);
+	else
+		adev->d->halt_output(dev);
+	adev->dmap_out->flags &= ~DMA_STARTED;
+	
+	f=claim_dma_lock();
+	clear_dma_ff(dmap->dma);
+	disable_dma(dmap->dma);
+	release_dma_lock(f);
+	
+	dmap->byte_counter = 0;
+	reorganize_buffers(dev, adev->dmap_out, 0);
+	dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
+	spin_unlock_irqrestore(&dmap->lock,flags);
+}
+
+static void dma_reset_input(int dev)
+{
+        struct audio_operations *adev = audio_devs[dev];
+	unsigned long flags;
+	struct dma_buffparms *dmap = adev->dmap_in;
+
+	spin_lock_irqsave(&dmap->lock,flags);
+	if (!(adev->flags & DMA_DUPLEX) || !adev->d->halt_input)
+		adev->d->halt_io(dev);
+	else
+		adev->d->halt_input(dev);
+	adev->dmap_in->flags &= ~DMA_STARTED;
+
+	dmap->qlen = dmap->qhead = dmap->qtail = dmap->user_counter = 0;
+	dmap->byte_counter = 0;
+	reorganize_buffers(dev, adev->dmap_in, 1);
+	spin_unlock_irqrestore(&dmap->lock,flags);
+}
+/* MUST be called with holding the dmap->lock */
+void DMAbuf_launch_output(int dev, struct dma_buffparms *dmap)
+{
+	struct audio_operations *adev = audio_devs[dev];
+
+	if (!((adev->enable_bits * adev->go) & PCM_ENABLE_OUTPUT))
+		return;		/* Don't start DMA yet */
+	dmap->dma_mode = DMODE_OUTPUT;
+
+	if (!(dmap->flags & DMA_ACTIVE) || !(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) {
+		if (!(dmap->flags & DMA_STARTED)) {
+			reorganize_buffers(dev, dmap, 0);
+			if (adev->d->prepare_for_output(dev, dmap->fragment_size, dmap->nbufs))
+				return;
+			if (!(dmap->flags & DMA_NODMA))
+				local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use,DMA_MODE_WRITE);
+			dmap->flags |= DMA_STARTED;
+		}
+		if (dmap->counts[dmap->qhead] == 0)
+			dmap->counts[dmap->qhead] = dmap->fragment_size;
+		dmap->dma_mode = DMODE_OUTPUT;
+		adev->d->output_block(dev, dmap->raw_buf_phys + dmap->qhead * dmap->fragment_size,
+				      dmap->counts[dmap->qhead], 1);
+		if (adev->d->trigger)
+			adev->d->trigger(dev,adev->enable_bits * adev->go);
+	}
+	dmap->flags |= DMA_ACTIVE;
+}
+
+int DMAbuf_sync(int dev)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	unsigned long flags;
+	int n = 0;
+	struct dma_buffparms *dmap;
+
+	if (!adev->go && !(adev->enable_bits & PCM_ENABLE_OUTPUT))
+		return 0;
+
+	if (adev->dmap_out->dma_mode == DMODE_OUTPUT) {
+		dmap = adev->dmap_out;
+		spin_lock_irqsave(&dmap->lock,flags);
+		if (dmap->qlen > 0 && !(dmap->flags & DMA_ACTIVE))
+			DMAbuf_launch_output(dev, dmap);
+		adev->dmap_out->flags |= DMA_SYNCING;
+		adev->dmap_out->underrun_count = 0;
+		while (!signal_pending(current) && n++ <= adev->dmap_out->nbufs && 
+		       adev->dmap_out->qlen && adev->dmap_out->underrun_count == 0) {
+			long t = dmabuf_timeout(dmap);
+			spin_unlock_irqrestore(&dmap->lock,flags);
+			/* FIXME: not safe may miss events */
+			t = interruptible_sleep_on_timeout(&adev->out_sleeper, t);
+			spin_lock_irqsave(&dmap->lock,flags);
+			if (!t) {
+				adev->dmap_out->flags &= ~DMA_SYNCING;
+				spin_unlock_irqrestore(&dmap->lock,flags);
+				return adev->dmap_out->qlen;
+			}
+		}
+		adev->dmap_out->flags &= ~(DMA_SYNCING | DMA_ACTIVE);
+		
+		/*
+		 * Some devices such as GUS have huge amount of on board RAM for the
+		 * audio data. We have to wait until the device has finished playing.
+		 */
+
+		/* still holding the lock */
+		if (adev->d->local_qlen) {   /* Device has hidden buffers */
+			while (!signal_pending(current) &&
+			       adev->d->local_qlen(dev)){
+				spin_unlock_irqrestore(&dmap->lock,flags);
+				interruptible_sleep_on_timeout(&adev->out_sleeper,
+							       dmabuf_timeout(dmap));
+				spin_lock_irqsave(&dmap->lock,flags);
+			}
+		}
+		spin_unlock_irqrestore(&dmap->lock,flags);
+	}
+	adev->dmap_out->dma_mode = DMODE_NONE;
+	return adev->dmap_out->qlen;
+}
+
+int DMAbuf_release(int dev, int mode)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap;
+	unsigned long flags;
+
+	dmap = adev->dmap_out;
+	if (adev->open_mode & OPEN_WRITE)
+		adev->dmap_out->closing = 1;
+
+	if (adev->open_mode & OPEN_READ){
+		adev->dmap_in->closing = 1;
+		dmap = adev->dmap_in;
+	}
+	if (adev->open_mode & OPEN_WRITE)
+		if (!(adev->dmap_out->mapping_flags & DMA_MAP_MAPPED))
+			if (!signal_pending(current) && (adev->dmap_out->dma_mode == DMODE_OUTPUT))
+				DMAbuf_sync(dev);
+	if (adev->dmap_out->dma_mode == DMODE_OUTPUT)
+		memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte, adev->dmap_out->bytes_in_use);
+
+	DMAbuf_reset(dev);
+	spin_lock_irqsave(&dmap->lock,flags);
+	adev->d->close(dev);
+
+	if (adev->open_mode & OPEN_WRITE)
+		close_dmap(adev, adev->dmap_out);
+
+	if (adev->open_mode == OPEN_READ ||
+	    (adev->open_mode != OPEN_WRITE &&
+	     (adev->flags & DMA_DUPLEX)))
+		close_dmap(adev, adev->dmap_in);
+	adev->open_mode = 0;
+	spin_unlock_irqrestore(&dmap->lock,flags);
+	return 0;
+}
+/* called with dmap->lock dold */
+int DMAbuf_activate_recording(int dev, struct dma_buffparms *dmap)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	int  err;
+
+	if (!(adev->open_mode & OPEN_READ))
+		return 0;
+	if (!(adev->enable_bits & PCM_ENABLE_INPUT))
+		return 0;
+	if (dmap->dma_mode == DMODE_OUTPUT) {	/* Direction change */
+		/* release lock - it's not recursive */
+		spin_unlock_irq(&dmap->lock);
+		DMAbuf_sync(dev);
+		DMAbuf_reset(dev);
+		spin_lock_irq(&dmap->lock);
+		dmap->dma_mode = DMODE_NONE;
+	}
+	if (!dmap->dma_mode) {
+		reorganize_buffers(dev, dmap, 1);
+		if ((err = adev->d->prepare_for_input(dev,
+				dmap->fragment_size, dmap->nbufs)) < 0)
+			return err;
+		dmap->dma_mode = DMODE_INPUT;
+	}
+	if (!(dmap->flags & DMA_ACTIVE)) {
+		if (dmap->needs_reorg)
+			reorganize_buffers(dev, dmap, 0);
+		local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);
+		adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size,
+				     dmap->fragment_size, 0);
+		dmap->flags |= DMA_ACTIVE;
+		if (adev->d->trigger)
+			adev->d->trigger(dev, adev->enable_bits * adev->go);
+	}
+	return 0;
+}
+/* aquires lock */
+int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	unsigned long flags;
+	int err = 0, n = 0;
+	struct dma_buffparms *dmap = adev->dmap_in;
+	int go;
+
+	if (!(adev->open_mode & OPEN_READ))
+		return -EIO;
+	spin_lock_irqsave(&dmap->lock,flags);
+	if (dmap->needs_reorg)
+		reorganize_buffers(dev, dmap, 0);
+	if (adev->dmap_in->mapping_flags & DMA_MAP_MAPPED) {
+/*		  printk(KERN_WARNING "Sound: Can't read from mmapped device (1)\n");*/
+		  spin_unlock_irqrestore(&dmap->lock,flags);
+		  return -EINVAL;
+	} else while (dmap->qlen <= 0 && n++ < 10) {
+		long timeout = MAX_SCHEDULE_TIMEOUT;
+		if (!(adev->enable_bits & PCM_ENABLE_INPUT) || !adev->go) {
+			spin_unlock_irqrestore(&dmap->lock,flags);
+			return -EAGAIN;
+		}
+		if ((err = DMAbuf_activate_recording(dev, dmap)) < 0) {
+			spin_unlock_irqrestore(&dmap->lock,flags);
+			return err;
+		}
+		/* Wait for the next block */
+
+		if (dontblock) {
+			spin_unlock_irqrestore(&dmap->lock,flags);
+			return -EAGAIN;
+		}
+		if ((go = adev->go))
+			timeout = dmabuf_timeout(dmap);
+
+		spin_unlock_irqrestore(&dmap->lock,flags);
+		timeout = interruptible_sleep_on_timeout(&adev->in_sleeper,
+							 timeout);
+		if (!timeout) {
+			/* FIXME: include device name */
+			err = -EIO;
+			printk(KERN_WARNING "Sound: DMA (input) timed out - IRQ/DRQ config error?\n");
+			dma_reset_input(dev);
+		} else
+			err = -EINTR;
+		spin_lock_irqsave(&dmap->lock,flags);
+	}
+	spin_unlock_irqrestore(&dmap->lock,flags);
+
+	if (dmap->qlen <= 0)
+		return err ? err : -EINTR;
+	*buf = &dmap->raw_buf[dmap->qhead * dmap->fragment_size + dmap->counts[dmap->qhead]];
+	*len = dmap->fragment_size - dmap->counts[dmap->qhead];
+
+	return dmap->qhead;
+}
+
+int DMAbuf_rmchars(int dev, int buff_no, int c)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_in;
+	int p = dmap->counts[dmap->qhead] + c;
+
+	if (dmap->mapping_flags & DMA_MAP_MAPPED)
+	{
+/*		  printk("Sound: Can't read from mmapped device (2)\n");*/
+		return -EINVAL;
+	}
+	else if (dmap->qlen <= 0)
+		return -EIO;
+	else if (p >= dmap->fragment_size) {  /* This buffer is completely empty */
+		dmap->counts[dmap->qhead] = 0;
+		dmap->qlen--;
+		dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
+	}
+	else dmap->counts[dmap->qhead] = p;
+
+	return 0;
+}
+/* MUST be called with dmap->lock hold */
+int DMAbuf_get_buffer_pointer(int dev, struct dma_buffparms *dmap, int direction)
+{
+	/*
+	 *	Try to approximate the active byte position of the DMA pointer within the
+	 *	buffer area as well as possible.
+	 */
+
+	int pos;
+	unsigned long f;
+
+	if (!(dmap->flags & DMA_ACTIVE))
+		pos = 0;
+	else {
+		int chan = dmap->dma;
+		
+		f=claim_dma_lock();
+		clear_dma_ff(chan);
+		
+		if(!isa_dma_bridge_buggy)
+			disable_dma(dmap->dma);
+		
+		pos = get_dma_residue(chan);
+		
+		pos = dmap->bytes_in_use - pos;
+
+		if (!(dmap->mapping_flags & DMA_MAP_MAPPED)) {
+			if (direction == DMODE_OUTPUT) {
+				if (dmap->qhead == 0)
+					if (pos > dmap->fragment_size)
+						pos = 0;
+			} else {
+				if (dmap->qtail == 0)
+					if (pos > dmap->fragment_size)
+						pos = 0;
+			}
+		}
+		if (pos < 0)
+			pos = 0;
+		if (pos >= dmap->bytes_in_use)
+			pos = 0;
+		
+		if(!isa_dma_bridge_buggy)
+			enable_dma(dmap->dma);
+			
+		release_dma_lock(f);
+	}
+	/* printk( "%04x ",  pos); */
+
+	return pos;
+}
+
+/*
+ *	DMAbuf_start_devices() is called by the /dev/music driver to start
+ *	one or more audio devices at desired moment.
+ */
+
+void DMAbuf_start_devices(unsigned int devmask)
+{
+	struct audio_operations *adev;
+	int dev;
+
+	for (dev = 0; dev < num_audiodevs; dev++) {
+		if (!(devmask & (1 << dev)))
+			continue;
+		if (!(adev = audio_devs[dev]))
+			continue;
+		if (adev->open_mode == 0)
+			continue;
+		if (adev->go)
+			continue;
+		/* OK to start the device */
+		adev->go = 1;
+		if (adev->d->trigger)
+			adev->d->trigger(dev,adev->enable_bits * adev->go);
+	}
+}
+/* via poll called without a lock ?*/
+int DMAbuf_space_in_queue(int dev)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	int len, max, tmp;
+	struct dma_buffparms *dmap = adev->dmap_out;
+	int lim = dmap->nbufs;
+
+	if (lim < 2)
+		lim = 2;
+
+	if (dmap->qlen >= lim)	/* No space at all */
+		return 0;
+
+	/*
+	 *	Verify that there are no more pending buffers than the limit
+	 *	defined by the process.
+	 */
+
+	max = dmap->max_fragments;
+	if (max > lim)
+		max = lim;
+	len = dmap->qlen;
+
+	if (adev->d->local_qlen) {
+		tmp = adev->d->local_qlen(dev);
+		if (tmp && len)
+			tmp--;	/* This buffer has been counted twice */
+		len += tmp;
+	}
+	if (dmap->byte_counter % dmap->fragment_size)	/* There is a partial fragment */
+		len = len + 1;
+
+	if (len >= max)
+		return 0;
+	return max - len;
+}
+/* MUST not hold the spinlock  - this function may sleep */
+static int output_sleep(int dev, int dontblock)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	int err = 0;
+	struct dma_buffparms *dmap = adev->dmap_out;
+	long timeout;
+	long timeout_value;
+
+	if (dontblock)
+		return -EAGAIN;
+	if (!(adev->enable_bits & PCM_ENABLE_OUTPUT))
+		return -EAGAIN;
+
+	/*
+	 * Wait for free space
+	 */
+	if (signal_pending(current))
+		return -EINTR;
+	timeout = (adev->go && !(dmap->flags & DMA_NOTIMEOUT));
+	if (timeout) 
+		timeout_value = dmabuf_timeout(dmap);
+	else
+		timeout_value = MAX_SCHEDULE_TIMEOUT;
+	timeout_value = interruptible_sleep_on_timeout(&adev->out_sleeper,
+						       timeout_value);
+	if (timeout != MAX_SCHEDULE_TIMEOUT && !timeout_value) {
+		printk(KERN_WARNING "Sound: DMA (output) timed out - IRQ/DRQ config error?\n");
+		dma_reset_output(dev);
+	} else {
+		if (signal_pending(current))
+			err = -EINTR;
+	}
+	return err;
+}
+/* called with the lock held */
+static int find_output_space(int dev, char **buf, int *size)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_out;
+	unsigned long active_offs;
+	long len, offs;
+	int maxfrags;
+	int occupied_bytes = (dmap->user_counter % dmap->fragment_size);
+
+	*buf = dmap->raw_buf;
+	if (!(maxfrags = DMAbuf_space_in_queue(dev)) && !occupied_bytes)
+		return 0;
+
+#ifdef BE_CONSERVATIVE
+	active_offs = dmap->byte_counter + dmap->qhead * dmap->fragment_size;
+#else
+	active_offs = DMAbuf_get_buffer_pointer(dev, dmap, DMODE_OUTPUT);
+	/* Check for pointer wrapping situation */
+	if (active_offs < 0 || active_offs >= dmap->bytes_in_use)
+		active_offs = 0;
+	active_offs += dmap->byte_counter;
+#endif
+
+	offs = (dmap->user_counter % dmap->bytes_in_use) & ~SAMPLE_ROUNDUP;
+	if (offs < 0 || offs >= dmap->bytes_in_use) {
+		printk(KERN_ERR "Sound: Got unexpected offs %ld. Giving up.\n", offs);
+		printk("Counter = %ld, bytes=%d\n", dmap->user_counter, dmap->bytes_in_use);
+		return 0;
+	}
+	*buf = dmap->raw_buf + offs;
+
+	len = active_offs + dmap->bytes_in_use - dmap->user_counter;	/* Number of unused bytes in buffer */
+
+	if ((offs + len) > dmap->bytes_in_use)
+		len = dmap->bytes_in_use - offs;
+	if (len < 0) {
+		return 0;
+	}
+	if (len > ((maxfrags * dmap->fragment_size) - occupied_bytes))
+		len = (maxfrags * dmap->fragment_size) - occupied_bytes;
+	*size = len & ~SAMPLE_ROUNDUP;
+	return (*size > 0);
+}
+/* aquires lock  */
+int DMAbuf_getwrbuffer(int dev, char **buf, int *size, int dontblock)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	unsigned long flags;
+	int err = -EIO;
+	struct dma_buffparms *dmap = adev->dmap_out;
+
+	if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+/*		printk(KERN_DEBUG "Sound: Can't write to mmapped device (3)\n");*/
+		return -EINVAL;
+	}
+	spin_lock_irqsave(&dmap->lock,flags);
+	if (dmap->needs_reorg)
+		reorganize_buffers(dev, dmap, 0);
+
+	if (dmap->dma_mode == DMODE_INPUT) {	/* Direction change */
+		spin_unlock_irqrestore(&dmap->lock,flags);
+		DMAbuf_reset(dev);
+		spin_lock_irqsave(&dmap->lock,flags);
+	}
+	dmap->dma_mode = DMODE_OUTPUT;
+
+	while (find_output_space(dev, buf, size) <= 0) {
+		spin_unlock_irqrestore(&dmap->lock,flags);
+		if ((err = output_sleep(dev, dontblock)) < 0) {
+			return err;
+		}
+		spin_lock_irqsave(&dmap->lock,flags);
+	}
+
+	spin_unlock_irqrestore(&dmap->lock,flags);
+	return 0;
+}
+/* has to aquire dmap->lock */
+int DMAbuf_move_wrpointer(int dev, int l)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_out;
+	unsigned long ptr;
+	unsigned long end_ptr, p;
+	int post;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dmap->lock,flags);
+	post= (dmap->flags & DMA_POST);
+	ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
+
+	dmap->flags &= ~DMA_POST;
+	dmap->cfrag = -1;
+	dmap->user_counter += l;
+	dmap->flags |= DMA_DIRTY;
+
+	if (dmap->byte_counter >= dmap->max_byte_counter) {
+		/* Wrap the byte counters */
+		long decr = dmap->byte_counter;
+		dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
+		decr -= dmap->byte_counter;
+		dmap->user_counter -= decr;
+	}
+	end_ptr = (dmap->user_counter / dmap->fragment_size) * dmap->fragment_size;
+
+	p = (dmap->user_counter - 1) % dmap->bytes_in_use;
+	dmap->neutral_byte = dmap->raw_buf[p];
+
+	/* Update the fragment based bookkeeping too */
+	while (ptr < end_ptr) {
+		dmap->counts[dmap->qtail] = dmap->fragment_size;
+		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+		dmap->qlen++;
+		ptr += dmap->fragment_size;
+	}
+
+	dmap->counts[dmap->qtail] = dmap->user_counter - ptr;
+
+	/*
+	 *	Let the low level driver perform some postprocessing to
+	 *	the written data.
+	 */
+	if (adev->d->postprocess_write)
+		adev->d->postprocess_write(dev);
+
+	if (!(dmap->flags & DMA_ACTIVE))
+		if (dmap->qlen > 1 || (dmap->qlen > 0 && (post || dmap->qlen >= dmap->nbufs - 1)))
+			DMAbuf_launch_output(dev, dmap);
+
+	spin_unlock_irqrestore(&dmap->lock,flags);
+	return 0;
+}
+
+int DMAbuf_start_dma(int dev, unsigned long physaddr, int count, int dma_mode)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;
+
+	if (dmap->raw_buf == NULL) {
+		printk(KERN_ERR "sound: DMA buffer(1) == NULL\n");
+		printk("Device %d, chn=%s\n", dev, (dmap == adev->dmap_out) ? "out" : "in");
+		return 0;
+	}
+	if (dmap->dma < 0)
+		return 0;
+	sound_start_dma(dmap, physaddr, count, dma_mode);
+	return count;
+}
+
+static int local_start_dma(struct audio_operations *adev, unsigned long physaddr, int count, int dma_mode)
+{
+	struct dma_buffparms *dmap = (dma_mode == DMA_MODE_WRITE) ? adev->dmap_out : adev->dmap_in;
+
+	if (dmap->raw_buf == NULL) {
+		printk(KERN_ERR "sound: DMA buffer(2) == NULL\n");
+		printk(KERN_ERR "Device %s, chn=%s\n", adev->name, (dmap == adev->dmap_out) ? "out" : "in");
+		return 0;
+	}
+	if (dmap->flags & DMA_NODMA)
+		return 1;
+	if (dmap->dma < 0)
+		return 0;
+	sound_start_dma(dmap, dmap->raw_buf_phys, dmap->bytes_in_use, dma_mode | DMA_AUTOINIT);
+	dmap->flags |= DMA_STARTED;
+	return count;
+}
+
+static void finish_output_interrupt(int dev, struct dma_buffparms *dmap)
+{
+	struct audio_operations *adev = audio_devs[dev];
+
+	if (dmap->audio_callback != NULL)
+		dmap->audio_callback(dev, dmap->callback_parm);
+	wake_up(&adev->out_sleeper);
+	wake_up(&adev->poll_sleeper);
+}
+/* called with dmap->lock held in irq context*/
+static void do_outputintr(int dev, int dummy)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_out;
+	int this_fragment;
+
+	if (dmap->raw_buf == NULL) {
+		printk(KERN_ERR "Sound: Error. Audio interrupt (%d) after freeing buffers.\n", dev);
+		return;
+	}
+	if (dmap->mapping_flags & DMA_MAP_MAPPED) {	/* Virtual memory mapped access */
+		/* mmapped access */
+		dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
+		if (dmap->qhead == 0) {	    /* Wrapped */
+			dmap->byte_counter += dmap->bytes_in_use;
+			if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */
+				long decr = dmap->byte_counter;
+				dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
+				decr -= dmap->byte_counter;
+				dmap->user_counter -= decr;
+			}
+		}
+		dmap->qlen++;	/* Yes increment it (don't decrement) */
+		if (!(adev->flags & DMA_AUTOMODE))
+			dmap->flags &= ~DMA_ACTIVE;
+		dmap->counts[dmap->qhead] = dmap->fragment_size;
+		DMAbuf_launch_output(dev, dmap);
+		finish_output_interrupt(dev, dmap);
+		return;
+	}
+
+	dmap->qlen--;
+	this_fragment = dmap->qhead;
+	dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
+
+	if (dmap->qhead == 0) {	/* Wrapped */
+		dmap->byte_counter += dmap->bytes_in_use;
+		if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */
+			long decr = dmap->byte_counter;
+			dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use);
+			decr -= dmap->byte_counter;
+			dmap->user_counter -= decr;
+		}
+	}
+	if (!(adev->flags & DMA_AUTOMODE))
+		dmap->flags &= ~DMA_ACTIVE;
+		
+	/*
+	 *	This is  dmap->qlen <= 0 except when closing when
+	 *	dmap->qlen < 0
+	 */
+	 
+	while (dmap->qlen <= -dmap->closing) {
+		dmap->underrun_count++;
+		dmap->qlen++;
+		if ((dmap->flags & DMA_DIRTY) && dmap->applic_profile != APF_CPUINTENS) {
+			dmap->flags &= ~DMA_DIRTY;
+			memset(adev->dmap_out->raw_buf, adev->dmap_out->neutral_byte,
+			       adev->dmap_out->buffsize);
+		}
+		dmap->user_counter += dmap->fragment_size;
+		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+	}
+	if (dmap->qlen > 0)
+		DMAbuf_launch_output(dev, dmap);
+	finish_output_interrupt(dev, dmap);
+}
+/* called in irq context */
+void DMAbuf_outputintr(int dev, int notify_only)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	unsigned long flags;
+	struct dma_buffparms *dmap = adev->dmap_out;
+
+	spin_lock_irqsave(&dmap->lock,flags);
+	if (!(dmap->flags & DMA_NODMA)) {
+		int chan = dmap->dma, pos, n;
+		unsigned long f;
+		
+		f=claim_dma_lock();
+		
+		if(!isa_dma_bridge_buggy)
+			disable_dma(dmap->dma);
+		clear_dma_ff(chan);
+		pos = dmap->bytes_in_use - get_dma_residue(chan);
+		if(!isa_dma_bridge_buggy)
+			enable_dma(dmap->dma);
+		release_dma_lock(f);
+		
+		pos = pos / dmap->fragment_size;	/* Actual qhead */
+		if (pos < 0 || pos >= dmap->nbufs)
+			pos = 0;
+		n = 0;
+		while (dmap->qhead != pos && n++ < dmap->nbufs)
+			do_outputintr(dev, notify_only);
+	}
+	else
+		do_outputintr(dev, notify_only);
+	spin_unlock_irqrestore(&dmap->lock,flags);
+}
+/* called with dmap->lock held in irq context */
+static void do_inputintr(int dev)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_in;
+
+	if (dmap->raw_buf == NULL) {
+		printk(KERN_ERR "Sound: Fatal error. Audio interrupt after freeing buffers.\n");
+		return;
+	}
+	if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+		if (dmap->qtail == 0) {		/* Wrapped */
+			dmap->byte_counter += dmap->bytes_in_use;
+			if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */
+				long decr = dmap->byte_counter;
+				dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+				decr -= dmap->byte_counter;
+				dmap->user_counter -= decr;
+			}
+		}
+		dmap->qlen++;
+
+		if (!(adev->flags & DMA_AUTOMODE)) {
+			if (dmap->needs_reorg)
+				reorganize_buffers(dev, dmap, 0);
+			local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use,DMA_MODE_READ);
+			adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size,
+					     dmap->fragment_size, 1);
+			if (adev->d->trigger)
+				adev->d->trigger(dev, adev->enable_bits * adev->go);
+		}
+		dmap->flags |= DMA_ACTIVE;
+	} else if (dmap->qlen >= (dmap->nbufs - 1)) {
+		printk(KERN_WARNING "Sound: Recording overrun\n");
+		dmap->underrun_count++;
+
+		/* Just throw away the oldest fragment but keep the engine running */
+		dmap->qhead = (dmap->qhead + 1) % dmap->nbufs;
+		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+	} else if (dmap->qlen >= 0 && dmap->qlen < dmap->nbufs) {
+		dmap->qlen++;
+		dmap->qtail = (dmap->qtail + 1) % dmap->nbufs;
+		if (dmap->qtail == 0) {		/* Wrapped */
+			dmap->byte_counter += dmap->bytes_in_use;
+			if (dmap->byte_counter >= dmap->max_byte_counter) {	/* Overflow */
+				long decr = dmap->byte_counter;
+				dmap->byte_counter = (dmap->byte_counter % dmap->bytes_in_use) + dmap->bytes_in_use;
+				decr -= dmap->byte_counter;
+				dmap->user_counter -= decr;
+			}
+		}
+	}
+	if (!(adev->flags & DMA_AUTOMODE) || (dmap->flags & DMA_NODMA)) {
+		local_start_dma(adev, dmap->raw_buf_phys, dmap->bytes_in_use, DMA_MODE_READ);
+		adev->d->start_input(dev, dmap->raw_buf_phys + dmap->qtail * dmap->fragment_size, dmap->fragment_size, 1);
+		if (adev->d->trigger)
+			adev->d->trigger(dev,adev->enable_bits * adev->go);
+	}
+	dmap->flags |= DMA_ACTIVE;
+	if (dmap->qlen > 0)
+	{
+		wake_up(&adev->in_sleeper);
+		wake_up(&adev->poll_sleeper);
+	}
+}
+/* called in irq context */
+void DMAbuf_inputintr(int dev)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_in;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dmap->lock,flags);
+
+	if (!(dmap->flags & DMA_NODMA)) {
+		int chan = dmap->dma, pos, n;
+		unsigned long f;
+		
+		f=claim_dma_lock();
+		if(!isa_dma_bridge_buggy)
+			disable_dma(dmap->dma);
+		clear_dma_ff(chan);
+		pos = dmap->bytes_in_use - get_dma_residue(chan);
+		if(!isa_dma_bridge_buggy)
+			enable_dma(dmap->dma);
+		release_dma_lock(f);
+
+		pos = pos / dmap->fragment_size;	/* Actual qhead */
+		if (pos < 0 || pos >= dmap->nbufs)
+			pos = 0;
+
+		n = 0;
+		while (dmap->qtail != pos && ++n < dmap->nbufs)
+			do_inputintr(dev);
+	} else
+		do_inputintr(dev);
+	spin_unlock_irqrestore(&dmap->lock,flags);
+}
+
+int DMAbuf_open_dma(int dev)
+{
+	/*
+	 *    NOTE!  This routine opens only the primary DMA channel (output).
+	 */
+	struct audio_operations *adev = audio_devs[dev];
+	int err;
+
+	if ((err = open_dmap(adev, OPEN_READWRITE, adev->dmap_out)) < 0)
+		return -EBUSY;
+	dma_init_buffers(adev->dmap_out);
+	adev->dmap_out->flags |= DMA_ALLOC_DONE;
+	adev->dmap_out->fragment_size = adev->dmap_out->buffsize;
+
+	if (adev->dmap_out->dma >= 0) {
+		unsigned long flags;
+
+		flags=claim_dma_lock();
+		clear_dma_ff(adev->dmap_out->dma);
+		disable_dma(adev->dmap_out->dma);
+		release_dma_lock(flags);
+	}
+	return 0;
+}
+
+void DMAbuf_close_dma(int dev)
+{
+	close_dmap(audio_devs[dev], audio_devs[dev]->dmap_out);
+}
+
+void DMAbuf_init(int dev, int dma1, int dma2)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	/*
+	 * NOTE! This routine could be called several times.
+	 */
+
+	/* drag in audio_syms.o */
+	{
+		extern char audio_syms_symbol;
+		audio_syms_symbol = 0;
+	}
+
+	if (adev && adev->dmap_out == NULL) {
+		if (adev->d == NULL)
+			panic("OSS: audio_devs[%d]->d == NULL\n", dev);
+
+		if (adev->parent_dev) {	 /* Use DMA map of the parent dev */
+			int parent = adev->parent_dev - 1;
+			adev->dmap_out = audio_devs[parent]->dmap_out;
+			adev->dmap_in = audio_devs[parent]->dmap_in;
+		} else {
+			adev->dmap_out = adev->dmap_in = &adev->dmaps[0];
+			adev->dmap_out->dma = dma1;
+			if (adev->flags & DMA_DUPLEX) {
+				adev->dmap_in = &adev->dmaps[1];
+				adev->dmap_in->dma = dma2;
+			}
+		}
+		/* Persistent DMA buffers allocated here */
+		if (sound_dmap_flag == DMAP_KEEP_ON_CLOSE) {
+			if (adev->dmap_in->raw_buf == NULL)
+				sound_alloc_dmap(adev->dmap_in);
+			if (adev->dmap_out->raw_buf == NULL)
+				sound_alloc_dmap(adev->dmap_out);
+		}
+	}
+}
+
+/* No kernel lock - DMAbuf_activate_recording protected by global cli/sti */
+static unsigned int poll_input(struct file * file, int dev, poll_table *wait)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_in;
+
+	if (!(adev->open_mode & OPEN_READ))
+		return 0;
+	if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+		if (dmap->qlen)
+			return POLLIN | POLLRDNORM;
+		return 0;
+	}
+	if (dmap->dma_mode != DMODE_INPUT) {
+		if (dmap->dma_mode == DMODE_NONE &&
+		    adev->enable_bits & PCM_ENABLE_INPUT &&
+		    !dmap->qlen && adev->go) {
+			unsigned long flags;
+			
+			spin_lock_irqsave(&dmap->lock,flags);
+			DMAbuf_activate_recording(dev, dmap);
+			spin_unlock_irqrestore(&dmap->lock,flags);
+		}
+		return 0;
+	}
+	if (!dmap->qlen)
+		return 0;
+	return POLLIN | POLLRDNORM;
+}
+
+static unsigned int poll_output(struct file * file, int dev, poll_table *wait)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	struct dma_buffparms *dmap = adev->dmap_out;
+	
+	if (!(adev->open_mode & OPEN_WRITE))
+		return 0;
+	if (dmap->mapping_flags & DMA_MAP_MAPPED) {
+		if (dmap->qlen)
+			return POLLOUT | POLLWRNORM;
+		return 0;
+	}
+	if (dmap->dma_mode == DMODE_INPUT)
+		return 0;
+	if (dmap->dma_mode == DMODE_NONE)
+		return POLLOUT | POLLWRNORM;
+	if (!DMAbuf_space_in_queue(dev))
+		return 0;
+	return POLLOUT | POLLWRNORM;
+}
+
+unsigned int DMAbuf_poll(struct file * file, int dev, poll_table *wait)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	poll_wait(file, &adev->poll_sleeper, wait);
+	return poll_input(file, dev, wait) | poll_output(file, dev, wait);
+}
+
+void DMAbuf_deinit(int dev)
+{
+	struct audio_operations *adev = audio_devs[dev];
+	/* This routine is called when driver is being unloaded */
+	if (!adev)
+		return;
+
+	/* Persistent DMA buffers deallocated here */
+	if (sound_dmap_flag == DMAP_KEEP_ON_CLOSE) {
+		sound_free_dmap(adev->dmap_out);
+		if (adev->flags & DMA_DUPLEX)
+			sound_free_dmap(adev->dmap_in);
+	}
+}
