diff --git a/packages/genodelabs/patches/usb.patch b/packages/genodelabs/patches/usb.patch new file mode 100644 index 0000000..4597947 --- /dev/null +++ b/packages/genodelabs/patches/usb.patch @@ -0,0 +1,193 @@ +From 5570eb3814bad4ef6ce33ddc42b74f9b9d22bdbc Mon Sep 17 00:00:00 2001 +From: Emery Hemingway +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 +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::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 _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 + 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 + 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("class", 0); + unsigned long vendor = policy.attribute_value("vendor_id", 0); + unsigned long product = policy.attribute_value("product_id", 0); + unsigned long bus = policy.attribute_value("bus", 0); + unsigned long dev = policy.attribute_value("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(4096, sizeof(Session_component)); + if (ram_quota < session_size) +@@ -1000,8 +1040,11 @@ class Usb::Root : public Genode::Root_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 +