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 cc7b477c808cdb8876a2f8713693dc6f0a4ef60f 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 | 57 +++++++++++++++++++--- 1 file changed, 49 insertions(+), 8 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..1a94a72cfe 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,8 +720,10 @@ 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), _packet_avail(ep, *this, &Session_component::_receive), @@ -716,11 +733,20 @@ class Usb::Session_component : public Session_rpc_object, 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 +999,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 +1013,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 +1038,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