1 /* $Id: at91pdc.c,v 1.2 2008/07/03 01:15:38 matt Exp $ */ 2 3 #include <sys/types.h> 4 #include <machine/bus.h> 5 #include <arm/at91/at91pdcvar.h> 6 7 int at91pdc_alloc_fifo(bus_dma_tag_t dmat, at91pdc_fifo_t *fifo, int size, 8 int flags) 9 { 10 bus_dma_segment_t segs; 11 int rsegs; 12 int err; 13 int f; 14 15 memset(fifo, 0, sizeof(*fifo)); 16 17 /* allocate map: */ 18 f = flags & (BUS_DMA_BUS1 | BUS_DMA_BUS2 | BUS_DMA_BUS3 | BUS_DMA_BUS4); 19 err = bus_dmamap_create(dmat, size, 1, size, 0, 20 BUS_DMA_WAITOK | f, 21 &fifo->f_dmamap); 22 if (err) 23 goto fail_0; 24 25 /* allocate DMA safe memory: */ 26 f |= flags & BUS_DMA_STREAMING; 27 err = bus_dmamem_alloc(dmat, size, 0, size, &segs, 1, &rsegs, 28 BUS_DMA_WAITOK | f); 29 if (err) 30 goto fail_1; 31 32 /* allocate virtual memory: */ 33 f |= flags & (BUS_DMA_COHERENT | BUS_DMA_NOCACHE); 34 err = bus_dmamem_map(dmat, &segs, 1, size, &fifo->f_buf, 35 BUS_DMA_WAITOK | f); 36 if (err) 37 goto fail_2; 38 39 /* connect physical to virtual memory: */ 40 f |= flags & (BUS_DMA_READ | BUS_DMA_WRITE); 41 f &= ~(BUS_DMA_COHERENT | BUS_DMA_NOCACHE); 42 err = bus_dmamap_load(dmat, fifo->f_dmamap, fifo->f_buf, size, NULL, 43 BUS_DMA_NOWAIT | f); 44 if (err) 45 goto fail_3; 46 47 /* initialize rest of the structure: */ 48 fifo->f_buf_size = size; 49 fifo->f_ndx = fifo->f_length = 0; 50 51 fifo->f_buf_addr = fifo->f_dmamap->dm_segs[0].ds_addr; 52 fifo->f_pdc_rd_ndx = fifo->f_pdc_wr_ndx = 0; 53 fifo->f_pdc_space = fifo->f_buf_size; 54 55 return 0; 56 fail_3: 57 bus_dmamem_unmap(dmat, fifo->f_buf, size); 58 fail_2: 59 bus_dmamem_free(dmat, &segs, rsegs); 60 fail_1: 61 bus_dmamap_destroy(dmat, fifo->f_dmamap); 62 fail_0: 63 return err; 64 } 65