[PATCH 15/27] hw/usb/dev-smartcard-reader: drop current_bulk_in pointer

Marc-AndrĂ© Lureau <[email protected]> Wed, 05 Aug 2026 15:51:05 +0400
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
Replace the eagerly-dequeued current_bulk_in pointer with a
ccid_bulk_in_peek() that returns the head of the ring without advancing
it. The element now stays at bulk_in_pending[start] while being
partially consumed, and start is advanced together with the num
decrement in ccid_bulk_in_release().

This removes a field from USBCCIDState and simplifies the bulk-in ring
buffer lifecycle from three states (queued, grabbed, released) down to
two (queued, released).

Note that this changes the semantic of bulk_in_pending_start in the
migration stream too. But since migration with pending current_bulk_in
was broken, this doesn't make further damages.

Signed-off-by: Marc-AndrĂ© Lureau <[email protected]>
---
 hw/usb/dev-smartcard-reader.c | 42 +++++++++++++++++++++---------------------
 1 file changed, 21 insertions(+), 21 deletions(-)

diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
index 699e236f624e..3f128791f3ef 100644
--- a/hw/usb/dev-smartcard-reader.c
+++ b/hw/usb/dev-smartcard-reader.c
@@ -296,7 +296,6 @@ struct USBCCIDState {
     uint32_t bulk_in_pending_start;
     uint32_t bulk_in_pending_end; /* first free */
     uint32_t bulk_in_pending_num;
-    BulkIn *current_bulk_in;
     uint8_t  bulk_out_data[BULK_OUT_DATA_SIZE];
     uint32_t bulk_out_pos;
     uint64_t last_answer_error;
@@ -583,24 +582,27 @@ static void ccid_bulk_in_clear(USBCCIDState *s)
     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)
 {
-    assert(s->current_bulk_in != NULL);
-    s->current_bulk_in->pos = 0;
-    s->current_bulk_in = NULL;
+    BulkIn *bulk_in;
+
+    assert(s->bulk_in_pending_num > 0);
+    bulk_in =
+        &s->bulk_in_pending[s->bulk_in_pending_start % BULK_IN_PENDING_NUM];
+    bulk_in->pos = 0;
+    s->bulk_in_pending_start++;
     s->bulk_in_pending_num--;
 }
 
-static void ccid_bulk_in_get(USBCCIDState *s)
+static BulkIn *ccid_bulk_in_peek(USBCCIDState *s)
 {
-    if (s->current_bulk_in != NULL || s->bulk_in_pending_num == 0) {
-        return;
+    if (s->bulk_in_pending_num == 0) {
+        return NULL;
     }
-    s->current_bulk_in =
-        &s->bulk_in_pending[(s->bulk_in_pending_start++) % BULK_IN_PENDING_NUM];
+    return &s->bulk_in_pending[
+        s->bulk_in_pending_start % BULK_IN_PENDING_NUM];
 }
 
 static void *ccid_reserve_recv_buf(USBCCIDState *s, uint16_t len)
@@ -1135,18 +1137,17 @@ err:
 static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
 {
     int len = 0;
+    BulkIn *bulk_in;
 
-    ccid_bulk_in_get(s);
-    if (s->current_bulk_in != NULL) {
-        assert(s->current_bulk_in->pos <= s->current_bulk_in->len);
-        len = MIN(s->current_bulk_in->len - s->current_bulk_in->pos,
-                  p->iov.size);
+    bulk_in = ccid_bulk_in_peek(s);
+    if (bulk_in != NULL) {
+        assert(bulk_in->pos <= bulk_in->len);
+        len = MIN(bulk_in->len - bulk_in->pos, p->iov.size);
         if (len) {
-            usb_packet_copy(p, s->current_bulk_in->data +
-                            s->current_bulk_in->pos, len);
+            usb_packet_copy(p, bulk_in->data + bulk_in->pos, len);
         }
-        s->current_bulk_in->pos += len;
-        if (s->current_bulk_in->pos == s->current_bulk_in->len
+        bulk_in->pos += len;
+        if (bulk_in->pos == bulk_in->len
             && (len != CCID_MAX_PACKET_SIZE || len < p->iov.size)) {
             ccid_bulk_in_release(s);
         }
@@ -1439,8 +1440,7 @@ static bool ccid_pre_save(void *opaque, Error **errp)
 {
     USBCCIDState *s = opaque;
 
-    if (s->pending_answers_num || s->bulk_in_pending_num ||
-        s->current_bulk_in) {
+    if (s->pending_answers_num || s->bulk_in_pending_num) {
         error_setg(errp, "usb-ccid has pending queue state which cannot be "
                    "migrated safely");
         return false;

-- 
2.55.0