PROVIDE_DMAAPI_INLINE ( flat, dma_unmap );
PROVIDE_DMAAPI_INLINE ( flat, dma_alloc );
PROVIDE_DMAAPI_INLINE ( flat, dma_free );
+PROVIDE_DMAAPI_INLINE ( flat, dma_umalloc );
+PROVIDE_DMAAPI_INLINE ( flat, dma_ufree );
PROVIDE_DMAAPI_INLINE ( flat, dma_set_mask );
PROVIDE_DMAAPI_INLINE ( flat, dma_phys );
dma->op->free ( dma, map, addr, len );
}
+/**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+static userptr_t dma_op_umalloc ( struct dma_device *dma,
+ struct dma_mapping *map,
+ size_t len, size_t align ) {
+ struct dma_operations *op = dma->op;
+
+ if ( ! op )
+ return UNULL;
+ return op->umalloc ( dma, map, len, align );
+}
+
+/**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+static void dma_op_ufree ( struct dma_mapping *map, userptr_t addr,
+ size_t len ) {
+ struct dma_device *dma = map->dma;
+
+ assert ( dma != NULL );
+ assert ( dma->op != NULL );
+ dma->op->ufree ( dma, map, addr, len );
+}
+
/**
* Set addressable space mask
*
PROVIDE_DMAAPI ( op, dma_unmap, dma_op_unmap );
PROVIDE_DMAAPI ( op, dma_alloc, dma_op_alloc );
PROVIDE_DMAAPI ( op, dma_free, dma_op_free );
+PROVIDE_DMAAPI ( op, dma_umalloc, dma_op_umalloc );
+PROVIDE_DMAAPI ( op, dma_ufree, dma_op_ufree );
PROVIDE_DMAAPI ( op, dma_set_mask, dma_op_set_mask );
PROVIDE_DMAAPI_INLINE ( op, dma_phys );
#include <ipxe/api.h>
#include <ipxe/io.h>
#include <ipxe/malloc.h>
+#include <ipxe/umalloc.h>
#include <config/ioapi.h>
#ifdef DMAAPI_OP
*/
void ( * free ) ( struct dma_device *dma, struct dma_mapping *map,
void *addr, size_t len );
+ /**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+ userptr_t ( * umalloc ) ( struct dma_device *dma,
+ struct dma_mapping *map,
+ size_t len, size_t align );
+ /**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+ void ( * ufree ) ( struct dma_device *dma, struct dma_mapping *map,
+ userptr_t addr, size_t len );
/**
* Set addressable space mask
*
}
}
+/**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+static inline __always_inline userptr_t
+DMAAPI_INLINE ( flat, dma_umalloc ) ( struct dma_device *dma,
+ struct dma_mapping *map,
+ size_t len, size_t align __unused ) {
+ userptr_t addr;
+
+ /* Allocate buffer */
+ addr = umalloc ( len );
+
+ /* Increment mapping count (for debugging) */
+ if ( DBG_LOG && addr ) {
+ map->dma = dma;
+ dma->mapped++;
+ }
+
+ return addr;
+}
+
+/**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+static inline __always_inline void
+DMAAPI_INLINE ( flat, dma_ufree ) ( struct dma_mapping *map,
+ userptr_t addr, size_t len __unused ) {
+
+ /* Free buffer */
+ ufree ( addr );
+
+ /* Decrement mapping count (for debugging) */
+ if ( DBG_LOG ) {
+ assert ( map->dma != NULL );
+ map->dma->mapped--;
+ map->dma = NULL;
+ }
+}
+
/**
* Set addressable space mask
*
*/
void dma_free ( struct dma_mapping *map, void *addr, size_t len );
+/**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+userptr_t dma_umalloc ( struct dma_device *dma, struct dma_mapping *map,
+ size_t len, size_t align );
+
+/**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+void dma_ufree ( struct dma_mapping *map, userptr_t addr, size_t len );
+
/**
* Set addressable space mask
*
dma->allocated--;
}
+/**
+ * Allocate and map DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping to fill in
+ * @v len Length of buffer
+ * @v align Physical alignment
+ * @ret addr Buffer address, or NULL on error
+ */
+static userptr_t efipci_dma_umalloc ( struct dma_device *dma,
+ struct dma_mapping *map,
+ size_t len, size_t align ) {
+ void *addr;
+
+ addr = efipci_dma_alloc ( dma, map, len, align );
+ return virt_to_user ( addr );
+}
+
+/**
+ * Unmap and free DMA-coherent buffer from external (user) memory
+ *
+ * @v dma DMA device
+ * @v map DMA mapping
+ * @v addr Buffer address
+ * @v len Length of buffer
+ */
+static void efipci_dma_ufree ( struct dma_device *dma, struct dma_mapping *map,
+ userptr_t addr, size_t len ) {
+
+ efipci_dma_free ( dma, map, user_to_virt ( addr, 0 ), len );
+}
+
/**
* Set addressable space mask
*
.unmap = efipci_dma_unmap,
.alloc = efipci_dma_alloc,
.free = efipci_dma_free,
+ .umalloc = efipci_dma_umalloc,
+ .ufree = efipci_dma_ufree,
.set_mask = efipci_dma_set_mask,
};