lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 11 Nov 2019 16:26:45 +0100
From:   Michael Olbrich <m.olbrich@...gutronix.de>
To:     linux-usb@...r.kernel.org
Cc:     Felipe Balbi <balbi@...nel.org>,
        Thinh Nguyen <Thinh.Nguyen@...opsys.com>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        linux-kernel@...r.kernel.org, kernel@...gutronix.de,
        Michael Olbrich <m.olbrich@...gutronix.de>
Subject: [PATCH 2/2] usb: dwc3: gadget: restart the transfer if a isoc request is queued too late

Currently, most gadget drivers handle isoc transfers on a best effort
bases: If the request queue runs empty, then there will simply be gaps in
the isoc data stream.

The UVC gadget depends on this behaviour. It simply provides new requests
when video frames are available and assumes that they are sent as soon as
possible.

The dwc3 gadget currently works differently: It assumes that there is a
contiguous stream of requests without any gaps. If a request is too late,
then it is dropped by the hardware.
For the UVC gadget this means that a live stream stops after the first
frame because all following requests are late.

This patch changes the behaviour of the dwc3 gadget driver to match the
expectations. If a request arrives too late, then the transfer will be
restart to create the needed gap.

A request is late if:
1. There are currently no requests queued in the hardware
2. The current frame number provided by DSTS does not match the frame
   number returned by the last transfer.

If this happens transfers are stopped. The following XferNotReady provides
the new correct frame number and restarts the transfer.

Signed-off-by: Michael Olbrich <m.olbrich@...gutronix.de>
---
 drivers/usb/dwc3/gadget.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index ac4673d91939..eb7f09929f28 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1473,6 +1473,14 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
 				return __dwc3_gadget_start_isoc(dep);
 			}
 		}
+		if ((dep->flags & DWC3_EP_TRANSFER_STARTED) &&
+		    list_empty(&dep->started_list) &&
+		    ((dep->frame_number & 0x3fff) !=
+		    __dwc3_gadget_get_frame(dwc))) {
+			dwc3_stop_active_transfer(dep, true, true);
+			dep->flags = DWC3_EP_ENABLED;
+			return 0;
+		}
 	}
 
 	return __dwc3_gadget_kick_transfer(dep, false);
-- 
2.20.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ