10#include <l4/cxx/ref_ptr>
14#include <l4/libblock-device/types.h>
15#include <l4/libblock-device/debug.h>
17namespace Block_device {
20template <
typename DEV>
21struct Device_dma_map_all_impl
23 using Device_type = DEV;
26 struct Dma_info :
public Block_device::Dma_region_info
30 cxx::Ref_ptr<Device_type> device;
34 cxx::Ref_ptr<Device_type> device)
35 : addr(addr), size(size), device(device)
39 virtual ~Dma_info()
override
41 device->dma_unmap_region(
this);
50 int dma_map_all(Block_device::Mem_region *region,
l4_addr_t offset,
54 if (!region->dma_info)
62 if (ret < 0 || size < num_sectors * device()->sector_size())
66 "Cannot resolve DMA address (ret = %d, %zu < %zu).\n", ret,
67 size, num_sectors * device()->sector_size());
71 auto dev = cxx::Ref_ptr<Device_type>(device());
72 auto dma_info = cxx::make_unique<Dma_info>(addr, size, dev);
74 cxx::unique_ptr<Block_device::Dma_region_info>(dma_info.release());
77 auto *dma_info =
static_cast<Dma_info *
>(region->dma_info.get());
78 *dma_addr = dma_info->addr + offset - region->
ds_offset();
83 void dma_unmap_region(Dma_info *dma_info)
85 auto ret = _dma->unmap(dma_info->addr, dma_info->size,
90 "Failed to unmap (ret = %d, addr = %llx, size = %zu)\n", ret,
91 dma_info->addr, dma_info->size);
96 {
return static_cast<Device_type *
>(
this); }
l4_uint64_t Dma_addr
Data type for DMA addresses.
Direction
Direction of the DMA transfers.
@ Bidirectional
device reads and writes to the memory
l4_addr_t ds_offset() const
L4::Cap< L4Re::Dataspace > ds() const
unsigned int l4_size_t
Unsigned size type.
unsigned long l4_addr_t
Address type.
L4::Detail::Shared_cap_impl< T, L4Re::Util::Smart_count_cap< L4_FP_ALL_SPACES > > Shared_cap
Shared capability that implements automatic free and unmap of the capability selector.
Cap< T > make_cap_rw(L4::Cap< T > cap) noexcept
Make an L4::Ipc::Cap<T> for the given capability with L4_CAP_FPAGE_RW rights.