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
This commit is contained in:
Sebastian Sumpf 2021-05-20 18:57:58 +02:00 committed by Christian Helmuth
parent 6910b880e7
commit 7fcf9053b9
2 changed files with 13 additions and 4 deletions

View File

@ -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; });

View File

@ -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<Sync_ctrl_urb>(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;