diff --git a/repos/os/src/drivers/platform/legacy/x86/device_pd.cc b/repos/os/src/drivers/platform/legacy/x86/device_pd.cc index 88c2338a3b..455a9f3342 100644 --- a/repos/os/src/drivers/platform/legacy/x86/device_pd.cc +++ b/repos/os/src/drivers/platform/legacy/x86/device_pd.cc @@ -31,28 +31,40 @@ void Platform::Device_pd::attach_dma_mem(Dataspace_capability ds_cap, addr_t page = ~0UL; - using Attach_dma_error = Pd_session::Attach_dma_error; - _pd.attach_dma(ds_cap, dma_addr).with_result( + bool retry = false; - [&] (Pd_session::Attach_dma_ok) { + do { + _pd.attach_dma(ds_cap, dma_addr).with_result( - page = dma_addr; + [&] (Pd_session::Attach_dma_ok) { - /* trigger eager mapping of memory */ - _pd.map(page, size); - }, - [&] (Attach_dma_error e) { - switch (e) { - case Attach_dma_error::OUT_OF_RAM: throw Out_of_ram(); - case Attach_dma_error::OUT_OF_CAPS: throw Out_of_caps(); - case Attach_dma_error::DENIED: - warning("Pd_session::attach_dma denied"); page = dma_addr; - break; + + /* trigger eager mapping of memory */ + _pd.map(page, size); + retry = false; + }, + [&] (Attach_dma_error e) { + switch (e) { + case Attach_dma_error::OUT_OF_RAM: + _address_space.upgrade_ram(); + retry = true; + break; + case Attach_dma_error::OUT_OF_CAPS: + _address_space.upgrade_caps(); + retry = true; + break; + case Attach_dma_error::DENIED: + warning("Pd_session::attach_dma denied"); + page = dma_addr; + retry = false; + break; + } } - }); + ); + } while (retry); /* sanity check */ if ((page == ~0UL) || (page != dma_addr)) { diff --git a/repos/os/src/drivers/platform/legacy/x86/device_pd.h b/repos/os/src/drivers/platform/legacy/x86/device_pd.h index 3263b9c23a..366aaac867 100644 --- a/repos/os/src/drivers/platform/legacy/x86/device_pd.h +++ b/repos/os/src/drivers/platform/legacy/x86/device_pd.h @@ -75,28 +75,31 @@ class Platform::Device_pd executable, writeable); }, [&] () { - enum { UPGRADE_CAP_QUOTA = 2 }; - Cap_quota const caps { UPGRADE_CAP_QUOTA }; - _cap_guard.withdraw(caps); - _env.pd().transfer_quota(_pd.rpc_cap(), caps); + upgrade_caps(); } ); }, [&] () { - enum { UPGRADE_RAM_QUOTA = 4096 }; - Ram_quota const ram { UPGRADE_RAM_QUOTA }; - _ram_guard.withdraw(ram); - _env.pd().transfer_quota(_pd.rpc_cap(), ram); + upgrade_ram(); } ); } - Local_addr attach_at(Dataspace_capability ds, - addr_t local_addr, - size_t size = 0, - off_t offset = 0) { - return attach(ds, size, offset, true, local_addr); }; + void upgrade_ram() + { + enum { UPGRADE_RAM_QUOTA = 4096 }; + Ram_quota const ram { UPGRADE_RAM_QUOTA }; + _ram_guard.withdraw(ram); + _env.pd().transfer_quota(_pd.rpc_cap(), ram); + } + void upgrade_caps() + { + enum { UPGRADE_CAP_QUOTA = 2 }; + Cap_quota const caps { UPGRADE_CAP_QUOTA }; + _cap_guard.withdraw(caps); + _env.pd().transfer_quota(_pd.rpc_cap(), caps); + } } _address_space; public: