mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-08 03:45:24 +00:00
usb_drv: change Usb session and raw driver
- Use 'label' attribute to identify device instead of bus/dev and vendor_id/product_id - Implement release_interface RPC - Report 'label' as well as 'bus' and 'dev' - Add policy handling to raw driver (includes reconfiguration at runtime) - Use own memory backing store for large DMA allocations Issue #1863.
This commit is contained in:
parent
3daa8a3d04
commit
716eab21e3
@ -208,17 +208,46 @@ Configuration snippet:
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
The optional 'devices' report lists the connected devices and gets updated when devices are added or removed.
|
||||
The optional 'devices' report lists the connected devices and gets updated
|
||||
when devices are added or removed.
|
||||
|
||||
Example report:
|
||||
|
||||
<devices>
|
||||
<device vendor_id="0x17ef" product_id="0x4816"/>
|
||||
<device vendor_id="0x0a5c" product_id="0x217f"/>
|
||||
<device vendor_id="0x8087" product_id="0x0020"/>
|
||||
<device vendor_id="0x8087" product_id="0x0020"/>
|
||||
<device vendor_id="0x1d6b" product_id="0x0002"/>
|
||||
<device vendor_id="0x1d6b" product_id="0x0002"/>
|
||||
</devices>
|
||||
!<devices>
|
||||
! <device label="usb-1-7" vendor_id="0x1f75" product_id="0x0917" bus="0x0001" dev="0x0007"/>
|
||||
! <device label="usb-1-6" vendor_id="0x13fe" product_id="0x5200" bus="0x0001" dev="0x0006"/>
|
||||
! <device label="usb-1-4" vendor_id="0x17ef" product_id="0x4816" bus="0x0001" dev="0x0004"/>
|
||||
! <device label="usb-1-3" vendor_id="0x0a5c" product_id="0x217f" bus="0x0001" dev="0x0003"/>
|
||||
! <device label="usb-2-2" vendor_id="0x8087" product_id="0x0020" bus="0x0002" dev="0x0002"/>
|
||||
! <device label="usb-1-2" vendor_id="0x8087" product_id="0x0020" bus="0x0001" dev="0x0002"/>
|
||||
! <device label="usb-2-1" vendor_id="0x1d6b" product_id="0x0002" bus="0x0002" dev="0x0001"/>
|
||||
! <device label="usb-1-1" vendor_id="0x1d6b" product_id="0x0002" bus="0x0001" dev="0x0001"/>
|
||||
!</devices>
|
||||
|
||||
There is no distinction yet for multiple devices of the same type.
|
||||
For every device a unique identifier is generated that is used to access the
|
||||
USB device. Only devices that have a valid policy configured at the USB driver
|
||||
can be accessed by a client. The following configuration allows 'comp1' to
|
||||
access the device 'usb-1-6':
|
||||
|
||||
!<start name="usb_drv">
|
||||
! <resource name="RAM" quantum="8M"/>
|
||||
! <provides><service name="Usb"/></provides>
|
||||
! <config uhci="yes" ehci="yes" xhci="yes">
|
||||
! <raw>
|
||||
! <report devices="yes"/>
|
||||
! <policy label="comp1 -> usb-1-6" vendor_id="0x13fe" product_id="0x5200" bus="0x0001" dev="0x0006"/>
|
||||
! </raw>
|
||||
! </config>
|
||||
!</start>
|
||||
|
||||
In addition to the mandatory 'label' attribute the policy node also
|
||||
contains optional attribute tuples of which at least one has to be present.
|
||||
The 'vendor_id' and 'product_id' tuple selects a device regardless of its
|
||||
location on the USB bus and is mostly used in static configurations. The
|
||||
'bus' and 'dev' tuple selects a specific device via its bus locations and
|
||||
device address. It is mostly used in dynamic configurations because the device
|
||||
address is not fixed and may change every time the same device is plugged in.
|
||||
|
||||
The configuration of the USB driver can be changed at runtime to satisfy
|
||||
dynamic configurations or rather policies when using the 'Usb' session
|
||||
interface.
|
||||
|
@ -1,9 +1,14 @@
|
||||
set usb_raw_device ""
|
||||
|
||||
#
|
||||
# Check if USB_RAW_DEVICE is set for Qemu
|
||||
#
|
||||
if {![info exists ::env(USB_RAW_DEVICE)] && [have_include power_on/qemu]} {
|
||||
puts "\nPlease define USB_RAW_DEVICE environment variable and set it to your USB device <bus.device>\n"
|
||||
exit 0
|
||||
if {[have_include power_on/qemu]} {
|
||||
if {![info exists ::env(USB_RAW_DEVICE)]} {
|
||||
puts "\nPlease define USB_RAW_DEVICE environment variable and set it to your USB device <bus.device>\n"
|
||||
exit 0
|
||||
}
|
||||
set usb_raw_device $::env(USB_RAW_DEVICE)
|
||||
}
|
||||
|
||||
#
|
||||
@ -67,7 +72,9 @@ append config {
|
||||
<resource name="RAM" quantum="7M"/>
|
||||
<provides><service name="Usb"/></provides>
|
||||
<config uhci="yes" ehci="yes" xhci="yes">
|
||||
<raw/>
|
||||
<raw>
|
||||
<policy label="usb_terminal -> usb_serial" vendor_id="0x67b" product_id="0x2303"/>
|
||||
</raw>
|
||||
</config>
|
||||
</start>
|
||||
<start name="usb_terminal">
|
||||
@ -97,7 +104,7 @@ append_platform_drv_boot_modules
|
||||
|
||||
build_boot_image $boot_modules
|
||||
|
||||
append qemu_args " -m 256 -nographic -usb -usbdevice host:$::env(USB_RAW_DEVICE) -nographic"
|
||||
append qemu_args " -m 256 -nographic -usb -usbdevice host:$usb_raw_device -nographic"
|
||||
|
||||
|
||||
run_genode_until forever
|
||||
|
@ -930,6 +930,12 @@ void kfree(const void *);
|
||||
void *kmalloc(size_t size, gfp_t flags);
|
||||
void *kcalloc(size_t n, size_t size, gfp_t flags);
|
||||
|
||||
/**
|
||||
* Genode specific for large DMA allocations
|
||||
*/
|
||||
void *dma_malloc(size_t size);
|
||||
void dma_free(void *ptr);
|
||||
|
||||
struct kmem_cache;
|
||||
|
||||
/**
|
||||
|
@ -110,6 +110,11 @@ class Genode::Slab_backend_alloc : public Genode::Allocator,
|
||||
return _range.alloc(size, out_addr);
|
||||
}
|
||||
|
||||
void free(void *addr)
|
||||
{
|
||||
_range.free(addr);
|
||||
}
|
||||
|
||||
void free(void *addr, size_t /* size */) override { }
|
||||
size_t overhead(size_t size) const override { return 0; }
|
||||
bool need_size_for_free() const override { return false; }
|
||||
@ -303,6 +308,22 @@ class Malloc
|
||||
_allocator[nr]->free((void *)(addr - 1));
|
||||
}
|
||||
|
||||
void *alloc_large(size_t size)
|
||||
{
|
||||
void *addr;
|
||||
if (!_back_allocator->alloc(size, &addr)) {
|
||||
PERR("Large back end allocation failed (%zu bytes)", size);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void free_large(void *ptr)
|
||||
{
|
||||
_back_allocator->free(ptr);
|
||||
}
|
||||
|
||||
Genode::addr_t phys_addr(void *a)
|
||||
{
|
||||
return _back_allocator->phys_addr((addr_t)a);
|
||||
@ -376,6 +397,18 @@ void atomic_set(atomic_t *p, unsigned int v) { (*(volatile int *)p) = v; }
|
||||
** Memory allocation, linux/slab.h **
|
||||
*************************************/
|
||||
|
||||
void *dma_malloc(size_t size)
|
||||
{
|
||||
return Malloc::dma()->alloc_large(size);
|
||||
}
|
||||
|
||||
|
||||
void dma_free(void *ptr)
|
||||
{
|
||||
Malloc::dma()->free_large(ptr);
|
||||
}
|
||||
|
||||
|
||||
void *kmalloc(size_t size, gfp_t flags)
|
||||
{
|
||||
void *addr = flags & GFP_NOIO ? Malloc::dma()->alloc(size) : Malloc::mem()->alloc(size);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/reporter.h>
|
||||
#include <os/session_policy.h>
|
||||
#include <root/component.h>
|
||||
#include <usb_session/rpc_object.h>
|
||||
#include <util/list.h>
|
||||
@ -21,6 +22,7 @@
|
||||
#include <extern_c_begin.h>
|
||||
#include <linux/usb.h>
|
||||
#include "raw.h"
|
||||
#include "lx_emul.h"
|
||||
#include <extern_c_end.h>
|
||||
#include <signal.h>
|
||||
|
||||
@ -50,7 +52,7 @@ struct Device : List<Device>::Element
|
||||
return &_l;
|
||||
}
|
||||
|
||||
static Device * device(uint16_t vendor, uint16_t product)
|
||||
static Device * device_product(uint16_t vendor, uint16_t product)
|
||||
{
|
||||
for (Device *d = list()->first(); d; d = d->next()) {
|
||||
if (d->udev->descriptor.idVendor == vendor && d->udev->descriptor.idProduct == product)
|
||||
@ -60,6 +62,18 @@ struct Device : List<Device>::Element
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
static Device * device_bus(long bus, long dev)
|
||||
{
|
||||
for (Device *d = list()->first(); d; d = d->next()) {
|
||||
if (d->udev->bus->busnum == bus && d->udev->devnum == dev)
|
||||
return d;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
static Genode::Reporter &device_list_reporter()
|
||||
{
|
||||
static Genode::Reporter _r("devices", 512*1024);
|
||||
@ -74,7 +88,13 @@ struct Device : List<Device>::Element
|
||||
for (Device *d = list()->first(); d; d = d->next()) {
|
||||
xml.node("device", [&] ()
|
||||
{
|
||||
char buf[7];
|
||||
char buf[16];
|
||||
|
||||
unsigned const bus = d->udev->bus->busnum;
|
||||
unsigned const dev = d->udev->devnum;
|
||||
|
||||
Genode::snprintf(buf, sizeof(buf), "usb-%d-%d", bus, dev);
|
||||
xml.attribute("label", buf);
|
||||
|
||||
Genode::snprintf(buf, sizeof(buf), "0x%4x",
|
||||
d->udev->descriptor.idVendor);
|
||||
@ -83,6 +103,12 @@ struct Device : List<Device>::Element
|
||||
Genode::snprintf(buf, sizeof(buf), "0x%4x",
|
||||
d->udev->descriptor.idProduct);
|
||||
xml.attribute("product_id", buf);
|
||||
|
||||
Genode::snprintf(buf, sizeof(buf), "0x%4x", bus);
|
||||
xml.attribute("bus", buf);
|
||||
|
||||
Genode::snprintf(buf, sizeof(buf), "0x%4x", dev);
|
||||
xml.attribute("dev", buf);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -176,13 +202,9 @@ class Usb::Worker
|
||||
|
||||
kfree(buf);
|
||||
|
||||
if (err < 0 && err != -EPIPE) {
|
||||
p.succeded = false;
|
||||
return;
|
||||
}
|
||||
|
||||
p.control.actual_size = err;
|
||||
p.succeded = true;
|
||||
|
||||
p.succeded = (err < 0 && err != -EPIPE) ? false : true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,7 +246,7 @@ class Usb::Worker
|
||||
|
||||
if (read)
|
||||
Genode::memcpy(_sink->packet_content(p), urb->transfer_buffer,
|
||||
urb->actual_length);
|
||||
urb->actual_length);
|
||||
}
|
||||
|
||||
_ack_packet(p);
|
||||
@ -237,7 +259,7 @@ class Usb::Worker
|
||||
data->worker->_async_finish(data->packet, urb,
|
||||
!!(data->packet.transfer.ep & USB_DIR_IN));
|
||||
kfree (data);
|
||||
kfree (urb->transfer_buffer);
|
||||
dma_free(urb->transfer_buffer);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
||||
@ -247,7 +269,7 @@ class Usb::Worker
|
||||
bool _bulk(Packet_descriptor &p, bool read)
|
||||
{
|
||||
unsigned pipe;
|
||||
void *buf = kmalloc(p.size(), GFP_NOIO);
|
||||
void *buf = dma_malloc(p.size());
|
||||
|
||||
if (read)
|
||||
pipe = usb_rcvbulkpipe(_device->udev, p.transfer.ep);
|
||||
@ -282,7 +304,7 @@ class Usb::Worker
|
||||
bool _irq(Packet_descriptor &p, bool read)
|
||||
{
|
||||
unsigned pipe;
|
||||
void *buf = kmalloc(p.size(), GFP_NOIO);
|
||||
void *buf = dma_malloc(p.size());
|
||||
|
||||
if (read)
|
||||
pipe = usb_rcvintpipe(_device->udev, p.transfer.ep);
|
||||
@ -501,11 +523,14 @@ class Usb::Session_component : public Session_rpc_object,
|
||||
Server::Entrypoint &_ep;
|
||||
unsigned long _vendor;
|
||||
unsigned long _product;
|
||||
long _bus = 0;
|
||||
long _dev = 0;
|
||||
Device *_device = nullptr;
|
||||
Signal_context_capability _sigh_state_change;
|
||||
Signal_rpc_member<Session_component> _packet_avail;
|
||||
Signal_rpc_member<Session_component> _ready_ack;
|
||||
Worker _worker;
|
||||
Ram_dataspace_capability _tx_ds;
|
||||
|
||||
|
||||
void _signal_state_change()
|
||||
@ -526,18 +551,22 @@ class Usb::Session_component : public Session_rpc_object,
|
||||
DEVICE_REMOVE,
|
||||
};
|
||||
|
||||
Session_component(Genode::Dataspace_capability tx_ds, Server::Entrypoint &ep,
|
||||
unsigned long vendor, unsigned long product)
|
||||
Session_component(Genode::Ram_dataspace_capability tx_ds, Server::Entrypoint &ep,
|
||||
unsigned long vendor, unsigned long product,
|
||||
long bus, long dev)
|
||||
: Session_rpc_object(tx_ds, ep.rpc_ep()),
|
||||
_ep(ep),
|
||||
_vendor(vendor), _product(product),
|
||||
_vendor(vendor), _product(product), _bus(bus), _dev(dev),
|
||||
_packet_avail(ep, *this, &Session_component::_receive),
|
||||
_ready_ack(ep, *this, &Session_component::_receive),
|
||||
_worker(sink())
|
||||
_worker(sink()), _tx_ds(tx_ds)
|
||||
{
|
||||
Device *device = Device::device(_vendor, _product);
|
||||
Device *device;
|
||||
if (bus && dev)
|
||||
device = Device::device_bus(bus, dev);
|
||||
else
|
||||
device = Device::device_product(_vendor, _product);
|
||||
if (device) {
|
||||
PDBG("Found device");
|
||||
state_change(DEVICE_ADD, device);
|
||||
}
|
||||
|
||||
@ -566,6 +595,15 @@ class Usb::Session_component : public Session_rpc_object,
|
||||
throw Interface_already_claimed();
|
||||
}
|
||||
|
||||
void release_interface(unsigned interface_num) override
|
||||
{
|
||||
usb_interface *iface = _device->interface(interface_num);
|
||||
if (!iface)
|
||||
throw Interface_not_found();
|
||||
|
||||
usb_driver_release_interface(&raw_intf_driver, iface);
|
||||
}
|
||||
|
||||
void config_descriptor(Device_descriptor *device_descr,
|
||||
Config_descriptor *config_descr) override
|
||||
{
|
||||
@ -622,7 +660,9 @@ class Usb::Session_component : public Session_rpc_object,
|
||||
bool session_device(Device *device)
|
||||
{
|
||||
usb_device_descriptor *descr = &device->udev->descriptor;
|
||||
return (descr->idVendor == _vendor && descr->idProduct == _product) ? true : false;
|
||||
return (descr->idVendor == _vendor && descr->idProduct == _product)
|
||||
|| (_bus && _dev && _bus == device->udev->bus->busnum &&
|
||||
_dev == device->udev->devnum) ? true : false;
|
||||
}
|
||||
|
||||
bool state_change(State state, Device *device)
|
||||
@ -661,6 +701,8 @@ class Usb::Session_component : public Session_rpc_object,
|
||||
if (_worker.device_ready())
|
||||
Signal_transmitter(_sigh_state_change).submit(1);
|
||||
}
|
||||
|
||||
Ram_dataspace_capability tx_ds() { return _tx_ds; }
|
||||
};
|
||||
|
||||
|
||||
@ -687,40 +729,83 @@ class Usb::Root : public Genode::Root_component<Session_component>
|
||||
|
||||
Server::Entrypoint &_ep;
|
||||
|
||||
Genode::Signal_rpc_member<Usb::Root> _config_dispatcher = {
|
||||
_ep, *this, &Usb::Root::_handle_config };
|
||||
|
||||
Genode::Reporter _config_reporter { "config" };
|
||||
|
||||
void _handle_config(unsigned)
|
||||
{
|
||||
Genode::config()->reload();
|
||||
|
||||
Genode::Xml_node config = Genode::config()->xml_node();
|
||||
|
||||
if (!_config_reporter.is_enabled())
|
||||
_config_reporter.enabled(true);
|
||||
|
||||
bool const uhci = config.attribute_value<bool>("uhci", false);
|
||||
bool const ehci = config.attribute_value<bool>("ehci", false);
|
||||
bool const xhci = config.attribute_value<bool>("xhci", false);
|
||||
|
||||
Genode::Reporter::Xml_generator xml(_config_reporter, [&] {
|
||||
if (uhci) xml.attribute("uhci", "yes");
|
||||
if (ehci) xml.attribute("ehci", "yes");
|
||||
if (xhci) xml.attribute("xhci", "yes");
|
||||
|
||||
xml.append(config.content_base(), config.content_size());
|
||||
});
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Session_component *_create_session(const char *args)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
|
||||
size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
||||
try {
|
||||
Xml_node raw = Genode::config()->xml_node().sub_node("raw");
|
||||
Genode::Session_label label(args);
|
||||
Genode::Session_policy policy(label, raw);
|
||||
|
||||
unsigned long vendor = Arg_string::find_arg(args, "vendor").ulong_value(0);
|
||||
unsigned long product = Arg_string::find_arg(args, "product").ulong_value(0);
|
||||
size_t ram_quota = Arg_string::find_arg(args, "ram_quota" ).ulong_value(0);
|
||||
size_t tx_buf_size = Arg_string::find_arg(args, "tx_buf_size").ulong_value(0);
|
||||
|
||||
/* check session quota */
|
||||
size_t session_size = max<size_t>(4096, sizeof(Session_component));
|
||||
if (ram_quota < session_size)
|
||||
throw Root::Quota_exceeded();
|
||||
unsigned long vendor = policy.attribute_value<unsigned long>("vendor", 0);
|
||||
unsigned long product = policy.attribute_value<unsigned long>("product", 0);
|
||||
unsigned long bus = policy.attribute_value<unsigned long>("bus", 0);
|
||||
unsigned long dev = policy.attribute_value<unsigned long>("dev", 0);
|
||||
|
||||
if (tx_buf_size > ram_quota - session_size) {
|
||||
PERR("Insufficient 'ram_quota',got %zu, need %zu",
|
||||
ram_quota, tx_buf_size + session_size);
|
||||
throw Root::Quota_exceeded();
|
||||
/* check session quota */
|
||||
size_t session_size = max<size_t>(4096, sizeof(Session_component));
|
||||
if (ram_quota < session_size)
|
||||
throw Root::Quota_exceeded();
|
||||
|
||||
if (tx_buf_size > ram_quota - session_size) {
|
||||
PERR("Insufficient 'ram_quota',got %zu, need %zu",
|
||||
ram_quota, tx_buf_size + session_size);
|
||||
throw Root::Quota_exceeded();
|
||||
}
|
||||
|
||||
Ram_dataspace_capability tx_ds = env()->ram_session()->alloc(tx_buf_size);
|
||||
Session_component *session = new (md_alloc())
|
||||
Session_component(tx_ds, _ep, vendor, product, bus, dev);
|
||||
::Session::list()->insert(session);
|
||||
return session;
|
||||
} catch (Genode::Session_policy::No_policy_defined) {
|
||||
PERR("Invalid session request, no matching policy for '%s'",
|
||||
Genode::Session_label(args).string());
|
||||
throw Genode::Root::Unavailable();
|
||||
}
|
||||
|
||||
Dataspace_capability tx_ds = env()->ram_session()->alloc(tx_buf_size);
|
||||
Session_component *session = new (md_alloc())
|
||||
Session_component(tx_ds, _ep, vendor, product);
|
||||
::Session::list()->insert(session);
|
||||
return session;
|
||||
}
|
||||
|
||||
void _destroy_session(Session_component *session)
|
||||
{
|
||||
Ram_dataspace_capability tx_ds = session->tx_ds();
|
||||
|
||||
::Session::list()->remove(session);
|
||||
Genode::Root_component<Session_component>::_destroy_session(session);
|
||||
|
||||
Genode::env()->ram_session()->free(tx_ds);
|
||||
}
|
||||
|
||||
public:
|
||||
@ -728,7 +813,10 @@ class Usb::Root : public Genode::Root_component<Session_component>
|
||||
Root(Server::Entrypoint &session_ep,
|
||||
Genode::Allocator *md_alloc)
|
||||
: Genode::Root_component<Session_component>(&session_ep.rpc_ep(), md_alloc),
|
||||
_ep(session_ep) { }
|
||||
_ep(session_ep)
|
||||
{
|
||||
Genode::config()->sigh(_config_dispatcher);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -753,14 +841,14 @@ int raw_notify(struct notifier_block *nb, unsigned long action, void *data)
|
||||
case USB_DEVICE_ADD:
|
||||
{
|
||||
::Session::list()->state_change(Usb::Session_component::DEVICE_ADD,
|
||||
new (env()->heap()) Device(udev));
|
||||
new (env()->heap()) Device(udev));
|
||||
break;
|
||||
}
|
||||
|
||||
case USB_DEVICE_REMOVE:
|
||||
{
|
||||
Device *dev = Device::device(udev->descriptor.idVendor,
|
||||
udev->descriptor.idProduct);
|
||||
Device *dev = Device::device_bus(udev->bus->busnum,
|
||||
udev->devnum);
|
||||
if (dev) {
|
||||
::Session::list()->state_change(Usb::Session_component::DEVICE_REMOVE, dev);
|
||||
destroy(env()->heap(), dev);
|
||||
|
@ -62,7 +62,7 @@ struct Usb::Pl2303_driver : Completion
|
||||
Server::Entrypoint &ep;
|
||||
Server::Signal_rpc_member<Pl2303_driver> dispatcher{ ep, *this, &Pl2303_driver::state_change };
|
||||
Genode::Allocator_avl alloc;
|
||||
Usb::Connection connection{ &alloc, VENDOR, PRODUCT, 512 * 1024, dispatcher };
|
||||
Usb::Connection connection{ &alloc, "usb_serial", 512 * 1024, dispatcher };
|
||||
Usb::Device device;
|
||||
Signal_context_capability connected_sigh;
|
||||
Signal_context_capability read_sigh;
|
||||
|
@ -87,10 +87,15 @@ class Usb::Session_client : public Genode::Rpc_client<Session>
|
||||
call<Rpc_ep_descr>(interface_num, alt_setting, endpoint_num, endpoint_descr);
|
||||
}
|
||||
|
||||
void claim_interface(unsigned interface_num)
|
||||
{
|
||||
call<Rpc_claim_interface>(interface_num);
|
||||
}
|
||||
void claim_interface(unsigned interface_num)
|
||||
{
|
||||
call<Rpc_claim_interface>(interface_num);
|
||||
}
|
||||
|
||||
void release_interface(unsigned interface_num)
|
||||
{
|
||||
call<Rpc_release_interface>(interface_num);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__USB_SESSION__CLIENT_H_ */
|
||||
|
@ -22,14 +22,17 @@ namespace Usb { struct Connection; }
|
||||
|
||||
struct Usb::Connection : Genode::Connection<Session>, Session_client
|
||||
{
|
||||
/**
|
||||
* Connect to a USB device.
|
||||
*/
|
||||
Connection(Genode::Range_allocator *tx_block_alloc,
|
||||
unsigned long vendor_id, unsigned long product_id,
|
||||
char const *label = "",
|
||||
Genode::size_t tx_buf_size = 512 * 1024,
|
||||
Genode::Signal_context_capability sigh_state_changed =
|
||||
Genode::Signal_context_capability())
|
||||
:
|
||||
Genode::Connection<Session>(session("ram_quota=%zd, tx_buf_size=%zd, vendor=%lu, product=%lu",
|
||||
3 * 4096 + tx_buf_size, tx_buf_size, vendor_id, product_id)),
|
||||
Genode::Connection<Session>(session("ram_quota=%zd, tx_buf_size=%zd, label=\"%s\"",
|
||||
3 * 4096 + tx_buf_size, tx_buf_size, label)),
|
||||
Session_client(cap(), tx_block_alloc, sigh_state_changed)
|
||||
{ }
|
||||
};
|
||||
|
@ -175,7 +175,12 @@ struct Usb::Session : public Genode::Session
|
||||
/**
|
||||
* Claim an interface number
|
||||
*/
|
||||
virtual void claim_interface(unsigned interface_num) = 0;
|
||||
virtual void claim_interface(unsigned interface_num) = 0;
|
||||
|
||||
/**
|
||||
* Release an interface number
|
||||
*/
|
||||
virtual void release_interface(unsigned interface_num) = 0;
|
||||
|
||||
GENODE_RPC(Rpc_plugged, bool, plugged);
|
||||
GENODE_RPC(Rpc_sigh_state_change, void, sigh_state_change, Signal_context_capability);
|
||||
@ -192,7 +197,8 @@ struct Usb::Session : public Genode::Session
|
||||
GENODE_RPC_THROW(Rpc_release_interface, void, release_interface, GENODE_TYPE_LIST(Interface_not_found),
|
||||
unsigned);
|
||||
GENODE_RPC_INTERFACE(Rpc_plugged, Rpc_sigh_state_change, Rpc_tx_cap, Rpc_config_descr,
|
||||
Rpc_iface_descr, Rpc_ep_descr, Rpc_alt_settings, Rpc_claim_interface);
|
||||
Rpc_iface_descr, Rpc_ep_descr, Rpc_alt_settings, Rpc_claim_interface,
|
||||
Rpc_release_interface);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__USB_SESSION__USB_SESSION_H_ */
|
||||
|
@ -51,7 +51,7 @@ namespace Usb_proxy_device_genode {
|
||||
|
||||
Data(unsigned int vendor_id, unsigned int product_id)
|
||||
: _alloc(Genode::env()->heap()),
|
||||
usb_connection(&_alloc, vendor_id, product_id)
|
||||
usb_connection(&_alloc)
|
||||
{
|
||||
/* wait until device and server are ready */
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user