qemu-usb: reread settings on configuration profile

changes. The alternative settings get reread on all interfaces as done before
"qemu-usb: fix device endpoint update" commit by introducing specific
reset_alt_settings function. The fallthrough case was intentionally before
the "qemu-usb: fix device endpoint update" case, which now is wrong.

Issue #4596
This commit is contained in:
Alexander Boettcher 2022-08-30 11:26:16 +02:00 committed by Christian Helmuth
parent adc4d47251
commit b888c95024
2 changed files with 35 additions and 1 deletions

View File

@ -28,7 +28,8 @@ static bool const verbose_warnings = false;
Mutex _mutex;
static void update_ep(USBDevice *, uint8_t, uint8_t);
static bool claim_interfaces(USBDevice *dev);
static bool claim_interfaces(USBDevice *);
static void reset_alt_settings(USBDevice *);
using Packet_alloc_failed = Usb::Session::Tx::Source::Packet_alloc_failed;
using Packet_type = Usb::Packet_descriptor::Type;
@ -182,8 +183,15 @@ struct Completion : Usb::Completion
case Packet_type::CONFIG:
if (!claim_interfaces(dev))
p->status = USB_RET_IOERROR;
else
reset_alt_settings(dev);
usb_generic_async_ctrl_complete(dev, p);
break;
case Packet_type::ALT_SETTING:
update_ep(dev, packet.interface.number, packet.interface.alt_setting);
usb_generic_async_ctrl_complete(dev, p);
break;
case Packet_type::CTRL:
usb_generic_async_ctrl_complete(dev, p);
break;
@ -664,6 +672,22 @@ struct Usb_host_device : List<Usb_host_device>::Element
}
}
void reset_alt_settings(USBDevice *udev)
{
/* retrieve device speed */
Usb::Config_descriptor cdescr;
Usb::Device_descriptor ddescr;
try { usb_raw.config_descriptor(&ddescr, &cdescr); }
catch (Usb::Session::Device_not_found) { return; }
for (unsigned i = 0; i < cdescr.num_interfaces; i++) {
udev->altsetting[i] = usb_raw.alt_settings(i);
}
}
void update_ep(USBDevice *udev)
{
usb_ep_reset(udev);
@ -709,6 +733,15 @@ struct Usb_host_device : List<Usb_host_device>::Element
OBJECT_CHECK(USBHostDevice, (obj), TYPE_USB_HOST_DEVICE)
static void reset_alt_settings(USBDevice *udev)
{
USBHostDevice *d = USB_HOST_DEVICE(udev);
Usb_host_device *dev = (Usb_host_device *)d->data;
dev->reset_alt_settings(udev);
}
static void update_ep(USBDevice *udev, uint8_t interface, uint8_t altsetting)
{
USBHostDevice *d = USB_HOST_DEVICE(udev);

View File

@ -297,6 +297,7 @@ struct Object_pool
for (unsigned i = USB_FIRST_FREE; i < MAX; i++) {
if (used[i] == false) {
used[i] = true;
memset(&obj[i], 0, sizeof(obj[i]));
return &obj[i];
}
}