aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorIgor Kotrasinski <i.kotrasinsk@samsung.com>2015-09-15 16:55:29 +0200
committerFelipe Balbi <balbi@ti.com>2015-09-21 14:42:35 -0500
commit21c3ee93867694e8c7382ff77b4645b50d3233e9 (patch)
treeb9c9c718220143a1f8c83399691907b97e324efc /drivers/usb
parentusb: musb: dsps: fix polling in device-only mode (diff)
downloadlinux-dev-21c3ee93867694e8c7382ff77b4645b50d3233e9.tar.xz
linux-dev-21c3ee93867694e8c7382ff77b4645b50d3233e9.zip
usb: gadget: dummy_hcd: emulate sending zlp in packet logic
currently, when a zlp flag is set and an urb/usb_request buffer is filled without a short packet, transfer() leaves its status at -EINPROGRESS and does not rescan for short packet. In a scenario where ep.maxpacket bytes are copied, URB_ZERO_PACKET is set, urb buffer is filled and usb_request buffer is not, transfer() returns with an urb with -EINPROGRESS status, which dummy_hcd treats as incomplete transfer. Check for zlp and rescan appropriately. Signed-off-by: Igor Kotrasinski <i.kotrasinsk@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/udc/dummy_hcd.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index 1379ad40d864..93b38f88e7b2 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -1429,15 +1429,24 @@ top:
req->req.status = 0;
}
- /* many requests terminate without a short packet */
+ /*
+ * many requests terminate without a short packet.
+ * send a zlp if demanded by flags.
+ */
} else {
- if (req->req.length == req->req.actual
- && !req->req.zero)
- req->req.status = 0;
- if (urb->transfer_buffer_length == urb->actual_length
- && !(urb->transfer_flags
- & URB_ZERO_PACKET))
- *status = 0;
+ if (req->req.length == req->req.actual) {
+ if (req->req.zero && to_host)
+ rescan = 1;
+ else
+ req->req.status = 0;
+ }
+ if (urb->transfer_buffer_length == urb->actual_length) {
+ if (urb->transfer_flags & URB_ZERO_PACKET &&
+ !to_host)
+ rescan = 1;
+ else
+ *status = 0;
+ }
}
/* device side completion --> continuable */