Next | Prev | Up | Top | Contents | Index

User-level DMA Library (udmalib)

A user-level interface for VME drivers provides access to DMA engines on CHALLENGE/Onyx (IP19) and POWER CHALLENGE/POWER Onyx (IP21) hardware platforms. This interface is meant to be used when performance is critical and the VME-bus board itself does not support DMA.

Users can move data between a buffer and a VME-bus board faster with a DMA engine than with normal PIO operations. However, because there is only one DMA engine per VME bus on the CHALLENGE series, the DMA engine is a scarce resource. The user-level DMA support library udmalib allocates the DMA engine exclusively to the first user to request it, and no other user can access it until the current user frees it up. See the usrdma(7M) and udmalib(3K) man pages for further detail and usage of user-level DMA library calls.

The following functions are supported by the user-level DMA library:

dma_open

Get exclusive use of a DMA engine

dma_close

Free up the DMA engine

dma_allocbuf

Allocate a buffer suitable for DMA

dma_freebuf

Free up a DMA buffer

dma_mkparms

Define a DMA operation

dma_freeparms

Free up DMA parms resources

dma_start

Perform DMA operation between a buffer and the VME bus
Here is a sample code fragment using the user DMA library:

#include <udmalib.h>
#include <stdio.h>

do_dma(int adap, void *vmeaddr, int size)
{
   udmaparm_t    *parms;
   udmaid_t     *dp;
   vmeparms_t    vparm;
   void        *iobuf;
   int          err = 0;

   if( (dp = dma_open(DMA_VMEBUS,adap)) == NULL ){
      (void)fprintf(stderr,
                  "unable to start adapter %d\n",adap);
      return 1;
   }

   /* get a buffer and phys address */
   if( (iobuf = dma_allocbuf(dp,size)) == NULL ) {
      (void)fprintf(stderr,"iobuf alloc failed\n");
      (void)dma_close(dp);
      return 1;
   }

   vparm.vp_block = 0;
   vparm.vp_datumsz = VME_DS_HALFWORD;
   vparm.vp_dir = VME_READ;
   vparm.vp_throt = VME_THROT_256;
   vparm.vp_release = VME_REL_RWD;
   vparm.vp_addrmod = 0xd;

   /* create DMA parms */
   if( (parms = dma_mkparms(dp,&vparm,iobuf,size)) == NULL )  {
      (void)fprintf(stderr,"dma failed\n");
      (void)dma_freebuf(dp,iobuf);
      (void)dma_close(dp);
      return 1;
   }

   if( err = dma_start(dp,vmeaddr,parms) )
      (void)fprintf(stderr,"dma failed\n");

   if( dma_freebuf(dp,iobuf) || 
       dma_freeparms(dp,parms) || 
       dma_close(dp) )
      (void)fprintf(stderr,"dma release failed\n");

   return err;
}

Next | Prev | Up | Top | Contents | Index