mirror of
https://github.com/ipxe/ipxe
synced 2025-12-17 18:11:49 +03:00
[dma] Provide dma_umalloc() for allocating large DMA-coherent buffers
Some devices (e.g. xHCI USB host controllers) may require the use of large areas of host memory for private use by the device. These allocations cannot be satisfied from iPXE's limited heap space, and so are currently allocated using umalloc() which will allocate external system memory (and alter the system memory map as needed). Provide dma_umalloc() to provide such allocations as part of the DMA API, since there is otherwise no way to guarantee that the allocated regions are usable for coherent DMA. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -504,6 +504,38 @@ static void efipci_dma_free ( struct dma_device *dma, struct dma_mapping *map,
|
||||
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
|
||||
*
|
||||
@@ -542,6 +574,8 @@ static struct dma_operations efipci_dma_operations = {
|
||||
.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,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user