All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Cerveny <M.Cerveny@computer.org>
To: Gerd Hoffmann <kraxel@redhat.com>
Cc: qemu-devel@nongnu.org, Martin Cerveny <M.Cerveny@computer.org>
Subject: [Qemu-devel] [PATCH 0/1] USB: bugfix on interrupt xfers with usb-redir
Date: Wed, 24 Jul 2019 14:58:58 +0200	[thread overview]
Message-ID: <20190724125859.14624-1-M.Cerveny@computer.org> (raw)

I have problem in xen with qemu xhci with usbredir backend.
Windows bluetooth (BCM20703) driver does not work without proposed patch.
Interrupt EP does not work as expected and described in USB spec.

usb_20.pdf/5.7.3 Interrupt Transfer Packet Size Constraint:
----
An endpoint must always transmit data payloads with a data field less than or equal to the endpoint’s
wMaxPacketSize value. A device can move data via an interrupt pipe that is larger than wMaxPacketSize.
A software client can accept this data via an IRP for the interrupt transfer that requires multiple bus
transactions without requiring an IRP-complete notification per transaction. This can be achieved by
specifying a buffer that can hold the desired data size. The size of the buffer is a multiple of
wMaxPacketSize with some remainder. The endpoint must transfer each transaction except the last as
wMaxPacketSize and the last transaction is the remainder. The multiple data transactions are moved over
the bus at the period established for the pipe.
When an interrupt transfer involves more data than can fit in one data payload of the currently established
maximum size, all data payloads are required to be maximum-sized except for the last data payload, which
will contain the remaining data. An interrupt transfer is complete when the endpoint does one of the
following:
• Has transferred exactly the amount of data expected
• Transfers a packet with a payload size less than wMaxPacketSize or transfers a zero-length packet
----

Examples of affected device on windows usbpcap decoded with wireshark:

- snip of configuration descriptor:
----
ENDPOINT DESCRIPTOR
    bLength: 7
    bDescriptorType: 0x05 (ENDPOINT)
    bEndpointAddress: 0x81  IN  Endpoint:1
        1... .... = Direction: IN Endpoint
        .... 0001 = Endpoint Number: 0x1
    bmAttributes: 0x03
        .... ..11 = Transfertype: Interrupt-Transfer (0x3)
    wMaxPacketSize: 16
        ...0 0... .... .... = Transactions per microframe: 1 (0)
        .... ..00 0001 0000 = Maximum Packet Size: 16
    bInterval: 1
----


- snip of two correct URB interrupts (len 70 and len 16) from non-virtualized communication and patched qemu:
----
USB URB
    [Source: 1.6.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffa901ed380050
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 6
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 70
    [Request in: 43377]
    [Time from request: 0.006005000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: 0e4401021000ffffff03ccffefffffffec1ff20fe8fe3ff7...
USB URB
    [Source: 1.6.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffa901ed380050
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 6
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 16
    [Request in: 43405]
    [Time from request: 0.002952000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: 0e0e0104100001020000000000000000
----


- snip of the same two (more URB 70=16+16+16+16+6, 16=16+0) in actual qemu:
----
USB URB
    [Source: 1.4.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffc5062ede69f0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 4
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 16
    [Request in: 72930]
    [Time from request: 0.004881000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: 0e4401021000ffffff03ccffefffffff
USB URB
    [Source: 1.4.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffc5062ede69f0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 4
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 16
    [Request in: 72947]
    [Time from request: 0.004244000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: ec1ff20fe8fe3ff78fff1c00040061f7
USB URB
    [Source: 1.4.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffc5062ede69f0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 4
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 16
    [Request in: 72957]
    [Time from request: 0.000073000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: ffff7ff8ffffff3f0000000000000000
USB URB
    [Source: 1.4.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffc5062ede69f0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 4
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 16
    [Request in: 72959]
    [Time from request: 0.001875000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: 00000000000000000000000000000000
USB URB
    [Source: 1.4.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffc5062ede69f0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 4
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 6
    [Request in: 72967]
    [Time from request: 0.000144000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: 000000000000


USB URB
    [Source: 1.4.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffc5062ede69f0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 4
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 16
    [Request in: 73298]
    [Time from request: 0.005657000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
Leftover Capture Data: 0e0e0104100001020700000000000000
USB URB
    [Source: 1.4.1]
    [Destination: host]
    USBPcap pseudoheader length: 27
    IRP ID: 0xffffc5062ede69f0
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (0x0009)
    IRP information: 0x01, Direction: PDO -> FDO
        0000 000. = Reserved: 0x00
        .... ...1 = Direction: PDO -> FDO (0x1)
    URB bus id: 1
    Device address: 4
    Endpoint: 0x81, Direction: IN
        1... .... = Direction: IN (1)
        .... 0001 = Endpoint number: 1
    URB transfer type: URB_INTERRUPT (0x01)
    Packet Data Length: 0
    [Request in: 73314]
    [Time from request: 0.001614000 seconds]
    [bInterfaceClass: Vendor Specific (0xff)]
----

I am not regular contributor. Maintainers should check and correct code or propose different solution.
Code is tested with qemu-xen (qemu-xen-4.12.0).

Regards, 

Martin 

Martin Cerveny (1):
  usb-redir: merge interrupt packets

 hw/usb/redirect.c | 69 ++++++++++++++++++++++++++++++++---------------
 1 file changed, 48 insertions(+), 21 deletions(-)

-- 
2.20.1



             reply	other threads:[~2019-07-24 12:59 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-24 12:58 Martin Cerveny [this message]
2019-07-24 12:58 ` [Qemu-devel] [PATCH 1/1] usb-redir: merge interrupt packets Martin Cerveny
2019-08-14 12:12   ` Gerd Hoffmann
2019-07-24 13:03 [Qemu-devel] [PATCH 0/1] USB: bugfix on interrupt xfers with usb-redir Martin Cerveny

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190724125859.14624-1-M.Cerveny@computer.org \
    --to=m.cerveny@computer.org \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.