From 7fcf9053b910cbd1d41fa96d5942120de3e80c04 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Thu, 20 May 2021 18:57:58 +0200 Subject: [PATCH] usb_hid: perform device destruction on unplug signal only - Do not perform desctruction on report updatea in EP because 'unregister_device' may block on Led state 'update' (synchronous control message) leading to the driver being stuck because no more signals are received - Check if device is present in 'submit_urb' calls fixes #4166 --- repos/dde_linux/src/drivers/usb_hid/main.cc | 7 +++---- repos/dde_linux/src/include/lx_emul/impl/usb.h | 10 ++++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/repos/dde_linux/src/drivers/usb_hid/main.cc b/repos/dde_linux/src/drivers/usb_hid/main.cc index 498f351c57..a0670670d0 100644 --- a/repos/dde_linux/src/drivers/usb_hid/main.cc +++ b/repos/dde_linux/src/drivers/usb_hid/main.cc @@ -160,8 +160,6 @@ Driver::Device::~Device() bool Driver::Device::deinit() { - if (udev) unregister_device(); - return !udev && !state_task.handling_signal && !urb_task.handling_signal; } @@ -224,8 +222,9 @@ void Driver::scan_report() if (!report_rom.constructed()) { report_rom.construct(env, "report"); report_rom->sigh(main_task->handler); - } else - report_rom->update(); + } + + report_rom->update(); devices.for_each([&] (Device & d) { d.updated = false; }); diff --git a/repos/dde_linux/src/include/lx_emul/impl/usb.h b/repos/dde_linux/src/include/lx_emul/impl/usb.h index b6f4c2e78d..7183651912 100644 --- a/repos/dde_linux/src/include/lx_emul/impl/usb.h +++ b/repos/dde_linux/src/include/lx_emul/impl/usb.h @@ -44,6 +44,13 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, usb_fill_control_urb(u, dev, pipe, (unsigned char *)dr, data, size, nullptr, nullptr); + if (!dev->bus || !dev->bus->controller) { + kfree(scu); + usb_free_urb(u); + kfree(dr); + return -ENODEV; + } + Genode::construct_at(scu, *(Usb::Connection*)(dev->bus->controller), *u); scu->send(timeout); @@ -76,6 +83,9 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) int usb_submit_urb(struct urb *urb, gfp_t mem_flags) { + if (!urb->dev->bus || !urb->dev->bus->controller) + return -ENODEV; + Urb * u = (Urb *)kzalloc(sizeof(Urb), mem_flags); if (!u) return 1;