2
0
Fork 0

WiP! patch usb configuration to suck less

This commit is contained in:
Ehmry - 2020-12-19 15:20:02 +01:00
parent 2d91f024a0
commit 28a4a17769
1 changed files with 193 additions and 0 deletions

View File

@ -0,0 +1,193 @@
From 5570eb3814bad4ef6ce33ddc42b74f9b9d22bdbc Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Sat, 19 Dec 2020 12:18:16 +0100
Subject: [PATCH 1/2] usb_block_drv: do not enable report by default,
diagnostics
---
repos/os/src/drivers/usb_block/main.cc | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/repos/os/src/drivers/usb_block/main.cc b/repos/os/src/drivers/usb_block/main.cc
index 578a5015e5..a244ddf0f5 100644
--- a/repos/os/src/drivers/usb_block/main.cc
+++ b/repos/os/src/drivers/usb_block/main.cc
@@ -110,12 +110,14 @@ struct Usb::Block_driver : Usb::Completion
log("Device plugged");
if (!initialize()) {
+ error("Initialization failed");
env.parent().exit(-1);
sleep_forever();
return;
}
/* all is well, announce the device */
+ log("Announce device");
Signal_transmitter(announce_sigh).submit();
}
@@ -795,9 +797,10 @@ struct Usb::Block_driver : Usb::Completion
device(&alloc, usb, ep), wake_up_handler(wake_up_handler)
{
parse_config(config.xml());
- reporter.enabled(true);
+ reporter.enabled(_report_device);
/* USB device gets initialized by handle_state_change() */
+ log("waiting for device to initialize…");
}
~Block_driver()
--
2.29.2
From a49df8eae1eda9f17640cfa7d11f23a53f45911b Mon Sep 17 00:00:00 2001
From: Emery Hemingway <ehmry@posteo.net>
Date: Sat, 19 Dec 2020 12:20:53 +0100
Subject: [PATCH 2/2] usb_drv: select raw session device by class
Select devices for raw Usb sessions by device class. This is for
simple scenarios where the number of attached USB devices is known
but not vendor and product identifiers or bus topology.
---
repos/dde_linux/src/drivers/usb/raw/raw.cc | 63 ++++++++++++++++++----
1 file changed, 53 insertions(+), 10 deletions(-)
diff --git a/repos/dde_linux/src/drivers/usb/raw/raw.cc b/repos/dde_linux/src/drivers/usb/raw/raw.cc
index efa86bf29b..88f2fd948c 100644
--- a/repos/dde_linux/src/drivers/usb/raw/raw.cc
+++ b/repos/dde_linux/src/drivers/usb/raw/raw.cc
@@ -55,6 +55,20 @@ struct Device : List<Device>::Element
return &_l;
}
+ static Device * device_class(uint8_t class_)
+ {
+ for (Device *d = list()->first(); d; d = d->next()) {
+ usb_interface *iface = d->interface(0);
+ if (!iface || !iface->cur_altsetting || !d->udev || !d->udev->bus)
+ continue;
+
+ if (iface->cur_altsetting->desc.bInterfaceClass == class_)
+ return d;
+ }
+
+ return nullptr;
+ }
+
static Device * device_product(uint16_t vendor, uint16_t product)
{
for (Device *d = list()->first(); d; d = d->next()) {
@@ -670,10 +684,6 @@ class Usb::Session_component : public Session_rpc_object,
private:
Genode::Entrypoint &_ep;
- unsigned long _vendor;
- unsigned long _product;
- long _bus = 0;
- long _dev = 0;
Device *_device = nullptr;
Signal_context_capability _sigh_state_change;
Io_signal_handler<Session_component> _packet_avail;
@@ -697,6 +707,11 @@ class Usb::Session_component : public Session_rpc_object,
public:
+ unsigned long _vendor;
+ unsigned long _product;
+ long _bus;
+ long _dev;
+
enum State {
DEVICE_ADD,
DEVICE_REMOVE,
@@ -705,22 +720,35 @@ class Usb::Session_component : public Session_rpc_object,
Session_component(Genode::Ram_dataspace_capability tx_ds,
Genode::Entrypoint &ep,
Genode::Region_map &rm,
+ unsigned long class_,
unsigned long vendor, unsigned long product,
- long bus, long dev, Usb::Cleaner &cleaner)
+ long bus, long dev,
+ Usb::Cleaner &cleaner)
: Session_rpc_object(tx_ds, ep.rpc_ep(), rm),
- _ep(ep), _vendor(vendor), _product(product), _bus(bus), _dev(dev),
+ _ep(ep),
_packet_avail(ep, *this, &Session_component::_receive),
_ready_ack(ep, *this, &Session_component::_receive),
- _worker(sink()), _tx_ds(tx_ds), _cleaner(cleaner)
+ _worker(sink()), _tx_ds(tx_ds), _cleaner(cleaner),
+ _vendor(vendor), _product(product), _bus(bus), _dev(dev)
{
Device *device;
if (bus && dev)
device = Device::device_bus(bus, dev);
- else
+ else if (_vendor || _product)
device = Device::device_product(_vendor, _product);
+ else if (class_)
+ device = Device::device_class(class_);
+ else
+ throw Service_denied();
+
if (device) {
state_change(DEVICE_ADD, device);
- }
+
+ _vendor = device->udev->descriptor.idVendor;
+ _product = device->udev->descriptor.idProduct;
+ _bus = device->udev->bus->busnum;
+ _dev = device->udev->devnum == dev;
+ } // else do nothing!?
/* register signal handlers */
_tx.sigh_packet_avail(_packet_avail);
@@ -973,6 +1001,11 @@ class Usb::Root : public Genode::Root_component<Session_component>
using namespace Genode;
using Genode::size_t;
+ bool diag = Arg_string::find_arg(args, "diag").bool_value(false);
+
+ if (diag)
+ log("request for ", args);
+
Session_label const label = label_from_args(args);
try {
Xml_node config_node = Lx_kit::env().config_rom().xml();
@@ -982,11 +1015,18 @@ class Usb::Root : public Genode::Root_component<Session_component>
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);
+ unsigned long class_ = policy.attribute_value<unsigned long>("class", 0);
unsigned long vendor = policy.attribute_value<unsigned long>("vendor_id", 0);
unsigned long product = policy.attribute_value<unsigned long>("product_id", 0);
unsigned long bus = policy.attribute_value<unsigned long>("bus", 0);
unsigned long dev = policy.attribute_value<unsigned long>("dev", 0);
+ if (!(class_ || (vendor && product) || (bus && dev))) {
+ error("policy lacks class, vendor/product, or bus/dev attributes");
+ error(policy);
+ throw Genode::Service_denied();
+ }
+
/* check session quota */
size_t session_size = max<size_t>(4096, sizeof(Session_component));
if (ram_quota < session_size)
@@ -1000,8 +1040,11 @@ class Usb::Root : public Genode::Root_component<Session_component>
Ram_dataspace_capability tx_ds = _env.ram().alloc(tx_buf_size);
Session_component *session = new (md_alloc())
- Session_component(tx_ds, _env.ep(), _env.rm(), vendor, product, bus, dev, _cleaner);
+ Session_component(
+ tx_ds, _env.ep(), _env.rm(), class_, vendor, product, bus, dev, _cleaner);
::Session::list()->insert(session);
+ if (diag)
+ log("serve device ", Hex(session->_vendor), ":", Hex(session->_product), " at ", Hex(session->_bus), ":", Hex(session->_dev), " to \"", label, "\"");
return session;
}
catch (Genode::Session_policy::No_policy_defined) {
--
2.29.2