[ep93xx] remove pre 2.6.39 patches and config
[openwrt/svn-archive/archive.git] / target / linux / ep93xx / patches-2.6.30 / 005-ep93xx-dma.patch
diff --git a/target/linux/ep93xx/patches-2.6.30/005-ep93xx-dma.patch b/target/linux/ep93xx/patches-2.6.30/005-ep93xx-dma.patch
deleted file mode 100644 (file)
index 3664132..0000000
+++ /dev/null
@@ -1,3622 +0,0 @@
---- /dev/null
-+++ b/arch/arm/mach-ep93xx/dma_ep93xx.c
-@@ -0,0 +1,2940 @@
-+/******************************************************************************
-+ * arch/arm/mach-ep9312/dma_ep93xx.c
-+ *
-+ * Support functions for the ep93xx internal DMA channels.
-+ * (see also Documentation/arm/ep93xx/dma.txt)
-+ *
-+ * Copyright (C) 2003  Cirrus Logic
-+ *
-+ * A large portion of this file is based on the dma api implemented by
-+ * Nicolas Pitre, dma-sa1100.c, copyrighted 2000.
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ ****************************************************************************/
-+#include <linux/autoconf.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/system.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/dma.h>
-+#include <asm/mach/dma.h>
-+#include "dma_ep93xx.h"
-+
-+/*****************************************************************************
-+ *
-+ * Debugging macros
-+ *
-+ ****************************************************************************/
-+#undef DEBUG
-+//#define DEBUG   1
-+#ifdef DEBUG
-+#define DPRINTK( fmt, arg... )  printk( fmt, ##arg )
-+#else
-+#define DPRINTK( fmt, arg... )
-+#endif
-+
-+/*****************************************************************************
-+ *
-+ * static global variables
-+ *
-+ ****************************************************************************/
-+ep93xx_dma_t dma_chan[MAX_EP93XX_DMA_CHANNELS];
-+
-+/*
-+ *  lock used to protect the list of dma channels while searching for a free
-+ *  channel during dma_request.
-+ */
-+//static spinlock_t dma_list_lock;
-+static spinlock_t dma_list_lock = SPIN_LOCK_UNLOCKED;
-+
-+/*****************************************************************************
-+ *
-+ *  Internal DMA processing functions.
-+ *
-+ ****************************************************************************/
-+/*****************************************************************************
-+ *
-+ *  get_dma_channel_from_handle()
-+ *
-+ *  If Handle is valid, returns the DMA channel # (0 to 9 for channels 1-10)
-+ *  If Handle is not valid, returns -1.
-+ *
-+ ****************************************************************************/
-+static int
-+dma_get_channel_from_handle(int handle)
-+{
-+      int channel;
-+
-+      /*
-+       *  Get the DMA channel # from the handle.
-+       */
-+      channel = ((int)handle & DMA_HANDLE_SPECIFIER_MASK) >> 28;
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (dma_chan[channel].last_valid_handle != (int)handle) {
-+              DPRINTK("DMA ERROR - invalid handle 0x%x \n", handle);
-+              return(-1);
-+      }
-+
-+      /*
-+       *  See if this instance is still open
-+       */
-+      if (!dma_chan[channel].ref_count )
-+              return(-1);
-+
-+      return(channel);
-+}
-+
-+static void dma_m2m_transfer_done(ep93xx_dma_t *dma)
-+{
-+      unsigned int uiCONTROL;
-+      unsigned int M2M_reg_base = dma->reg_base;
-+      unsigned int read_back;
-+
-+      DPRINTK("1  ");
-+
-+      outl( 0, M2M_reg_base+M2M_OFFSET_INTERRUPT );
-+
-+      if (dma->total_buffers) {
-+              /*
-+               * The current_buffer has already been tranfered, so add the
-+               * byte count to the total_bytes field.
-+               */
-+              dma->total_bytes = dma->total_bytes +
-+                      dma->buffer_queue[dma->current_buffer].size;
-+
-+              /*
-+               * Mark the current_buffer as used.
-+               */
-+              dma->buffer_queue[dma->current_buffer].used = TRUE;
-+
-+              /*
-+               * Increment the used buffer counter
-+               */
-+              dma->used_buffers++;
-+
-+              DPRINTK("#%d", dma->current_buffer);
-+
-+              /*
-+               * Increment the current_buffer
-+               */
-+              dma->current_buffer = (dma->current_buffer + 1) %
-+                                    MAX_EP93XX_DMA_BUFFERS;
-+
-+              /*
-+               * check if there's a new buffer to transfer.
-+               */
-+              if (dma->new_buffers && dma->xfer_enable) {
-+                      /*
-+                       * We have a new buffer to transfer so program in the
-+                       * buffer values.  Since a STALL interrupt was
-+                       * triggered, we program the buffer descriptor 0
-+                       *
-+                       * Set the SAR_BASE/DAR_BASE/BCR registers with values
-+                       * from the next buffer in the queue.
-+                       */
-+                      outl( dma->buffer_queue[dma->current_buffer].source,
-+                            M2M_reg_base + M2M_OFFSET_SAR_BASE0 );
-+
-+                      outl( dma->buffer_queue[dma->current_buffer].dest,
-+                            M2M_reg_base + M2M_OFFSET_DAR_BASE0 );
-+
-+                      outl( dma->buffer_queue[dma->current_buffer].size,
-+                            M2M_reg_base + M2M_OFFSET_BCR0 );
-+
-+                      DPRINTK("SAR_BASE0 - 0x%x\n", dma->buffer_queue[dma->current_buffer].source);
-+                      DPRINTK("DAR_BASE0 - 0x%x\n", dma->buffer_queue[dma->current_buffer].dest);
-+                      DPRINTK("BCR0 - 0x%x\n", dma->buffer_queue[dma->current_buffer].size);
-+
-+                      /*
-+                       * Decrement the new buffer counter
-+                       */
-+                      dma->new_buffers--;
-+
-+                      /*
-+                       * If there's a second new buffer, we program the
-+                       * second buffer descriptor.
-+                       */
-+                      if (dma->new_buffers) {
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].source,
-+                                    M2M_reg_base+M2M_OFFSET_SAR_BASE1 );
-+
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].dest,
-+                                    M2M_reg_base+M2M_OFFSET_DAR_BASE1 );
-+
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].size,
-+                                    M2M_reg_base+M2M_OFFSET_BCR1 );
-+
-+                              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+                              uiCONTROL |= CONTROL_M2M_NFBINTEN;
-+                              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+                              dma->new_buffers--;
-+                      }
-+              } else {
-+                      DPRINTK("2 \n");
-+                      /*
-+                       * There's a chance we setup both buffer descriptors,
-+                       * but didn't service the NFB quickly enough, causing
-+                       * the channel to transfer both buffers, then enter the
-+                       * stall state.  So, we need to be able to process the
-+                       * second buffer.
-+                       */
-+                      if ((dma->used_buffers + dma->new_buffers) < dma->total_buffers)
-+                      {
-+                              DPRINTK("3 ");
-+
-+                              /*
-+                               * The current_buffer has already been
-+                               * tranferred, so add the byte count to the
-+                               * total_bytes field.
-+                               */
-+                              dma->total_bytes = dma->total_bytes +
-+                                      dma->buffer_queue[dma->current_buffer].size;
-+
-+                              /*
-+                               * Mark the current_buffer as used.
-+                               */
-+                              dma->buffer_queue[dma->current_buffer].used = TRUE;
-+
-+                              /*
-+                               * Increment the used buffer counter
-+                               */
-+                              dma->used_buffers++;
-+
-+                              DPRINTK("#%d", dma->current_buffer);
-+
-+                              /*
-+                               * Increment the current buffer pointer.
-+                               */
-+                              dma->current_buffer = (dma->current_buffer + 1) %
-+                                                    MAX_EP93XX_DMA_BUFFERS;
-+
-+                      }
-+
-+                      /*
-+                       * No new buffers to transfer, so disable the channel.
-+                       */
-+                      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+                      uiCONTROL &= ~CONTROL_M2M_ENABLE;
-+                      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+                      /*
-+                       * Indicate that this channel is in the pause by
-+                       * starvation state by setting the pause bit to true.
-+                       */
-+                      dma->pause = TRUE;
-+              }
-+      } else {
-+              /*
-+               * No buffers to transfer, or old buffers to mark as used,
-+               * so disable the channel
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~CONTROL_M2M_ENABLE;
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+              /*
-+               * Must read the control register back after a write.
-+               */
-+              read_back = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+
-+              /*
-+               * Indicate that this channel is in the pause by
-+               * starvation state by setting the pause bit to true.
-+               */
-+              dma->pause = TRUE;
-+      }
-+}
-+
-+static void dma_m2m_next_frame_buffer(ep93xx_dma_t *dma)
-+{
-+      int loop;
-+      unsigned int uiCONTROL;
-+      unsigned int M2M_reg_base = dma->reg_base;
-+
-+      DPRINTK("5  ");
-+
-+      if (dma->total_buffers) {
-+              DPRINTK("6  ");
-+              /*
-+               * The iCurrentBuffer has already been transfered.  so add the
-+               * byte count from the current buffer to the total byte count.
-+               */
-+              dma->total_bytes = dma->total_bytes +
-+                      dma->buffer_queue[dma->current_buffer].size;
-+
-+              /*
-+               * Mark the Current Buffer as used.
-+               */
-+              dma->buffer_queue[dma->current_buffer].used = TRUE;
-+
-+              /*
-+               * Increment the used buffer counter
-+               */
-+              dma->used_buffers++;
-+
-+              DPRINTK("#%d", dma->current_buffer);
-+
-+              if ((dma->buffer_queue[
-+                  (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) ||
-+                  (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) {
-+                      DPRINTK("7  ");
-+
-+                      /*
-+                       * This is the last Buffer in this transaction, so
-+                       * disable the NFB interrupt.  We shouldn't get an NFB
-+                       * int when the FSM moves to the ON state where it
-+                       * would typically get the NFB int indicating a new
-+                       * buffer can be programmed.  Instead, once in the ON
-+                       * state, the DMA will just proceed to complete the
-+                       * transfer of the current buffer, move the FSB
-+                       * directly to the STALL state where a STALL interrupt
-+                       * will be generated.
-+                       */
-+                      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+                      uiCONTROL &= ~CONTROL_M2M_NFBINTEN ;
-+                      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+                      /*
-+                       * The current buffer has been transferred, so
-+                       * increment the current buffer counter to reflect
-+                       * this.
-+                       */
-+                      dma->current_buffer = (dma->current_buffer + 1) %
-+                                            MAX_EP93XX_DMA_BUFFERS;
-+
-+                      DPRINTK("End of NFB handling. \n");
-+                      DPRINTK("CONTROL - 0x%x \n",
-+                                inl(M2M_reg_base+M2M_OFFSET_CONTROL) );
-+                      DPRINTK("STATUS - 0x%x \n",
-+                                inl(M2M_reg_base+M2M_OFFSET_STATUS) );
-+                      DPRINTK("SAR_BASE0 - 0x%x \n",
-+                                inl(M2M_reg_base+M2M_OFFSET_SAR_BASE0) );
-+                      DPRINTK("SAR_CUR0 - 0x%x \n",
-+                                inl(M2M_reg_base+M2M_OFFSET_SAR_CURRENT0) );
-+                      DPRINTK("DAR_BASE0 - 0x%x \n",
-+                                inl(M2M_reg_base+M2M_OFFSET_DAR_BASE0) );
-+                      DPRINTK("DAR_CUR0 - 0x%x \n",
-+                                inl(M2M_reg_base+M2M_OFFSET_DAR_CURRENT0) );
-+
-+                      DPRINTK("Buffer buf_id   source    size    last    used \n");
-+                      for (loop = 0; loop < 32; loop ++)
-+                              DPRINTK("%d             0x%x            0x%x             0x%x           %d               %d \n",
-+                                      loop, dma->buffer_queue[loop].buf_id,
-+                                      dma->buffer_queue[loop].source,
-+                                      dma->buffer_queue[loop].size,
-+                                      dma->buffer_queue[loop].last,
-+                                      dma->buffer_queue[loop].used);
-+                      DPRINTK("pause   0x%x           0x%x             0x%x           %d               %d \n",
-+                              dma->pause_buf.buf_id, dma->pause_buf.source,
-+                              dma->pause_buf.size, dma->pause_buf.last,
-+                              dma->pause_buf.used);
-+
-+                      DPRINTK("Pause - %d \n", dma->pause);
-+                      DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
-+                      DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
-+                      DPRINTK("total buffer - %d \n", dma->total_buffers);
-+                      DPRINTK("new buffers - %d \n", dma->new_buffers);
-+                      DPRINTK("current buffer - %d \n", dma->current_buffer);
-+                      DPRINTK("last buffer - %d \n", dma->last_buffer);
-+                      DPRINTK("used buffers - %d \n", dma->used_buffers);
-+                      DPRINTK("callback addr - 0x%p \n", dma->callback);
-+
-+              } else if (dma->new_buffers) {
-+                      DPRINTK("8  ");
-+                      /*
-+                       * We have a new buffer, so increment the current
-+                       * buffer to point to the next buffer, which is already
-+                       * programmed into the DMA. Next time around, it'll be
-+                       * pointing to the current buffer.
-+                       */
-+                      dma->current_buffer = (dma->current_buffer + 1) %
-+                                            MAX_EP93XX_DMA_BUFFERS;
-+
-+                      /*
-+                       * We know we have a new buffer to program as the next
-+                       * buffer, so check which set of SAR_BASE/DAR_BASE/BCR
-+                       * registers to program.
-+                       */
-+                      if ( inl(M2M_reg_base+M2M_OFFSET_STATUS) & STATUS_M2M_NB ) {
-+                              /*
-+                               * Set the SAR_BASE1/DAR_BASE1/BCR1 registers
-+                               * with values from the next buffer in the
-+                               * queue.
-+                               */
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].source,
-+                                    M2M_reg_base+M2M_OFFSET_SAR_BASE1 );
-+
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].dest,
-+                                    M2M_reg_base+M2M_OFFSET_DAR_BASE1 );
-+
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].size,
-+                                    M2M_reg_base+M2M_OFFSET_BCR1 );
-+                      } else {
-+                              /*
-+                               * Set the SAR_BASE0/DAR_BASE0/BCR0 registers
-+                               * with values from the next buffer in the
-+                               * queue.
-+                               */
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].source,
-+                                    M2M_reg_base+M2M_OFFSET_SAR_BASE0 );
-+
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].dest,
-+                                    M2M_reg_base+M2M_OFFSET_DAR_BASE0 );
-+
-+                              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                      MAX_EP93XX_DMA_BUFFERS].size,
-+                                    M2M_reg_base+M2M_OFFSET_BCR0 );
-+                      }
-+
-+                      /*
-+                       *  Decrement the new buffers counter
-+                       */
-+                      dma->new_buffers--;
-+              }
-+      } else {
-+              /*
-+               * Total number of buffers is 0 - really we should never get
-+               * here, but just in case.
-+               */
-+              DPRINTK("9 \n");
-+
-+              /*
-+               *  No new buffers to transfer, so Disable the channel
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~CONTROL_M2M_ENABLE;
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+              /*
-+               *  Indicate that the channel is paused by starvation.
-+               */
-+              dma->pause = 1;
-+      }
-+}
-+
-+/*****************************************************************************
-+ *
-+ * dma_m2m_irq_handler
-+ *
-+ ****************************************************************************/
-+static irqreturn_t
-+dma_m2m_irq_handler(int irq, void *dev_id)
-+{
-+      ep93xx_dma_t *dma = (ep93xx_dma_t *)dev_id;
-+      unsigned int M2M_reg_base = dma->reg_base;
-+      ep93xx_dma_dev_t dma_int = UNDEF_INT;
-+      int status;
-+
-+//    printk("+m2m irq=%d\n", irq);
-+
-+      /*
-+       *  Determine what kind of dma interrupt this is.
-+       */
-+      status = inl(M2M_reg_base + M2M_OFFSET_INTERRUPT);
-+      if ( status & INTERRUPT_M2M_DONEINT )
-+              dma_int = DONE; // we're done with a requested dma
-+      else if ( status & INTERRUPT_M2M_NFBINT )
-+              dma_int = NFB;  // we're done with one dma buffer
-+
-+      DPRINTK("IRQ: b=%#x st=%#x\n", (int)dma->current_buffer, dma_int);
-+
-+      switch (dma_int) {
-+      /*
-+       *  Next Frame Buffer Interrupt.  If there's a new buffer program it
-+       *  Check if this is the last buffer in the transfer,
-+       *  and if it is, disable the NFB int to prevent being
-+       *  interrupted for another buffer when we know there won't be
-+       *  another.
-+       */
-+      case NFB:
-+              dma_m2m_next_frame_buffer(dma);
-+              break;
-+      /*
-+       *  Done interrupt generated, indicating that the transfer is complete.
-+       */
-+      case DONE:
-+              dma_m2m_transfer_done(dma);
-+              break;
-+
-+      default:
-+              break;
-+      }
-+
-+      if ((dma_int != UNDEF_INT) && dma->callback)
-+              dma->callback(dma_int, dma->device, dma->user_data);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+/*****************************************************************************
-+ *
-+ * dma_m2p_irq_handler
-+ *
-+ *
-+ *
-+ ****************************************************************************/
-+static irqreturn_t
-+dma_m2p_irq_handler(int irq, void *dev_id)
-+{
-+      ep93xx_dma_t *dma = (ep93xx_dma_t *) dev_id;
-+      unsigned int M2P_reg_base = dma->reg_base;
-+      unsigned int read_back;
-+      ep93xx_dma_dev_t dma_int = UNDEF_INT;
-+      unsigned int loop, uiCONTROL, uiINTERRUPT;
-+
-+      /*
-+       *  Determine what kind of dma interrupt this is.
-+       */
-+      if ( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_STALLINT )
-+              dma_int = STALL;
-+      else if ( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_NFBINT )
-+              dma_int = NFB;
-+      else if ( inl(M2P_reg_base+M2P_OFFSET_INTERRUPT) & INTERRUPT_M2P_CHERRORINT )
-+              dma_int = CHERROR;
-+
-+      /*
-+       *  Stall Interrupt: The Channel is stalled, meaning nothing is
-+       *  programmed to transfer right now.  So, we're back to the
-+       *  beginnning.  If there's a buffer to transfer, program it into
-+       *  max and base 0 registers.
-+       */
-+      if (dma_int == STALL) {
-+              DPRINTK("1  ");
-+
-+              if (dma->total_buffers) {
-+                      /*
-+                       * The current_buffer has already been tranfered, so
-+                       * add the byte count to the total_bytes field.
-+                       */
-+                      dma->total_bytes = dma->total_bytes +
-+                              dma->buffer_queue[dma->current_buffer].size;
-+
-+                      /*
-+                       *  Mark the current_buffer as used.
-+                       */
-+                      dma->buffer_queue[dma->current_buffer].used = TRUE;
-+
-+                      /*
-+                       *  Increment the used buffer counter
-+                       */
-+                      dma->used_buffers++;
-+
-+                      DPRINTK("#%d", dma->current_buffer);
-+
-+                      /*
-+                       *  Increment the current_buffer
-+                       */
-+                      dma->current_buffer = (dma->current_buffer + 1) %
-+                                            MAX_EP93XX_DMA_BUFFERS;
-+
-+                      /*
-+                       *  check if there's a new buffer to transfer.
-+                       */
-+                      if (dma->new_buffers && dma->xfer_enable) {
-+                              /*
-+                               * We have a new buffer to transfer so program
-+                               * in the buffer values.  Since a STALL
-+                               * interrupt was triggered, we program the
-+                               * base0 and maxcnt0
-+                               *
-+                               * Set the MAXCNT0 register with the buffer
-+                               * size
-+                               */
-+                              outl( dma->buffer_queue[dma->current_buffer].size,
-+                                        M2P_reg_base+M2P_OFFSET_MAXCNT0 );
-+
-+                              /*
-+                               * Set the BASE0 register with the buffer base
-+                               * address
-+                               */
-+                              outl( dma->buffer_queue[dma->current_buffer].source,
-+                                        M2P_reg_base+M2P_OFFSET_BASE0 );
-+
-+                              /*
-+                               *  Decrement the new buffer counter
-+                               */
-+                              dma->new_buffers--;
-+
-+                              if (dma->new_buffers) {
-+                                      DPRINTK("A  ");
-+                                      /*
-+                                       * Set the MAXCNT1 register with the
-+                                       * buffer size
-+                                       */
-+                                      outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                                                                      MAX_EP93XX_DMA_BUFFERS].size,
-+                                                M2P_reg_base+M2P_OFFSET_MAXCNT1 );
-+
-+                                      /*
-+                                       * Set the BASE1 register with the
-+                                       * buffer base address
-+                                       */
-+                                      outl( dma->buffer_queue[dma->current_buffer + 1 %
-+                                                                                      MAX_EP93XX_DMA_BUFFERS].source,
-+                                                M2P_reg_base+M2P_OFFSET_BASE1 );
-+
-+                                      /*
-+                                       *  Decrement the new buffer counter
-+                                       */
-+                                      dma->new_buffers--;
-+
-+                                      /*
-+                                       *  Enable the NFB Interrupt.
-+                                       */
-+                                      uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+                                      uiCONTROL |= CONTROL_M2P_NFBINTEN;
-+                                      outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+                              }
-+                      } else {
-+                              /*
-+                               *  No new buffers.
-+                               */
-+                              DPRINTK("2 \n");
-+
-+                              /*
-+                               *  There's a chance we setup both buffer descriptors, but
-+                               *  didn't service the NFB quickly enough, causing the channel
-+                               *  to transfer both buffers, then enter the stall state.
-+                               *  So, we need to be able to process the second buffer.
-+                               */
-+                              if ((dma->used_buffers + dma->new_buffers) < dma->total_buffers) {
-+                                      DPRINTK("3 ");
-+
-+                                      /*
-+                                       *  The current_buffer has already been tranfered, so add the
-+                                       *  byte count to the total_bytes field.
-+                                       */
-+                                      dma->total_bytes = dma->total_bytes +
-+                                              dma->buffer_queue[dma->current_buffer].size;
-+
-+                                      /*
-+                                       *  Mark the current_buffer as used.
-+                                       */
-+                                      dma->buffer_queue[dma->current_buffer].used = TRUE;
-+
-+                                      /*
-+                                       *  Increment the used buffer counter
-+                                       */
-+                                      dma->used_buffers++;
-+
-+                                      DPRINTK("#%d", dma->current_buffer);
-+
-+                                      /*
-+                                       *  Increment the current buffer pointer.
-+                                       */
-+                                      dma->current_buffer = (dma->current_buffer + 1) %
-+                                              MAX_EP93XX_DMA_BUFFERS;
-+
-+                              }
-+
-+                              /*
-+                               *  No new buffers to transfer, so disable the channel.
-+                               */
-+                              uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+                              uiCONTROL &= ~CONTROL_M2P_ENABLE;
-+                              outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+                              /*
-+                               *  Indicate that this channel is in the pause by starvation
-+                               *  state by setting the pause bit to true.
-+                               */
-+                              dma->pause = TRUE;
-+
-+                              DPRINTK("STATUS - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_STATUS) );
-+                              DPRINTK("CONTROL - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
-+                              DPRINTK("REMAIN - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
-+                              DPRINTK("PPALLOC - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
-+                              DPRINTK("BASE0 - 0x%x \n",        inl(M2P_reg_base+M2P_OFFSET_BASE0) );
-+                              DPRINTK("MAXCNT0 - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
-+                              DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
-+                              DPRINTK("BASE1 - 0x%x \n",        inl(M2P_reg_base+M2P_OFFSET_BASE1) );
-+                              DPRINTK("MAXCNT1 - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
-+                              DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
-+
-+                              DPRINTK("Buffer buf_id   source    size    last    used \n");
-+                              for (loop = 0; loop < 32; loop ++)
-+                                      DPRINTK("%d             0x%x            0x%x             0x%x           %d               %d \n",
-+                                                      loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source,
-+                                                      dma->buffer_queue[loop].size,
-+                                                      dma->buffer_queue[loop].last, dma->buffer_queue[loop].used);
-+                              DPRINTK("pause   0x%x           0x%x             0x%x           %d               %d \n",
-+                                              dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size,
-+                                              dma->pause_buf.last, dma->pause_buf.used);
-+
-+                              DPRINTK("Pause - %d \n", dma->pause);
-+                              DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
-+                              DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
-+                              DPRINTK("total buffer - %d \n", dma->total_buffers);
-+                              DPRINTK("new buffers - %d \n", dma->new_buffers);
-+                              DPRINTK("current buffer - %d \n", dma->current_buffer);
-+                              DPRINTK("last buffer - %d \n", dma->last_buffer);
-+                              DPRINTK("used buffers - %d \n", dma->used_buffers);
-+                              DPRINTK("callback addr - 0x%p \n", dma->callback);
-+                      }
-+              } else {
-+                      /*
-+                       *  No buffers to transfer, or old buffers to mark as used,
-+                       *  so Disable the channel
-+                       */
-+                      uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+                      uiCONTROL &= ~CONTROL_M2P_ENABLE;
-+                      outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+                      /*
-+                       *  Must read the control register back after a write.
-+                       */
-+                      read_back = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+
-+                      /*
-+                       *  Indicate that this channel is in the pause by
-+                       *  starvation state by setting the pause bit to true.
-+                       */
-+                      dma->pause = TRUE;
-+              }
-+      }
-+
-+      /*
-+       *  Next Frame Buffer Interrupt.  If there's a new buffer program it
-+       *  Check if this is the last buffer in the transfer,
-+       *  and if it is, disable the NFB int to prevent being
-+       *  interrupted for another buffer when we know there won't be
-+       *  another.
-+       */
-+      if (dma_int == NFB) {
-+              DPRINTK("5  ");
-+
-+              if (dma->total_buffers) {
-+                      DPRINTK("6  ");
-+                      /*
-+                       *  The iCurrentBuffer has already been transfered.  so add the
-+                       *  byte count from the current buffer to the total byte count.
-+                       */
-+                      dma->total_bytes = dma->total_bytes +
-+                              dma->buffer_queue[dma->current_buffer].size;
-+
-+                      /*
-+                       *  Mark the Current Buffer as used.
-+                       */
-+                      dma->buffer_queue[dma->current_buffer].used = TRUE;
-+
-+                      /*
-+                       *  Increment the used buffer counter
-+                       */
-+                      dma->used_buffers++;
-+
-+                      DPRINTK("#%d", dma->current_buffer);
-+
-+                      if ((dma->buffer_queue[
-+                          (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].last) ||
-+                          (dma->new_buffers == 0) || (dma->xfer_enable == FALSE)) {
-+                              DPRINTK("7  ");
-+
-+                              /*
-+                               *  This is the last Buffer in this transaction, so disable
-+                               *  the NFB interrupt.  We shouldn't get an NFB int when the
-+                               *  FSM moves to the ON state where it would typically get the
-+                               *  NFB int indicating a new buffer can be programmed.
-+                               *  Instead, once in the ON state, the DMA will just proceed
-+                               *  to complet the transfer of the current buffer, move the
-+                               *  FSB directly to the STALL state where a STALL interrupt
-+                               *  will be generated.
-+                               */
-+                              uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+                              uiCONTROL &= ~CONTROL_M2P_NFBINTEN;
-+                              outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+                              /*
-+                               *  The current buffer has been transferred, so increment
-+                               *  the current buffer counter to reflect this.
-+                               */
-+                              dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS;
-+
-+                              DPRINTK("End of NFB handling. \n");
-+                              DPRINTK("STATUS - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_STATUS) );
-+                              DPRINTK("CONTROL - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
-+                              DPRINTK("REMAIN - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
-+                              DPRINTK("PPALLOC - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
-+                              DPRINTK("BASE0 - 0x%x \n",        inl(M2P_reg_base+M2P_OFFSET_BASE0) );
-+                              DPRINTK("MAXCNT0 - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
-+                              DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
-+                              DPRINTK("BASE1 - 0x%x \n",        inl(M2P_reg_base+M2P_OFFSET_BASE1) );
-+                              DPRINTK("MAXCNT1 - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
-+                              DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
-+
-+                              DPRINTK("Buffer buf_id   source    size    last    used \n");
-+                              for (loop = 0; loop < 32; loop ++)
-+                                      DPRINTK("%d             0x%x            0x%x             0x%x           %d               %d \n",
-+                                                      loop, dma->buffer_queue[loop].buf_id, dma->buffer_queue[loop].source,
-+                                                      dma->buffer_queue[loop].size,
-+                                                      dma->buffer_queue[loop].last, dma->buffer_queue[loop].used);
-+                              DPRINTK("pause   0x%x           0x%x             0x%x           %d               %d \n",
-+                                              dma->pause_buf.buf_id, dma->pause_buf.source, dma->pause_buf.size,
-+                                              dma->pause_buf.last, dma->pause_buf.used);
-+
-+                              DPRINTK("Pause - %d \n", dma->pause);
-+                              DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
-+                              DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
-+                              DPRINTK("total buffer - %d \n", dma->total_buffers);
-+                              DPRINTK("new buffers - %d \n", dma->new_buffers);
-+                              DPRINTK("current buffer - %d \n", dma->current_buffer);
-+                              DPRINTK("last buffer - %d \n", dma->last_buffer);
-+                              DPRINTK("used buffers - %d \n", dma->used_buffers);
-+                              DPRINTK("callback addr - 0x%p \n", dma->callback);
-+
-+                      } else if (dma->new_buffers) {
-+                              DPRINTK("8  ");
-+                              /*
-+                               *  we have a new buffer, so increment the current buffer to
-+                               *  point to the next buffer, which is already programmed into
-+                               *  the DMA. Next time around, it'll be pointing to the
-+                               *  current buffer.
-+                               */
-+                              dma->current_buffer = (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS;
-+
-+                              /*
-+                               *  we know we have a new buffer to program as the next
-+                               *  buffer, so check which set of MAXCNT and BASE registers
-+                               *  to program.
-+                               */
-+                              if ( inl(M2P_reg_base+M2P_OFFSET_STATUS) & STATUS_M2P_NEXTBUFFER ) {
-+                                      /*
-+                                       *  Set the MAXCNT1 register with the buffer size
-+                                       */
-+                                      outl( dma->buffer_queue[
-+                                            (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size,
-+                                            M2P_reg_base+M2P_OFFSET_MAXCNT1 );
-+
-+                                      /*
-+                                       *  Set the BASE1 register with the buffer base address
-+                                       */
-+                                      outl( dma->buffer_queue[
-+                                            (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source,
-+                                            M2P_reg_base+M2P_OFFSET_BASE1 );
-+                              } else {
-+                                      /*
-+                                       *  Set the MAXCNT0 register with the buffer size
-+                                       */
-+                                      outl( dma->buffer_queue[
-+                                            (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].size,
-+                                             M2P_reg_base+M2P_OFFSET_MAXCNT0 );
-+
-+                                      /*
-+                                       *  Set the BASE0 register with the buffer base address
-+                                       */
-+                                      outl( dma->buffer_queue[
-+                                            (dma->current_buffer + 1) % MAX_EP93XX_DMA_BUFFERS].source,
-+                                            M2P_reg_base+M2P_OFFSET_BASE0 );
-+                              }
-+
-+                              /*
-+                               *  Decrement the new buffers counter
-+                               */
-+                              dma->new_buffers--;
-+                      }
-+              } else {
-+                      /*
-+                       *  Total number of buffers is 0 - really we should never get here,
-+                       *  but just in case.
-+                       */
-+                      DPRINTK("9 \n");
-+
-+                      /*
-+                       *  No new buffers to transfer, so Disable the channel
-+                       */
-+                      uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+                      uiCONTROL &= ~CONTROL_M2P_ENABLE;
-+                      outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+              }
-+      }
-+
-+      /*
-+       *  Channel Error Interrupt, or perhipheral interrupt, specific to the
-+       *  memory to/from peripheral channels.
-+       */
-+      if (dma_int == CHERROR) {
-+              /*
-+               *  just clear the interrupt, it's really up to the peripheral
-+               *  driver to determine if any further action is necessary.
-+               */
-+              uiINTERRUPT = inl(M2P_reg_base+M2P_OFFSET_INTERRUPT);
-+              uiINTERRUPT &= ~INTERRUPT_M2P_CHERRORINT;
-+              outl( uiINTERRUPT, M2P_reg_base+M2P_OFFSET_INTERRUPT );
-+      }
-+
-+      /*
-+       *  Make sure the interrupt was valid, and if it was, then check
-+       *  if a callback function was installed for this DMA channel.  If a
-+       *  callback was installed call it.
-+       */
-+      if ((dma_int != UNDEF_INT) && dma->callback)
-+              dma->callback(dma_int, dma->device, dma->user_data);
-+
-+      return IRQ_HANDLED;
-+}
-+
-+/*****************************************************************************
-+ *
-+ * ep9312_dma_open_m2p(int device)
-+ *
-+ * Description: This function will attempt to open a M2P/P2M DMA channel.
-+ *                      If the open is successful, the channel number is returned,
-+ *                      otherwise a negative number is returned.
-+ *
-+ * Parameters:
-+ *  device:    device for which the dma channel is requested.
-+ *
-+ ****************************************************************************/
-+static int
-+dma_open_m2p(int device)
-+{
-+      int channel = -1;
-+      unsigned int loop;
-+      unsigned int M2P_reg_base;
-+      unsigned int uiPWRCNT;
-+      /*unsigned long flags;*/
-+
-+      DPRINTK("DMA Open M2P with hw dev %d\n", device);
-+
-+      /*
-+       *  Lock the dma channel list.
-+       */
-+      //spin_lock_irqsave(&dma_list_lock, flags);
-+      spin_lock(&dma_list_lock);
-+
-+      /*
-+       * Verify that the device requesting DMA isn't already using a DMA channel
-+       */
-+      if (device >= 10)
-+              loop = 1;                // Rx transfer requested
-+      else
-+              loop = 0;                // Tx transfer requested
-+
-+      for (; loop < 10; loop = loop + 2)
-+              /*
-+               *  Before checking for a matching device, check that the
-+               *  channel is in use, otherwise the device field is
-+               *  invalid.
-+               */
-+              if (dma_chan[loop].ref_count)
-+                      if (device == dma_chan[loop].device) {
-+                              DPRINTK("DMA Open M2P - Error\n");
-+                              return(-1);
-+                      }
-+
-+      /*
-+       *  Get a DMA channel instance for the given hardware device.
-+       *  If this is a TX look for even numbered channels, else look for
-+       *  odd numbered channels
-+       */
-+      if (device >= 10)
-+              loop = 1;                /* Rx transfer requested */
-+      else
-+              loop = 0;                /* Tx transfer requested */
-+
-+      for (; loop < 10; loop = loop + 2)
-+              if (!dma_chan[loop].ref_count) {
-+                      /*
-+                       *  Capture the channel and increment the reference count.
-+                       */
-+                      channel = loop;
-+                      dma_chan[channel].ref_count++;
-+                      break;
-+              }
-+
-+      /*
-+       *  Unlock the dma channel list.
-+       */
-+      //spin_unlock_irqrestore(&dma_list_lock, flags);
-+      spin_unlock(&dma_list_lock);
-+      /*
-+       *  See if we got a valid channel.
-+       */
-+      if (channel < 0)
-+              return(-1);
-+
-+      /*
-+       *  Point regs to the correct dma channel register base.
-+       */
-+      M2P_reg_base = dma_chan[channel].reg_base;
-+
-+      /*
-+       *  Turn on the clock for the specified DMA channel
-+       *  TODO: need to use the correct register name for the
-+       *  power control register.
-+       */
-+      uiPWRCNT = inl(/*SYSCON_PWRCNT*/EP93XX_SYSCON_CLOCK_CONTROL);
-+      switch (channel) {
-+      case 0:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH0;
-+              break;
-+
-+      case 1:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH1;
-+              break;
-+
-+      case 2:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH2;
-+              break;
-+
-+      case 3:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH3;
-+              break;
-+
-+      case 4:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH4;
-+              break;
-+
-+      case 5:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH5;
-+              break;
-+
-+      case 6:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH6;
-+              break;
-+
-+      case 7:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH7;
-+              break;
-+
-+      case 8:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH8;
-+              break;
-+
-+      case 9:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2PCH9;
-+              break;
-+
-+      default:
-+              return(-1);
-+      }
-+      outl( uiPWRCNT, /*SYSCON_PWRCNT*/EP93XX_SYSCON_CLOCK_CONTROL );
-+
-+      /*
-+       *  Clear out the control register before any further setup.
-+       */
-+      outl( 0, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+      /*
-+       *  Setup the peripheral port value in the DMA channel registers.
-+       */
-+      if (device < 10)
-+              outl( (unsigned int)device, M2P_reg_base+M2P_OFFSET_PPALLOC );
-+      else
-+              outl( (unsigned int)(device - 10), M2P_reg_base+M2P_OFFSET_PPALLOC );
-+
-+      /*
-+       *  Let's hold on to the value of the Hw device for comparison later.
-+       */
-+      dma_chan[channel].device = device;
-+
-+      /*
-+       *  Success.
-+       */
-+      return(channel);
-+}
-+
-+/*****************************************************************************
-+ *
-+ * dma_open_m2m(int device)
-+ *
-+ * Description: This function will attempt to open a M2M DMA channel.
-+ *                      If the open is successful, the channel number is returned,
-+ *                      otherwise a negative number is returned.
-+ *
-+ * Parameters:
-+ *  device:    device for which the dma channel is requested.
-+ *
-+ ****************************************************************************/
-+static int
-+dma_open_m2m(int device)
-+{
-+      int channel = -1;
-+      unsigned int loop;
-+      unsigned int M2M_reg_base;
-+      unsigned int uiPWRCNT, uiCONTROL;
-+      /*unsigned long flags;*/
-+
-+      DPRINTK("DMA Open M2M with hw dev %d\n", device);
-+
-+      /*
-+       *  Lock the dma channel list.
-+       */
-+      //spin_lock_irqsave(&dma_list_lock, flags);
-+      spin_lock(&dma_list_lock);
-+
-+
-+      /*
-+       *  Check if this device is already allocated a channel.
-+       *  TODO: can one M2M device be allocated multiple channels?
-+       */
-+      for (loop = 10; loop < 12; loop++)
-+              /*
-+               *  Before checking for a matching device, check that the
-+               *  channel is in use, otherwise the device field is
-+               *  invalid.
-+               */
-+              if (dma_chan[loop].ref_count)
-+                      if (device == dma_chan[loop].device) {
-+                              DPRINTK("Error - dma_open_m2m - already allocated channel\n");
-+
-+                              /*
-+                               *  Unlock the dma channel list.
-+                               */
-+                              //spin_unlock_irqrestore(&dma_list_lock, flags);
-+                              spin_unlock(&dma_list_lock);
-+                              /*
-+                               *  Fail.
-+                               */
-+                              return(-1);
-+                      }
-+
-+      /*
-+       *  Get a DMA channel instance for the given hardware device.
-+       */
-+      for (loop = 10; loop < 12; loop++)
-+              if (!dma_chan[loop].ref_count) {
-+                      /*
-+                       *  Capture the channel and increment the reference count.
-+                       */
-+                      channel = loop;
-+                      dma_chan[channel].ref_count++;
-+                      break;
-+              }
-+
-+      /*
-+       *  Unlock the dma channel list.
-+       */
-+      //spin_unlock(dma_list_lock);
-+      spin_unlock(&dma_list_lock);
-+      //spin_unlock_irqrestore(&dma_list_lock, flags);
-+
-+      /*
-+       *  See if we got a valid channel.
-+       */
-+      if (channel < 0)
-+              return(-1);
-+
-+      /*
-+       *  Point regs to the correct dma channel register base.
-+       */
-+      M2M_reg_base = dma_chan[channel].reg_base;
-+
-+      /*
-+       *  Turn on the clock for the specified DMA channel
-+       *  TODO: need to use the correct register name for the
-+       *  power control register.
-+       */
-+      uiPWRCNT = inl(/*SYSCON_PWRCNT*/EP93XX_SYSCON_CLOCK_CONTROL);
-+      switch (channel) {
-+      case 10:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH0;
-+              break;
-+
-+      case 11:
-+              uiPWRCNT |= SYSCON_PWRCNT_DMA_M2MCH1;
-+              break;
-+
-+      default:
-+              return(-1);
-+      }
-+      outl( uiPWRCNT, /*SYSCON_PWRCNT*/EP93XX_SYSCON_CLOCK_CONTROL);
-+
-+      DPRINTK("DMA Open - power control: 0x%x \n", inl(SYSCON_PWRCNT) );
-+
-+      /*
-+       *  Clear out the control register before any further setup.
-+       */
-+      outl( 0, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+      /*
-+       *  Setup the transfer mode and the request source selection within
-+       *  the DMA M2M channel registers.
-+       */
-+      switch (device) {
-+      case DMA_MEMORY:
-+              /*
-+               * Clear TM field, set RSS field to 0
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~(CONTROL_M2M_TM_MASK | CONTROL_M2M_RSS_MASK);
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+              break;
-+
-+      case DMA_IDE:
-+              /*
-+               * Set RSS field to 3, Set NO_HDSK, Set PW field to 1
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_PW_MASK);
-+              uiCONTROL |= (3<<CONTROL_M2M_RSS_SHIFT) |
-+                      CONTROL_M2M_NO_HDSK |
-+                      (2<<CONTROL_M2M_PW_SHIFT);
-+
-+              uiCONTROL &= ~(CONTROL_M2M_ETDP_MASK);
-+              uiCONTROL &= ~(CONTROL_M2M_DACKP);
-+              uiCONTROL &= ~(CONTROL_M2M_DREQP_MASK);
-+
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+              inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              break;
-+
-+      case DMARx_SSP:
-+              /*
-+               * Set RSS field to 1, Set NO_HDSK, Set TM field to 2
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
-+              uiCONTROL |= (1<<CONTROL_M2M_RSS_SHIFT) |
-+                      CONTROL_M2M_NO_HDSK |
-+                      (2<<CONTROL_M2M_TM_SHIFT);
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+              break;
-+
-+      case DMATx_SSP:
-+              /*
-+               * Set RSS field to 2, Set NO_HDSK, Set TM field to 1
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
-+              uiCONTROL |= (2<<CONTROL_M2M_RSS_SHIFT) |
-+                      CONTROL_M2M_NO_HDSK |
-+                      (1<<CONTROL_M2M_TM_SHIFT);
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+              break;
-+
-+      case DMATx_EXT_DREQ:
-+              /*
-+               * Set TM field to 2, set RSS field to 0
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
-+              uiCONTROL |= 1<<CONTROL_M2M_TM_SHIFT;
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+              break;
-+
-+      case DMARx_EXT_DREQ:
-+              /*
-+               * Set TM field to 2, set RSS field to 0
-+               */
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~(CONTROL_M2M_RSS_MASK|CONTROL_M2M_TM_MASK);
-+              uiCONTROL |= 2<<CONTROL_M2M_TM_SHIFT;
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+              break;
-+
-+      default:
-+              return -1;
-+      }
-+
-+      /*
-+       *  Let's hold on to the value of the Hw device for comparison later.
-+       */
-+      dma_chan[channel].device = device;
-+
-+      /*
-+       *  Success.
-+       */
-+      return(channel);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int dma_config_m2m(ep93xx_dma_t * dma, unsigned int flags_m2m,
-+ *                       dma_callback callback, unsigned int user_data)
-+ *
-+ *  Description: Configure the DMA channel and install a callback function.
-+ *                       This function will have to be called for every transfer
-+ *
-+ *  dma:              Pointer to the dma instance data for the M2M channel to
-+ *                      configure.
-+ *  flags_m2m   Flags used to configure an M2M dma channel and determine
-+ *                      if a callback function and user_data information are included
-+ *                      in this call.
-+ *  callback  function pointer which is called near the end of the
-+ *                      dma channel's irq handler.
-+ *  user_data   defined by the calling driver.
-+ *
-+ ****************************************************************************/
-+static int
-+dma_config_m2m(ep93xx_dma_t * dma, unsigned int flags_m2m,
-+                         dma_callback callback, unsigned int user_data)
-+{
-+      unsigned long flags;
-+      unsigned int M2M_reg_base, uiCONTROL;
-+
-+      /*
-+       *  Make sure the channel is disabled before configuring the channel.
-+       *
-+       *  TODO: Is this correct??   Making a big change here...
-+       */
-+      /* if (!dma->pause || (!dma->pause && dma->xfer_enable)) */
-+      if (dma->xfer_enable) {
-+              /*
-+               *  DMA channel is not paused, so we can't configure it.
-+               */
-+              DPRINTK("DMA channel not paused, so can't configure! \n");
-+              return(-1);
-+      }
-+
-+      /*
-+       *  Mask interrupts.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  Setup a pointer into the dma channel's register set.
-+       */
-+      M2M_reg_base = dma->reg_base;
-+
-+      uiCONTROL = inl(M2M_reg_base + M2M_OFFSET_CONTROL);
-+      outl(0, M2M_reg_base + M2M_OFFSET_CONTROL);
-+      inl(M2M_reg_base + M2M_OFFSET_CONTROL);
-+      outl(uiCONTROL, M2M_reg_base + M2M_OFFSET_CONTROL);
-+
-+      /*
-+       *  By default we disable the stall interrupt.
-+       */
-+      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+      uiCONTROL &= ~CONTROL_M2M_STALLINTEN;
-+      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+      /*
-+       *  By default we disable the done interrupt.
-+       */
-+      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+      uiCONTROL &= ~CONTROL_M2M_DONEINTEN;
-+      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+      /*
-+       *  Set up the transfer control fields based on values passed in
-+       *  the flags_m2m field.
-+       */
-+      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+
-+      if ( flags_m2m & DESTINATION_HOLD )
-+              uiCONTROL |= CONTROL_M2M_DAH;
-+      else
-+              uiCONTROL &= ~CONTROL_M2M_DAH;
-+
-+      if ( flags_m2m & SOURCE_HOLD )
-+              uiCONTROL |= CONTROL_M2M_SAH;
-+      else
-+              uiCONTROL &= ~CONTROL_M2M_SAH;
-+
-+      uiCONTROL &= ~CONTROL_M2M_TM_MASK;
-+      uiCONTROL |= (((flags_m2m & TRANSFER_MODE_MASK) >> TRANSFER_MODE_SHIFT) <<
-+                                CONTROL_M2M_TM_SHIFT) & CONTROL_M2M_TM_MASK;
-+
-+      uiCONTROL &= ~CONTROL_M2M_PWSC_MASK;
-+      uiCONTROL |= (((flags_m2m & WAIT_STATES_MASK) >> WAIT_STATES_SHIFT) <<
-+                                CONTROL_M2M_PWSC_SHIFT) & CONTROL_M2M_PWSC_MASK;
-+
-+      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+      inl(M2M_reg_base + M2M_OFFSET_CONTROL);
-+
-+      /*
-+       *  Save the callback function in the dma instance for this channel.
-+       */
-+      dma->callback = callback;
-+
-+      /*
-+       *  Save the user data in the the dma instance for this channel.
-+       */
-+      dma->user_data = user_data;
-+
-+      /*
-+       *  Put the dma instance into the pause state by setting the
-+       *  pause bit to true.
-+       */
-+      dma->pause = TRUE;
-+
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int dma_start(int handle, unsigned int channels, unsigned int * handles)
-+ *
-+ *  Description: Initiate a transfer on up to 3 channels.
-+ *
-+ *  handle:    handle for the channel to initiate transfer on.
-+ *  channels:   number of channels to initiate transfers on.
-+ *  handles:  pointer to an array of handles, one for each channel which
-+ *                       is to be started.
-+ *
-+ ****************************************************************************/
-+static int
-+dma_start_m2m(int channel, ep93xx_dma_t * dma)
-+{
-+      unsigned long flags;
-+      unsigned int M2M_reg_base = dma->reg_base;
-+      unsigned int uiCONTROL;
-+
-+      /*
-+       *  Mask interrupts while we get this started.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  Make sure the channel has at least one buffer in the queue.
-+       */
-+      if (dma->new_buffers < 1) {
-+              /*
-+               *  Unmask irqs
-+               */
-+              local_irq_restore(flags);
-+
-+              DPRINTK("DMA Start: Channel starved.\n");
-+
-+              /*
-+               *  This channel does not have enough buffers queued up,
-+               *  so enter the pause by starvation state.
-+               */
-+              dma->xfer_enable = TRUE;
-+              dma->pause = TRUE;
-+
-+              /*
-+               *  Success.
-+               */
-+              return(0);
-+      }
-+
-+      /*
-+       *  Clear any pending interrupts.
-+       */
-+      outl(0x0, M2M_reg_base+M2M_OFFSET_INTERRUPT);
-+
-+      /*
-+       *  Set up one or both buffer descriptors with values from the next one or
-+       *  two buffers in the queue.  By default disable the next frame buffer
-+       *  interrupt on the channel.
-+       */
-+      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+      uiCONTROL &= ~CONTROL_M2M_NFBINTEN;
-+      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+      /*
-+       * enable the done interrupt.
-+       */
-+      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+      uiCONTROL |= CONTROL_M2M_DONEINTEN;
-+      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+      /*
-+       *  Update the dma channel instance transfer state.
-+       */
-+      dma->xfer_enable = TRUE;
-+      dma->pause = FALSE;
-+
-+      /*
-+       *  Program up the first buffer descriptor with a source and destination
-+       *  and a byte count.
-+       */
-+      outl( dma->buffer_queue[dma->current_buffer].source,
-+            M2M_reg_base+M2M_OFFSET_SAR_BASE0 );
-+
-+      outl( dma->buffer_queue[dma->current_buffer].dest,
-+            M2M_reg_base+M2M_OFFSET_DAR_BASE0 );
-+
-+      outl( dma->buffer_queue[dma->current_buffer].size,
-+            M2M_reg_base+M2M_OFFSET_BCR0 );
-+
-+      /*
-+       *  Decrement the new buffers counter.
-+       */
-+      dma->new_buffers--;
-+
-+      /*
-+       * Set up the second buffer descriptor with a second buffer if we have
-+       * a second buffer.
-+       */
-+      if (dma->new_buffers) {
-+              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                      MAX_EP93XX_DMA_BUFFERS].source,
-+                    M2M_reg_base+M2M_OFFSET_SAR_BASE1 );
-+
-+              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                      MAX_EP93XX_DMA_BUFFERS].dest,
-+                    M2M_reg_base+M2M_OFFSET_DAR_BASE1 );
-+
-+              outl( dma->buffer_queue[(dma->current_buffer + 1) %
-+                                      MAX_EP93XX_DMA_BUFFERS].size,
-+                    M2M_reg_base+M2M_OFFSET_BCR1 );
-+
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL |= CONTROL_M2M_NFBINTEN;
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+
-+              dma->new_buffers--;
-+      }
-+
-+      /*
-+       *  Now we enable the channel.  This initiates the transfer.
-+       */
-+      uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+      uiCONTROL |= CONTROL_M2M_ENABLE;
-+      outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+      inl(M2M_reg_base + M2M_OFFSET_CONTROL);
-+
-+      /*
-+       *  If this is a memory to memory transfer, we need to s/w trigger the
-+       *  transfer by setting the start bit within the control register.
-+       */
-+      if (dma->device == DMA_MEMORY) {
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL |= CONTROL_M2M_START;
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+      }
-+
-+      DPRINTK("DMA - It's been started!!");
-+      DPRINTK("CONTROL - 0x%x \n",    inl(M2M_reg_base+M2M_OFFSET_CONTROL) );
-+      DPRINTK("STATUS - 0x%x \n",      inl(M2M_reg_base+M2M_OFFSET_STATUS) );
-+      DPRINTK("BCR0 - 0x%x \n",          dma->buffer_queue[dma->current_buffer].size);
-+      DPRINTK("SAR_BASE0 - 0x%x \n",  inl(M2M_reg_base+M2M_OFFSET_SAR_BASE0) );
-+      DPRINTK("SAR_CUR0 - 0x%x \n",   inl(M2M_reg_base+M2M_OFFSET_SAR_CURRENT0) );
-+      DPRINTK("DAR_BASE0 - 0x%x \n",  inl(M2M_reg_base+M2M_OFFSET_DAR_BASE0) );
-+      DPRINTK("DAR_CUR0 - 0x%x \n",   inl(M2M_reg_base+M2M_OFFSET_DAR_CURRENT0) );
-+
-+      /*
-+       *  Unmask irqs
-+       */
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  DMA interface functions
-+ *
-+ ****************************************************************************/
-+
-+/*****************************************************************************
-+ *
-+ *  int dma_init(int handle, unsigned int flags_m2p, unsigned int flags_m2m,
-+ *                       dma_callback callback, unsigned int user_data)
-+ *
-+ *  Description: Configure the DMA channel and install a callback function.
-+ *
-+ *  handle:    Handle unique the each instance of the dma interface, used
-+ *                      to verify this call.
-+ *  flags_m2p   Flags used to configure an M2P/P2M dma channel and determine
-+ *                      if a callback function and user_data information are included
-+ *                      in this call. This field should be NULL if handle represents
-+ *                      an M2M channel.
-+ *  flags_m2m   Flags used to configure an M2M dma channel and determine
-+ *                      if a callback function and user_data information are included
-+ *                      in this call. This field should be NULL if handle represents
-+ *                      an M2P/P2M channel.
-+ *  callback  function pointer which is called near the end of the
-+ *                      dma channel's irq handler.
-+ *  user_data   defined by the calling driver.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_config(int handle, unsigned int flags_m2p, unsigned int flags_m2m,
-+                dma_callback callback, unsigned int user_data)
-+{
-+      int  channel;
-+      ep93xx_dma_t * dma;
-+      unsigned long flags;
-+      unsigned int M2P_reg_base, uiCONTROL;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR
-+                         "DMA Config: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      DPRINTK("DMA Config \n");
-+
-+      dma = &dma_chan[channel];
-+
-+      local_irq_save(flags);
-+
-+      /*
-+       *  Check if the channel is currently transferring.
-+       */
-+      if (dma->xfer_enable) {
-+              local_irq_restore(flags);
-+              return(-EINVAL);
-+      }
-+
-+      /*
-+       *  Check if this is an m2m function.
-+       */
-+      if (channel >= 10) {
-+              local_irq_restore(flags);
-+
-+              /*
-+               *  Call another function to handle m2m config.
-+               */
-+              return(dma_config_m2m(dma, flags_m2m, callback, user_data));
-+      }
-+
-+      /*
-+       *  Setup a pointer into the dma channel's register set.
-+       */
-+      M2P_reg_base = dma->reg_base;
-+
-+      /*
-+       *  By default we enable the stall interrupt.
-+       */
-+      uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+      uiCONTROL |= CONTROL_M2P_STALLINTEN;
-+      outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+      /*
-+       *  Configure the channel for an error from the peripheral.
-+       */
-+      uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+      if ( flags_m2p && CHANNEL_ERROR_INT_ENABLE )
-+              uiCONTROL |= CONTROL_M2P_CHERRORINTEN;
-+      else
-+              uiCONTROL &= ~CONTROL_M2P_CHERRORINTEN;
-+      outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+      uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+      if ( flags_m2p && CHANNEL_ABORT )
-+              uiCONTROL |= CONTROL_M2P_ABRT;
-+      else
-+              uiCONTROL &= ~CONTROL_M2P_ABRT;
-+      outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+      uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+      if ( flags_m2p && IGNORE_CHANNEL_ERROR )
-+              uiCONTROL |= CONTROL_M2P_ICE;
-+      else
-+              uiCONTROL &= ~CONTROL_M2P_ICE;
-+      outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+
-+      /*
-+       *  Save the callback function in the dma instance for this channel.
-+       */
-+      dma->callback = callback;
-+
-+      /*
-+       *  Save the user data in the the dma instance for this channel.
-+       */
-+      dma->user_data = user_data;
-+
-+      /*
-+       *  Put the dma instance into the pause state by setting the
-+       *  pause bit to true.
-+       */
-+      dma->pause = TRUE;
-+
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int dma_start(int handle, unsigned int channels, unsigned int * handles)
-+ *
-+ *  Description: Initiate a transfer on up to 3 channels.
-+ *
-+ *  handle:    handle for the channel to initiate transfer on.
-+ *  channels:   number of channels to initiate transfers on.
-+ *  handles:  pointer to an array of handles, one for each channel which
-+ *                       is to be started.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_start(int handle, unsigned int channels, unsigned int * handles)
-+{
-+      ep93xx_dma_t * dma_pointers[3];
-+      unsigned int M2P_reg_bases[3];
-+      unsigned int loop, uiCONTROL;
-+      unsigned long flags;
-+      int  channel;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR "DMA Start: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      if (channels < 1) {
-+              printk(KERN_ERR "DMA Start: Invalid parameter.\n");
-+              return(-EINVAL);
-+      }
-+
-+      DPRINTK("DMA Start \n");
-+
-+      /*
-+       *  Mask off registers.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  Check if this is a start multiple.
-+       */
-+      if (channels > 1) {
-+              DPRINTK("DMA ERROR: Start, multiple start not supported yet \n");
-+              return(-1);
-+      } else {
-+              /*
-+               *  Check if this channel is already transferring.
-+               */
-+              if (dma_chan[channel].xfer_enable && !dma_chan[channel].pause) {
-+                      printk(KERN_ERR
-+                                 "DMA Start: Invalid command for channel %d.\n", channel);
-+
-+                      /*
-+                       *  Unmask irqs
-+                       */
-+                      local_irq_restore(flags);
-+
-+                      /*
-+                       *  This channel is already transferring, so return an error.
-+                       */
-+                      return(-EINVAL);
-+              }
-+
-+              /*
-+               *  If this is an M2M channel, call a different function.
-+               */
-+              if (channel >= 10) {
-+                      /*
-+                       *  Unmask irqs
-+                       */
-+                      local_irq_restore(flags);
-+
-+                      /*
-+                       *  Call the m2m start function.  Only start one channel.
-+                       */
-+                      return(dma_start_m2m(channel, &dma_chan[channel]));
-+              }
-+
-+              /*
-+               *  Make sure the channel has at least one buffer in the queue.
-+               */
-+              if (dma_chan[channel].new_buffers < 1) {
-+                      DPRINTK("DMA Start: Channel starved.\n");
-+
-+                      /*
-+                       *  This channel does not have enough buffers queued up,
-+                       *  so enter the pause by starvation state.
-+                       */
-+                      dma_chan[channel].xfer_enable = TRUE;
-+                      dma_chan[channel].pause = TRUE;
-+
-+                      /*
-+                       *  Unmask irqs
-+                       */
-+                      local_irq_restore(flags);
-+
-+                      /*
-+                       *  Success.
-+                       */
-+                      return(0);
-+              }
-+
-+              /*
-+               *  Set up a dma instance pointer for this dma channel.
-+               */
-+              dma_pointers[0] = &dma_chan[channel];
-+
-+              /*
-+               * Set up a pointer to the register set for this channel.
-+               */
-+              M2P_reg_bases[0] = dma_pointers[0]->reg_base;
-+      }
-+
-+      /*
-+       *  Setup both MAXCNT registers with values from the next two buffers
-+       *  in the queue, and enable the next frame buffer interrupt on the channel.
-+       */
-+      for (loop = 0; loop < channels; loop++) {
-+              /*
-+               *  Check if we need to restore a paused transfer.
-+               */
-+              if (dma_pointers[loop]->pause_buf.buf_id != -1)
-+                      outl( dma_pointers[loop]->pause_buf.size,
-+                            M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 );
-+              else
-+                      outl( dma_pointers[loop]->buffer_queue[dma_pointers[loop]->current_buffer].size,
-+                            M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT0 );
-+      }
-+
-+      for (loop = 0; loop < channels; loop++) {
-+              /*
-+               *  Enable the specified dma channels.
-+               */
-+              uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL);
-+              uiCONTROL |= CONTROL_M2P_ENABLE;
-+              outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL );
-+
-+              /*
-+               *  Update the dma channel instance transfer state.
-+               */
-+              dma_pointers[loop]->xfer_enable = TRUE;
-+              dma_pointers[loop]->pause = FALSE;
-+      }
-+
-+      /*
-+       *  Program up the BASE0 registers for all specified channels, this
-+       *  will initiate transfers on all specified channels.
-+       */
-+      for (loop = 0; loop < channels; loop++)
-+              /*
-+               *  Check if we need to restore a paused transfer.
-+               */
-+              if (dma_pointers[loop]->pause_buf.buf_id != -1) {
-+                      outl( dma_pointers[loop]->pause_buf.source,
-+                            M2P_reg_bases[loop]+M2P_OFFSET_BASE0 );
-+
-+                      /*
-+                       *  Set the pause buffer to NULL
-+                       */
-+                      dma_pointers[loop]->pause_buf.buf_id = -1;
-+                      dma_pointers[loop]->pause_buf.size = 0;
-+              } else if(dma_pointers[loop]->new_buffers){
-+                      outl( dma_pointers[loop]->buffer_queue[
-+                                dma_pointers[loop]->current_buffer].source,
-+                            M2P_reg_bases[loop]+M2P_OFFSET_BASE0 );
-+            dma_pointers[loop]->new_buffers--;
-+
-+          }
-+
-+      /*
-+       *  Before restoring irqs setup the second MAXCNT/BASE
-+       *  register with a second buffer.
-+       */
-+      for (loop = 0; loop < channels; loop++)
-+              if (dma_pointers[loop]->new_buffers) {
-+              /*
-+               *  By default we enable the next frame buffer interrupt.
-+               */
-+              uiCONTROL = inl(M2P_reg_bases[loop]+M2P_OFFSET_CONTROL);
-+              uiCONTROL |= CONTROL_M2P_NFBINTEN;
-+              outl( uiCONTROL, M2P_reg_bases[loop]+M2P_OFFSET_CONTROL );
-+
-+                      outl( dma_pointers[loop]->buffer_queue[
-+                                (dma_pointers[loop]->current_buffer + 1) %
-+                                MAX_EP93XX_DMA_BUFFERS].size,
-+                            M2P_reg_bases[loop]+M2P_OFFSET_MAXCNT1 );
-+
-+                      outl( dma_pointers[loop]->buffer_queue[
-+                                (dma_pointers[loop]->current_buffer + 1) %
-+                                MAX_EP93XX_DMA_BUFFERS].source,
-+                            M2P_reg_bases[loop]+M2P_OFFSET_BASE1 );
-+            dma_pointers[loop]->new_buffers--;
-+              }
-+
-+      /*
-+        DPRINTK("DMA - It's been started!!");
-+        DPRINTK("STATUS - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_STATUS) );
-+        DPRINTK("CONTROL - 0x%x \n",  inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
-+        DPRINTK("REMAIN - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
-+        DPRINTK("PPALLOC - 0x%x \n",  inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
-+        DPRINTK("BASE0 - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_BASE0) );
-+        DPRINTK("MAXCNT0 - 0x%x \n",  inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
-+        DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
-+        DPRINTK("BASE1 - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_BASE1) );
-+        DPRINTK("MAXCNT1 - 0x%x \n",  inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
-+        DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
-+
-+        DPRINTK("Pause - %d \n", dma_pointers[0]->pause);
-+        DPRINTK("xfer_enable - %d \n", dma_pointers[0]->xfer_enable);
-+        DPRINTK("total bytes - 0x%x \n", dma_pointers[0]->total_bytes);
-+        DPRINTK("total buffer - %d \n", dma_pointers[0]->total_buffers);
-+        DPRINTK("new buffers - %d \n", dma_pointers[0]->new_buffers);
-+        DPRINTK("current buffer - %d \n", dma_pointers[0]->current_buffer);
-+        DPRINTK("last buffer - %d \n", dma_pointers[0]->last_buffer);
-+        DPRINTK("used buffers - %d \n", dma_pointers[0]->used_buffers);
-+      */
-+      /*
-+       *  Unmask irqs
-+       */
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int ep93xx_dma_add_buffer(int handle, unsigned int * address,
-+ *                                             unsigned int size, unsigned int last)
-+ *
-+ *  Description: Add a buffer entry to the DMA buffer queue.
-+ *
-+ *  handle:    handle for the channel to add this buffer to.
-+ *  address:  Pointer to an integer which is the start address of the
-+ *                      buffer which is to be added to the queue.
-+ *  size:        size of the buffer in bytes.
-+ *  last:        1 if this is the last buffer in this stream, 0 otherwise.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_add_buffer(int handle, unsigned int source, unsigned int dest,
-+                    unsigned int size, unsigned int last,
-+                    unsigned int buf_id)
-+{
-+      unsigned long flags;
-+      ep93xx_dma_t * dma;
-+      int  channel;
-+#if 0
-+      static int peak_total_buffers=0;
-+#endif
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR
-+                         "DMA Add Buffer: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      /*
-+       *  Get a pointer to the dma instance.
-+       */
-+      dma = &dma_chan[channel];
-+
-+#if 0
-+      if( dma->total_buffers > peak_total_buffers )
-+      {
-+          peak_total_buffers=dma->total_buffers;
-+          printk("peak_total_buffers=%d\n", peak_total_buffers );
-+      }
-+#endif
-+      /*
-+       *  Mask interrupts and hold on to the original state.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  If the buffer queue is full, last_buffer is the same as current_buffer and
-+       *  we're not tranfering, or last_buffer is pointing to a used buffer, then exit.
-+       *  TODO: do I need to do any more checks?
-+       */
-+      if (dma->total_buffers >= MAX_EP93XX_DMA_BUFFERS)
-+      {
-+              DPRINTK("too many dma buffers: MAX_EP93XX_DMA_BUFFERS set to low ?\n");
-+              /*
-+               *  Restore the state of the irqs
-+               */
-+              local_irq_restore(flags);
-+
-+              /*
-+               *  Fail.
-+               */
-+              return(-1);
-+      }
-+
-+      /*
-+       *  Add this buffer to the queue
-+       */
-+      dma->buffer_queue[dma->last_buffer].source = source;
-+      dma->buffer_queue[dma->last_buffer].dest = dest;
-+      dma->buffer_queue[dma->last_buffer].size = size;
-+      dma->buffer_queue[dma->last_buffer].last = last;
-+      dma->buffer_queue[dma->last_buffer].buf_id = buf_id;
-+
-+      /*
-+       *  Reset the used field of the buffer structure.
-+       */
-+      dma->buffer_queue[dma->last_buffer].used = FALSE;
-+
-+      /*
-+       *  Increment the End Item Pointer.
-+       */
-+      dma->last_buffer = (dma->last_buffer + 1) % MAX_EP93XX_DMA_BUFFERS;
-+
-+      /*
-+       *  Increment the new buffers counter and the total buffers counter
-+       */
-+      dma->new_buffers++;
-+      dma->total_buffers++;
-+
-+      /*
-+       *  restore the interrupt state.
-+       */
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Check if the channel was starved into a stopped state.
-+       */
-+      if (dma->pause && dma->xfer_enable) {
-+              if (dma->new_buffers >= 1) {
-+                      DPRINTK("DMA - calling start from add after starve. \n");
-+
-+                      /*
-+                       *  The channel was starved into a stopped state, and we've got
-+                       *  2 new buffers, so start tranferring again.
-+                       */
-+                      ep93xx_dma_start(handle, 1, 0);
-+              }
-+      }
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int ep93xx_dma_remove_buffer(int handle, unsigned int * address,
-+ *                                                            unsigned int * size)
-+ *
-+ *  Description: Remove a buffer entry from the DMA buffer queue. If
-+ *                       buffer was removed successfully, return 0, otherwise
-+ *                       return -1.
-+ *
-+ *  handle:    handle for the channel to remove a buffer from.
-+ *  address:  Pointer to an integer which is filled in with the start
-+ *                      address of the removed buffer.
-+ *  size:        Pointer to an integer which is filled in with the size in
-+ *                      bytes of the removed buffer.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_remove_buffer(int handle, unsigned int * buf_id)
-+{
-+      unsigned int test;
-+      unsigned int loop;
-+      int return_val = -1;
-+      unsigned long flags;
-+      ep93xx_dma_t *dma;
-+      int  channel;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR
-+                         "DMA Remove Buffer: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      dma = &dma_chan[channel];
-+
-+      /*
-+       *  Mask interrupts and hold on to the original state.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  Make sure there are used buffers to be returned.
-+       */
-+      if (dma->used_buffers) {
-+              test = dma->last_buffer;
-+
-+              for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++) {
-+                      if (dma->buffer_queue[test].used && (dma->buffer_queue[test].buf_id != -1)) {
-+                              /*DPRINTK("buffer %d used \n", test); */
-+
-+                              /*
-+                               *  This is a used buffer, fill in the buf_id pointer
-+                               *  with the buf_id for this buffer.
-+                               */
-+                              *buf_id = dma->buffer_queue[test].buf_id;
-+
-+                              /*
-+                               *  Reset this buffer structure
-+                               */
-+                              dma->buffer_queue[test].buf_id = -1;
-+
-+                              /*
-+                               *  Decrement the used buffer counter, and the total buffer counter.
-+                               */
-+                              dma->used_buffers--;
-+                              dma->total_buffers--;
-+
-+                              /*
-+                               *  Successful removal of a buffer, so set the return
-+                               *  value to 0, then exit this loop.
-+                               */
-+                              return_val = 0;
-+                              break;
-+                      }
-+
-+                      /*
-+                       *  This buffer isn't used, let's see if the next one is.
-+                       */
-+                      test = (test + 1) % MAX_EP93XX_DMA_BUFFERS;
-+              }
-+      }
-+
-+      /*
-+       *  Restore interrupts.
-+       */
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Success.
-+       */
-+      return(return_val);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int ep93xx_dma_pause(int handle, unsigned int channels,
-+ *                                       unsigned int * handles)
-+ *
-+ *  Description: Disable any ongoing transfer for the given channel, retaining
-+ *                       the state of the current buffer transaction so that upon
-+ *                       resume, the dma will continue where it left off.
-+ *
-+ *  handle:    Handle for the channel to be paused.  If this is a pause for
-+ *                      for multiple channels, handle is a valid handle for one of
-+ *                      the channels to be paused.
-+ *  channels:   number of channel to pause transfers on.
-+ *  handles:  Pointer to an array of handles, one for each channel which
-+ *                      to be paused.  If this pause is intended only for one
-+ *                      channel, this field should be set to NULL.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_pause(int handle, unsigned int channels, unsigned int * handles)
-+{
-+      unsigned long flags;
-+      ep93xx_dma_t * dma;
-+      int channel;
-+
-+      DPRINTK("ep93xx_dma_pause \n");
-+
-+      /*
-+       *  Mask interrupts and hold on to the original state.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              /*
-+               *  restore interrupts.
-+               */
-+              local_irq_restore(flags);
-+
-+              printk(KERN_ERR
-+                         "DMA Pause: Invalid dma handle.\n");
-+
-+              /*
-+               *  Fail.
-+               */
-+              return(-EINVAL);
-+      }
-+
-+      DPRINTK("DMA %d: pause \n", channel);
-+
-+      /*
-+       *  Set up a pointer to the dma instance data.
-+       */
-+      dma = &dma_chan[channel];
-+
-+      /*
-+       *  Check if we're already paused.
-+       */
-+      if (dma->pause) {
-+              /*
-+               *  We're paused, but are we stopped?
-+               */
-+              if (dma->xfer_enable)
-+                      /*
-+                       *  Put the channel in the stopped state.
-+                       */
-+                      dma->xfer_enable = FALSE;
-+
-+              DPRINTK("DMA Pause - already paused.");
-+      } else {
-+              /*
-+               *  Put the channel into the stopped state.
-+               */
-+              dma->xfer_enable = FALSE;
-+              dma->pause = TRUE;
-+      }
-+
-+      /*
-+       *  restore interrupts.
-+       */
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Already paused, so exit.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  void ep93xx_dma_flush(int handle)
-+ *
-+ *  Description: Flushes all queued buffers and transfers in progress
-+ *                       for the given channel.  Return the buffer entries
-+ *                       to the calling function.
-+ *
-+ *  handle:    handle for the channel for which the flush is intended.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_flush(int handle)
-+{
-+      unsigned int loop;
-+      unsigned long flags;
-+      ep93xx_dma_t * dma;
-+      int  channel;
-+      unsigned int M2P_reg_base,uiCONTROL;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR "DMA Flush: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      DPRINTK("DMA %d: flush \n", channel);
-+
-+      /*
-+       *  Set up a pointer to the dma instance data for this channel
-+       */
-+      dma = &dma_chan[channel];
-+
-+      /*
-+       *  Mask interrupts and hold on to the original state.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  Disable the dma channel
-+       */
-+      if (channel < 10) {
-+              /*
-+               *  M2P channel
-+               */
-+              uiCONTROL = inl(dma->reg_base+M2P_OFFSET_CONTROL);
-+              uiCONTROL &= ~CONTROL_M2P_ENABLE;
-+              outl( uiCONTROL, dma->reg_base+M2P_OFFSET_CONTROL );
-+      } else {
-+              /*
-+               *  M2M channel
-+               */
-+              uiCONTROL = inl(dma->reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~CONTROL_M2M_ENABLE;
-+              outl( uiCONTROL, dma->reg_base+M2M_OFFSET_CONTROL );
-+      }
-+
-+      for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++)
-+      {
-+              dma->buffer_queue[loop].buf_id = -1;
-+              dma->buffer_queue[loop].last = 0;
-+      }
-+
-+      /*
-+       *  Set the Current and Last item to zero.
-+       */
-+      dma->current_buffer = 0;
-+      dma->last_buffer = 0;
-+
-+      /*
-+       *  Reset the Buffer counters
-+       */
-+      dma->used_buffers = 0;
-+      dma->new_buffers = 0;
-+      dma->total_buffers = 0;
-+
-+      /*
-+       *  reset the Total bytes counter.
-+       */
-+      dma->total_bytes = 0;
-+
-+    /*
-+     * Reset the paused buffer.
-+     */
-+     dma->pause_buf.last = 0;
-+     dma->pause_buf.buf_id = -1;
-+
-+      M2P_reg_base = dma_chan[channel].reg_base;
-+
-+      /*
-+       *  restore interrupts.
-+       */
-+      local_irq_restore(flags);
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int ep93xx_dma_queue_full(int handle)
-+ *
-+ *  Description: Query to determine if the DMA queue of buffers for
-+ *                      a given channel is full.
-+ *                      0 = queue is full
-+ *                      1 = queue is not full
-+ *
-+ *  handle:    handle for the channel to query.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_queue_full(int handle)
-+{
-+      int list_full = 0;
-+      unsigned long flags;
-+      int  channel;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR "DMA Queue Full: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      DPRINTK("DMA %d: queue full \n", channel);
-+
-+      /*
-+       *  Mask interrupts and hold on to the original state.
-+       */
-+      local_irq_save(flags);
-+
-+      /*
-+       *  If the last item is equal to the used item then
-+       *  the queue is full.
-+       */
-+      if (dma_chan[channel].total_buffers < MAX_EP93XX_DMA_BUFFERS)
-+              list_full =  FALSE;
-+      else
-+              list_full = TRUE;
-+
-+      /*
-+       *  restore interrupts.
-+       */
-+      local_irq_restore(flags);
-+
-+      return(list_full);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int ep93xx_dma_get_position()
-+ *
-+ *  Description:  Takes two integer pointers and fills them with the start
-+ *                and current address of the buffer currently transferring
-+ *                on the specified DMA channel.
-+ *
-+ *  handle         handle for the channel to query.
-+ *  *buf_id        buffer id for the current buffer transferring on the
-+ *                 dma channel.
-+ *  *total         total bytes transferred on the channel.  Only counts
-+ *                 whole buffers transferred.
-+ *  *current_frac  number of bytes transferred so far in the current buffer.
-+ ****************************************************************************/
-+int
-+ep93xx_dma_get_position(int handle, unsigned int * buf_id,
-+                        unsigned int * total, unsigned int * current_frac )
-+{
-+      int  channel;
-+      ep93xx_dma_t * dma;
-+      unsigned int buf_id1, total1, current_frac1, buf_id2, total2;
-+      unsigned int Status, NextBuffer, StateIsBufNext, M2P_reg_base=0;
-+      unsigned int pause1, pause2;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.  See if this is a
-+       *  valid handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+      if (channel < 0) {
-+              printk(KERN_ERR "DMA Get Position: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      dma = &dma_chan[channel];
-+
-+      /*
-+       * If DMA moves to a new buffer in the middle of us grabbing the
-+       * buffer info, then do it over again.
-+       */
-+      do{
-+              buf_id1 = dma->buffer_queue[dma->current_buffer].buf_id;
-+              total1  = dma->total_bytes;
-+              pause1  = dma->pause;
-+
-+              if (channel < 10) {
-+                      // M2P
-+                      M2P_reg_base = dma->reg_base;
-+
-+                      Status = inl(M2P_reg_base+M2P_OFFSET_STATUS);
-+
-+                      NextBuffer = ((Status & STATUS_M2P_NEXTBUFFER) != 0);
-+
-+                      StateIsBufNext = ((Status & STATUS_M2P_CURRENT_MASK) ==
-+                                        STATUS_M2P_DMA_BUF_NEXT);
-+
-+                      if( NextBuffer ^ StateIsBufNext )
-+                              current_frac1 = inl(M2P_reg_base+M2P_OFFSET_CURRENT1) -
-+                                              inl(M2P_reg_base+M2P_OFFSET_BASE1);
-+                      else
-+                              current_frac1 = inl(M2P_reg_base+M2P_OFFSET_CURRENT0) -
-+                                              inl(M2P_reg_base+M2P_OFFSET_BASE0);
-+
-+              } else {
-+                      // M2M - TODO implement this for M2M
-+                      current_frac1 = 0;
-+              }
-+
-+              buf_id2 = dma->buffer_queue[dma->current_buffer].buf_id;
-+              total2 = dma->total_bytes;
-+              pause2  = dma->pause;
-+
-+      } while ( (buf_id1 != buf_id2) || (total1 != total2) || (pause1 != pause2) );
-+
-+      if (pause1)
-+              current_frac1 = 0;
-+
-+      if (buf_id)
-+              *buf_id = buf_id1;
-+
-+      if (total)
-+              *total  = total1;
-+
-+      if (current_frac)
-+              *current_frac = current_frac1;
-+
-+//    DPRINTK("DMA buf_id %d, total %d, frac %d\n", buf_id1, total1, current_frac1);
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int ep93xx_dma_get_total(int handle)
-+ *
-+ *  Description:      Returns the total number of bytes transferred on the
-+ *                    specified channel since the channel was requested.
-+ *
-+ *  handle:    handle for the channel to query.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_get_total(int handle)
-+{
-+      int  channel;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR "DMA Get Total: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      DPRINTK("DMA %d: total: %d \n", channel, dma_chan[channel].total_bytes);
-+
-+      /*
-+       *  Return the total number of bytes transferred on this channel since
-+       *  it was requested.
-+       */
-+      return(dma_chan[channel].total_bytes);
-+}
-+
-+/*****************************************************************************
-+ *
-+ *  int ep93xx_dma_is_done(int handle)
-+ *
-+ *  Description:      Determines if the specified channel is done
-+ *                    transferring the requested data.
-+ *
-+ *  handle:    handle for the channel to query.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_is_done(int handle)
-+{
-+      ep93xx_dma_t *dma;
-+      int channel;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR "ep93xx_dma_is_done: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+        /*
-+         * Get a pointer to the DMA channel state structure.
-+         */
-+        dma = &dma_chan[channel];
-+
-+        /*
-+         * See if there are any buffers remaining to be provided to the HW.
-+         */
-+        if (dma->new_buffers)
-+            return 0;
-+
-+        /*
-+         * See if this is a M2P or M2M channel.
-+         */
-+        if (channel < 10) {
-+            /*
-+             * If the bytes remaining register of the HW is not zero, then
-+             * there is more work to be done.
-+             */
-+            if (inl(dma->reg_base + M2P_OFFSET_REMAIN) != 0)
-+                return 0;
-+        } else {
-+            /*
-+             * If either byte count register in the HW is not zero, then there
-+             * is more work to be done.
-+             */
-+            if ((inl(dma->reg_base + M2M_OFFSET_BCR0) != 0) ||
-+                (inl(dma->reg_base + M2M_OFFSET_BCR1) != 0))
-+                return 0;
-+        }
-+
-+        /*
-+         * The DMA is complete.
-+         */
-+        return 1;
-+}
-+
-+/*****************************************************************************
-+ * ep93xx_dma_request
-+ *
-+ * Description: This function will allocate a DMA channel for a particular
-+ * hardware peripheral.  Before initiating a transfer on the allocated
-+ * channel, the channel must be set up and buffers have to queued up.
-+ *
-+ *  handle:    pointer to an integer which is filled in with a unique
-+ *                      handle for this instance of the dma interface.
-+ *  device_id   string with the device name, primarily used by /proc.
-+ *  device      hardware device ID for which the requested dma channel will
-+ *                      transfer data.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_request(int * handle, const char *device_id,
-+                                 ep93xx_dma_dev_t device)
-+{
-+      ep93xx_dma_t *dma = NULL;
-+      int channel;
-+      unsigned int error = 0;
-+      unsigned int loop;
-+      unsigned int M2P_reg_base;
-+
-+      /*
-+       *  Check if the device requesting a DMA channel is a valid device.
-+       */
-+      if ((device >= UNDEF_DMA) || (device < 0))
-+              return(-ENODEV);
-+
-+      /*
-+       *  We've got a valid hardware device requesting a DMA channel.
-+       *  Now check if the device should open an M2P or M2M channel
-+       */
-+      if (device < 20)
-+              channel = dma_open_m2p(device);
-+      else
-+              channel = dma_open_m2m(device);
-+
-+      /*
-+       *  Check if we successfully opened a DMA channel
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR "%s: Could not open dma channel for this device.\n",
-+                         device_id);
-+              return(-EBUSY);
-+      }
-+
-+      dma = &dma_chan[channel];
-+
-+        if(dma->terminated==1) {
-+           free_irq(dma->irq, (void *) dma);
-+           dma->terminated=0;
-+        }
-+
-+      /*
-+       *  Request the appropriate IRQ for the specified channel
-+       */
-+      if (channel < 10)
-+              error = request_irq(dma->irq, dma_m2p_irq_handler,
-+                                  IRQF_DISABLED, device_id, (void *) dma);
-+      else
-+              error = request_irq(dma->irq, &dma_m2m_irq_handler,
-+                                  IRQF_DISABLED, device_id, (void *) dma);
-+
-+      /*
-+       *  Check for any errors during the irq request
-+       */
-+      if (error) {
-+              printk(KERN_ERR "%s: unable to request IRQ %d for DMA channel\n",
-+                         device_id, dma->irq);
-+              return(error);
-+      }
-+
-+      /*
-+       *  Generate a valid handle and exit.
-+       *
-+       *  Increment the last valid handle.
-+       *  Check for wraparound (unlikely, but we like to be complete).
-+       */
-+      dma->last_valid_handle++;
-+
-+      if ( (dma->last_valid_handle & DMA_HANDLE_SPECIFIER_MASK) !=
-+           (channel << 28) )
-+              dma->last_valid_handle = (channel << 28) + 1;
-+
-+      /*
-+       *  Fill in the handle pointer with a valid handle for
-+       *  this dma channel instance.
-+       */
-+      *handle = dma->last_valid_handle;
-+
-+      DPRINTK("Handle for channel %d: 0x%x\n", channel, *handle);
-+
-+      /*
-+       * Save the device ID and device name.
-+       */
-+      dma->device = device;
-+      dma->device_id = device_id;
-+
-+      /*
-+       *  Init all fields within the dma instance.
-+       */
-+      for (loop = 0; loop < MAX_EP93XX_DMA_BUFFERS; loop++)
-+              dma->buffer_queue[loop].buf_id = -1;
-+
-+      /*
-+       *  Initialize all buffer queue variables.
-+       */
-+      dma->current_buffer = 0;
-+      dma->last_buffer = 0;
-+
-+      dma->new_buffers = 0;
-+      dma->used_buffers = 0;
-+      dma->total_buffers = 0;
-+
-+      /*
-+       *  Initialize the total bytes variable
-+       */
-+      dma->total_bytes = 0;
-+
-+      /*
-+       *  Initialize the transfer and pause state variables to 0.
-+       */
-+      dma->xfer_enable = 0;
-+
-+      dma->pause = 0;
-+
-+      /*
-+       *  Initialize the pause buffer structure.
-+       */
-+      dma->pause_buf.buf_id = -1;
-+
-+      /*
-+       *  Initialize the callback function and user data fields.
-+       */
-+      dma->callback = NULL;
-+
-+      /*
-+       * User data used as a parameter for the Callback function.  The user
-+       * sets up the data and sends it with the callback function.
-+       */
-+      dma->user_data = 0;
-+
-+      M2P_reg_base = dma_chan[channel].reg_base;
-+
-+      /*
-+       *  Debugging message.
-+       */
-+      DPRINTK("Successfully requested dma channel %d\n", channel);
-+      DPRINTK("STATUS - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_STATUS) );
-+      DPRINTK("CONTROL - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_CONTROL) );
-+      DPRINTK("REMAIN - 0x%x \n",      inl(M2P_reg_base+M2P_OFFSET_REMAIN) );
-+      DPRINTK("PPALLOC - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_PPALLOC) );
-+      DPRINTK("BASE0 - 0x%x \n",        inl(M2P_reg_base+M2P_OFFSET_BASE0) );
-+      DPRINTK("MAXCNT0 - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_MAXCNT0) );
-+      DPRINTK("CURRENT0 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT0) );
-+      DPRINTK("BASE1 - 0x%x \n",        inl(M2P_reg_base+M2P_OFFSET_BASE1) );
-+      DPRINTK("MAXCNT1 - 0x%x \n",    inl(M2P_reg_base+M2P_OFFSET_MAXCNT1) );
-+      DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
-+
-+      DPRINTK("Buffer source     size    last    used \n");
-+      for (loop = 0; loop < 5; loop ++)
-+              DPRINTK("%d             0x%x             0x%x           %d               %d \n",
-+                      loop, dma->buffer_queue[loop].source, dma->buffer_queue[loop].size,
-+                      dma->buffer_queue[loop].last, dma->buffer_queue[loop].used);
-+      DPRINTK("pause   0x%x            0x%x           %d               %d \n",
-+              dma->pause_buf.source, dma->pause_buf.size,
-+              dma->pause_buf.last, dma->pause_buf.used);
-+
-+      DPRINTK("Pause - %d \n", dma->pause);
-+      DPRINTK("xfer_enable - %d \n", dma->xfer_enable);
-+      DPRINTK("total bytes - 0x%x \n", dma->total_bytes);
-+      DPRINTK("total buffer - %d \n", dma->total_buffers);
-+      DPRINTK("new buffers - %d \n", dma->new_buffers);
-+      DPRINTK("current buffer - %d \n", dma->current_buffer);
-+      DPRINTK("last buffer - %d \n", dma->last_buffer);
-+      DPRINTK("used buffers - %d \n", dma->used_buffers);
-+
-+      DPRINTK("CURRENT1 - 0x%x \n",   inl(M2P_reg_base+M2P_OFFSET_CURRENT1) );
-+      DPRINTK("VIC0IRQSTATUS - 0x%x, VIC0INTENABLE - 0x%x \n",
-+              *(unsigned int *)(VIC0IRQSTATUS),
-+              *(unsigned int *)(VIC0INTENABLE));
-+
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ * ep93xx_dma_free
-+ *
-+ * Description: This function will free the dma channel for future requests.
-+ *
-+ *  handle:    handle for the channel to be freed.
-+ *
-+ ****************************************************************************/
-+int
-+ep93xx_dma_free(int handle)
-+{
-+      ep93xx_dma_t *dma;
-+      unsigned int M2M_reg_base, M2P_reg_base, uiCONTROL;
-+      int channel;
-+
-+      /*
-+       *  Get the DMA hw channel # from the handle.
-+       */
-+      channel = dma_get_channel_from_handle(handle);
-+
-+      /*
-+       *  See if this is a valid handle.
-+       */
-+      if (channel < 0) {
-+              printk(KERN_ERR "DMA Free: Invalid dma handle.\n");
-+              return(-EINVAL);
-+      }
-+
-+      /*
-+       *  Get a pointer to the dma instance.
-+       */
-+      dma = &dma_chan[channel];
-+
-+      /*
-+       *  Disable the dma channel
-+       */
-+      if (channel < 10) {
-+              /*
-+               *  M2P channel
-+               */
-+              M2P_reg_base = dma->reg_base;
-+
-+              uiCONTROL = inl(M2P_reg_base+M2P_OFFSET_CONTROL);
-+              uiCONTROL &= ~CONTROL_M2P_ENABLE;
-+              outl( uiCONTROL, M2P_reg_base+M2P_OFFSET_CONTROL );
-+      } else {
-+              /*
-+               *  M2M channel
-+               */
-+              M2M_reg_base = dma->reg_base;
-+
-+              uiCONTROL = inl(M2M_reg_base+M2M_OFFSET_CONTROL);
-+              uiCONTROL &= ~CONTROL_M2M_ENABLE;
-+              outl( uiCONTROL, M2M_reg_base+M2M_OFFSET_CONTROL );
-+      }
-+
-+      /*
-+       *  Free the interrupt servicing this dma channel
-+       */
-+      //free_irq(dma->irq, (void *) dma);
-+        dma->terminated=1;
-+
-+      /*
-+       *  Decrement the reference count for this instance of the dma interface
-+       */
-+      dma->ref_count--;
-+
-+      /*
-+       *  Set the transfer and pause state variables to 0
-+       *  (unititialized state).
-+       */
-+      dma->xfer_enable = 0;
-+      dma->pause = 0;
-+
-+      /*
-+       *  Debugging message.
-+       */
-+      DPRINTK("Successfully freed dma channel %d\n", channel);
-+      /*
-+       *  Success.
-+       */
-+      return(0);
-+}
-+
-+/*****************************************************************************
-+ *
-+ * ep93xx_dma_init(void)
-+ *
-+ * Description: This function is called during system initialization to
-+ * setup the interrupt number and register set base address for each DMA
-+ * channel.
-+ *
-+ ****************************************************************************/
-+static int __init
-+ep93xx_dma_init(void)
-+{
-+      int channel;
-+
-+      /*
-+       * Init some values in each dma instance.
-+       */
-+      for (channel = 0; channel < MAX_EP93XX_DMA_CHANNELS; channel++) {
-+              /*
-+               *  IRQ for the specified dma channel.
-+               */
-+              dma_chan[channel].irq = IRQ_EP93XX_DMAM2P0 + channel;
-+
-+                 dma_chan[channel].terminated = 0;
-+
-+              /*
-+               *  Initial value of the dma channel handle.
-+               */
-+              dma_chan[channel].last_valid_handle = channel << 28;
-+
-+              /*
-+               *  Give the instance a pointer to the dma channel register
-+               *  base.
-+               */
-+              if (channel < 10)
-+                      dma_chan[channel].reg_base = DMAM2PChannelBase[channel];
-+              else
-+                      dma_chan[channel].reg_base = DMAM2MChannelBase[channel - 10];
-+
-+              /*
-+               *  Initialize the reference count for this channel.
-+               */
-+              dma_chan[channel].ref_count = 0;
-+      }
-+
-+      DPRINTK("DMA Interface intitialization complete\n");
-+
-+      /*
-+       * Success
-+       */
-+      return 0;
-+}
-+
-+arch_initcall(ep93xx_dma_init);
-+
-+EXPORT_SYMBOL(ep93xx_dma_free);
-+EXPORT_SYMBOL(ep93xx_dma_request);
-+EXPORT_SYMBOL(ep93xx_dma_flush);
-+EXPORT_SYMBOL(ep93xx_dma_pause);
-+EXPORT_SYMBOL(ep93xx_dma_remove_buffer);
-+EXPORT_SYMBOL(ep93xx_dma_add_buffer);
-+EXPORT_SYMBOL(ep93xx_dma_start);
-+EXPORT_SYMBOL(ep93xx_dma_config);
---- /dev/null
-+++ b/arch/arm/mach-ep93xx/dma_ep93xx.h
-@@ -0,0 +1,676 @@
-+/*****************************************************************************
-+ *
-+ * arch/arm/mach-ep93xx/dma_ep93xx.h
-+ *
-+ * DESCRIPTION:    93XX DMA controller API private defintions.
-+ *
-+ * Copyright Cirrus Logic Corporation, 2003.  All rights reserved
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ ****************************************************************************/
-+#ifndef _EP93XX_DMA_H_
-+#define _EP93XX_DMA_H_
-+
-+// as it turns out the ide dma is the biggest dma buffer hog so far
-+// in case the HDD is "thinking" (seek/buffer flush)
-+// the continueing r/w DMAs to the HDD will be queued up to up to PRD_ENTRIES entries...
-+#include <linux/ide.h>
-+#define MAX_EP93XX_DMA_BUFFERS      PRD_ENTRIES
-+
-+#ifndef TRUE
-+#define TRUE                        1
-+#endif
-+
-+#ifndef FALSE
-+#define FALSE                       0
-+#endif
-+
-+#ifndef NULL
-+#define NULL                        0
-+#endif
-+
-+#define EP93XX_DMA_BASE                       (EP93XX_AHB_VIRT_BASE + 0x00000000)
-+
-+/*****************************************************************************
-+ * 0x8000.0000 -> 0x8000.003C M2P Channel 0 Registers (Tx)
-+ * 0x8000.0040 -> 0x8000.007C M2P Channel 1 Registers (Rx)
-+ * 0x8000.0080 -> 0x8000.00BC M2P Channel 2 Registers (Tx)
-+ * 0x8000.00C0 -> 0x8000.00FC M2P Channel 3 Registers (Rx)
-+ * 0x8000.0100 -> 0x8000.013C M2M Channel 0 Registers
-+ * 0x8000.0140 -> 0x8000.017C M2M Channel 1 Registers
-+ * 0x8000.0180 -> 0x8000.01BC Not Used
-+ * 0x8000.01C0 -> 0x8000.01FC Not Used
-+ * 0x8000.0200 -> 0x8000.023C M2P Channel 5 Registers (Rx)
-+ * 0x8000.0240 -> 0x8000.027C M2P Channel 4 Registers (Tx)
-+ * 0x8000.0280 -> 0x8000.02BC M2P Channel 7 Registers (Rx)
-+ * 0x8000.02C0 -> 0x8000.02FC M2P Channel 6 Registers (Tx)
-+ * 0x8000.0300 -> 0x8000.033C M2P Channel 9 Registers (Rx)
-+ * 0x8000.0340 -> 0x8000.037C M2P Channel 8 Registers (Tx)
-+ * 0x8000.0380 DMA Channel Arbitration register
-+ * 0x8000.03C0 DMA Global Interrupt register
-+ * 0x8000.03C4 -> 0x8000.03FC Not Used
-+ *
-+ *
-+ * Internal M2P/P2M Channel Register Map
-+ *
-+ * Offset Name      Access  Bits Reset Value
-+ * 0x00   CONTROL   R/W     6    0
-+ * 0x04   INTERRUPT R/W TC* 3    0
-+ * 0x08   PPALLOC   R/W     4    channel dependant
-+ *                               (see reg description)
-+ * 0x0C   STATUS    RO      8    0
-+ * 0x10   reserved
-+ * 0x14   REMAIN    RO      16   0
-+ * 0X18   Reserved
-+ * 0X1C   Reserved
-+ * 0x20   MAXCNT0   R/W     16   0
-+ * 0x24   BASE0     R/W     32   0
-+ * 0x28   CURRENT0  RO      32   0
-+ * 0x2C   Reserved
-+ * 0x30   MAXCNT1   R/W     16   0
-+ * 0x34   BASE1     R/W     32   0
-+ * 0X38   CURRENT1  RO      32   0
-+ * 0X3C   Reserved
-+ *
-+ * M2M Channel Register Map
-+ * Offset Name         Access   Bits Reset Value
-+ *
-+ * 0x00   CONTROL      R/W      22   0
-+ * 0x04   INTERRUPT    R/W TC*  3    0
-+ * 0x08   Reserved
-+ * 0x0C   STATUS       R/W TC*  14   0
-+ * 0x10   BCR0         R/W      16   0
-+ * 0x14   BCR1         R/W      16   0
-+ * 0x18   SAR_BASE0    R/W      32   0
-+ * 0x1C   SAR_BASE1    R/W      32   0
-+ * 0x20   Reserved
-+ * 0x24   SAR_CURRENT0 RO       32   0
-+ * 0x28   SAR_CURRENT1 RO       32   0
-+ * 0x2C   DAR_BASE0    R/W      32   0
-+ * 0x30   DAR_BASE1    R/W      32   0
-+ * 0x34   DAR_CURRENT0 RO       32   0
-+ * 0X38   Reserved
-+ * 0X3C   DAR_CURRENT1 RO       32   0
-+ * * Write this location once to clear the bit (see
-+ * Interrupt/Status register description for which bits
-+ * this rule applies to).
-+ *
-+ ****************************************************************************/
-+
-+
-+/*----------------------------------------------------------------------------------*/
-+/* M2P Registers                                                                    */
-+/*----------------------------------------------------------------------------------*/
-+/*
-+ * M2P CONTROL register bit defines
-+ */
-+#define CONTROL_M2P_STALLINTEN      0x00000001            /* Enables the STALL interrupt  */
-+#define CONTROL_M2P_NFBINTEN        0x00000002            /* Enables the NFB interrupt    */
-+#define CONTROL_M2P_CHERRORINTEN    0x00000008      /* Enables the ChError interrupt*/
-+#define CONTROL_M2P_ENABLE                0x00000010      /* Enables the channel          */
-+#define CONTROL_M2P_ABRT                  0x00000020      /* Determines how DMA behaves in*/
-+                                                              /* NEXT state with peripheral   */
-+                                                    /* error                        */
-+                                                              /* 0: NEXT -> ON, ignore error  */
-+                                                              /* 1: NEXT -> STALL, disable ch.*/
-+#define CONTROL_M2P_ICE                           0x00000040      /* Ignore Channel Error         */
-+
-+/*
-+ * M2P INTERRUPT register bit defines
-+ */
-+#define INTERRUPT_M2P_STALLINT      0x00000001            /* Indicates channel stalled.   */
-+#define INTERRUPT_M2P_NFBINT        0x00000002                /* Indicates channel is hungry. */
-+#define INTERRUPT_M2P_CHERRORINT    0x00000008            /* Peripheral detects error     */
-+
-+
-+/*
-+ * STATUS register bit defines
-+ */
-+#define STATUS_M2P_STALL            0x00000001                /* A '1' indicates channel is       */
-+                                                    /* stalled                          */
-+#define STATUS_M2P_NFB                            0x00000002      /* A '1' indicates channel has moved*/
-+                                                              /* from NEXT state to ON state, but */
-+                                                              /* waiting for next buffer to be    */
-+                                                    /* programmed.                      */
-+#define STATUS_M2P_CHERROR                0x00000008      /* Enables the ChError interrupt    */
-+#define STATUS_M2P_CURRENT_MASK     0x00000030      /* Current state of the FSM         */
-+#define STATUS_M2P_CURRENT_SHIFT    4
-+#define STATUS_M2P_NEXTBUFFER     0x00000040      /* Informs the int handler after an */
-+                                                              /* NFB int which pair of maxcnt and */
-+                                                    /* base regs to update.             */
-+#define STATUS_M2P_BYTES_MASK       0x0000f800                /* number of valid DMA data         */
-+#define STATUS_M2P_BYTES_SHIFT      7               /* currently in                     */
-+                                                                                          /* packer/unpacker                  */
-+
-+#define STATUS_M2P_DMA_NO_BUF         0x00000000
-+#define STATUS_M2P_DMA_BUF_ON         0x00000010
-+#define STATUS_M2P_DMA_BUF_NEXT               0x00000020
-+
-+/*
-+ * Register masks to mask off reserved bits after reading register.
-+ */
-+#define M2P_MASK_PPALLOC            0x0000000f
-+#define M2P_MASK_REMAIN             0x0000ffff
-+#define M2P_MASK_MAXCNT0            0x0000ffff
-+#define M2P_MASK_BASE0              0xffffffff
-+#define M2P_MASK_CURRENT0           0xffffffff
-+#define M2P_MASK_MAXCNT1            0x0000ffff
-+#define M2P_MASK_BASE1              0xffffffff
-+#define M2P_MASK_CURRENT1           0xffffffff
-+
-+
-+/*----------------------------------------------------------------------------------*/
-+/* M2M Registers                                                                    */
-+/*----------------------------------------------------------------------------------*/
-+
-+#define CONTROL_M2M_STALLINTEN        0x00000001  /* Enables the STALL interrupt                     */
-+#define CONTROL_M2M_SCT                       0x00000002  /* Source Copy Transfer. Setup a                   */
-+                                                                                  /* block transfer from 1 memory source             */
-+                                                                                  /* location.                                       */
-+#define CONTROL_M2M_DONEINTEN 0x00000004  /* Enables the DONE interrupt which                */
-+                                                                                  /* indicates if the xfer completed                 */
-+                                                                                  /* successfully                                    */
-+#define CONTROL_M2M_ENABLE            0x00000008  /* Enables the channel                             */
-+#define CONTROL_M2M_START             0x00000010  /* Initiates the xfer. 'software trigger'          */
-+#define CONTROL_M2M_BWC_MASK  0x000001e0  /* Bandwidth control. Indicate number of           */
-+#define CONTROL_M2M_BWC_SHIFT   5                     /* bytes in a transfer.                            */
-+#define CONTROL_M2M_PW_MASK           0x00000600  /* Peripheral width. Used for xfers                */
-+#define CONTROL_M2M_PW_SHIFT    9                     /* between memory and external peripheral.         */
-+                                                                                  /* 00: byte, 01: halfword, 10: word.               */
-+#define CONTROL_M2M_DAH                       0x00000800  /* Destination Address Hold                        */
-+#define CONTROL_M2M_SAH                       0x00001000  /* Source Address Hold                             */
-+#define CONTROL_M2M_TM_MASK     0x00006000  /* Transfer Mode. 00: sw triggered,                */
-+#define CONTROL_M2M_TM_SHIFT    13                    /* 01: hw initiated M2P, 01: hw initiated P2M      */
-+#define CONTROL_M2M_ETDP_MASK 0x00018000  /* End-of-Transfer/Terminal Count pin              */
-+#define CONTROL_M2M_ETDP_SHIFT  15                /* direction and polarity.                         */
-+#define CONTROL_M2M_DACKP             0x00020000  /* DMA acknowledge pin polarity                    */
-+
-+#define CONTROL_M2M_DREQP_MASK  0x00180000    /* DMA request pin polarity. must be set           */
-+#define CONTROL_M2M_DREQP_SHIFT 19                    /* before enable bit.                              */
-+#define CONTROL_M2M_NFBINTEN  0x00200000  /* Enables generation of the NFB interrupt.        */
-+#define CONTROL_M2M_RSS_MASK    0x00c00000    /* Request source selection:                       */
-+#define CONTROL_M2M_RSS_SHIFT 22                      /*              000 - External DReq[0]                     */
-+                                                                                  /*          001 - External DReq[1]                     */
-+                                                                                  /*          01X - Internal SSPRx                       */
-+                                                                                  /*          10X - Internal SSPTx                       */
-+                                                                                  /*          11X - Internal IDE                         */
-+#define CONTROL_M2M_NO_HDSK           0x01000000  /* No handshake.  When set the peripheral doesn't  */
-+                                                                                  /* require the regular handshake protocal. Must    */
-+                                                                              /* be set for SSP and IDE operations, optional     */
-+                                                                                  /* for external peripherals.                       */
-+#define CONTROL_M2M_PWSC_MASK   0xfe000000    /* Peripheral wait states count. Gives the latency */
-+#define CONTROL_M2M_PWSC_SHIFT        25                      /* (in PCLK cycles) needed by the peripheral to    */
-+                                                                              /* deassert its' request once the M2M xfer w/ DMA  */
-+                                                                              /* is complete.                                    */
-+
-+/*
-+ * M2M INTERRUPT register bit defines
-+ */
-+#define INTERRUPT_M2M_STALLINT        0x00000001      /* Stall interrupt indicates channel stalled. */
-+#define INTERRUPT_M2M_DONEINT 0x00000002      /* Transaction done.                          */
-+#define INTERRUPT_M2M_NFBINT  0x00000004      /* Next frame buffer interrupt indicates      */
-+                                                                                      /* channel requires a new buffer              */
-+
-+
-+
-+/*
-+ * M2M STATUS register bit defines
-+ */
-+#define STATUS_M2M_STALL              0x00000001  /* A '1' indicates channel is stalled           */
-+#define STATUS_M2M_CURRENTSTATE_MASK  0x0000003e  /* Indicates state of M2M Channel control       */
-+#define STATUS_M2M_CURRENTSTATE_SHIFT 1               /* FSM (0-2):                                   */
-+                                                                                  /*  000 - IDLE, 001 - STALL, 010 - MEM_RD,      */
-+                                                                                  /*  011 - MEM_WR, 100 - BWC_WAIT                */
-+                                                                                  /* and M2M buffer FSM (3-2):                    */
-+                                                                                  /*  00 - NO_BUF, 01 - BUF_ON, 10 - BUF_NEXT     */
-+#define STATUS_M2M_DONE                   0x00000040  /* Transfer completed successfully if 1.        */
-+#define STATUS_M2M_TCS_MASK           0x00000180  /* Terminal Count status. Indicates whether or  */
-+#define STATUS_M2M_TCS_SHIFT    7                     /* or not the actual byte count reached         */
-+                                                                              /* programmed limit for buffer descriptor       */
-+#define STATUS_M2M_EOTS_MASK    0x00000600  /* End-of-Transfer status for buffer            */
-+#define STATUS_M2M_EOTS_SHIFT   9
-+#define STATUS_M2M_NFB                        0x00000800  /* A '1' indicates channel has moved            */
-+                                                                                  /* from NEXT state to ON state, but the next    */
-+                                                                                  /* byte count reg for next buffer has not been  */
-+                                                                                  /* programmed yet.                              */
-+#define STATUS_M2M_NB                 0x00001000  /* NextBuffer status. Informs NFB service       */
-+                                                                                  /* routine, after NFB int, which pair of buffer */
-+                                                                                  /* descriptor registers is free to update.      */
-+#define STATUS_M2M_DREQS              0x00002000  /* DREQ status.  Reflects the status of the     */
-+                                                                                  /* synchronized external peripherals DMA        */
-+                                                                                  /* request signal.                              */
-+
-+/*
-+ * Register masks to mask off reserved bits after reading register.
-+ */
-+#define M2M_MASK_BCR0             0x0000ffff
-+#define M2M_MASK_BCR1             0x0000ffff
-+#define M2M_MASK_SAR_BASE0        0xffffffff
-+#define M2M_MASK_SAR_BASE1        0xffffffff
-+#define M2M_MASK_SAR_CURRENT0     0xffffffff
-+#define M2M_MASK_SAR_CURRENT1     0xffffffff
-+#define M2M_MASK_DAR_BASE0        0xffffffff
-+#define M2M_MASK_DAR_BASE1        0xffffffff
-+#define M2M_MASK_DAR_CURRENT0     0xffffffff
-+#define M2M_MASK_DAR_CURRENT1     0xffffffff
-+
-+
-+//
-+/* 8000_0000 - 8000_ffff: DMA  */
-+#define DMA_OFFSET              0x000000
-+#define DMA_BASE                (EP93XX_DMA_BASE)
-+#define DMAMP_TX_0_CONTROL      (DMA_BASE+0x0000)
-+#define DMAMP_TX_0_INTERRUPT    (DMA_BASE+0x0004)
-+#define DMAMP_TX_0_PPALLOC      (DMA_BASE+0x0008)
-+#define DMAMP_TX_0_STATUS       (DMA_BASE+0x000C)
-+#define DMAMP_TX_0_REMAIN       (DMA_BASE+0x0014)
-+#define DMAMP_TX_0_MAXCNT0      (DMA_BASE+0x0020)
-+#define DMAMP_TX_0_BASE0        (DMA_BASE+0x0024)
-+#define DMAMP_TX_0_CURRENT0     (DMA_BASE+0x0028)
-+#define DMAMP_TX_0_MAXCNT1      (DMA_BASE+0x0030)
-+#define DMAMP_TX_0_BASE1        (DMA_BASE+0x0034)
-+#define DMAMP_TX_0_CURRENT1     (DMA_BASE+0x0038)
-+
-+#define DMAMP_RX_1_CONTROL      (DMA_BASE+0x0040)
-+#define DMAMP_RX_1_INTERRUPT    (DMA_BASE+0x0044)
-+#define DMAMP_RX_1_PPALLOC      (DMA_BASE+0x0048)
-+#define DMAMP_RX_1_STATUS       (DMA_BASE+0x004C)
-+#define DMAMP_RX_1_REMAIN       (DMA_BASE+0x0054)
-+#define DMAMP_RX_1_MAXCNT0      (DMA_BASE+0x0060)
-+#define DMAMP_RX_1_BASE0        (DMA_BASE+0x0064)
-+#define DMAMP_RX_1_CURRENT0     (DMA_BASE+0x0068)
-+#define DMAMP_RX_1_MAXCNT1      (DMA_BASE+0x0070)
-+#define DMAMP_RX_1_BASE1        (DMA_BASE+0x0074)
-+#define DMAMP_RX_1_CURRENT1     (DMA_BASE+0x0078)
-+
-+#define DMAMP_TX_2_CONTROL      (DMA_BASE+0x0080)
-+#define DMAMP_TX_2_INTERRUPT    (DMA_BASE+0x0084)
-+#define DMAMP_TX_2_PPALLOC      (DMA_BASE+0x0088)
-+#define DMAMP_TX_2_STATUS       (DMA_BASE+0x008C)
-+#define DMAMP_TX_2_REMAIN       (DMA_BASE+0x0094)
-+#define DMAMP_TX_2_MAXCNT0      (DMA_BASE+0x00A0)
-+#define DMAMP_TX_2_BASE0        (DMA_BASE+0x00A4)
-+#define DMAMP_TX_2_CURRENT0     (DMA_BASE+0x00A8)
-+#define DMAMP_TX_2_MAXCNT1      (DMA_BASE+0x00B0)
-+#define DMAMP_TX_2_BASE1        (DMA_BASE+0x00B4)
-+#define DMAMP_TX_2_CURRENT1     (DMA_BASE+0x00B8)
-+
-+#define DMAMP_RX_3_CONTROL      (DMA_BASE+0x00C0)
-+#define DMAMP_RX_3_INTERRUPT    (DMA_BASE+0x00C4)
-+#define DMAMP_RX_3_PPALLOC      (DMA_BASE+0x00C8)
-+#define DMAMP_RX_3_STATUS       (DMA_BASE+0x00CC)
-+#define DMAMP_RX_3_REMAIN       (DMA_BASE+0x00D4)
-+#define DMAMP_RX_3_MAXCNT0      (DMA_BASE+0x00E0)
-+#define DMAMP_RX_3_BASE0        (DMA_BASE+0x00E4)
-+#define DMAMP_RX_3_CURRENT0     (DMA_BASE+0x00E8)
-+#define DMAMP_RX_3_MAXCNT1      (DMA_BASE+0x00F0)
-+#define DMAMP_RX_3_BASE1        (DMA_BASE+0x00F4)
-+#define DMAMP_RX_3_CURRENT1     (DMA_BASE+0x00F8)
-+
-+#define DMAMM_0_CONTROL         (DMA_BASE+0x0100)
-+#define DMAMM_0_INTERRUPT       (DMA_BASE+0x0104)
-+#define DMAMM_0_STATUS          (DMA_BASE+0x010C)
-+#define DMAMM_0_BCR0            (DMA_BASE+0x0110)
-+#define DMAMM_0_BCR1            (DMA_BASE+0x0114)
-+#define DMAMM_0_SAR_BASE0       (DMA_BASE+0x0118)
-+#define DMAMM_0_SAR_BASE1       (DMA_BASE+0x011C)
-+#define DMAMM_0_SAR_CURRENT0    (DMA_BASE+0x0124)
-+#define DMAMM_0_SAR_CURRENT1    (DMA_BASE+0x0128)
-+#define DMAMM_0_DAR_BASE0       (DMA_BASE+0x012C)
-+#define DMAMM_0_DAR_BASE1       (DMA_BASE+0x0130)
-+#define DMAMM_0_DAR_CURRENT0    (DMA_BASE+0x0134)
-+#define DMAMM_0_DAR_CURRENT1    (DMA_BASE+0x013C)
-+
-+#define DMAMM_1_CONTROL         (DMA_BASE+0x0140)
-+#define DMAMM_1_INTERRUPT       (DMA_BASE+0x0144)
-+#define DMAMM_1_STATUS          (DMA_BASE+0x014C)
-+#define DMAMM_1_BCR0            (DMA_BASE+0x0150)
-+#define DMAMM_1_BCR1            (DMA_BASE+0x0154)
-+#define DMAMM_1_SAR_BASE0       (DMA_BASE+0x0158)
-+#define DMAMM_1_SAR_BASE1       (DMA_BASE+0x015C)
-+#define DMAMM_1_SAR_CURRENT0    (DMA_BASE+0x0164)
-+#define DMAMM_1_SAR_CURRENT1    (DMA_BASE+0x0168)
-+#define DMAMM_1_DAR_BASE0       (DMA_BASE+0x016C)
-+#define DMAMM_1_DAR_BASE1       (DMA_BASE+0x0170)
-+#define DMAMM_1_DAR_CURRENT0    (DMA_BASE+0x0174)
-+#define DMAMM_1_DAR_CURRENT1    (DMA_BASE+0x017C)
-+
-+#define DMAMP_RX_5_CONTROL      (DMA_BASE+0x0200)
-+#define DMAMP_RX_5_INTERRUPT    (DMA_BASE+0x0204)
-+#define DMAMP_RX_5_PPALLOC      (DMA_BASE+0x0208)
-+#define DMAMP_RX_5_STATUS       (DMA_BASE+0x020C)
-+#define DMAMP_RX_5_REMAIN       (DMA_BASE+0x0214)
-+#define DMAMP_RX_5_MAXCNT0      (DMA_BASE+0x0220)
-+#define DMAMP_RX_5_BASE0        (DMA_BASE+0x0224)
-+#define DMAMP_RX_5_CURRENT0     (DMA_BASE+0x0228)
-+#define DMAMP_RX_5_MAXCNT1      (DMA_BASE+0x0230)
-+#define DMAMP_RX_5_BASE1        (DMA_BASE+0x0234)
-+#define DMAMP_RX_5_CURRENT1     (DMA_BASE+0x0238)
-+
-+#define DMAMP_TX_4_CONTROL      (DMA_BASE+0x0240)
-+#define DMAMP_TX_4_INTERRUPT    (DMA_BASE+0x0244)
-+#define DMAMP_TX_4_PPALLOC      (DMA_BASE+0x0248)
-+#define DMAMP_TX_4_STATUS       (DMA_BASE+0x024C)
-+#define DMAMP_TX_4_REMAIN       (DMA_BASE+0x0254)
-+#define DMAMP_TX_4_MAXCNT0      (DMA_BASE+0x0260)
-+#define DMAMP_TX_4_BASE0        (DMA_BASE+0x0264)
-+#define DMAMP_TX_4_CURRENT0     (DMA_BASE+0x0268)
-+#define DMAMP_TX_4_MAXCNT1      (DMA_BASE+0x0270)
-+#define DMAMP_TX_4_BASE1        (DMA_BASE+0x0274)
-+#define DMAMP_TX_4_CURRENT1     (DMA_BASE+0x0278)
-+
-+#define DMAMP_RX_7_CONTROL      (DMA_BASE+0x0280)
-+#define DMAMP_RX_7_INTERRUPT    (DMA_BASE+0x0284)
-+#define DMAMP_RX_7_PPALLOC      (DMA_BASE+0x0288)
-+#define DMAMP_RX_7_STATUS       (DMA_BASE+0x028C)
-+#define DMAMP_RX_7_REMAIN       (DMA_BASE+0x0294)
-+#define DMAMP_RX_7_MAXCNT0      (DMA_BASE+0x02A0)
-+#define DMAMP_RX_7_BASE0        (DMA_BASE+0x02A4)
-+#define DMAMP_RX_7_CURRENT0     (DMA_BASE+0x02A8)
-+#define DMAMP_RX_7_MAXCNT1      (DMA_BASE+0x02B0)
-+#define DMAMP_RX_7_BASE1        (DMA_BASE+0x02B4)
-+#define DMAMP_RX_7_CURRENT1     (DMA_BASE+0x02B8)
-+
-+#define DMAMP_TX_6_CONTROL      (DMA_BASE+0x02C0)
-+#define DMAMP_TX_6_INTERRUPT    (DMA_BASE+0x02C4)
-+#define DMAMP_TX_6_PPALLOC      (DMA_BASE+0x02C8)
-+#define DMAMP_TX_6_STATUS       (DMA_BASE+0x02CC)
-+#define DMAMP_TX_6_REMAIN       (DMA_BASE+0x02D4)
-+#define DMAMP_TX_6_MAXCNT0      (DMA_BASE+0x02E0)
-+#define DMAMP_TX_6_BASE0        (DMA_BASE+0x02E4)
-+#define DMAMP_TX_6_CURRENT0     (DMA_BASE+0x02E8)
-+#define DMAMP_TX_6_MAXCNT1      (DMA_BASE+0x02F0)
-+#define DMAMP_TX_6_BASE1        (DMA_BASE+0x02F4)
-+#define DMAMP_TX_6_CURRENT1     (DMA_BASE+0x02F8)
-+
-+#define DMAMP_RX_9_CONTROL      (DMA_BASE+0x0300)
-+#define DMAMP_RX_9_INTERRUPT    (DMA_BASE+0x0304)
-+#define DMAMP_RX_9_PPALLOC      (DMA_BASE+0x0308)
-+#define DMAMP_RX_9_STATUS       (DMA_BASE+0x030C)
-+#define DMAMP_RX_9_REMAIN       (DMA_BASE+0x0314)
-+#define DMAMP_RX_9_MAXCNT0      (DMA_BASE+0x0320)
-+#define DMAMP_RX_9_BASE0        (DMA_BASE+0x0324)
-+#define DMAMP_RX_9_CURRENT0     (DMA_BASE+0x0328)
-+#define DMAMP_RX_9_MAXCNT1      (DMA_BASE+0x0330)
-+#define DMAMP_RX_9_BASE1        (DMA_BASE+0x0334)
-+#define DMAMP_RX_9_CURRENT1     (DMA_BASE+0x0338)
-+
-+#define DMAMP_TX_8_CONTROL      (DMA_BASE+0x0340)
-+#define DMAMP_TX_8_INTERRUPT    (DMA_BASE+0x0344)
-+#define DMAMP_TX_8_PPALLOC      (DMA_BASE+0x0348)
-+#define DMAMP_TX_8_STATUS       (DMA_BASE+0x034C)
-+#define DMAMP_TX_8_REMAIN       (DMA_BASE+0x0354)
-+#define DMAMP_TX_8_MAXCNT0      (DMA_BASE+0x0360)
-+#define DMAMP_TX_8_BASE0        (DMA_BASE+0x0364)
-+#define DMAMP_TX_8_CURRENT0     (DMA_BASE+0x0368)
-+#define DMAMP_TX_8_MAXCNT1      (DMA_BASE+0x0370)
-+#define DMAMP_TX_8_BASE1        (DMA_BASE+0x0374)
-+#define DMAMP_TX_8_CURRENT1     (DMA_BASE+0x0378)
-+
-+#define DMA_ARBITRATION         (DMA_BASE+0x0380)
-+#define DMA_INTERRUPT           (DMA_BASE+0x03C0)
-+
-+
-+/*
-+ * DMA Register Base addresses and Offsets
-+ */
-+#define DMA_M2P_TX_0_BASE       DMAMP_TX_0_CONTROL
-+#define DMA_M2P_RX_1_BASE       DMAMP_RX_1_CONTROL
-+#define DMA_M2P_TX_2_BASE       DMAMP_TX_2_CONTROL
-+#define DMA_M2P_RX_3_BASE       DMAMP_RX_3_CONTROL
-+#define DMA_M2M_0_BASE          DMAMM_0_CONTROL
-+#define DMA_M2M_1_BASE          DMAMM_1_CONTROL
-+#define DMA_M2P_RX_5_BASE       DMAMP_RX_5_CONTROL
-+#define DMA_M2P_TX_4_BASE       DMAMP_TX_4_CONTROL
-+#define DMA_M2P_RX_7_BASE       DMAMP_RX_7_CONTROL
-+#define DMA_M2P_TX_6_BASE       DMAMP_TX_6_CONTROL
-+#define DMA_M2P_RX_9_BASE       DMAMP_RX_9_CONTROL
-+#define DMA_M2P_TX_8_BASE       DMAMP_TX_8_CONTROL
-+
-+#define M2P_OFFSET_CONTROL          0x0000
-+#define M2P_OFFSET_INTERRUPT        0x0004
-+#define M2P_OFFSET_PPALLOC          0x0008
-+#define M2P_OFFSET_STATUS           0x000C
-+#define M2P_OFFSET_REMAIN           0x0014
-+#define M2P_OFFSET_MAXCNT0          0x0020
-+#define M2P_OFFSET_BASE0            0x0024
-+#define M2P_OFFSET_CURRENT0         0x0028
-+#define M2P_OFFSET_MAXCNT1          0x0030
-+#define M2P_OFFSET_BASE1            0x0034
-+#define M2P_OFFSET_CURRENT1         0x0038
-+
-+#define M2M_OFFSET_CONTROL          0x0000
-+#define M2M_OFFSET_INTERRUPT        0x0004
-+#define M2M_OFFSET_STATUS           0x000C
-+#define M2M_OFFSET_BCR0             0x0010
-+#define M2M_OFFSET_BCR1             0x0014
-+#define M2M_OFFSET_SAR_BASE0        0x0018
-+#define M2M_OFFSET_SAR_BASE1        0x001C
-+#define M2M_OFFSET_SAR_CURRENT0     0x0024
-+#define M2M_OFFSET_SAR_CURRENT1     0x0028
-+#define M2M_OFFSET_DAR_BASE0        0x002C
-+#define M2M_OFFSET_DAR_BASE1        0x0030
-+#define M2M_OFFSET_DAR_CURRENT0     0x0034
-+#define M2M_OFFSET_DAR_CURRENT1     0x003C
-+
-+
-+
-+//-----------------------------------------------------------------------------
-+// PWRCNT Register Defines
-+//-----------------------------------------------------------------------------
-+#define SYSCON_PWRCNT_FIREN             0x80000000
-+#define SYSCON_PWRCNT_UARTBAUD          0x20000000
-+#define SYSCON_PWRCNT_USHEN             0x10000000
-+#define SYSCON_PWRCNT_DMA_M2MCH1        0x08000000
-+#define SYSCON_PWRCNT_DMA_M2MCH0        0x04000000
-+#define SYSCON_PWRCNT_DMA_M2PCH8        0x02000000
-+#define SYSCON_PWRCNT_DMA_M2PCH9        0x01000000
-+#define SYSCON_PWRCNT_DMA_M2PCH6        0x00800000
-+#define SYSCON_PWRCNT_DMA_M2PCH7        0x00400000
-+#define SYSCON_PWRCNT_DMA_M2PCH4        0x00200000
-+#define SYSCON_PWRCNT_DMA_M2PCH5        0x00100000
-+#define SYSCON_PWRCNT_DMA_M2PCH2        0x00080000
-+#define SYSCON_PWRCNT_DMA_M2PCH3        0x00040000
-+#define SYSCON_PWRCNT_DMA_M2PCH0        0x00020000
-+#define SYSCON_PWRCNT_DMA_M2PCH1        0x00010000
-+
-+#ifndef __ASSEMBLY__
-+/*
-+ * DMA Register Base addresses
-+ */
-+static unsigned int const DMAM2PChannelBase[10] =
-+{
-+    DMA_M2P_TX_0_BASE,
-+    DMA_M2P_RX_1_BASE,
-+    DMA_M2P_TX_2_BASE,
-+    DMA_M2P_RX_3_BASE,
-+    DMA_M2P_TX_4_BASE,
-+    DMA_M2P_RX_5_BASE,
-+    DMA_M2P_TX_6_BASE,
-+    DMA_M2P_RX_7_BASE,
-+    DMA_M2P_TX_8_BASE,
-+    DMA_M2P_RX_9_BASE
-+};
-+
-+static unsigned int const DMAM2MChannelBase[2] =
-+{
-+    DMA_M2M_0_BASE,
-+    DMA_M2M_1_BASE
-+};
-+
-+#endif /* __ASSEMBLY__ */
-+
-+/*****************************************************************************
-+ *
-+ * DMA buffer structure type.
-+ *
-+ ****************************************************************************/
-+typedef struct ep93xx_dma_buffer_s
-+{
-+    unsigned int    source;     /* buffer physical source address.          */
-+    unsigned int    dest;       /* buffer physical destination address,     */
-+                                /* only used with the 2 M2M channels.       */
-+    unsigned int    size;       /* buffer size in bytes                     */
-+    unsigned int    last;       /* 1 if this is the last buffer             */
-+                                /* in this transaction.  If 1,              */
-+                                /* disable the NFBint so we aren't          */
-+                                /* interrupted for another buffer           */
-+                                /* when we know there won't be another.     */
-+    unsigned int    used;       /* This field is set to 1 by the DMA        */
-+                                /* interface after the buffer is transferred*/
-+    int    buf_id;              /* unique identifyer specified by the       */
-+                                /* the driver which requested the dma       */
-+} ep93xx_dma_buffer_t;
-+
-+typedef ep93xx_dma_buffer_t * ep93xx_dma_buffer_p;
-+
-+/*****************************************************************************
-+ *
-+ * Instance definition for the DMA interface.
-+ *
-+ ****************************************************************************/
-+typedef struct ep9312_dma_s
-+{
-+    /*
-+     *  This 1 when the instance is in use, and 0 when it's not.
-+     */
-+    unsigned int ref_count;
-+
-+    /*
-+     * This is the last valid handle for this instance.  When giving out a
-+     * new handle this will be incremented and given out.
-+     */
-+    int last_valid_handle;
-+
-+    /*
-+     * device specifies one of the 20 DMA hardware ports this
-+     * DMA channel will service.
-+     */
-+    ep93xx_dma_dev_t device;
-+
-+    /*
-+     * DMABufferQueue is the queue of buffer structure pointers which the
-+     * dma channel will use to setup transfers.
-+     */
-+    ep93xx_dma_buffer_t buffer_queue[MAX_EP93XX_DMA_BUFFERS];
-+
-+    /*
-+     * currnt_buffer : This is the buffer currently being transfered on
-+     *                 this channel.
-+     * last_buffer : This is the last buffer for this transfer.
-+     * Note: current_buffer + 1 is already programmed into the dma
-+     *       channel as the next buffer to transfer. Don't write
-+     *       over either entry.
-+     */
-+    int current_buffer;
-+    int last_buffer;
-+
-+    /*
-+     * The following 3 fields are buffer counters.
-+     *
-+     * iNewBuffers: Buffers in the queue which have not been transfered.
-+     * iUsedBuffers: Buffers in the queue which have have been tranferred,
-+     *               and are waiting to be returned.
-+     * iTotalBuffers: Total number of buffers in the queue.
-+     */
-+    int new_buffers;
-+    int used_buffers;
-+    int total_buffers;
-+
-+    /*
-+     * uiTotalBytes has the total bytes transfered on the channel since the
-+     * last flush.  This value does not include the bytes tranfered in the
-+     * current buffer.  A byte count is only added after a complete buffer
-+     * is tranfered.
-+     */
-+    unsigned int total_bytes;
-+
-+    /*
-+     *  Interrupt number for this channel
-+     */
-+    unsigned int irq;
-+
-+    /*
-+     * Indicates whether or not the channel is currently enabled to transfer
-+     * data.
-+     */
-+    unsigned int xfer_enable;
-+
-+    /*
-+     * pause indicates if the dma channel was paused by calling the pause
-+     * ioctl.
-+     */
-+    unsigned int pause;
-+
-+    /*
-+     *  buffer structure used during a pause to capture the current
-+     *  address and remaining bytes for the buffer actively being transferred
-+     *  on the channel. This buffer will be used to reprogram the dma
-+     *  channel upon a resume.
-+     */
-+    ep93xx_dma_buffer_t pause_buf;
-+
-+    /*
-+     * DMACallback is a function pointer which the calling application can
-+     * use install a function to.  this fuction can be used to notify the
-+     * calling application of an interrupt.
-+     */
-+    dma_callback callback;
-+
-+    /*
-+     * User data used as a parameter for the Callback function.  The user
-+     * sets up the data and sends it with the callback function.
-+     */
-+    unsigned int user_data;
-+
-+    /*
-+     * A string representation of the device attached to the channel.
-+     */
-+    const char * device_id;
-+
-+    /*
-+     * The register base address for this dma channel.
-+     */
-+    unsigned int reg_base;
-+
-+    /*
-+     * terminated indicates
-+     */
-+    unsigned int terminated;
-+
-+
-+} ep93xx_dma_t;
-+
-+/*****************************************************************************
-+ *
-+ * DMA macros
-+ *
-+ ****************************************************************************/
-+#define DMA_HANDLE_SPECIFIER_MASK   0xF0000000
-+#define DMA_CH0_HANDLE_SPECIFIER    0x00000000
-+#define DMA_CH1_HANDLE_SPECIFIER    0x10000000
-+#define DMA_CH2_HANDLE_SPECIFIER    0x20000000
-+#define DMA_CH3_HANDLE_SPECIFIER    0x30000000
-+#define DMA_CH4_HANDLE_SPECIFIER    0x40000000
-+#define DMA_CH5_HANDLE_SPECIFIER    0x50000000
-+#define DMA_CH6_HANDLE_SPECIFIER    0x60000000
-+#define DMA_CH7_HANDLE_SPECIFIER    0x70000000
-+#define DMA_CH8_HANDLE_SPECIFIER    0x80000000
-+#define DMA_CH9_HANDLE_SPECIFIER    0x90000000
-+#define DMA_CH10_HANDLE_SPECIFIER   0xA0000000
-+#define DMA_CH11_HANDLE_SPECIFIER   0xB0000000
-+
-+#endif // _DMADRV_H_