diff --git a/repos/dde_linux/src/drivers/usb_host/raw.cc b/repos/dde_linux/src/drivers/usb_host/raw.cc index b804e2bde0..9476809077 100644 --- a/repos/dde_linux/src/drivers/usb_host/raw.cc +++ b/repos/dde_linux/src/drivers/usb_host/raw.cc @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2014-2017 Genode Labs GmbH + * Copyright (C) 2014-2021 Genode Labs GmbH * * This file is distributed under the terms of the GNU General Public License * version 2. @@ -38,200 +38,69 @@ constexpr bool verbose_raw = false; namespace Usb { class Session_component; class Root; - class Worker; class Cleaner; } /** * Keep track of all registered USB devices (via raw driver) */ -struct Device : List::Element +class Device : public List::Element { - usb_device *udev; + using Tx = Usb::Session_rpc_object::Tx; + using Packet_descriptor = Usb::Packet_descriptor; - static List *list() - { - static List _l; - return &_l; - } - - static Device * device_by_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) - return d; - } - - return nullptr; - } - - - static Device * device_by_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 Device * device_by_class(long class_value, Session_label label) - { - for (Device *d = list()->first(); d; d = d->next()) { - if (class_value == d->device_class_value() && label == d->label()) - return d; - } - - return nullptr; - } - - static void report_device_list(); - - Device(usb_device *udev) : udev(udev) - { - list()->insert(this); - report_device_list(); - } - - ~Device() - { - list()->remove(this); - report_device_list(); - } - - usb_interface *interface(unsigned index) - { - if (!udev || !udev->actconfig) - return nullptr; - - if (index >= udev->actconfig->desc.bNumInterfaces) - return nullptr; - - usb_interface *iface = udev->actconfig->interface[index]; - return iface; - } - - template - void _with_interface(unsigned index, FN const &fn) - { - if (!udev || !udev->actconfig) - return; - - if (index >= udev->actconfig->desc.bNumInterfaces) - return; - - usb_interface * const interface_ptr = udev->actconfig->interface[index]; - - if (!interface_ptr) - return; - - fn(*interface_ptr); - } - - template - void _for_each_interface(FN const &fn) - { - if (!udev || !udev->actconfig) - return; - - for (unsigned i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) - _with_interface(i, fn); - } - - /** - * Return pseudo device class of USB device - * - * The returned value expresses the type of USB device. If the device - * has at least one HID interface, the value is USB_CLASS_HID. Otherwise, - * the class of the first interface is interpreted at type the device. - * - * Note this classification of USB devices is meant as an interim solution - * only to assist the implementation of access-control policies. - */ - unsigned device_class_value() - { - unsigned result = 0; - - _with_interface(0, [&] (usb_interface &interface) { - if (interface.cur_altsetting) - result = interface.cur_altsetting->desc.bInterfaceClass; }); - - _for_each_interface([&] (usb_interface &interface) { - if (interface.cur_altsetting) - if (interface.cur_altsetting->desc.bInterfaceClass == USB_CLASS_HID) - result = USB_CLASS_HID; }); - - return result; - } - - void report(Xml_generator &xml) - { - if (!udev || !udev->actconfig) - return; - - using namespace Genode; - - using Value = String<64>; - - xml.attribute("label", label()); - xml.attribute("vendor_id", Value(Hex(udev->descriptor.idVendor))); - xml.attribute("product_id", Value(Hex(udev->descriptor.idProduct))); - xml.attribute("bus", Value(Hex(udev->bus->busnum))); - xml.attribute("dev", Value(Hex(udev->devnum))); - xml.attribute("class", Value(Hex(device_class_value()))); - - _for_each_interface([&] (usb_interface &interface) { - - if (!interface.cur_altsetting) - return; - - xml.node("interface", [&] () { - - uint8_t const class_value = - interface.cur_altsetting->desc.bInterfaceClass; - - xml.attribute("class", Value(Hex(class_value))); - }); - }); - } - - usb_host_endpoint *endpoint(usb_interface *iface, unsigned alt_setting, - unsigned endpoint_num) - { - return &iface->altsetting[alt_setting].endpoint[endpoint_num]; - } - - Session_label label() - { - if (!udev || !udev->bus) - return Session_label("usb-unknown"); - return Session_label("usb-", udev->bus->busnum, "-", udev->devnum); - } -}; - - -/** - * Handle packet stream request, this way the entrypoint always returns to it's - * server loop - */ -class Usb::Worker : public Genode::Weak_object -{ private: - completion _packet_avail; + usb_device &_udev; + Lx::Task _task { _run, this, "device_worker", + Lx::Task::PRIORITY_2, + Lx::scheduler() }; + completion _packet_avail; + Tx::Sink *_sink { nullptr }; - Session::Tx::Sink *_sink; - Device *_device = nullptr; Signal_context_capability _sigh_ready; - Lx::Task *_task = nullptr; - unsigned _p_in_flight = 0; - bool _device_ready = false; + unsigned _p_in_flight { 0 }; - void _ack_packet(Packet_descriptor &p) + template + void _with_packet_stream(FN const &fn) { - _sink->acknowledge_packet(p); - _p_in_flight--; + if (_sink == nullptr) return; + fn(*_sink); + } + + template + void _with_interface(unsigned index, FN const &fn) + { + if (!_udev.actconfig) + return; + + if (index >= _udev.actconfig->desc.bNumInterfaces) + return; + + usb_interface * const interface_ptr = _udev.actconfig->interface[index]; + + if (!interface_ptr) + return; + + fn(*interface_ptr); + } + + template + void _for_each_interface(FN const &fn) + { + if (!_udev.actconfig) + return; + + for (unsigned i = 0; i < _udev.actconfig->desc.bNumInterfaces; i++) + _with_interface(i, fn); + } + + void _ack_packet(Packet_descriptor p) + { + _with_packet_stream([&](Tx::Sink &sink) { + sink.acknowledge_packet(p); + _p_in_flight--; + }); } /** @@ -242,7 +111,7 @@ class Usb::Worker : public Genode::Weak_object char *buffer = _sink->packet_content(p); int length; - if ((length = usb_string(_device->udev, p.string.index, buffer, p.size())) < 0) { + if ((length = usb_string(&_udev, p.string.index, buffer, p.size())) < 0) { warning("Could not read string descriptor index: ", (unsigned)p.string.index); p.string.length = 0; } else { @@ -259,13 +128,16 @@ class Usb::Worker : public Genode::Weak_object { void *buf = kmalloc(4096, GFP_NOIO); - int err = usb_control_msg(_device->udev, usb_rcvctrlpipe(_device->udev, 0), + int err = usb_control_msg(&_udev, usb_rcvctrlpipe(&_udev, 0), p.control.request, p.control.request_type, p.control.value, p.control.index, buf, p.size(), p.control.timeout); - if (err > 0 && p.size()) - Genode::memcpy(_sink->packet_content(p), buf, err); + if (err > 0 && p.size()) { + _with_packet_stream([&](Tx::Sink &sink) { + Genode::memcpy(sink.packet_content(p), buf, err); + }); + } kfree(buf); @@ -302,7 +174,7 @@ class Usb::Worker : public Genode::Weak_object if (p.size()) Genode::memcpy(buf, _sink->packet_content(p), p.size()); - int err = usb_control_msg(_device->udev, usb_sndctrlpipe(_device->udev, 0), + int err = usb_control_msg(&_udev, usb_sndctrlpipe(&_udev, 0), p.control.request, p.control.request_type, p.control.value, p.control.index, buf, p.size(), p.control.timeout); @@ -313,7 +185,7 @@ class Usb::Worker : public Genode::Weak_object if (p.control.request == USB_REQ_CLEAR_FEATURE && p.control.value == USB_ENDPOINT_HALT) { - usb_reset_endpoint(_device->udev, p.control.index); + usb_reset_endpoint(&_udev, p.control.index); } } else { p.control.actual_size = 0; @@ -342,24 +214,23 @@ class Usb::Worker : public Genode::Weak_object */ struct Complete_data { - Weak_ptr worker; + Device *device; Packet_descriptor packet; - Complete_data(Weak_ptr &w, Packet_descriptor &p) - : worker(w), packet(p) { } + Complete_data(Device *device, Packet_descriptor &p) + : device(device), packet(p) { } }; Complete_data * alloc_complete_data(Packet_descriptor &p) { void * data = kmalloc(sizeof(Complete_data), GFP_KERNEL); - construct_at(data, this->weak_ptr(), p); + construct_at(data, this, p); return reinterpret_cast(data); } static void free_complete_data(Complete_data *data) { data->packet.~Packet_descriptor(); - data->worker.~Weak_ptr(); kfree (data); } @@ -380,8 +251,10 @@ class Usb::Worker : public Genode::Weak_object * controller used the offsets into the original buffer to * store the data. */ - Genode::memcpy(_sink->packet_content(p), urb->transfer_buffer, - urb->transfer_buffer_length); + _with_packet_stream([&](Tx::Sink &sink) { + Genode::memcpy(sink.packet_content(p), urb->transfer_buffer, + urb->transfer_buffer_length); + }); } } else if (urb->status == -ESHUTDOWN) { p.error = Packet_descriptor::NO_DEVICE_ERROR; @@ -401,13 +274,8 @@ class Usb::Worker : public Genode::Weak_object { Complete_data *data = (Complete_data *)urb->context; - { - Locked_ptr worker(data->worker); - - if (worker.valid()) - worker->_async_finish(data->packet, urb, - !!(data->packet.transfer.ep & USB_DIR_IN)); - } + data->device->_async_finish(data->packet, urb, + !!(data->packet.transfer.ep & USB_DIR_IN)); free_complete_data(data); dma_free(urb->transfer_buffer); @@ -423,9 +291,9 @@ class Usb::Worker : public Genode::Weak_object void *buf = dma_malloc(p.size()); if (read) - pipe = usb_rcvbulkpipe(_device->udev, p.transfer.ep); + pipe = usb_rcvbulkpipe(&_udev, p.transfer.ep); else { - pipe = usb_sndbulkpipe(_device->udev, p.transfer.ep); + pipe = usb_sndbulkpipe(&_udev, p.transfer.ep); Genode::memcpy(buf, _sink->packet_content(p), p.size()); } @@ -433,13 +301,13 @@ class Usb::Worker : public Genode::Weak_object if (!bulk_urb) { error("Failed to allocate bulk URB"); dma_free(buf); - p.error = Usb::Packet_descriptor::MEMORY_ERROR; + p.error = Packet_descriptor::MEMORY_ERROR; return false; } Complete_data *data = alloc_complete_data(p); - usb_fill_bulk_urb(bulk_urb, _device->udev, pipe, buf, p.size(), + usb_fill_bulk_urb(bulk_urb, &_udev, pipe, buf, p.size(), _async_complete, data); int ret = usb_submit_urb(bulk_urb, GFP_KERNEL); @@ -471,9 +339,9 @@ class Usb::Worker : public Genode::Weak_object void *buf = dma_malloc(p.size()); if (read) - pipe = usb_rcvintpipe(_device->udev, p.transfer.ep); + pipe = usb_rcvintpipe(&_udev, p.transfer.ep); else { - pipe = usb_sndintpipe(_device->udev, p.transfer.ep); + pipe = usb_sndintpipe(&_udev, p.transfer.ep); Genode::memcpy(buf, _sink->packet_content(p), p.size()); } @@ -491,8 +359,8 @@ class Usb::Worker : public Genode::Weak_object if (p.transfer.polling_interval == Usb::Packet_descriptor::DEFAULT_POLLING_INTERVAL) { - usb_host_endpoint *ep = read ? _device->udev->ep_in[p.transfer.ep & 0x0f] - : _device->udev->ep_out[p.transfer.ep & 0x0f]; + usb_host_endpoint *ep = read ? _udev.ep_in[p.transfer.ep & 0x0f] + : _udev.ep_out[p.transfer.ep & 0x0f]; if (!ep) { error("could not get ep: ", p.transfer.ep); @@ -506,7 +374,7 @@ class Usb::Worker : public Genode::Weak_object } else polling_interval = p.transfer.polling_interval; - usb_fill_int_urb(irq_urb, _device->udev, pipe, buf, p.size(), + usb_fill_int_urb(irq_urb, &_udev, pipe, buf, p.size(), _async_complete, data, polling_interval); int ret = usb_submit_urb(irq_urb, GFP_KERNEL); @@ -551,12 +419,12 @@ class Usb::Worker : public Genode::Weak_object void *buf = dma_malloc(p.size()); if (read) { - pipe = usb_rcvisocpipe(_device->udev, p.transfer.ep); - ep = _device->udev->ep_in[p.transfer.ep & 0x0f]; + pipe = usb_rcvisocpipe(&_udev, p.transfer.ep); + ep = _udev.ep_in[p.transfer.ep & 0x0f]; } else { - pipe = usb_sndisocpipe(_device->udev, p.transfer.ep); - ep = _device->udev->ep_out[p.transfer.ep & 0x0f]; + pipe = usb_sndisocpipe(&_udev, p.transfer.ep); + ep = _udev.ep_out[p.transfer.ep & 0x0f]; Genode::memcpy(buf, _sink->packet_content(p), p.size()); } @@ -576,7 +444,7 @@ class Usb::Worker : public Genode::Weak_object } Complete_data *data = alloc_complete_data(p); - urb->dev = _device->udev; + urb->dev = &_udev; urb->pipe = pipe; urb->start_frame = -1; urb->stream_id = 0; @@ -619,8 +487,10 @@ class Usb::Worker : public Genode::Weak_object */ void _alt_setting(Packet_descriptor &p) { - int err = usb_set_interface(_device->udev, p.interface.number, + + int err = usb_set_interface(&_udev, p.interface.number, p.interface.alt_setting); + if (!err) p.succeded = true; else @@ -632,7 +502,7 @@ class Usb::Worker : public Genode::Weak_object */ void _config(Packet_descriptor &p) { - usb_host_config *config = _device->udev->actconfig; + usb_host_config *config = _udev.actconfig; if (config) { for (unsigned i = 0; i < config->desc.bNumInterfaces; i++) { @@ -643,7 +513,7 @@ class Usb::Worker : public Genode::Weak_object } } - int err = usb_set_configuration(_device->udev, p.number); + int err = usb_set_configuration(&_udev, p.number); if (!err) p.succeded = true; @@ -656,7 +526,7 @@ class Usb::Worker : public Genode::Weak_object */ void _release_interface(Packet_descriptor &p) { - usb_interface *iface = _device->interface(p.number); + usb_interface *iface = interface(p.number); if (!iface) return; @@ -670,12 +540,11 @@ class Usb::Worker : public Genode::Weak_object */ void _dispatch() { - /* - * Get packets until there are no more free ack slots or avaiable - * packets - */ - while (_p_in_flight < _sink->ack_slots_free() && _sink->packet_avail()) - { + /* + * Get packets until there are no more free ack slots or avaiable + * packets + */ + while (_sink && _p_in_flight < _sink->ack_slots_free() && _sink->packet_avail()) { Packet_descriptor p = _sink->get_packet(); if (verbose_raw) @@ -683,13 +552,6 @@ class Usb::Worker : public Genode::Weak_object _p_in_flight++; - if (!_device || !_device->udev || - _device->udev->state == USB_STATE_NOTATTACHED) { - p.error = Packet_descriptor::NO_DEVICE_ERROR; - _ack_packet(p); - continue; - } - if (!_sink->packet_valid(p)) { p.error = Packet_descriptor::PACKET_INVALID_ERROR; _ack_packet(p); @@ -741,18 +603,6 @@ class Usb::Worker : public Genode::Weak_object } } - void _wait_for_device() - { - wait_queue_head_t wait; - _wait_event(wait, _device); - _wait_event(wait, _device->udev->actconfig); - - if (_sigh_ready.valid()) - Signal_transmitter(_sigh_ready).submit(1); - - _device_ready = true; - } - /** * Wait for packets */ @@ -760,7 +610,11 @@ class Usb::Worker : public Genode::Weak_object { /* wait for device to become ready */ init_completion(&_packet_avail); - _wait_for_device(); + wait_queue_head_t wait; + _wait_event(wait, ready()); + + if (_sigh_ready.valid()) + Signal_transmitter(_sigh_ready).submit(); while (true) { wait_for_completion(&_packet_avail); @@ -768,53 +622,183 @@ class Usb::Worker : public Genode::Weak_object } } + static void _run(void *data) + { + Device *device = static_cast(data); + device->_wait(); + } + public: - static void run(void *worker) + Device(usb_device &udev) : _udev(udev) { - Worker *w = static_cast(worker); - w->_wait(); + list()->insert(this); + + if (!Lx::scheduler().active()) { + Lx::scheduler().schedule(); } + + report_device_list(); } - Worker(Session::Tx::Sink *sink) - : _sink(sink) - { } - - ~Worker() + ~Device() { - Weak_object::lock_for_destruction(); - } - - void start() - { - if (!_task) { - _task = new (Lx::Malloc::mem()) Lx::Task(run, this, "raw_worker", - Lx::Task::PRIORITY_2, - Lx::scheduler()); - if (!Lx::scheduler().active()) { - Lx::scheduler().schedule(); - } - } - } - - void stop() - { - if (_task) { - Lx::scheduler().remove(_task); - destroy(Lx::Malloc::mem(), _task); - _task = nullptr; - } + Lx::scheduler().remove(&_task); + list()->remove(this); + report_device_list(); } void packet_avail() { ::complete(&_packet_avail); } - void device(Device *device, Signal_context_capability sigh_ready = Signal_context_capability()) + unsigned num_interfaces() const { - _device = device; - _sigh_ready = sigh_ready; + if (ready()) + return _udev.actconfig->desc.bNumInterfaces; + + return 0; } - bool device_ready() { return _device_ready; } + void packet_stream(Tx::Sink *sink) + { + _sink = sink; + _p_in_flight = 0; + + if (!_sink) { + _sigh_ready = Signal_context_capability { }; + } + } + + bool ready() const { return _udev.actconfig; } + + void sigh_ready(Signal_context_capability sigh_ready) + { + _sigh_ready = sigh_ready; + } + + static List *list() + { + static List _l; + return &_l; + } + + static Device * device_by_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) + return d; + } + + return nullptr; + } + + static Device * device_by_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 Device * device_by_class(long class_value, Session_label label) + { + for (Device *d = list()->first(); d; d = d->next()) { + if (class_value == d->device_class_value() && label == d->label()) + return d; + } + + return nullptr; + } + + static void report_device_list(); + + + usb_interface *interface(unsigned index) + { + if (!_udev.actconfig) + return nullptr; + + if (index >= _udev.actconfig->desc.bNumInterfaces) + return nullptr; + + usb_interface *iface = _udev.actconfig->interface[index]; + return iface; + } + + + /** + * Return pseudo device class of USB device + * + * The returned value expresses the type of USB device. If the device + * has at least one HID interface, the value is USB_CLASS_HID. Otherwise, + * the class of the first interface is interpreted at type the device. + * + * Note this classification of USB devices is meant as an interim solution + * only to assist the implementation of access-control policies. + */ + unsigned device_class_value() + { + unsigned result = 0; + + _with_interface(0, [&] (usb_interface &interface) { + if (interface.cur_altsetting) + result = interface.cur_altsetting->desc.bInterfaceClass; }); + + _for_each_interface([&] (usb_interface &interface) { + if (interface.cur_altsetting) + if (interface.cur_altsetting->desc.bInterfaceClass == USB_CLASS_HID) + result = USB_CLASS_HID; }); + + return result; + } + + long bus() const { return _udev.bus->busnum; } + long dev() const { return _udev.devnum; } + + usb_device &udev() const { return _udev; } + + void report(Xml_generator &xml) + { + if (!_udev.actconfig) + return; + + using namespace Genode; + using Value = String<64>; + + xml.attribute("label", label()); + xml.attribute("vendor_id", Value(Hex(_udev.descriptor.idVendor))); + xml.attribute("product_id", Value(Hex(_udev.descriptor.idProduct))); + xml.attribute("bus", Value(Hex(_udev.bus->busnum))); + xml.attribute("dev", Value(Hex(_udev.devnum))); + xml.attribute("class", Value(Hex(device_class_value()))); + + _for_each_interface([&] (usb_interface &interface) { + + if (!interface.cur_altsetting) + return; + + xml.node("interface", [&] () { + + uint8_t const class_value = + interface.cur_altsetting->desc.bInterfaceClass; + + xml.attribute("class", Value(Hex(class_value))); + }); + }); + } + + usb_host_endpoint *endpoint(usb_interface *iface, unsigned alt_setting, + unsigned endpoint_num) + { + return &iface->altsetting[alt_setting].endpoint[endpoint_num]; + } + + Session_label label() + { + if (!_udev.bus) + return Session_label("usb-unknown"); + return Session_label("usb-", _udev.bus->busnum, "-", _udev.devnum); + } }; @@ -858,7 +842,9 @@ class Usb::Cleaner : List<::Interface> ::Interface *interface = new(Lx::Malloc::mem()) ::Interface(iface); insert(interface); _task.unblock(); - Lx::scheduler().schedule(); + + if (!Lx::scheduler().active()) + Lx::scheduler().schedule(); } }; @@ -883,7 +869,6 @@ class Usb::Session_component : public Session_rpc_object, Signal_context_capability _sigh_state_change; Io_signal_handler _packet_avail; Io_signal_handler _ready_ack; - Worker _worker; Ram_dataspace_capability _tx_ds; Usb::Cleaner &_cleaner; @@ -896,8 +881,12 @@ class Usb::Session_component : public Session_rpc_object, void _receive() { - _worker.packet_avail(); - Lx::scheduler().schedule(); + if (!_device) return; + + if (!Lx::scheduler().active()) { + _device->packet_avail(); + Lx::scheduler().schedule(); + } } public: @@ -919,7 +908,7 @@ class Usb::Session_component : public Session_rpc_object, _bus(bus), _dev(dev), _class(class_), _packet_avail(ep, *this, &Session_component::_receive), _ready_ack(ep, *this, &Session_component::_receive), - _worker(sink()), _tx_ds(tx_ds), _cleaner(cleaner) + _tx_ds(tx_ds), _cleaner(cleaner) { Device *device_ptr; if (bus && dev) { @@ -930,8 +919,10 @@ class Usb::Session_component : public Session_rpc_object, device_ptr = Device::device_by_class(_class, _label); } - if (device_ptr) + if (device_ptr) { + device_ptr->packet_stream(sink()); state_change(DEVICE_ADD, device_ptr); + } /* register signal handlers */ _tx.sigh_packet_avail(_packet_avail); @@ -940,13 +931,12 @@ class Usb::Session_component : public Session_rpc_object, ~Session_component() { /* release claimed interfaces */ - if (_device && _device->udev && _device->udev->actconfig) { - unsigned const num = _device->udev->actconfig->desc.bNumInterfaces; - for (unsigned i = 0; i < num; i++) + if (_device && _device->ready()) + for (unsigned i = 0; i < _device->num_interfaces() ; i++) release_interface(i); - } - _worker.stop(); + if (_device) + _device->packet_stream(nullptr); } /*********************** @@ -960,7 +950,7 @@ class Usb::Session_component : public Session_rpc_object, if (!_device) throw Device_not_found(); - usb_interface *iface = _device->interface(interface_num); + usb_interface *iface = _device->interface(interface_num); if (!iface) throw Interface_not_found(); @@ -986,15 +976,15 @@ class Usb::Session_component : public Session_rpc_object, if (!_device) throw Device_not_found(); - Genode::memcpy(device_descr, &_device->udev->descriptor, sizeof(usb_device_descriptor)); + Genode::memcpy(device_descr, &_device->udev().descriptor, sizeof(usb_device_descriptor)); - if (_device->udev->actconfig) - Genode::memcpy(config_descr, &_device->udev->actconfig->desc, sizeof(usb_config_descriptor)); + if (_device->udev().actconfig) + Genode::memcpy(config_descr, &_device->udev().actconfig->desc, sizeof(usb_config_descriptor)); else Genode::memset(config_descr, 0, sizeof(usb_config_descriptor)); - device_descr->num = _device->udev->devnum; - device_descr->speed = _device->udev->speed; + device_descr->num = _device->udev().devnum; + device_descr->speed = _device->udev().speed; } unsigned alt_settings(unsigned index) override @@ -1054,10 +1044,10 @@ class Usb::Session_component : public Session_rpc_object, unsigned endpoint_num, Endpoint_descriptor *endpoint_descr) override { - if (!_device || !_device->udev) + if (!_device) throw Device_not_found(); - usb_interface *iface = usb_ifnum_to_if(_device->udev, interface_num); + usb_interface *iface = usb_ifnum_to_if(&_device->udev(), interface_num); if (!iface) throw Interface_not_found(); @@ -1071,12 +1061,12 @@ class Usb::Session_component : public Session_rpc_object, bool session_device(Device *device) { - usb_device_descriptor *descr = &device->udev->descriptor; + usb_device_descriptor *descr = &device->udev().descriptor; usb_interface *iface = device->interface(0); return (descr->idVendor == _vendor && descr->idProduct == _product) - || (_bus && _dev && _bus == device->udev->bus->busnum && - _dev == device->udev->devnum) + || (_bus && _dev && _bus == device->bus() && + _dev == device->dev()) || (iface && iface->cur_altsetting && _class == device->device_class_value() && _label == device->label())? true : false; @@ -1091,20 +1081,20 @@ class Usb::Session_component : public Session_rpc_object, if (_device) warning("Device type already present (vendor: ", - Hex(device->udev->descriptor.idVendor), - " product: ", Hex(device->udev->descriptor.idProduct), + Hex(device->udev().descriptor.idVendor), + " product: ", Hex(device->udev().descriptor.idProduct), ") Overwrite!"); _device = device; - _worker.device(_device, _sigh_state_change); - _worker.start(); + _device->packet_stream(sink()); + _device->sigh_ready(_sigh_state_change); return true; case DEVICE_REMOVE: if (!session_device(device)) return false; + _device = nullptr; - _worker.stop(); _signal_state_change(); return true; } @@ -1116,8 +1106,8 @@ class Usb::Session_component : public Session_rpc_object, { _sigh_state_change = sigh; - if (_worker.device_ready()) - Signal_transmitter(_sigh_state_change).submit(1); + if (_device && _device->ready()) + Signal_transmitter(_sigh_state_change).submit(); } Ram_dataspace_capability tx_ds() { return _tx_ds; } @@ -1278,7 +1268,7 @@ void Device::report_device_list() for (Device *d = list()->first(); d; d = d->next()) { - if (!d->udev || !d->udev->bus) { + if (!d->udev().bus) { Genode::warning("device ", d->label().string(), " state incomplete"); continue; } @@ -1301,13 +1291,12 @@ int raw_notify(struct notifier_block *nb, unsigned long action, void *data) " vendor: ", Hex(udev->descriptor.idVendor), " product: ", Hex(udev->descriptor.idProduct)); - switch (action) { case USB_DEVICE_ADD: { ::Session::list()->state_change(Usb::Session_component::DEVICE_ADD, - new (Lx::Malloc::mem()) Device(udev)); + new (Lx::Malloc::mem()) Device(*udev)); break; }