mpc107Dma.c
上传用户:luoyougen
上传日期:2008-05-12
资源大小:23136k
文件大小:47k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* mpc107Dma.c - MPC107 DMA Interface support */
  2. /* Copyright 1996-2000 Wind River Systems, Inc. */
  3. #include "copyright_wrs.h"
  4. /*
  5. modification history
  6. --------------------
  7. 01b,11sep00,rcs correct headerfile paths
  8. 01a,18jun00,bri written
  9. */
  10. /*
  11. DESCRIPTION
  12. This module contains routines for the DMA interface of MPC107 .
  13. The DMA controller transfers blocks of data independent of the local processor
  14. or PCI hosts. Data movement occurs on the PCI and/or memory bus. The MPC107
  15. has two DMA channels, each with a 64-byte queue to facilitate the gathering
  16. and sending of data.Both the local processor and PCI masters can initiate a
  17. DMA transfer.
  18. Some of the features of the MPC107 DMA unit are:
  19. Two DMA channels and both channels accessible by processor core
  20. and remote PCI masters.
  21. Misaligned transfer capability.
  22. Chaining mode (including scatter gathering) and Direct mode.
  23. Interrupt on completed segment, chain, and error conditions.
  24. Four DMA transfer types:
  25. Local memory to local memory,PCI memory to PCI memory,
  26. PCI memory to local memory, and  Local memory to PCI memory.
  27. This module provides support for "chained" (periodic and non periodic )DMA
  28. and "direct" DMA  transfers on both DMA channels .
  29. All the four DMA transfer types are supported by this module (local memory to
  30. local memory,local memory to PCI mmeory, PCI memory to local memory and
  31. PCI to PCI memory) .
  32. The descriptors for the chained DMA are built in the local memory .
  33. .SH INITIALIZATION
  34. This driver is initialized from the BSP, usually as part of sysHwInit().
  35. The routine mpc107DmaInit() should be called to initialize the  driver .
  36. */
  37. /* includes */
  38. #include "vxWorks.h"
  39. #include "semLib.h"
  40. #include "sysLib.h"
  41. #include "drv/multi/mpc107.h"
  42. #include "drv/dma/mpc107Dma.h"
  43. #include "drv/intrCtl/mpc107Epic.h"
  44. #include "errno.h"
  45. #include "errnoLib.h"
  46. #include "cacheLib.h"
  47. #include "intLib.h"
  48. #include "memLib.h"
  49. #include "stdlib.h"
  50. /* static file scope locals */
  51. MPC107_DMA_DESCRIPTOR  *pFirstDescriptorCh0 = NULL; /* Pointer to DMA */
  52.                                                      /* descriptor */
  53. MPC107_DMA_DESCRIPTOR *pFirstDescriptorCh1 = NULL; /* Pointer to DMA */
  54.                                                      /* descriptor */
  55. BOOL  chainedDma0FirstTime = FALSE;/* Flag for chained DMA CH0 */
  56. BOOL  chainedDma1FirstTime = FALSE;/* Flag for chained DMA CH1 */
  57. ULONG  dmaBuildDescrInProgCh0 = 0;  /* Flag for building descriptors */
  58. ULONG  dmaBuildDescrInProgCh1 = 0;  /* Flag for building descriptors */
  59. SEM_ID  semIdDirectDmaCh0;           /* Semaphore for direct DMA CH0 */
  60. SEM_ID  semIdDirectDmaCh1;           /* Semaphore for direct DMA CH1 */
  61. SEM_ID  semIdChainDmaCh0;            /* Semaphore for chained DMA CH0 */
  62. SEM_ID  semIdChainDmaCh1;            /* Semaphore for chained DMA CH1 */
  63. /* forward Declarations */
  64. void  mpc107DmaCh0Int (void); /* ISR for channel 0 */
  65. void  mpc107DmaCh1Int (void); /* ISR for channel 1 */
  66. LOCAL STATUS mpc107DmaChainStart (UINT32 channelNumber);
  67. LOCAL STATUS mpc107DmaPeriodicStart (UINT32 channelNumber,UINT32 timePeriod);
  68. /***************************************************************************
  69. *
  70. * mpc107DmaInit - initialize DMA  controller
  71. *
  72. * The DMA interface is initialized to be in "Direct DMA transfer" mode and
  73. * DMA  interrupts(End of Transfer Interrupt and Error Interrupt) are
  74. * disabled .
  75. * This routine also attaches the interrupt handlers of the DMA interface.
  76. *
  77. * This routine should be called only once, during hardware initialization,
  78. * before using the DMA interface.
  79. *
  80. * RETURNS: N/A
  81. */
  82. void mpc107DmaInit (void)
  83.     {
  84.     /*
  85.      * Initialize the  DMA Channel Zero for the following :
  86.      * Error Interrupt Disabled,
  87.      * End of Transfer Interrupt Disabled
  88.      * Direct Mode DMA transfer
  89.      */
  90.     MPC107EUMBBARWRITE(MPC107_DMA_DMR0, MPC107_DMA_DMR0_DEFAULT);
  91.     /*
  92.      * Initialize the  DMA Channel One for the following :
  93.      * Error Interrupt Disabled,
  94.      * End of Transfer Interrupt Disabled
  95.      * Direct Mode DMA transfer
  96.      */
  97.     MPC107EUMBBARWRITE(MPC107_DMA_DMR1, MPC107_DMA_DMR1_DEFAULT);
  98.     /*
  99.      * Semaphore used for mutual exclusion in Direct DMA transfer
  100.      * of Channel Zero
  101.      */
  102.     semIdDirectDmaCh0 = semBCreate ((INT32)SEM_FULL, SEM_Q_PRIORITY);
  103.     /*
  104.      * Semaphore used for mutual exclusion in Direct DMA transfer
  105.      * of Channel One
  106.      */
  107.     semIdDirectDmaCh1 = semBCreate ((INT32)SEM_FULL, SEM_Q_PRIORITY);
  108.     /*
  109.      * Semaphore used for mutual exclusion in Chained DMA transfer
  110.      * of Channel Zero
  111.      */
  112.     semIdChainDmaCh0  = semBCreate ((INT32)SEM_FULL, SEM_Q_PRIORITY);
  113.     /*
  114.      * Semaphore used for mutual exclusion in Chained DMA transfer
  115.      * of Channel One
  116.      */
  117.     semIdChainDmaCh1  = semBCreate ((INT32)SEM_FULL, SEM_Q_PRIORITY);
  118.     /* The ISR handlers should be hooked here */
  119.     intConnect ((VOIDFUNCPTR*)MPC107_EPIC_DMA0_INT_VECT,
  120.                                  (VOIDFUNCPTR)mpc107DmaCh0Int, 0);
  121.     intConnect ((VOIDFUNCPTR*)MPC107_EPIC_DMA1_INT_VECT,
  122.                                  (VOIDFUNCPTR)mpc107DmaCh1Int, 0);
  123.     }
  124. /***************************************************************************
  125. *
  126. * mpc107DmaStartDirect - start  "Direct" DMA transfer
  127. *
  128. * This routine is used for starting "Direct" mode of DMA transfer."Direct"
  129. * mode of DMA transfer can be done on both the DMA channels .All the registers
  130. * of the corresponding channel are initialized to perform "Direct" DMA transfer.
  131. *
  132. * RETURNS:  OK, or ERROR if channel is configured for Periodic DMA or
  133. * <numberOfBytes> is zero or channel specified by <channelNumber> is
  134. * not valid .
  135. */
  136. STATUS mpc107DmaStartDirect
  137.     (
  138.     UINT32  channelNumber,      /* Channel Number */
  139.     UINT32  transferType,       /* Transfer Type */
  140.     UINT32  sourceAddress,      /* Source Address */
  141.     UINT32  destinationAddress, /* Destinantion Address */
  142.     UINT32  numberOfBytes       /* Number of Bytes */
  143.     )
  144.     {
  145.     UINT32 statusOfDmaReg = 0;
  146.     UINT32 dataReadDmaReg = 0;
  147.     if (channelNumber == MPC107_DMA_CHANNEL0) /* channel 0 */
  148.         {
  149.         /* Reading of DMA Mode Register */
  150.         statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0);
  151.         if ( (!(statusOfDmaReg & MPC107_DMA_DMR_CTM) &&
  152.                (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0)
  153.             {
  154.             /* This channel is configured for Periodic DMA */
  155.             errnoSet (EBUSY);
  156.             return (ERROR);
  157.             }
  158.         if (numberOfBytes != 0) /* number of bytes is non-zero */
  159.             {
  160.             semTake (semIdDirectDmaCh0, WAIT_FOREVER); /* Take the semaphore */
  161.             /* waiting for the channel to be free */
  162.             while (MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB);
  163.             /* Program the Source Address Register */
  164.             MPC107EUMBBARWRITE(MPC107_DMA_SAR0, sourceAddress);
  165.             /* Program the Destination Address Register */
  166.             MPC107EUMBBARWRITE(MPC107_DMA_DAR0, destinationAddress);
  167.             /* Program the number of bytes in the Byte Count Register */
  168.             MPC107EUMBBARWRITE(MPC107_DMA_BCR0, numberOfBytes);
  169.             /* Program the Current Descriptor Address Register 0 */
  170.             dataReadDmaReg =  (MPC107EUMBBARREAD(MPC107_DMA_CDAR0) &
  171.                                MPC107_DMA_CDAR_ADDR_MASK) |
  172.                               (transferType << MPC107_DMA_CDAR_CTT_SHIFT) ;
  173.             MPC107EUMBBARWRITE(MPC107_DMA_CDAR0, dataReadDmaReg);
  174.             /* Program the DMA Mode Register 0 to start DMA */
  175.             dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &
  176.                            !((MPC107_DMA_DMR_CS) | MPC107_DMA_DMR_CTM) ;
  177.             /*
  178.              * Clear the Channel Start Bit  and  the Channel Transfer Mode
  179.              * to be Direct DMA
  180.              */
  181.             MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg);
  182.             /* Set the Channel Start Bit to start DMA transfer */
  183.             MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg |
  184.                                MPC107_DMA_DMR_CS);
  185.             semGive (semIdDirectDmaCh0); /* release the semaphore */
  186.             }
  187.         else
  188.             {
  189.             errnoSet (EINVAL);
  190.             return (ERROR);
  191.             }
  192.         }
  193.     else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */
  194.         {
  195.         statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1);
  196.         if ( (!(statusOfDmaReg & MPC107_DMA_DMR_CTM) &&
  197.                (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0)
  198.             {
  199.             /* This channel is configured for Periodic DMA */
  200.             errnoSet (EBUSY);
  201.             return (ERROR);
  202.             }
  203.         if (numberOfBytes != 0) /* If number of bytes is not zero */
  204.             {
  205.             semTake (semIdDirectDmaCh1, WAIT_FOREVER); /* Take the semaphore */
  206.             /* Polling to see when the channel is free */
  207.             while (MPC107EUMBBARREAD(MPC107_DMA_DSR1) & MPC107_DMA_DSR_CB);
  208.             /* Program the Source Address Register */
  209.             MPC107EUMBBARWRITE(MPC107_DMA_SAR1, sourceAddress);
  210.             /* Program the Destination Address Register */
  211.             MPC107EUMBBARWRITE(MPC107_DMA_DAR1, destinationAddress);
  212.             /* Program the number of bytes in the Byte Count Register */
  213.             MPC107EUMBBARWRITE(MPC107_DMA_BCR1, numberOfBytes);
  214.             /* Program the Current Descriptor Address Register 1 */
  215.             dataReadDmaReg =  MPC107EUMBBARREAD(MPC107_DMA_CDAR1) &
  216.                                 (MPC107_DMA_CDAR_ADDR_MASK |
  217.                                 (transferType << MPC107_DMA_CDAR_CTT_SHIFT));
  218.             MPC107EUMBBARWRITE(MPC107_DMA_CDAR1, dataReadDmaReg);
  219.             /* Program the DMA Mode Register 1 to start DMA */
  220.             dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &
  221.                            !((MPC107_DMA_DMR_CS) | MPC107_DMA_DMR_CTM) ;
  222.             /*
  223.              * Clear the Channel Start Bit  and  the Channel Transfer Mode
  224.              * to be Direct DMA
  225.              */
  226.             MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg);
  227.             /* Set the Channel Start Bit to start DMA transfer */
  228.             MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg
  229.                               | MPC107_DMA_DMR_CS);
  230.             semGive (semIdDirectDmaCh1); /* Release the semaphore */
  231.             }
  232.         else
  233.             {
  234.             errnoSet (EINVAL);
  235.             return (ERROR); /* Number of bytes is Zero */
  236.             }
  237.         }
  238.     else
  239.         {
  240.         errnoSet (EINVAL);
  241.         return (ERROR) ; /* Undefined Channel Number */
  242.         }
  243.     return (OK) ;
  244.     }
  245. /***************************************************************************
  246. *
  247. * mpc107DmaChainStart  -  start Chained (non-periodic) DMA Transfer
  248. *
  249. * NOTES
  250. *
  251. * This routine  initializes the specified DMA channel for a "chained"
  252. * (non-periodic) DMA transfer.This routine is called in the routine
  253. * mpc107DmaChainedStart() after the "DMA descriptors" are built using the
  254. * routine  mpc107DmaBuildDescriptor().
  255. *
  256. * RETURNS: OK, or ERROR if channel specified by <channelNumber> is not
  257. * a valid channel or the channel is configured for "periodic" DMA .
  258. */
  259. LOCAL STATUS mpc107DmaChainStart
  260.     (
  261.     UINT32  channelNumber  /* channel number */
  262.     )
  263.     {
  264.     UINT32  statusOfDmaReg;
  265.     UINT32  dataReadDmaReg;
  266.     if (channelNumber == MPC107_DMA_CHANNEL0) /* channel 0 */
  267.         {
  268.         statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0);
  269.         if ( (!(statusOfDmaReg & MPC107_DMA_DMR_CTM) &&
  270.                (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0 )
  271.             {
  272.             /* This channel is configured for Periodic DMA */
  273.             errnoSet (EBUSY);
  274.             return (ERROR);
  275.             }
  276.         else if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) != 0)
  277.             {
  278.             /* This channel is configured for Direct DMA */
  279.             /* Waiting for the channel to be free */
  280.             while (MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB);
  281.             /* Program the Current Descriptor Address Register 0 */
  282.             MPC107EUMBBARWRITE(MPC107_DMA_CDAR0, (UINT32)pFirstDescriptorCh0);
  283.             /* Program the DMA Mode Register 0 to start DMA */
  284.             dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &
  285.                            !(MPC107_DMA_DMR_CS) & !(MPC107_DMA_DMR_CTM);
  286.             /*
  287.              * Clear the Channel Start Bit  and  the Channel Transfer Mode
  288.              * to be Chained  DMA
  289.              */
  290.             MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg);
  291.             /* Set the Channel Start Bit to start DMA transfer */
  292.             MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg |
  293.                                MPC107_DMA_DMR_CS);
  294.             }
  295.         else if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) == 0)
  296.             {
  297.             /* This channel is configured for Chained DMA */
  298.             /* If Chained DMA is already in progress  */
  299.             if ((MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB) != 0)
  300.                 {
  301.                 /*
  302.                  * Set the channel continue bit to in DMA Mode Register 0
  303.                  * to start DMA
  304.                  */
  305.                 dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0);
  306.                 MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg |
  307.                                    MPC107_DMA_DMR_CC);
  308.                 }
  309.             /*
  310.              * If chained DMA is not in progress  and the descriptors are
  311.              * built afresh
  312.              */
  313.             else if ((chainedDma0FirstTime))
  314.                 {
  315.                 /* Program the Current Descriptor Address Register 0 */
  316.                 MPC107EUMBBARWRITE(MPC107_DMA_CDAR0,
  317.                                   (UINT32)pFirstDescriptorCh0);
  318.                 /* Program the DMA Mode Register 0 to start DMA */
  319.                 dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &
  320.                                                  !(MPC107_DMA_DMR_CS) &
  321.                                                  !(MPC107_DMA_DMR_CTM);
  322.                 /*
  323.                  * Clear the Channel Start Bit  and  the Channel Transfer Mode
  324.                  * to be Chained  DMA
  325.                  */
  326.                 MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg);
  327.                 /* Set the Channel Start Bit to start DMA transfer */
  328.                 MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg |
  329.                                   MPC107_DMA_DMR_CS);
  330.                 }
  331.             }
  332.         }
  333.     else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */
  334.         {
  335.         statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1);
  336.         if ( (!(statusOfDmaReg & MPC107_DMA_DMR_CTM) &&
  337.               (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0)
  338.             {
  339.             /* This channel is configured for Periodic DMA */
  340.             errnoSet (EBUSY);
  341.             return (ERROR);
  342.             }
  343.         else if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) != 0)
  344.             {
  345.             /* This channel is configured for Direct DMA */
  346.             /* Waiting for the channel to be free */
  347.             while (MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB);
  348.             /* Program the Current Descriptor Address Register 1 */
  349.             MPC107EUMBBARWRITE(MPC107_DMA_CDAR1, (UINT32)pFirstDescriptorCh1);
  350.             /* Program the DMA Mode Register 1 to start DMA */
  351.             dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &
  352.                            !(MPC107_DMA_DMR_CS) & !(MPC107_DMA_DMR_CTM);
  353.             /*
  354.              * Clear the Channel Start Bit  and  the Channel Transfer Mode
  355.              * to be Chained  DMA
  356.              */
  357.             MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg);
  358.             /* Set the Channel Start Bit to start DMA transfer */
  359.             MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg |
  360.                                MPC107_DMA_DMR_CS);
  361.             }
  362.         else if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) == 0)
  363.             {
  364.             /* This channel is configured for Chained DMA */
  365.             /* if Chained DMA is already in progress  */
  366.             if ((MPC107EUMBBARREAD(MPC107_DMA_DSR1) & MPC107_DMA_DSR_CB) != 0)
  367.                 {
  368.                /*
  369.                 * Set the channel continue bit to in DMA Mode Register 1
  370.                 * to start DMA
  371.                 */
  372.                 dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1);
  373.                 MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg |
  374.                                    MPC107_DMA_DMR_CC);
  375.                 }
  376.             /*
  377.              * if chained DMA is not in progress  and the descriptors are
  378.              * built afresh
  379.              */
  380.             else if ((chainedDma1FirstTime))
  381.                 {
  382.                 /* Program the Current Descriptor Address Register 1 */
  383.                 MPC107EUMBBARWRITE(MPC107_DMA_CDAR1,
  384.                                   (UINT32)pFirstDescriptorCh1);
  385.                 /* Program the DMA Mode Register 1 to start DMA */
  386.                 dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &
  387.                                                  !(MPC107_DMA_DMR_CS) &
  388.                                                  !(MPC107_DMA_DMR_CTM);
  389.                 /*
  390.                  * Clear the Channel Start Bit  and  the Channel Transfer Mode
  391.                  * to be Chained  DMA
  392.                  */
  393.                 MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg);
  394.                 /* Set the Channel Start Bit to start DMA transfer */
  395.                 MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg |
  396.                                    MPC107_DMA_DMR_CS);
  397.                 }
  398.             }
  399.         }
  400.     else
  401.         {
  402.         errnoSet (EINVAL);
  403.         return (ERROR);
  404.         }
  405.     return (OK);
  406.     }
  407. /***************************************************************************
  408. *
  409. * mpc107DmaPeriodicStart -  start Periodic Chained DMA
  410. *
  411. * This routine initializes the specified  DMA channel for a  "periodic"
  412. * DMA transfer.
  413. * This routine is called in the routine mpc107DmaChainedStart() after the
  414. * "DMA descriptors" are built using the routine  mpc107DmaBuildDescriptor().
  415. * All the descriptors for a "periodic" DMA should be built before starting
  416. * the chained DMA transfer. Descriptors  cannot be added while a periodic
  417. * DMA transfer is taking place.
  418. *
  419. * RETURNS: OK, or ERROR if the channel specified by <channelNumber> is not a
  420. * valid channel or the  channel is already configured for "periodic" DMA .
  421. */
  422. LOCAL STATUS mpc107DmaPeriodicStart
  423.     (
  424.     UINT32 channelNumber,  /* DMA Channel Number */
  425.     UINT32 timePeriod      /* Time period */
  426.     )
  427.     {
  428.     UINT32  tempDataRead;
  429.     STATUS  status;
  430.     if (channelNumber == MPC107_DMA_CHANNEL0) /* channel 0 */
  431.         {
  432.         /* Disable interrupt for the timer */
  433.         tempDataRead = MPC107EUMBBARREAD(MPC107_EPIC_TM2_VEC_REG) |
  434.                                           MPC107_EPIC_TM_VECREG_INTMASK;
  435.         /* Program the count based on time period  and Clear  Count Inhibit */
  436.         MPC107EUMBBARWRITE(MPC107_EPIC_TM2_BASE_COUNT_REG,
  437.                            timePeriod & ! (MPC107_EPIC_TM_BASE_COUNT_CI));
  438.         /* Start Periodic DMA transfer and Set the periodic DMA Enable Bit */
  439.         status = mpc107DmaChainStart (channelNumber);
  440.         if (status == OK)
  441.             {
  442.             tempDataRead = MPC107EUMBBARREAD(MPC107_DMA_DMR0) |
  443.                                              MPC107_DMA_DMR_PDE;
  444.             MPC107EUMBBARWRITE(MPC107_DMA_DMR0, tempDataRead);
  445.             }
  446.         return (status);
  447.         }
  448.     else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */
  449.         {
  450.         /* Disable interrupt for the timer */
  451.         tempDataRead = MPC107EUMBBARREAD(MPC107_EPIC_TM3_VEC_REG) |
  452.                                           MPC107_EPIC_TM_VECREG_INTMASK;
  453.         /* Program the count based on time period  and Clear  Count Inhibit */
  454.         MPC107EUMBBARWRITE(MPC107_EPIC_TM3_BASE_COUNT_REG,
  455.                            timePeriod & ! (MPC107_EPIC_TM_BASE_COUNT_CI));
  456.         /* Start Periodic DMA transfer and Set the periodic DMA Enable Bit */
  457.         status = mpc107DmaChainStart (channelNumber);
  458.         if (status == OK)
  459.             {
  460.             tempDataRead = MPC107EUMBBARREAD(MPC107_DMA_DMR1) |
  461.                                              MPC107_DMA_DMR_PDE;
  462.             MPC107EUMBBARWRITE(MPC107_DMA_DMR1, tempDataRead);
  463.             }
  464.         return (status);
  465.         }
  466.     else
  467.         {
  468.         errnoSet (EINVAL);
  469.         return (ERROR);
  470.         }
  471.     return (OK);
  472.     }
  473. /***************************************************************************
  474. *
  475. * mpc107DmaChainedStart - start  a  "Chained" (Periodic or Non Periodic) DMA
  476. *
  477. * This routine is used for starting a "chained" (Periodic or Non Periodic)
  478. * DMA  transfer.
  479. *
  480. * The <timePeriod> specified should be in microseconds. If a zero <timePeriod>
  481. * is specified, a "chained" DMA transfer is started. If a nonzero <timePeriod>
  482. * is specified, a "periodic" chained DMA transfer is started. The <timePeriod>
  483. * should not be less than the time it takes for the DMA transfer for periodic
  484. * DMA transfers.
  485. * This routine should be called after the "DMA descriptors" are built using
  486. * the routine  mpc107DmaBuildDescriptor().All the descriptors for a "periodic"
  487. * DMA should be built before starting the chained DMA transfer. Descriptors
  488. * cannot be added while a periodic DMA transfer is taking place.
  489. * The routine  mpc107DmaStopPeriodic()  has to be used to stop the on-going
  490. * periodic DMA  before a new periodic DMA can be started with a new set of
  491. * descriptors.
  492. *
  493. * RETURNS: OK, or ERROR if channel specified by <channelNumber> is not a valid
  494. * channel or the channel is already configured for "periodic" DMA .
  495. */
  496. STATUS mpc107DmaChainedStart
  497.     (
  498.     UINT32  channelNumber, /* DMA Channel Number  */
  499.     UINT32  timePeriod     /* time period for repetition for a periodic */
  500.                                /* DMA transfer, zero for chained DMA. */
  501.                                /* Time period is specified in  multiples  */
  502.                                /* of Microseconds */
  503.     )
  504.     {
  505.     if ((channelNumber == MPC107_DMA_CHANNEL0) ||
  506.         (channelNumber == MPC107_DMA_CHANNEL1))
  507.         {
  508.         if (timePeriod == NULL) /* If time period specified is zero */
  509.             {
  510.             /* Start Chained DMA */
  511.             return (mpc107DmaChainStart (channelNumber));
  512.             }
  513.         else
  514.             {
  515.             /* Start Periodic DMA */
  516.             return (mpc107DmaPeriodicStart (channelNumber, timePeriod));
  517.             }
  518.         }
  519.     else
  520.         {
  521.         errnoSet (EINVAL);
  522.         return (ERROR);
  523.         }
  524.    }
  525. /***************************************************************************
  526. *
  527. * mpc107DmaPeriodicStop -  stop Periodic DMA
  528. *
  529. * This routine is used for stopping "periodic" chained  DMA transfer for the
  530. * specified DMA channel.
  531. *
  532. * RETURNS: OK, or ERROR if specified <channelNumber> is not a valid channel.
  533. */
  534. STATUS mpc107DmaPeriodicStop
  535.     (
  536.     UINT32  channelNumber   /* Channel Number  */
  537.     )
  538.     {
  539.     MPC107_DMA_DESCRIPTOR *pTempDescriptor;
  540.     MPC107_DMA_DESCRIPTOR *pTempFirstDescriptor;
  541.     UINT32 dataReadDmaReg;
  542.     if (channelNumber == MPC107_DMA_CHANNEL0)
  543.         {
  544.         /* Set  Count Inhibit to Inhibit Timer */
  545.         MPC107EUMBBARWRITE(MPC107_EPIC_TM2_BASE_COUNT_REG,
  546.                            MPC107_EPIC_TM_BASE_COUNT_CI);
  547.         /* Disable Periodic DMA by Clearing  the periodic DMA Enable Bit */
  548.         dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &
  549.                                           !(MPC107_DMA_DMR_PDE);
  550.         MPC107EUMBBARWRITE(MPC107_DMA_DMR0, dataReadDmaReg);
  551.         /* Release all the Descriptors */
  552.         pTempFirstDescriptor = pFirstDescriptorCh0;
  553.         /* If Descriptors Already Exist */
  554.         if (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK) != 0)
  555.             {
  556.             while (((UINT32)pTempFirstDescriptor &
  557.                                       MPC107_DMA_NDAR_ADDR_MASK ) != NULL )
  558.                 {
  559.                 pTempDescriptor = pTempFirstDescriptor;
  560.                 pTempFirstDescriptor = pTempFirstDescriptor
  561.                                       -> pNextDescriptorAddress;
  562.                 free ((void *)((UINT32)pTempDescriptor & 
  563.                                MPC107_DMA_NDAR_ADDR_MASK));
  564.                 }
  565.             }
  566.             pFirstDescriptorCh0 = NULL;
  567.             chainedDma0FirstTime = FALSE;
  568.         }
  569.     else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */
  570.         {
  571.         /* Set  Count Inhibit to Inhibit Timer */
  572.         MPC107EUMBBARWRITE(MPC107_EPIC_TM3_BASE_COUNT_REG,
  573.                            MPC107_EPIC_TM_BASE_COUNT_CI);
  574.         /* Disable Periodic DMA by Clearing  the periodic DMA Enable Bit */
  575.         dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &
  576.                                           !(MPC107_DMA_DMR_PDE);
  577.         MPC107EUMBBARWRITE(MPC107_DMA_DMR1, dataReadDmaReg);
  578.         /* Release all the Descriptors */
  579.         pTempFirstDescriptor = pFirstDescriptorCh1;
  580.         /* Descriptors Already Exist */
  581.         if (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK) != 0)
  582.             {
  583.             while (((UINT32)pTempFirstDescriptor &
  584.                                           MPC107_DMA_NDAR_ADDR_MASK) != NULL)
  585.                 {
  586.                 pTempDescriptor = pTempFirstDescriptor;
  587.                 pTempFirstDescriptor = pTempFirstDescriptor
  588.                                       -> pNextDescriptorAddress;
  589.                 free ((void *)((UINT32)pTempDescriptor & 
  590.                                MPC107_DMA_NDAR_ADDR_MASK));
  591.                 }
  592.             }
  593.             pFirstDescriptorCh1 = NULL;
  594.             chainedDma1FirstTime = FALSE;
  595.         }
  596.     else
  597.         {
  598.         errnoSet (EINVAL);
  599.         return (ERROR);
  600.         }
  601.     return (OK);
  602.     }
  603. /***************************************************************************
  604. *
  605. * mpc107DmaBuildDecsriptor - build  DMA  descriptors
  606. *
  607. * This routine is used for creation of a DMA descriptor required
  608. * for chained (periodic or non-periodic) DMA transfers.
  609. * Before a chained DMA transfer can be started, a set of descriptors can
  610. * be setup by calling this routine as many number of times as required
  611. * with the appropriate parameters. The routine mpc107DmaChainedStart should be
  612. * called after the descriptors are built.
  613. *
  614. * If a periodic DMA is in progress, then the descriptor cannot be built and
  615. * the routine returns an error. If periodic DMA is not in progress then the
  616. * descriptor is formed. A periodic chained DMA with a new set of descriptors
  617. * can only be started by stopping the chained periodic DMA in progress using
  618. * the routine mpc107DmaPeriodicStop.
  619. *
  620. * RETURNS:  OK, or ERROR if channel is configured for Periodic DMA or
  621. * <numberOfBytes> is zero or channel specified by <channelNumber> is
  622. * not valid .
  623. */
  624. STATUS mpc107DmaBuildDecsriptor
  625.     (
  626.     UINT32  channelNumber,      /* Channel Number  */
  627.     UCHAR * pSourceAddress,      /* Pointer to  DMA start Address  */
  628.     UCHAR * pDestinationAddress, /* Pointer to DMA destination address */
  629.     UINT32 transferType,        /* specifies whether the transfer */
  630.                                      /* is "PCI to PCI"  */
  631.                                      /* or "Memory to Memory" */
  632.                                      /* or "Memory to PCI" */
  633.                                      /* or  "Memory to Memory" */
  634.     UINT32 numberOfBytes             /* Number of bytes to be sent by DMA */
  635.     )
  636.     {
  637.     MPC107_DMA_DESCRIPTOR * pTempDescriptor;
  638.     MPC107_DMA_DESCRIPTOR * pTempFirstDescriptor;
  639.     ULONG  statusOfDmaReg;
  640.     if (numberOfBytes == 0) /* number of bytes is zero */
  641.         {
  642.         /* if the number of bytes is zero return an error */
  643.         errnoSet (EINVAL);
  644.         return (ERROR);
  645.         }
  646.     if (channelNumber == MPC107_DMA_CHANNEL0) /* channel 0 */
  647.         {
  648.         statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR0);
  649.         if ((!(statusOfDmaReg & MPC107_DMA_DMR_CTM) &&
  650.               (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0)
  651.             {
  652.             /* This channel is configured for Periodic DMA */
  653.             errnoSet (EBUSY);
  654.             return (ERROR);
  655.             }
  656.         semTake (semIdChainDmaCh0, WAIT_FOREVER);
  657.         /* If Direct DMA is configured */
  658.         if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) != 0)
  659.             {
  660.             /* Polling to see when the channel is free */
  661.             while (MPC107EUMBBARREAD(MPC107_DMA_DSR0) & MPC107_DMA_DSR_CB);
  662.             }
  663.         /* Flag set to indicate that the descriptors are  being built */
  664.         dmaBuildDescrInProgCh0 = 1;
  665.         pTempFirstDescriptor = pFirstDescriptorCh0;
  666.         /* if Descriptors Already Exist */
  667.         if (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK) != 0)
  668.             {
  669.             while (((UINT32)pTempFirstDescriptor &
  670.                     MPC107_DMA_NDAR_ADDR_MASK) != NULL )
  671.                 {
  672.                 pTempDescriptor = pTempFirstDescriptor;
  673.                 /*
  674.                  * Disable End of Segment Interrupt &
  675.                  * Disable End of Transfer Interrupt
  676.                  * For each descriptor except the last one
  677.                  */
  678.                 pTempFirstDescriptor -> pNextDescriptorAddress = 
  679.                    (MPC107_DMA_DESCRIPTOR *)
  680.                       ((UINT32)pTempFirstDescriptor -> pNextDescriptorAddress &
  681.                        (!((UINT32)MPC107_DMA_NDAR_EOTD)  &
  682.                         !((UINT32)MPC107_DMA_NDAR_NDEOSIE)));
  683.                 pTempFirstDescriptor = pTempFirstDescriptor
  684.                                     -> pNextDescriptorAddress;
  685.                 }
  686.             /* Next Descriptor */
  687.             pTempDescriptor  -> pNextDescriptorAddress  =
  688.                 (MPC107_DMA_DESCRIPTOR *) memalign(MPC107_DMA_MEM_ALIGN,
  689.                 sizeof(MPC107_DMA_DESCRIPTOR));
  690.             /* Flush the data cache */
  691.             cacheFlush (DATA_CACHE, pTempDescriptor  -> pNextDescriptorAddress,
  692.                        sizeof(MPC107_DMA_DESCRIPTOR));
  693.             /* Source  Address for the Next Descriptor */
  694.             pTempDescriptor  -> pNextDescriptorAddress
  695.                              -> pSourceAddress  = (UCHAR *)pSourceAddress;
  696.             /* Destinantion  Address for the Next Descriptor */
  697.             pTempDescriptor  -> pNextDescriptorAddress
  698.                              -> pDestinationAddress  =
  699.                                (UCHAR *)pDestinationAddress;
  700.             /* Number of bytes  for the Next Descriptor */
  701.             pTempDescriptor  -> pNextDescriptorAddress
  702.                              -> numberOfBytes  = numberOfBytes;
  703.             /*
  704.              * Disable End of Segment Interrupt &
  705.              * Enable End of Transfer Interrupt
  706.              */
  707.             pTempDescriptor  -> pNextDescriptorAddress
  708.                              -> pNextDescriptorAddress
  709.                              = (MPC107_DMA_DESCRIPTOR *) MPC107_DMA_NDAR_EOTD;
  710.             }
  711.         else            /* Descriptors donot exist */
  712.             {
  713.             /* First  Descriptor */
  714.             pFirstDescriptorCh0 = (MPC107_DMA_DESCRIPTOR *)
  715.             memalign(MPC107_DMA_MEM_ALIGN, sizeof(MPC107_DMA_DESCRIPTOR));
  716.             /* Flush the data cache */
  717.             cacheFlush (DATA_CACHE, pFirstDescriptorCh0,
  718.                         sizeof(MPC107_DMA_DESCRIPTOR));
  719.             /* Source  Address for the Current Descriptor */
  720.             pFirstDescriptorCh0 -> pSourceAddress  = (UCHAR *)pSourceAddress;
  721.             /* Destinantion Address for the Current Descriptor */
  722.             pFirstDescriptorCh0 -> pDestinationAddress =
  723.                                    (UCHAR *) pDestinationAddress;
  724.             /* Number of Bytes  for the current Descriptor */
  725.             pFirstDescriptorCh0  -> numberOfBytes  = numberOfBytes;
  726.             /*
  727.              * Disable End of Segment Interrupt &
  728.              * Enable End of Transfer Interrupt
  729.              */
  730.             pFirstDescriptorCh0  -> pNextDescriptorAddress =
  731.             (MPC107_DMA_DESCRIPTOR *)MPC107_DMA_NDAR_EOTD;
  732.             /*
  733.              * Set a Global Flag to indicate that the descriptors are being
  734.              * built afresh again or are being built for the first time
  735.              */
  736.             chainedDma0FirstTime = TRUE;
  737.             }
  738.         /* Flag cleared to indicate that the descriptors have been  built  */
  739.         dmaBuildDescrInProgCh0 = 0;
  740.         semGive (semIdChainDmaCh0);
  741.         }
  742.     else if (channelNumber == MPC107_DMA_CHANNEL1) /* channel 1 */
  743.         {
  744.         statusOfDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DMR1);
  745.         if ((!(statusOfDmaReg & MPC107_DMA_DMR_CTM) &&
  746.               (statusOfDmaReg & MPC107_DMA_DMR_PDE)) != 0)
  747.             {
  748.             /* This channel is configured for Periodic DMA */
  749.             errnoSet(EBUSY);
  750.             return (ERROR);
  751.             }
  752.         semTake (semIdChainDmaCh1, WAIT_FOREVER);
  753.         /* if Direct DMA is configured */
  754.         if ((statusOfDmaReg & MPC107_DMA_DMR_CTM) != 0)
  755.             {
  756.             /* Polling to see when the channel is free */
  757.             while (MPC107EUMBBARREAD(MPC107_DMA_DSR1) & MPC107_DMA_DSR_CB);
  758.             }
  759.         /* Flag set to indicate that the  descriptors are  being built */
  760.         dmaBuildDescrInProgCh1 = 1;
  761.         pTempFirstDescriptor =  pFirstDescriptorCh1;
  762.         /* If Descriptors Already Exist */
  763.         if (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK) != 0)
  764.             {
  765.             while (((UINT32)pTempFirstDescriptor &
  766.                                   MPC107_DMA_NDAR_ADDR_MASK) != NULL )
  767.                 {
  768.                 pTempDescriptor = pTempFirstDescriptor;
  769.                 /*
  770.                  * Disable End of Segment Interrupt &
  771.                  * Disable End of Transfer Interrupt
  772.                  * For each descriptor except the last one
  773.                  */
  774.                 pTempFirstDescriptor -> pNextDescriptorAddress = 
  775.                    (MPC107_DMA_DESCRIPTOR *)
  776.                       ((UINT32)pTempFirstDescriptor -> pNextDescriptorAddress &
  777.                        (!(UINT32)MPC107_DMA_NDAR_EOTD &
  778.                         (UINT32)MPC107_DMA_NDAR_NDEOSIE));
  779.                 pTempFirstDescriptor = pTempFirstDescriptor ->
  780.                                        pNextDescriptorAddress;
  781.                 }
  782.             /* Next Descriptor */
  783.             pTempDescriptor  -> pNextDescriptorAddress
  784.                                = (MPC107_DMA_DESCRIPTOR *)memalign
  785.                                  (MPC107_DMA_MEM_ALIGN,
  786.                                  sizeof(MPC107_DMA_DESCRIPTOR));
  787.             /* Flush the data cache */
  788.             cacheFlush (DATA_CACHE, pTempDescriptor  -> pNextDescriptorAddress,
  789.                        sizeof(MPC107_DMA_DESCRIPTOR));
  790.             /* Source  Address for the Next Descriptor */
  791.             pTempDescriptor  -> pNextDescriptorAddress
  792.                              -> pSourceAddress
  793.                              = (UCHAR*)pSourceAddress;
  794.             /* Destinantion  Address for the Next Descriptor */
  795.             pTempDescriptor  -> pNextDescriptorAddress
  796.                              -> pDestinationAddress
  797.                              = (UCHAR*) pDestinationAddress;
  798.             /* Number of bytes  for the Next Descriptor */
  799.             pTempDescriptor  -> pNextDescriptorAddress
  800.                              -> numberOfBytes  = numberOfBytes;
  801.             /*
  802.              * Disable End of Segment Interrupt &
  803.              * Enable End of Transfer Interrupt
  804.              */
  805.             pTempDescriptor  -> pNextDescriptorAddress
  806.                              -> pNextDescriptorAddress
  807.                              = (MPC107_DMA_DESCRIPTOR *)MPC107_DMA_NDAR_EOTD;
  808.             }
  809.         else            /* Descriptors donot exist */
  810.             {
  811.             /* First  Descriptor */
  812.             pFirstDescriptorCh1 = memalign(MPC107_DMA_MEM_ALIGN,
  813.                                   sizeof(MPC107_DMA_DESCRIPTOR));
  814.             /* Flush the data cache */
  815.             cacheFlush (DATA_CACHE, pFirstDescriptorCh1,
  816.                                     sizeof(MPC107_DMA_DESCRIPTOR));
  817.             /* Source  Address for the Current Descriptor */
  818.             pFirstDescriptorCh1 -> pSourceAddress  =
  819.                                    (UCHAR *)pSourceAddress;
  820.             /* Destinantion Address for the Current Descriptor */
  821.             pFirstDescriptorCh1 -> pDestinationAddress =
  822.                                    (UCHAR *)pDestinationAddress;
  823.             /* Number of Bytes  for the current Descriptor */
  824.             pFirstDescriptorCh1  -> numberOfBytes  = numberOfBytes;
  825.             /*
  826.              * Disable End of Segment Interrupt &
  827.              * Enable End of Transfer Interrupt
  828.              */
  829.             pFirstDescriptorCh1  -> pNextDescriptorAddress =
  830.                 (MPC107_DMA_DESCRIPTOR*)MPC107_DMA_NDAR_EOTD;
  831.             /*
  832.              * Set a Global Flag to indicate that the descriptors are being
  833.              * built afresh again or are being built for the first time
  834.              */
  835.             chainedDma1FirstTime = TRUE;
  836.             }
  837.         /* Flag cleared to indicate that the  descriptors have been  built */
  838.         dmaBuildDescrInProgCh1 = 0;
  839.         semGive (semIdChainDmaCh1);
  840.         }
  841.     else
  842.         {
  843.         errnoSet (EINVAL);
  844.         return (ERROR);
  845.         }
  846.     return (OK);
  847.     }
  848. /***************************************************************************
  849. *
  850. * mpc107DmaStatus  -  query DMA status and DMA Transfer Mode
  851. *
  852. * This  routine purpose is to query the  specified DMA channel for DMA
  853. * transfer status and DMA transfer mode.
  854. *
  855. * RETURNS :
  856. * This routine returns one of the following :
  857. * MPC107_DMA_PERIODIC_CH_BUSY  or  MPC107_DMA_PERIODIC_CH_FREE or
  858. * MPC107_DMA_CHAIN_CH_BUSY  or  MPC107_DMA_CHAIN_CH_FREE or
  859. * MPC107_DMA_DIRECT_CH_BUSY  or   MPC107_DMA_CHAIN_CH_FREE or
  860. * MPC107_DMA_UNDEF_CH
  861. */
  862. INT32 mpc107DmaStatus
  863.     (
  864.     ULONG  channel           /* Channel Number */
  865.     )
  866.     {
  867.     ULONG  dmaModeRegRead;   /* Data read from the DMA Mode register */
  868.     UINT32  dmaStatusReg;     /* DMA status Register */
  869.     UINT32  dmaModeReg;       /* DMA mode Register */
  870.     if (channel == MPC107_DMA_CHANNEL0) /*  Channel 0 */
  871.         {
  872.         dmaStatusReg = (UINT32)MPC107_DMA_DSR0; /* Status Register of Ch0 */
  873.         dmaModeReg = (UINT32)MPC107_DMA_DMR0;   /* Mode Register of Ch0 */
  874.         }
  875.     else if (channel == MPC107_DMA_CHANNEL1) /* Channel 1 */
  876.         {
  877.         dmaStatusReg = (UINT32)MPC107_DMA_DSR1; /* Status Register of Ch1 */
  878.         dmaModeReg = (UINT32)MPC107_DMA_DMR1;    /* Mode Register of Ch1 */
  879.         }
  880.     else
  881.         return (MPC107_DMA_UNDEF_CH); /* If the Channel is  undefined */
  882.     dmaModeRegRead = MPC107EUMBBARREAD(dmaModeReg);
  883.     /* if Chained DMA is configured */
  884.     if ((dmaModeRegRead & MPC107_DMA_DMR_CTM) == 0 )
  885.         {
  886.         /* if Periodic  DMA is configured */
  887.         if ((dmaModeRegRead & MPC107_DMA_DMR_PDE) != 0)
  888.             {
  889.             if ((MPC107EUMBBARREAD(dmaStatusReg) & MPC107_DMA_DSR_CB) != 0)
  890.                 {
  891.                 /*
  892.                  * Periodic Chained DMA is configured
  893.                  * and Channel Is Busy
  894.                  */
  895.                 return (MPC107_DMA_PERIODIC_CH_BUSY);
  896.                 }
  897.             else
  898.                 {
  899.                 /*
  900.                  * Periodic Chained DMA is configured
  901.                  * and Channel Is Not Busy (FREE)
  902.                  */
  903.                 return (MPC107_DMA_PERIODIC_CH_FREE);
  904.                 }
  905.             }
  906.         else
  907.             {
  908.             if ((MPC107EUMBBARREAD(dmaStatusReg) & MPC107_DMA_DSR_CB) != 0)
  909.                 {
  910.                 /* Chained DMA is configured  and Channel Is Busy  */
  911.                 return (MPC107_DMA_CHAIN_CH_BUSY);
  912.                 }
  913.             else
  914.                 {
  915.                 /*
  916.                  * Chained DMA is configured and
  917.                  * Channel Is Not Busy (FREE)
  918.                  */
  919.                 return (MPC107_DMA_CHAIN_CH_FREE);
  920.                 }
  921.             }
  922.         }
  923.         /* if Direct DMA is configured */
  924.     else if ((dmaModeRegRead & MPC107_DMA_DMR_CTM) != 0)
  925.         {
  926.         if ((MPC107EUMBBARREAD(dmaStatusReg) & MPC107_DMA_DSR_CB) != 0)
  927.             {
  928.             /* Direct  DMA is configured  and Channel Is Busy  */
  929.             return (MPC107_DMA_DIRECT_CH_BUSY);
  930.             }
  931.         else
  932.             {
  933.             /*
  934.              * Direct  DMA is configured and
  935.              * Channel Is Not Busy (FREE)
  936.              */
  937.             return (MPC107_DMA_DIRECT_CH_FREE);
  938.             }
  939.         }
  940.     return (OK);
  941.     }
  942. /***************************************************************************
  943. *
  944. * mpc107DmaCh0Int -  ISR Handler for DMA channel 0
  945. *
  946. * This routine services the interrupts of DMA channel 0.
  947. *
  948. * RETURNS: N/A
  949. */
  950. void mpc107DmaCh0Int (void)
  951.     {
  952.     MPC107_DMA_DESCRIPTOR * pTempDescriptor;
  953.     MPC107_DMA_DESCRIPTOR * pTempFirstDescriptor;
  954.     ULONG  dataReadDmaReg;
  955.     ULONG  dataReadTemp;
  956.     /* Read the status Register of DMA Channel 0 */
  957.     dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DSR0);
  958.     /* if End of Chain / Direct Transfer Interrupt received */
  959.     if ((dataReadDmaReg & MPC107_DMA_DSR_EOCAI) != 0)
  960.         {
  961.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_DMR0);
  962.         /* if End of Interrupt Enabled */
  963.         if ((dataReadTemp & MPC107_DMA_DMR_EOTIE) != 0)
  964.             {
  965.             if ((!(dataReadDmaReg & MPC107_DMA_DMR_CTM) &&
  966.                   (dataReadDmaReg & MPC107_DMA_DMR_PDE)) != 0)
  967.                 {
  968.                 /* This channel is configured for Periodic DMA */
  969.                 }
  970.             else if ( !(dataReadDmaReg & MPC107_DMA_DMR_CTM) &&
  971.                       !(dmaBuildDescrInProgCh0))
  972.                 {
  973.                 /* This channel is configured for Chained DMA */
  974.                 /* Release all the Descriptors */
  975.                 pTempFirstDescriptor = pFirstDescriptorCh0;
  976.                 /* Descriptors Already Exist */
  977.                 if (((UINT32)pTempFirstDescriptor &
  978.                      MPC107_DMA_NDAR_ADDR_MASK) != 0)
  979.                     {
  980.                     while (((UINT32)pTempFirstDescriptor  &
  981.                             MPC107_DMA_NDAR_ADDR_MASK) != NULL )
  982.                         {
  983.                         pTempDescriptor = pTempFirstDescriptor;
  984.                         pTempFirstDescriptor = pTempFirstDescriptor
  985.                                              -> pNextDescriptorAddress;
  986.                         free ((void *)((UINT32)pTempDescriptor &
  987.                                MPC107_DMA_NDAR_ADDR_MASK));
  988.                         }
  989.                     }
  990.                     pFirstDescriptorCh0 = NULL;
  991.                     chainedDma0FirstTime = FALSE; /* Reset the flag */
  992.                 }
  993.             }
  994.         }
  995.     /* if End of Segment Transfer Interrupt received */
  996.     if ((dataReadDmaReg & MPC107_DMA_DSR_EOSI) != 0)
  997.         {
  998.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_CDAR0) &
  999.                                          MPC107_DMA_CDAR_EOSIE;
  1000.         /* if End Of Segment Interrupt is Enabled  */
  1001.         if (dataReadTemp != 0)
  1002.             {
  1003.             }
  1004.         }
  1005.     /* If PCI Error  Interrupt received */
  1006.     if ((dataReadDmaReg & MPC107_DMA_DSR_PE) != 0)
  1007.         {
  1008.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &
  1009.                                          MPC107_DMA_DMR_EIE;
  1010.         /* If Error  Interrupts are  Enabled  */
  1011.         if (dataReadTemp != 0 )
  1012.             {
  1013.             }
  1014.         }
  1015.     /* If Local Memory Error   Interrupt received */
  1016.     if ((dataReadDmaReg & MPC107_DMA_DSR_LME) != 0)
  1017.         {
  1018.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_DMR0) &
  1019.                                          MPC107_DMA_DMR_EIE;
  1020.         /* If Error  Interrupts are  Enabled  */
  1021.         if (dataReadTemp != 0)
  1022.             {
  1023.             }
  1024.         }
  1025.     }
  1026. /***************************************************************************
  1027. *
  1028. * mpc107DmaCh1Int -  ISR Handler for DMA channel 1
  1029. *
  1030. * This routine services the interrupts of DMA channel 1.
  1031. *
  1032. * RETURNS: N/A
  1033. */
  1034. void mpc107DmaCh1Int (void)
  1035.     {
  1036.     MPC107_DMA_DESCRIPTOR * pTempDescriptor;
  1037.     MPC107_DMA_DESCRIPTOR * pTempFirstDescriptor;
  1038.     ULONG  dataReadDmaReg;
  1039.     ULONG  dataReadTemp;
  1040.     /* Read the status Register of DMA Channel 1 */
  1041.     dataReadDmaReg = MPC107EUMBBARREAD(MPC107_DMA_DSR1);
  1042.     /* If End of Chain / Direct Transfer Interrupt received */
  1043.     if (dataReadDmaReg & MPC107_DMA_DSR_EOCAI)
  1044.         {
  1045.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_DMR1);
  1046.         /* If End of Interrupt Enabled */
  1047.         if ( dataReadTemp & MPC107_DMA_DMR_EOTIE )
  1048.             {
  1049.             if ( !( dataReadDmaReg & MPC107_DMA_DMR_CTM) &&
  1050.                   ( dataReadDmaReg & MPC107_DMA_DMR_PDE))
  1051.                 {
  1052.                 /* This channel is configured for Periodic DMA */
  1053.                 }
  1054.             else if ( !( dataReadDmaReg & MPC107_DMA_DMR_CTM)  &&
  1055.                       !(dmaBuildDescrInProgCh1))
  1056.                 {
  1057.                 /* This channel is configured for Chained DMA */
  1058.                 /* Release all the Descriptors */
  1059.                 pTempFirstDescriptor = pFirstDescriptorCh1;
  1060.                 /* Descriptors Already Exist */
  1061.                 if (((UINT32)pTempFirstDescriptor & MPC107_DMA_NDAR_ADDR_MASK))
  1062.                     {
  1063.                     while (((UINT32)pTempFirstDescriptor  &
  1064.                             MPC107_DMA_NDAR_ADDR_MASK) != NULL )
  1065.                         {
  1066.                         pTempDescriptor = pTempFirstDescriptor;
  1067.                         pTempFirstDescriptor = pTempFirstDescriptor
  1068.                                         -> pNextDescriptorAddress;
  1069.                         free ((void *) ((UINT32)pTempDescriptor &
  1070.                                          MPC107_DMA_NDAR_ADDR_MASK));
  1071.                         }
  1072.                     }
  1073.                     pFirstDescriptorCh1 = NULL;
  1074.                     chainedDma1FirstTime = FALSE; /* Reset the flag */
  1075.                 }
  1076.             }
  1077.         }
  1078.     /* If End of Segment Transfer Interrupt received */
  1079.     if (dataReadDmaReg & MPC107_DMA_DSR_EOSI)
  1080.         {
  1081.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_CDAR1) &
  1082.                                          MPC107_DMA_CDAR_EOSIE;
  1083.         /* If End Of Segment Interrupt is Enabled  */
  1084.         if (dataReadTemp)
  1085.             {
  1086.             }
  1087.         }
  1088.     /* If PCI Error  Interrupt received */
  1089.     if (dataReadDmaReg & MPC107_DMA_DSR_PE)
  1090.         {
  1091.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &
  1092.                                          MPC107_DMA_DMR_EIE;
  1093.         /* If Error  Interrupts are  Enabled  */
  1094.         if (dataReadTemp)
  1095.             {
  1096.             }
  1097.         }
  1098.     /* If Local Memory Error   Interrupt received */
  1099.     if (dataReadDmaReg & MPC107_DMA_DSR_LME)
  1100.         {
  1101.         dataReadTemp = MPC107EUMBBARREAD(MPC107_DMA_DMR1) &
  1102.                                          MPC107_DMA_DMR_EIE;
  1103.         /* If Error  Interrupts are  Enabled  */
  1104.         if (dataReadTemp)
  1105.             {
  1106.             }
  1107.         }
  1108.     }