qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/1] USB: bugfix on interrupt xfers with usb-redir
@ 2019-07-24 13:03 Martin Cerveny
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Cerveny @ 2019-07-24 13:03 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel, Martin Cerveny

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



^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Qemu-devel] [PATCH 0/1] USB: bugfix on interrupt xfers with usb-redir
@ 2019-07-24 12:58 Martin Cerveny
  0 siblings, 0 replies; 2+ messages in thread
From: Martin Cerveny @ 2019-07-24 12:58 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel, Martin Cerveny

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



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-07-24 13:03 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-24 13:03 [Qemu-devel] [PATCH 0/1] USB: bugfix on interrupt xfers with usb-redir Martin Cerveny
  -- strict thread matches above, loose matches on Subject: below --
2019-07-24 12:58 Martin Cerveny

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).