mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 22:47:50 +00:00
genode_c_api: unify shared dataspace callbacks
* Unifies the declaration of callbacks which manage driver/client shared dataspaces * Move the Linux driver-specific callback implementation to the lx_emul library from the PC's USB host driver Fix genodelabs/genode#4439
This commit is contained in:
parent
b1e2e654a9
commit
b80146a6f7
32
repos/dde_linux/src/include/lx_emul/shared_dma_buffer.h
Normal file
32
repos/dde_linux/src/include/lx_emul/shared_dma_buffer.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* \brief Lx_emul support to allocate shared DMA buffer for Genode's C API
|
||||||
|
* \author Stefan Kalkowski
|
||||||
|
* \date 2022-03-02
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is distributed under the terms of the GNU General Public License
|
||||||
|
* version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LX_EMUL__SHARED_DMA_BUFFER_H_
|
||||||
|
#define _LX_EMUL__SHARED_DMA_BUFFER_H_
|
||||||
|
|
||||||
|
#include <genode_c_api/base.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct genode_shared_dataspace *
|
||||||
|
lx_emul_shared_dma_buffer_allocate(unsigned long size);
|
||||||
|
|
||||||
|
void lx_emul_shared_dma_buffer_free(struct genode_shared_dataspace * ds);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _LX_EMUL__SHARED_DMA_BUFFER_H_ */
|
58
repos/dde_linux/src/lib/lx_emul/shared_dma_buffer.cc
Normal file
58
repos/dde_linux/src/lib/lx_emul/shared_dma_buffer.cc
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* \brief Lx_emul backend for shared dma buffers
|
||||||
|
* \author Stefan Kalkowski
|
||||||
|
* \date 2022-03-02
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Genode Labs GmbH
|
||||||
|
*
|
||||||
|
* This file is distributed under the terms of the GNU General Public License
|
||||||
|
* version 2.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <base/attached_dataspace.h>
|
||||||
|
|
||||||
|
#include <lx_kit/env.h>
|
||||||
|
#include <lx_kit/memory.h>
|
||||||
|
#include <lx_emul/page_virt.h>
|
||||||
|
#include <lx_emul/shared_dma_buffer.h>
|
||||||
|
|
||||||
|
struct genode_shared_dataspace : Genode::Attached_dataspace {};
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" struct genode_shared_dataspace *
|
||||||
|
lx_emul_shared_dma_buffer_allocate(unsigned long size)
|
||||||
|
{
|
||||||
|
Genode::Attached_dataspace & ds =
|
||||||
|
Lx_kit::env().memory.alloc_dataspace(size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have to call virt_to_pages eagerly here,
|
||||||
|
* to get contingous page objects registered
|
||||||
|
*/
|
||||||
|
lx_emul_virt_to_pages(ds.local_addr<void>(), size >> 12);
|
||||||
|
return static_cast<genode_shared_dataspace*>(&ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern "C" void
|
||||||
|
lx_emul_shared_dma_buffer_free(struct genode_shared_dataspace * ds)
|
||||||
|
{
|
||||||
|
lx_emul_forget_pages(ds->local_addr<void>(), ds->size());
|
||||||
|
Lx_kit::env().memory.free_dataspace(ds->local_addr<void>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Genode::addr_t
|
||||||
|
genode_shared_dataspace_local_address(struct genode_shared_dataspace * ds)
|
||||||
|
{
|
||||||
|
return (Genode::addr_t)ds->local_addr<void>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Genode::Dataspace_capability
|
||||||
|
genode_shared_dataspace_capability(struct genode_shared_dataspace * ds)
|
||||||
|
{
|
||||||
|
return ds->cap();
|
||||||
|
}
|
@ -26,7 +26,7 @@ extern "C" {
|
|||||||
struct genode_env;
|
struct genode_env;
|
||||||
struct genode_allocator;
|
struct genode_allocator;
|
||||||
struct genode_signal_handler;
|
struct genode_signal_handler;
|
||||||
struct genode_attached_dataspace;
|
struct genode_shared_dataspace;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
@ -43,10 +43,9 @@ struct genode_attached_dataspace;
|
|||||||
#include <base/allocator.h>
|
#include <base/allocator.h>
|
||||||
#include <base/attached_dataspace.h>
|
#include <base/attached_dataspace.h>
|
||||||
|
|
||||||
struct genode_env : Genode::Env { };
|
struct genode_env : Genode::Env { };
|
||||||
struct genode_allocator : Genode::Allocator { };
|
struct genode_allocator : Genode::Allocator { };
|
||||||
struct genode_signal_handler : Genode::Signal_dispatcher_base { };
|
struct genode_signal_handler : Genode::Signal_dispatcher_base { };
|
||||||
struct genode_attached_dataspace : Genode::Attached_dataspace { };
|
|
||||||
|
|
||||||
static inline auto genode_env_ptr(Genode::Env &env)
|
static inline auto genode_env_ptr(Genode::Env &env)
|
||||||
{
|
{
|
||||||
@ -69,11 +68,30 @@ static inline Genode::Signal_context_capability cap(genode_signal_handler *sigh_
|
|||||||
return *static_cast<Genode::Signal_handler<Genode::Meta::Empty> *>(dispatcher_ptr);
|
return *static_cast<Genode::Signal_handler<Genode::Meta::Empty> *>(dispatcher_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline auto genode_attached_dataspace_ptr(Genode::Attached_dataspace &ds)
|
/**
|
||||||
{
|
* Returns local address of attached shared dataspace
|
||||||
return static_cast<genode_attached_dataspace *>(&ds);
|
*/
|
||||||
}
|
Genode::addr_t
|
||||||
|
genode_shared_dataspace_local_address(struct genode_shared_dataspace * ds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns capability of shared dataspace
|
||||||
|
*/
|
||||||
|
Genode::Dataspace_capability
|
||||||
|
genode_shared_dataspace_capability(struct genode_shared_dataspace * ds);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback definition to allocate and attach a dataspace to share
|
||||||
|
*/
|
||||||
|
typedef struct genode_shared_dataspace *
|
||||||
|
(*genode_shared_dataspace_alloc_attach_t) (unsigned long size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback definition to detach and free dataspace
|
||||||
|
*/
|
||||||
|
typedef void
|
||||||
|
(*genode_shared_dataspace_free_t) (struct genode_shared_dataspace * ds);
|
||||||
|
|
||||||
#endif /* _INCLUDE__GENODE_C_API__BASE_H_ */
|
#endif /* _INCLUDE__GENODE_C_API__BASE_H_ */
|
||||||
|
@ -29,18 +29,6 @@ extern "C" {
|
|||||||
** Initialization **
|
** Initialization **
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback called during peer session request to allocate dma-capable shared buffer
|
|
||||||
*/
|
|
||||||
typedef struct genode_attached_dataspace * (*genode_block_alloc_peer_buffer_t)
|
|
||||||
(unsigned long size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback called when closing peer session to free shared buffer
|
|
||||||
*/
|
|
||||||
typedef void (*genode_block_free_peer_buffer_t)
|
|
||||||
(struct genode_attached_dataspace * ds);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize block root component
|
* Initialize block root component
|
||||||
*
|
*
|
||||||
@ -49,8 +37,8 @@ typedef void (*genode_block_free_peer_buffer_t)
|
|||||||
void genode_block_init(struct genode_env *env,
|
void genode_block_init(struct genode_env *env,
|
||||||
struct genode_allocator *alloc,
|
struct genode_allocator *alloc,
|
||||||
struct genode_signal_handler *handler,
|
struct genode_signal_handler *handler,
|
||||||
genode_block_alloc_peer_buffer_t,
|
genode_shared_dataspace_alloc_attach_t,
|
||||||
genode_block_free_peer_buffer_t);
|
genode_shared_dataspace_free_t);
|
||||||
|
|
||||||
|
|
||||||
/**************************************
|
/**************************************
|
||||||
|
@ -34,18 +34,6 @@ extern "C" {
|
|||||||
** Initialization **
|
** Initialization **
|
||||||
********************/
|
********************/
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback called during peer session request to allocate dma-capable shared buffer
|
|
||||||
*/
|
|
||||||
typedef struct genode_attached_dataspace * (*genode_usb_alloc_peer_buffer_t)
|
|
||||||
(unsigned long size);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback called when closing peer session to free shared buffer
|
|
||||||
*/
|
|
||||||
typedef void (*genode_usb_free_peer_buffer_t)
|
|
||||||
(struct genode_attached_dataspace * ds);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to copy over config descriptor for given device
|
* Callback to copy over config descriptor for given device
|
||||||
*/
|
*/
|
||||||
@ -81,13 +69,13 @@ typedef int (*genode_usb_rpc_endp_desc_t)
|
|||||||
unsigned alt, unsigned endp, void * buf, unsigned long buf_size);
|
unsigned alt, unsigned endp, void * buf, unsigned long buf_size);
|
||||||
|
|
||||||
struct genode_usb_rpc_callbacks {
|
struct genode_usb_rpc_callbacks {
|
||||||
genode_usb_alloc_peer_buffer_t alloc_fn;
|
genode_shared_dataspace_alloc_attach_t alloc_fn;
|
||||||
genode_usb_free_peer_buffer_t free_fn;
|
genode_shared_dataspace_free_t free_fn;
|
||||||
genode_usb_rpc_config_desc_t cfg_desc_fn;
|
genode_usb_rpc_config_desc_t cfg_desc_fn;
|
||||||
genode_usb_rpc_alt_settings_t alt_settings_fn;
|
genode_usb_rpc_alt_settings_t alt_settings_fn;
|
||||||
genode_usb_rpc_iface_desc_t iface_desc_fn;
|
genode_usb_rpc_iface_desc_t iface_desc_fn;
|
||||||
genode_usb_rpc_iface_extra_t iface_extra_fn;
|
genode_usb_rpc_iface_extra_t iface_extra_fn;
|
||||||
genode_usb_rpc_endp_desc_t endp_desc_fn;
|
genode_usb_rpc_endp_desc_t endp_desc_fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,55 +24,68 @@
|
|||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
struct genode_block_session : Rpc_object<Block::Session>
|
class genode_block_session : public Rpc_object<Block::Session>
|
||||||
{
|
{
|
||||||
enum { MAX_REQUESTS = 32 };
|
private:
|
||||||
|
|
||||||
struct Request {
|
friend class Root;
|
||||||
enum State { FREE, IN_FLY, DONE };
|
|
||||||
|
|
||||||
State state { FREE };
|
enum { MAX_REQUESTS = 32 };
|
||||||
genode_block_request dev_req { GENODE_BLOCK_UNAVAIL, 0, 0, nullptr };
|
|
||||||
Block::Request peer_req {};
|
|
||||||
};
|
|
||||||
|
|
||||||
Attached_dataspace & ds;
|
struct Request {
|
||||||
Block::Request_stream rs;
|
enum State { FREE, IN_FLY, DONE };
|
||||||
Request requests[MAX_REQUESTS];
|
|
||||||
|
|
||||||
template <typename FUNC>
|
State state { FREE };
|
||||||
void first_request(Request::State state, FUNC const & fn)
|
genode_block_request dev_req { GENODE_BLOCK_UNAVAIL,
|
||||||
{
|
0, 0, nullptr };
|
||||||
for (unsigned idx = 0; idx < MAX_REQUESTS; idx++) {
|
Block::Request peer_req {};
|
||||||
if (requests[idx].state == state) {
|
};
|
||||||
fn(requests[idx]);
|
|
||||||
return;
|
genode_shared_dataspace * _ds;
|
||||||
|
Block::Request_stream _rs;
|
||||||
|
Request _requests[MAX_REQUESTS];
|
||||||
|
|
||||||
|
template <typename FUNC>
|
||||||
|
void _first_request(Request::State state, FUNC const & fn)
|
||||||
|
{
|
||||||
|
for (unsigned idx = 0; idx < MAX_REQUESTS; idx++) {
|
||||||
|
if (_requests[idx].state == state) {
|
||||||
|
fn(_requests[idx]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename FUNC>
|
template <typename FUNC>
|
||||||
void for_each_request(Request::State state, FUNC const & fn)
|
void _for_each_request(Request::State state, FUNC const & fn)
|
||||||
{
|
{
|
||||||
for (unsigned idx = 0; idx < MAX_REQUESTS; idx++) {
|
for (unsigned idx = 0; idx < MAX_REQUESTS; idx++) {
|
||||||
if (requests[idx].state == state)
|
if (_requests[idx].state == state)
|
||||||
fn(requests[idx]);
|
fn(_requests[idx]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
genode_block_session(Env & env,
|
/*
|
||||||
Block::Session::Info info,
|
* Non_copyable
|
||||||
Signal_context_capability cap,
|
*/
|
||||||
size_t buffer_size);
|
genode_block_session(const genode_block_session&);
|
||||||
|
genode_block_session & operator=(const genode_block_session&);
|
||||||
|
|
||||||
Info info() const override { return rs.info(); }
|
public:
|
||||||
|
|
||||||
Capability<Tx> tx_cap() override { return rs.tx_cap(); }
|
genode_block_session(Env & env,
|
||||||
|
Block::Session::Info info,
|
||||||
|
Signal_context_capability cap,
|
||||||
|
size_t buffer_size);
|
||||||
|
|
||||||
genode_block_request * request();
|
Info info() const override { return _rs.info(); }
|
||||||
void ack(genode_block_request * req, bool success);
|
|
||||||
|
|
||||||
void notify_peers() { rs.wakeup_client_if_needed(); }
|
Capability<Tx> tx_cap() override { return _rs.tx_cap(); }
|
||||||
|
|
||||||
|
genode_block_request * request();
|
||||||
|
void ack(genode_block_request * req, bool success);
|
||||||
|
|
||||||
|
void notify_peers() { _rs.wakeup_client_if_needed(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -131,9 +144,9 @@ class Root : public Root_component<genode_block_session>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static ::Root * _block_root = nullptr;
|
static ::Root * _block_root = nullptr;
|
||||||
static genode_block_alloc_peer_buffer_t _alloc_peer_buffer = nullptr;
|
static genode_shared_dataspace_alloc_attach_t _alloc_peer_buffer = nullptr;
|
||||||
static genode_block_free_peer_buffer_t _free_peer_buffer = nullptr;
|
static genode_shared_dataspace_free_t _free_peer_buffer = nullptr;
|
||||||
|
|
||||||
|
|
||||||
genode_block_request * genode_block_session::request()
|
genode_block_request * genode_block_session::request()
|
||||||
@ -142,7 +155,7 @@ genode_block_request * genode_block_session::request()
|
|||||||
|
|
||||||
genode_block_request * ret = nullptr;
|
genode_block_request * ret = nullptr;
|
||||||
|
|
||||||
rs.with_requests([&] (Block::Request request) {
|
_rs.with_requests([&] (Block::Request request) {
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return Response::RETRY;
|
return Response::RETRY;
|
||||||
@ -156,7 +169,7 @@ genode_block_request * genode_block_session::request()
|
|||||||
|
|
||||||
Response response = Response::RETRY;
|
Response response = Response::RETRY;
|
||||||
|
|
||||||
first_request(Request::FREE, [&] (Request & r) {
|
_first_request(Request::FREE, [&] (Request & r) {
|
||||||
|
|
||||||
r.state = Request::IN_FLY;
|
r.state = Request::IN_FLY;
|
||||||
r.peer_req = request;
|
r.peer_req = request;
|
||||||
@ -178,8 +191,8 @@ genode_block_request * genode_block_session::request()
|
|||||||
|
|
||||||
r.dev_req.blk_nr = op.block_number;
|
r.dev_req.blk_nr = op.block_number;
|
||||||
r.dev_req.blk_cnt = op.count;
|
r.dev_req.blk_cnt = op.count;
|
||||||
r.dev_req.addr = (void*)((addr_t)ds.local_addr<void>()
|
r.dev_req.addr = (void*)
|
||||||
+ request.offset);
|
(genode_shared_dataspace_local_address(_ds) + request.offset);
|
||||||
|
|
||||||
ret = &r.dev_req;
|
ret = &r.dev_req;
|
||||||
response = Response::ACCEPTED;
|
response = Response::ACCEPTED;
|
||||||
@ -194,14 +207,14 @@ genode_block_request * genode_block_session::request()
|
|||||||
|
|
||||||
void genode_block_session::ack(genode_block_request * req, bool success)
|
void genode_block_session::ack(genode_block_request * req, bool success)
|
||||||
{
|
{
|
||||||
for_each_request(Request::IN_FLY, [&] (Request & r) {
|
_for_each_request(Request::IN_FLY, [&] (Request & r) {
|
||||||
if (&r.dev_req == req)
|
if (&r.dev_req == req)
|
||||||
r.state = Request::DONE;
|
r.state = Request::DONE;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Acknowledge any pending packets */
|
/* Acknowledge any pending packets */
|
||||||
rs.try_acknowledge([&](Block::Request_stream::Ack & ack) {
|
_rs.try_acknowledge([&](Block::Request_stream::Ack & ack) {
|
||||||
first_request(Request::DONE, [&] (Request & r) {
|
_first_request(Request::DONE, [&] (Request & r) {
|
||||||
r.state = Request::FREE;
|
r.state = Request::FREE;
|
||||||
r.peer_req.success = success;
|
r.peer_req.success = success;
|
||||||
ack.submit(r.peer_req);
|
ack.submit(r.peer_req);
|
||||||
@ -215,8 +228,8 @@ genode_block_session::genode_block_session(Env & env,
|
|||||||
Signal_context_capability cap,
|
Signal_context_capability cap,
|
||||||
size_t buffer_size)
|
size_t buffer_size)
|
||||||
:
|
:
|
||||||
ds(*static_cast<Attached_dataspace*>(_alloc_peer_buffer(buffer_size))),
|
_ds(_alloc_peer_buffer(buffer_size)),
|
||||||
rs(env.rm(), ds.cap(), env.ep(), cap, info) { }
|
_rs(env.rm(), genode_shared_dataspace_capability(_ds), env.ep(), cap, info) { }
|
||||||
|
|
||||||
|
|
||||||
genode_block_session * ::Root::_create_session(const char * args,
|
genode_block_session * ::Root::_create_session(const char * args,
|
||||||
@ -262,9 +275,9 @@ void ::Root::_destroy_session(genode_block_session * session)
|
|||||||
si.block_session = nullptr;
|
si.block_session = nullptr;
|
||||||
});
|
});
|
||||||
|
|
||||||
Attached_dataspace & ds = session->ds;
|
genode_shared_dataspace * ds = session->_ds;
|
||||||
Genode::destroy(md_alloc(), session);
|
Genode::destroy(md_alloc(), session);
|
||||||
_free_peer_buffer(genode_attached_dataspace_ptr(ds));
|
_free_peer_buffer(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -344,11 +357,12 @@ void ::Root::notify_peers()
|
|||||||
_env(env), _sigh_cap(cap) { }
|
_env(env), _sigh_cap(cap) { }
|
||||||
|
|
||||||
|
|
||||||
extern "C" void genode_block_init(genode_env *env_ptr,
|
extern "C" void
|
||||||
genode_allocator *alloc_ptr,
|
genode_block_init(genode_env * env_ptr,
|
||||||
genode_signal_handler *sigh_ptr,
|
genode_allocator * alloc_ptr,
|
||||||
genode_block_alloc_peer_buffer_t alloc_func,
|
genode_signal_handler * sigh_ptr,
|
||||||
genode_block_free_peer_buffer_t free_func)
|
genode_shared_dataspace_alloc_attach_t alloc_func,
|
||||||
|
genode_shared_dataspace_free_t free_func)
|
||||||
{
|
{
|
||||||
static ::Root root(*static_cast<Env*>(env_ptr),
|
static ::Root root(*static_cast<Env*>(env_ptr),
|
||||||
*static_cast<Allocator*>(alloc_ptr),
|
*static_cast<Allocator*>(alloc_ptr),
|
||||||
|
@ -60,7 +60,7 @@ class genode_usb_session : public Usb::Session_rpc_object
|
|||||||
Constructible<Usb::Packet_descriptor> packets[MAX_PACKETS_IN_FLY] { };
|
Constructible<Usb::Packet_descriptor> packets[MAX_PACKETS_IN_FLY] { };
|
||||||
|
|
||||||
::Root & _root;
|
::Root & _root;
|
||||||
Attached_dataspace & _ds;
|
genode_shared_dataspace * _ds;
|
||||||
Signal_context_capability _sigh_state_cap {};
|
Signal_context_capability _sigh_state_cap {};
|
||||||
genode_usb_session_handle_t _id;
|
genode_usb_session_handle_t _id;
|
||||||
Session_label const _label;
|
Session_label const _label;
|
||||||
@ -68,12 +68,16 @@ class genode_usb_session : public Usb::Session_rpc_object
|
|||||||
|
|
||||||
void _ack(int err, Usb::Packet_descriptor p);
|
void _ack(int err, Usb::Packet_descriptor p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non_copyable
|
||||||
|
*/
|
||||||
genode_usb_session(const genode_usb_session&);
|
genode_usb_session(const genode_usb_session&);
|
||||||
|
genode_usb_session & operator=(const genode_usb_session&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
genode_usb_session(::Root & root,
|
genode_usb_session(::Root & root,
|
||||||
Attached_dataspace & ds,
|
genode_shared_dataspace * ds,
|
||||||
Env & env,
|
Env & env,
|
||||||
Signal_context_capability cap,
|
Signal_context_capability cap,
|
||||||
genode_usb_session_handle_t id,
|
genode_usb_session_handle_t id,
|
||||||
@ -425,7 +429,8 @@ bool genode_usb_session::request(genode_usb_request_callbacks & req, void * data
|
|||||||
|
|
||||||
addr_t offset = (addr_t)sink()->packet_content(p) -
|
addr_t offset = (addr_t)sink()->packet_content(p) -
|
||||||
(addr_t)sink()->ds_local_base();
|
(addr_t)sink()->ds_local_base();
|
||||||
void * addr = (void*)((addr_t)_ds.local_addr<void>() + offset);
|
void * addr = (void*)(genode_shared_dataspace_local_address(_ds)
|
||||||
|
+ offset);
|
||||||
|
|
||||||
switch (p.type) {
|
switch (p.type) {
|
||||||
case Packet_descriptor::STRING:
|
case Packet_descriptor::STRING:
|
||||||
@ -482,13 +487,14 @@ void genode_usb_session::handle_response(genode_usb_request_handle_t id,
|
|||||||
|
|
||||||
|
|
||||||
genode_usb_session::genode_usb_session(::Root & root,
|
genode_usb_session::genode_usb_session(::Root & root,
|
||||||
Attached_dataspace & ds,
|
genode_shared_dataspace * ds,
|
||||||
Env & env,
|
Env & env,
|
||||||
Signal_context_capability cap,
|
Signal_context_capability cap,
|
||||||
genode_usb_session_handle_t id,
|
genode_usb_session_handle_t id,
|
||||||
Session_label const label)
|
Session_label const label)
|
||||||
:
|
:
|
||||||
Usb::Session_rpc_object(ds.cap(), env.ep().rpc_ep(), env.rm()),
|
Usb::Session_rpc_object(genode_shared_dataspace_capability(ds),
|
||||||
|
env.ep().rpc_ep(), env.rm()),
|
||||||
_root(root),
|
_root(root),
|
||||||
_ds(ds),
|
_ds(ds),
|
||||||
_id(id),
|
_id(id),
|
||||||
@ -548,9 +554,8 @@ genode_usb_session * ::Root::_create_session(const char * args,
|
|||||||
throw Insufficient_ram_quota();
|
throw Insufficient_ram_quota();
|
||||||
}
|
}
|
||||||
|
|
||||||
Attached_dataspace & ds =
|
genode_shared_dataspace * ds = _callbacks->alloc_fn(tx_buf_size);
|
||||||
*static_cast<Attached_dataspace*>(_callbacks->alloc_fn(tx_buf_size));
|
genode_usb_session * ret = new (md_alloc())
|
||||||
genode_usb_session * ret = new (md_alloc())
|
|
||||||
genode_usb_session(*this, ds, _env, _sigh_cap, _id_alloc.alloc(), label);
|
genode_usb_session(*this, ds, _env, _sigh_cap, _id_alloc.alloc(), label);
|
||||||
_sessions.insert(&ret->_le);
|
_sessions.insert(&ret->_le);
|
||||||
|
|
||||||
@ -576,11 +581,11 @@ void ::Root::_destroy_session(genode_usb_session * session)
|
|||||||
});
|
});
|
||||||
|
|
||||||
genode_usb_session_handle_t id = session->_id;
|
genode_usb_session_handle_t id = session->_id;
|
||||||
Attached_dataspace & ds = session->_ds;
|
genode_shared_dataspace * ds = session->_ds;
|
||||||
_sessions.remove(&session->_le);
|
_sessions.remove(&session->_le);
|
||||||
Genode::destroy(md_alloc(), session);
|
Genode::destroy(md_alloc(), session);
|
||||||
_id_alloc.free((addr_t)id);
|
_id_alloc.free((addr_t)id);
|
||||||
_callbacks->free_fn(genode_attached_dataspace_ptr(ds));
|
_callbacks->free_fn(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,41 +16,19 @@
|
|||||||
#include <base/env.h>
|
#include <base/env.h>
|
||||||
|
|
||||||
#include <lx_emul/init.h>
|
#include <lx_emul/init.h>
|
||||||
#include <lx_emul/page_virt.h>
|
|
||||||
#include <lx_kit/env.h>
|
#include <lx_kit/env.h>
|
||||||
#include <lx_kit/init.h>
|
#include <lx_kit/init.h>
|
||||||
#include <lx_user/io.h>
|
#include <lx_user/io.h>
|
||||||
|
|
||||||
#include <usb.h>
|
#include <genode_c_api/usb.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace Genode;
|
using namespace Genode;
|
||||||
|
|
||||||
|
|
||||||
extern "C" struct genode_attached_dataspace *
|
|
||||||
genode_usb_allocate_peer_buffer(unsigned long size)
|
|
||||||
{
|
|
||||||
Attached_dataspace & ds = Lx_kit::env().memory.alloc_dataspace(size);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We have to call virt_to_pages eagerly here,
|
|
||||||
* to get contingous page objects registered
|
|
||||||
*/
|
|
||||||
lx_emul_virt_to_pages(ds.local_addr<void>(), size >> 12);
|
|
||||||
return genode_attached_dataspace_ptr(ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void genode_usb_free_peer_buffer(struct genode_attached_dataspace * ptr)
|
|
||||||
{
|
|
||||||
Attached_dataspace *ds = static_cast<Attached_dataspace*>(ptr);
|
|
||||||
lx_emul_forget_pages(ds->local_addr<void>(), ds->size());
|
|
||||||
Lx_kit::env().memory.free_dataspace(ds->local_addr<void>());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static bool _bios_handoff;
|
static bool _bios_handoff;
|
||||||
|
|
||||||
|
extern struct genode_usb_rpc_callbacks genode_usb_rpc_callbacks_obj;
|
||||||
|
|
||||||
|
|
||||||
extern "C" int inhibit_pci_fixup(char const *name)
|
extern "C" int inhibit_pci_fixup(char const *name)
|
||||||
{
|
{
|
||||||
|
@ -4,10 +4,12 @@ REL_PRG_DIR := $(PRG_DIR)/../..
|
|||||||
|
|
||||||
TARGET := pc_usb_host_drv
|
TARGET := pc_usb_host_drv
|
||||||
LIBS := base pc_lx_emul
|
LIBS := base pc_lx_emul
|
||||||
INC_DIR := $(REL_PRG_DIR)
|
|
||||||
|
INC_DIR += $(REL_PRG_DIR)
|
||||||
SRC_CC += main.cc
|
SRC_CC += main.cc
|
||||||
SRC_CC += misc.cc
|
SRC_CC += misc.cc
|
||||||
SRC_CC += time.cc
|
SRC_CC += time.cc
|
||||||
|
SRC_CC += lx_emul/shared_dma_buffer.cc
|
||||||
SRC_C += dummies.c
|
SRC_C += dummies.c
|
||||||
SRC_C += lx_emul.c
|
SRC_C += lx_emul.c
|
||||||
SRC_C += usb.c
|
SRC_C += usb.c
|
||||||
|
@ -15,11 +15,14 @@
|
|||||||
#include <linux/usb.h>
|
#include <linux/usb.h>
|
||||||
#include <linux/usb/hcd.h>
|
#include <linux/usb/hcd.h>
|
||||||
|
|
||||||
|
#include <lx_emul/shared_dma_buffer.h>
|
||||||
#include <lx_emul/task.h>
|
#include <lx_emul/task.h>
|
||||||
#include <lx_user/init.h>
|
#include <lx_user/init.h>
|
||||||
#include <lx_user/io.h>
|
#include <lx_user/io.h>
|
||||||
|
|
||||||
#include <usb.h>
|
#include <genode_c_api/usb.h>
|
||||||
|
|
||||||
|
struct usb_interface;
|
||||||
|
|
||||||
struct usb_find_request {
|
struct usb_find_request {
|
||||||
genode_usb_bus_num_t bus;
|
genode_usb_bus_num_t bus;
|
||||||
@ -153,8 +156,8 @@ static int endpoint_descriptor(genode_usb_bus_num_t bus,
|
|||||||
|
|
||||||
|
|
||||||
struct genode_usb_rpc_callbacks genode_usb_rpc_callbacks_obj = {
|
struct genode_usb_rpc_callbacks genode_usb_rpc_callbacks_obj = {
|
||||||
.alloc_fn = genode_usb_allocate_peer_buffer,
|
.alloc_fn = lx_emul_shared_dma_buffer_allocate,
|
||||||
.free_fn = genode_usb_free_peer_buffer,
|
.free_fn = lx_emul_shared_dma_buffer_free,
|
||||||
.cfg_desc_fn = config_descriptor,
|
.cfg_desc_fn = config_descriptor,
|
||||||
.alt_settings_fn = alt_settings,
|
.alt_settings_fn = alt_settings,
|
||||||
.iface_desc_fn = interface_descriptor,
|
.iface_desc_fn = interface_descriptor,
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* \brief USB related definitions for kernel/genode c-api
|
|
||||||
* \author Stefan Kalkowski
|
|
||||||
* \date 2021-09-17
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) 2021 Genode Labs GmbH
|
|
||||||
*
|
|
||||||
* This file is distributed under the terms of the GNU General Public License
|
|
||||||
* version 2.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <genode_c_api/usb.h>
|
|
||||||
|
|
||||||
struct usb_interface;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct genode_attached_dataspace *
|
|
||||||
genode_usb_allocate_peer_buffer(unsigned long size);
|
|
||||||
|
|
||||||
void genode_usb_free_peer_buffer(struct genode_attached_dataspace * ptr);
|
|
||||||
|
|
||||||
extern struct genode_usb_rpc_callbacks genode_usb_rpc_callbacks_obj;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user