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:
#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; }