[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