<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML dir=ltr><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<TITLE>Message</TITLE>

<META content="MSHTML 6.00.2800.1528" name=GENERATOR></HEAD>
<BODY>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN class=339013216-16012006>can 
somebody provide an example usage of the ppc4xx_ scatter/gather dma 
</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN 
class=339013216-16012006>library by mvista ?</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN 
class=339013216-16012006></SPAN></FONT>&nbsp;</DIV>
<BLOCKQUOTE dir=ltr 
style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #0000ff 2px solid; MARGIN-RIGHT: 0px">
  <DIV></DIV>
  <DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left><FONT 
  face=Tahoma size=2>-----Original Message-----<BR><B>From:</B> 
  linuxppc-embedded-bounces@ozlabs.org 
  [mailto:linuxppc-embedded-bounces@ozlabs.org] <B>On Behalf Of 
  </B>ductusrhe<BR><B>Sent:</B> Mittwoch, 7. Dezember 2005 22:33<BR><B>To:</B> 
  linuxppc-embedded@ozlabs.org<BR><B>Subject:</B> ppc4xx DMA fixes for 
  simultaneous sg transfers<BR><BR></FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>Linux 2.4.20 (probably 2.6 
  as well?)</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>Conclusion:<BR>Scatter/gather DMA is not thread safe.</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>Background:<BR>1. We run 
  all four dma channels simultaneously in SG mode on the PPC440EP, </FONT><FONT 
  face="Courier New" color=#000000 size=2>starting and stopping them in 
  different threads.<BR>2. Also we need to change channel configs between 
  different transfers, i.e. run ppc4xx_init_dma_channel() to set read or write 
  mode.</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>Problem and cause:<BR>1. 
  All is well when running one channel at a time, but when starting/stopping a 
  new channel during the time another is active can - if you are unlucky - cause 
  problems.<BR>&nbsp;&nbsp; Because all channels SG start/stop bits are in the 
  same register (ASGC), it must not be read then changed and written to the way 
  it was done.<BR>&nbsp;&nbsp; That can cause a channel that is just done, to 
  start again, or a newly started channel to stop.<BR>&nbsp;&nbsp; The register 
  includes a feature that can be used as a semaphore - the read enable (mask) 
  bits, but it was not used correctly in the code, it was enabled for all 
  channels in the start-up.<BR>2. It is said in the comment of 
  ppc4xx_init_dma_channel() that it should only be used once in the start-up. If 
  you comply, you will not have any problem with it.<BR>&nbsp;&nbsp; However, 
  when running this for a channel when other channels are active, can cause 
  channels to stop or maybe never give an interrupt or false interrupts. The 
  method clears the entire status register, not only the bits for the given 
  channel.</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>Solution:<BR>1. - In 
  ppc4xx_alloc_dma_handle(), do not touch the ASGC register!<BR>&nbsp;&nbsp; - 
  In ppc4xx_enable_dma_sgl() and ppc4xx_disable_dma_sgl(), when setting the ASGC 
  register, only change the given channel.<BR>&nbsp;&nbsp;&nbsp;&nbsp; That's 
  done without reading the register at all, just set/clear the enable bit of the 
  channel to change, then set the MASK_ENABLE for the same 
  channel.<BR>&nbsp;&nbsp; Probably this is the way the register was intended to 
  be handled?</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>2. - In 
  ppc4xx_init_dma_channel(), only clear the correct bits of the DMASR register, 
  not the whole register.<BR>&nbsp;&nbsp;&nbsp;&nbsp; (The polarity was also not 
  set as it's supposed to in this function, but there exists a patch for 
  that)</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face="Courier New"><FONT color=#000000 size=2>I can send a patch 
  with our changes, that works very well and stable, but there are many changes 
  and not all of them in line with the current official version of the files (we 
  handle the sg descriptor list differently). </FONT><FONT color=#000000 
  size=2>Maybe someone feeling for it will take a look at the changes and make 
  them into the real code, since the above fixes does not interfere with the 
  usage, only improves thread safety.</FONT></FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>I have no idea if this has 
  been fixed in some patch already... but I have not seen it on this list 
  anyway.<BR>I'm not a regular poster, just want to help others avoid some of 
  the struggle when running many channels.</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2></FONT>&nbsp;</DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>/Ronnie 
  Hedlund<BR></FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>Our changed code:<BR>In 
  "ppc4xx_dma.c"<BR>-----------------------<BR>/*<BR>&nbsp;*&nbsp; The comment 
  states that this function should only be run at start-up, and never 
  more.<BR>&nbsp;*&nbsp; That is unacceptable, with the fix it can be run 
  anywhere as long as the given channel is not running.<BR>&nbsp;*/<BR>int 
  ppc4xx_init_dma_channel(unsigned int dmanr, ppc_dma_ch_t * 
  p_init)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int 
  status_bits[] = { DMA_CS0 | DMA_TS0 | 
  DMA_CH0_ERR,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  DMA_CS1 | DMA_TS1 | 
  DMA_CH1_ERR,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  DMA_CS2 | DMA_TS2 | 
  DMA_CH2_ERR,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  DMA_CS3 | DMA_TS3 | DMA_CH3_ERR};</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int 
  polarity;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint32_t control = 
  0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ppc_dma_ch_t *p_dma_ch = 
  &amp;dma_channels[dmanr];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DMA_MODE_READ = (unsigned long) 
  DMA_TD; /* Peripheral to Memory 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DMA_MODE_WRITE = 
  0;&nbsp;&nbsp;&nbsp;&nbsp; /* Memory to Peripheral */</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!p_init) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_init_dma_channel: NULL 
  p_init\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return DMA_STATUS_NULL_POINTER;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dmanr &gt;= 
  MAX_PPC4xx_DMA_CHANNELS) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_init_dma_channel: bad channel %d\n", 
  dmanr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return DMA_STATUS_BAD_CHANNEL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2>#if DCRN_POL &gt; 
  0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; polarity = 
  mfdcr(DCRN_POL);<BR>#else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity = 0;<BR>#endif</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Setup the control 
  register based on the values passed 
  to<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * us in p_init.&nbsp; 
  Then, over-write the control register with 
  this<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * new 
  value.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; control |= 
  SET_DMA_CONTROL;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (dmanr) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  0:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /* clear all polarity signals and then "or" in new signal levels 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity &amp;= 
  ~GET_DMA_POLARITY(0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity |= p_init-&gt;polarity;<BR>#if DCRN_POL &gt; 
  0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_POL, 
  polarity);<BR>#endif<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_DMACR0, 
  control);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  1:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity &amp;= 
  ~GET_DMA_POLARITY(1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity |= p_init-&gt;polarity;<BR>#if DCRN_POL &gt; 
  0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_POL, 
  polarity);<BR>#endif<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_DMACR1, 
  control);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  2:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity &amp;= 
  ~GET_DMA_POLARITY(2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity |= p_init-&gt;polarity;<BR>#if DCRN_POL &gt; 
  0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_POL, 
  polarity);<BR>#endif<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_DMACR2, 
  control);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  3:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity &amp;= 
  ~GET_DMA_POLARITY(3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  polarity |= p_init-&gt;polarity;<BR>#if DCRN_POL &gt; 
  0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_POL, 
  polarity);<BR>#endif<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  mtdcr(DCRN_DMACR3, 
  control);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  default:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return DMA_STATUS_BAD_CHANNEL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* save these values in our 
  dma channel structure */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  memcpy(p_dma_ch, p_init, sizeof 
  (ppc_dma_ch_t));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * The peripheral width 
  values written in the control register 
  are:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; 
  PW_8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; 
  PW_16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  1<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; 
  PW_32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; 
  PW_64&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  3<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  *<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; Since the 
  DMA count register takes the number of 
  "transfers",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; 
  we need to divide the count sent to us in 
  certain<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; 
  functions by the appropriate number.&nbsp; It so happens that 
  our<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; right 
  shift value is equal to the peripheral width 
  value.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p_dma_ch-&gt;shift = 
  p_init-&gt;pwidth;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Save the control word 
  for easy access.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p_dma_ch-&gt;control = 
  control;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * clear status register 
  for the channel<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * only TS, 
  CS and RI needs to be 
  cleared.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtdcr(DCRN_DMASR, 
  status_bits[dmanr]);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
  DMA_STATUS_GOOD;<BR>}</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 size=2><BR>In 
  "ppc4xx_sgdma.c"<BR>-----------------------</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>int<BR>ppc4xx_alloc_dma_handle(sgl_handle_t * phandle, unsigned int 
  mode, unsigned int dmanr)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sgl_list_info_t *psgl = NULL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ppc_dma_ch_t *p_dma_ch = 
  &amp;dma_channels[dmanr];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  //uint32_t sg_command;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dmanr &gt;= 
  MAX_PPC4xx_DMA_CHANNELS) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_alloc_dma_handle: invalid channel 0x%x\n", 
  dmanr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return DMA_STATUS_BAD_CHANNEL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!phandle) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_alloc_dma_handle: null handle 
  pointer\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return DMA_STATUS_NULL_POINTER;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Get memory for the 
  listinfo struct */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psgl = 
  kmalloc(sizeof(sgl_list_info_t), 
  GFP_KERNEL);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (psgl == NULL) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  *phandle = (sgl_handle_t) 
  NULL;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return DMA_STATUS_OUT_OF_MEMORY;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memset(psgl, 0, 
  sizeof(sgl_list_info_t));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* dma_addr is unused now 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psgl-&gt;dmanr = 
  dmanr;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /*<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Modify and save the 
  control word. These words will 
  be<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * written to each sgl 
  descriptor.&nbsp; The DMA engine 
  then<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * loads this control 
  word into the control 
  register<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * every time it 
  reads a new descriptor.<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psgl-&gt;control = 
  p_dma_ch-&gt;control;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Clear 
  all mode bits */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;control &amp;= ~(DMA_TM_MASK | 
  DMA_TD);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Save control word 
  and mode */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psgl-&gt;control |= 
  (mode | DMA_CE_ENABLE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 
  PPC Errata? DMA else ignore count on first in list 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psgl-&gt;control |= 
  SET_DMA_TCE(1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* In MM mode, we must set 
  ETD/TCE */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (mode == 
  DMA_MODE_MM)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;control |= DMA_ETD_OUTPUT | 
  DMA_TCE_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
  (p_dma_ch-&gt;int_enable) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /* Enable channel interrupt 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;control |= 
  DMA_CIE_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;control &amp;= 
  ~DMA_CIE_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* we must not touch the 
  SGC, it can cause problems to other channels! */</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; psgl-&gt;sgl_control = 
  SG_LINK;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (p_dma_ch-&gt;int_enable) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  if 
  (p_dma_ch-&gt;tce_enable)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /* reuse as Terminal Count Interrupt Enable on all descr. 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;sgl_control |= 
  SG_TCI_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;sgl_control |= SG_ERI_ENABLE | 
  SG_ETI_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *phandle = (sgl_handle_t) 
  psgl;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 
  DMA_STATUS_GOOD;<BR>}</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>void<BR>ppc4xx_enable_dma_sgl(sgl_handle_t 
  handle)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sgl_list_info_t 
  *psgl = (sgl_list_info_t *) 
  handle;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ppc_dma_ch_t 
  *p_dma_ch;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint32_t 
  sg_command;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!handle) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_enable_dma_sgl: null 
  handle\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if 
  (psgl-&gt;dmanr &gt; (MAX_PPC4xx_DMA_CHANNELS - 1)) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_enable_dma_sgl: bad channel in handle 
  %d\n",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;dmanr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if 
  (!psgl-&gt;phead) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_enable_dma_sgl: sg list 
  empty\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p_dma_ch = 
  &amp;dma_channels[psgl-&gt;dmanr];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;ptail-&gt;control_count &amp;= ~SG_LINK; /* make this the last 
  dscrptr */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 
  (p_dma_ch-&gt;int_enable)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  /* Require Terminal Count interrupt on last 
  */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;ptail-&gt;control_count |= 
  SG_TCI_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* No more changes to tail 
  object allowed */<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  //dma_cache_wback((unsigned long)psgl-&gt;ptail, 
  sizeof(ppc_sgl_t));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  dma_cache_wback_inv((unsigned long)psgl-&gt;ptail, 
  sizeof(ppc_sgl_t));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  ppc4xx_set_sg_addr(psgl-&gt;dmanr, 
  virt_to_phys(psgl-&gt;phead));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sg_command = 
  0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (psgl-&gt;dmanr) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  0:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = SSG0_ENABLE | 
  SSG0_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  1:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = SSG1_ENABLE | 
  SSG1_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  2:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = SSG2_ENABLE | 
  SSG2_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  3:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = SSG3_ENABLE | 
  SSG3_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  default:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_enable_dma_sgl: bad channel: %d\n", 
  psgl-&gt;dmanr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtdcr(DCRN_ASGC, 
  sg_command);&nbsp;&nbsp; /* start transfer */<BR>}</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>void<BR>ppc4xx_disable_dma_sgl(sgl_handle_t 
  handle)<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sgl_list_info_t 
  *psgl = (sgl_list_info_t *) 
  handle;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint32_t 
  sg_command;</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!handle) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_disable_dma_sgl: null 
  handle\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if 
  (psgl-&gt;dmanr &gt; (MAX_PPC4xx_DMA_CHANNELS - 1)) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_disable_dma_sgl: bad channel in handle 
  %d\n",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  psgl-&gt;dmanr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  return;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sg_command = 0; //disable 
  dma<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (psgl-&gt;dmanr) 
  {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  0:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = 
  SSG0_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  1:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = 
  SSG1_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  2:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = 
  SSG2_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case 
  3:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sg_command = 
  SSG3_MASK_ENABLE;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  break;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  default:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  printk("ppc4xx_disable_dma_sgl: bad channel: %d\n", 
  psgl-&gt;dmanr);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
  size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtdcr(DCRN_ASGC, 
  sg_command);&nbsp;&nbsp; /* stop transfer */<BR>}</FONT></DIV>
  <DIV><FONT face="Courier New" color=#000000 
size=2>&nbsp;</DIV></BLOCKQUOTE></FONT></BODY></HTML>