Blame SOURCES/kvm-hw-usb-dev-smartcard-reader-Handle-64-B-USB-packets.patch

357786
From a05d849be393110a4efacb148197434c095e06e2 Mon Sep 17 00:00:00 2001
357786
From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
357786
Date: Thu, 16 Aug 2018 10:41:54 +0200
357786
Subject: [PATCH 3/5] hw/usb/dev-smartcard-reader: Handle 64 B USB packets
357786
MIME-Version: 1.0
357786
Content-Type: text/plain; charset=UTF-8
357786
Content-Transfer-Encoding: 8bit
357786
357786
RH-Author: Marc-André Lureau <marcandre.lureau@redhat.com>
357786
Message-id: <20180816104154.18782-1-marcandre.lureau@redhat.com>
357786
Patchwork-id: 81855
357786
O-Subject: [RHEL-7.6 qemu-kvm-rhev PATCH] hw/usb/dev-smartcard-reader: Handle 64 B USB packets
357786
Bugzilla: 1589147
357786
RH-Acked-by: Gerd Hoffmann <kraxel@redhat.com>
357786
RH-Acked-by: Igor Mammedov <imammedo@redhat.com>
357786
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
357786
357786
From: Jakub Jelen <jjelen@redhat.com>
357786
357786
The current code was not correctly handling 64 B (Max USB 1.1 payload size)
357786
packets and therefore preventing some of the messages from smart card to
357786
pass through to the guest.
357786
357786
If the smart card in host responded with 34 B of data in APDU layer, the
357786
CCID headers added up to 64 B. The packet was send, but not correctly
357786
committed per USB specification (8.5.3.2  Variable-length Data Stage):
357786
357786
>   When all of the data structure is returned to the host, the function
357786
> should indicate that the Data stage is ended by returning a packet
357786
> that is shorter than the MaxPacketSize for the pipe.  If the data
357786
> structure is an exact multiple of wMaxPacketSize for the pipe, the
357786
> function will return a zero-length packet to indicate the end of the
357786
> Data stage.
357786
357786
This lead the guest applications to timeout while waiting for the rest
357786
of data (the emulation layer is answering with NAK until the timeout).
357786
357786
This patch is checking the current maximum packet size and if the
357786
payload of this size is detected, the message buffer is not yet released.
357786
With the next call, the empty buffer is sent and the message buffer
357786
is finally released.
357786
357786
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
357786
Message-id: 20180516115544.3897-2-jjelen@redhat.com
357786
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
357786
357786
(cherry picked from commit 8030dca376fa1bc4d8a6be7628196578f8783ab3)
357786
357786
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
357786
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
357786
---
357786
 hw/usb/dev-smartcard-reader.c | 14 +++++++++-----
357786
 1 file changed, 9 insertions(+), 5 deletions(-)
357786
357786
diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c
357786
index e646805..214d3e9 100644
357786
--- a/hw/usb/dev-smartcard-reader.c
357786
+++ b/hw/usb/dev-smartcard-reader.c
357786
@@ -1064,7 +1064,8 @@ err:
357786
     return;
357786
 }
357786
 
357786
-static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
357786
+static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p,
357786
+    unsigned int max_packet_size)
357786
 {
357786
     int len = 0;
357786
 
357786
@@ -1072,10 +1073,13 @@ static void ccid_bulk_in_copy_to_guest(USBCCIDState *s, USBPacket *p)
357786
     if (s->current_bulk_in != NULL) {
357786
         len = MIN(s->current_bulk_in->len - s->current_bulk_in->pos,
357786
                   p->iov.size);
357786
-        usb_packet_copy(p, s->current_bulk_in->data +
357786
-                        s->current_bulk_in->pos, len);
357786
+        if (len) {
357786
+            usb_packet_copy(p, s->current_bulk_in->data +
357786
+                            s->current_bulk_in->pos, len);
357786
+        }
357786
         s->current_bulk_in->pos += len;
357786
-        if (s->current_bulk_in->pos == s->current_bulk_in->len) {
357786
+        if (s->current_bulk_in->pos == s->current_bulk_in->len
357786
+            && len != max_packet_size) {
357786
             ccid_bulk_in_release(s);
357786
         }
357786
     } else {
357786
@@ -1107,7 +1111,7 @@ static void ccid_handle_data(USBDevice *dev, USBPacket *p)
357786
     case USB_TOKEN_IN:
357786
         switch (p->ep->nr) {
357786
         case CCID_BULK_IN_EP:
357786
-            ccid_bulk_in_copy_to_guest(s, p);
357786
+            ccid_bulk_in_copy_to_guest(s, p, dev->ep_ctl.max_packet_size);
357786
             break;
357786
         case CCID_INT_IN_EP:
357786
             if (s->notify_slot_change) {
357786
-- 
357786
1.8.3.1
357786