[PATCH 10/27] hw/usb/dev-smartcard-reader: reset all I/O state on device reset
Marc-André Lureau <[email protected]> Wed, 05 Aug 2026 15:51:00 +0400
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
Clear bulk-in entries (len/pos), current_bulk_in pointer, bulk-out
position, error status, and protocol parameters during reset. Previously
only the bulk-in ring buffer indices and pending answers were cleared,
leaving stale state that could corrupt subsequent transfers.
Move ccid_reset() after its callees to avoid forward declarations.
Drop redundant initialization from realize() since it calls reset().
Fixes: 367071447ec5 ("usb-ccid: add CCID bus")
Signed-off-by: Marc-André Lureau <[email protected]>
---
hw/usb/dev-smartcard-reader.c | 60 +++++++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 28 deletions(-)
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index bed641be4512..12c82c8f6458 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -574,9 +574,16 @@ static void ccid_remove_pending_answer(USBCCIDState *s,
static void ccid_bulk_in_clear(USBCCIDState *s)
{
+ int i;
+
+ for (i = 0; i < BULK_IN_PENDING_NUM; i++) {
+ s->bulk_in_pending[i].len = 0;
+ s->bulk_in_pending[i].pos = 0;
+ }
s->bulk_in_pending_start = 0;
s->bulk_in_pending_end = 0;
s->bulk_in_pending_num = 0;
+ s->current_bulk_in = NULL;
}
static void ccid_bulk_in_release(USBCCIDState *s)
@@ -621,26 +628,6 @@ static void *ccid_reserve_recv_buf(USBCCIDState *s, uint16_t len)
return bulk_in->data;
}
-static void ccid_reset(USBCCIDState *s)
-{
- ccid_bulk_in_clear(s);
- ccid_clear_pending_answers(s);
-}
-
-static void ccid_detach(USBCCIDState *s)
-{
- ccid_reset(s);
-}
-
-static void ccid_handle_reset(USBDevice *dev)
-{
- USBCCIDState *s = USB_CCID_DEV(dev);
-
- DPRINTF(s, 1, "Reset\n");
-
- ccid_reset(s);
-}
-
static const char *ccid_control_to_str(USBCCIDState *s, int request)
{
switch (request) {
@@ -918,6 +905,31 @@ static void ccid_reset_parameters(USBCCIDState *s)
s->abProtocolDataStructure = defaultProtocolDataStructure;
}
+static void ccid_reset(USBCCIDState *s)
+{
+ ccid_bulk_in_clear(s);
+ ccid_clear_pending_answers(s);
+ s->bulk_out_pos = 0;
+ s->last_answer_error = 0;
+ s->notify_slot_change = false;
+ ccid_reset_error_status(s);
+ ccid_reset_parameters(s);
+}
+
+static void ccid_detach(USBCCIDState *s)
+{
+ ccid_reset(s);
+}
+
+static void ccid_handle_reset(USBDevice *dev)
+{
+ USBCCIDState *s = USB_CCID_DEV(dev);
+
+ DPRINTF(s, 1, "Reset\n");
+
+ ccid_reset(s);
+}
+
/* NOTE: only a single slot is supported (SLOT_0) */
static void ccid_on_slot_change(USBCCIDState *s, bool full)
{
@@ -1349,14 +1361,6 @@ static void ccid_realize(USBDevice *dev, Error **errp)
s->dev.speedmask = USB_SPEED_MASK_FULL;
s->notify_slot_change = false;
s->powered = true;
- s->pending_answers_num = 0;
- s->last_answer_error = 0;
- s->bulk_in_pending_start = 0;
- s->bulk_in_pending_end = 0;
- s->current_bulk_in = NULL;
- ccid_reset_error_status(s);
- s->bulk_out_pos = 0;
- ccid_reset_parameters(s);
ccid_reset(s);
s->debug = parse_debug_env("QEMU_CCID_DEBUG", D_VERBOSE, s->debug);
}
--
2.55.0