diff options
author | Igor Kotrasinski <i.kotrasinsk@samsung.com> | 2015-09-15 16:55:29 +0200 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2015-09-21 21:42:35 +0200 |
commit | 21c3ee93867694e8c7382ff77b4645b50d3233e9 (patch) | |
tree | b9c9c718220143a1f8c83399691907b97e324efc /drivers/usb/gadget/udc/dummy_hcd.c | |
parent | usb: musb: dsps: fix polling in device-only mode (diff) | |
download | linux-21c3ee93867694e8c7382ff77b4645b50d3233e9.tar.xz linux-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/gadget/udc/dummy_hcd.c')
-rw-r--r-- | drivers/usb/gadget/udc/dummy_hcd.c | 25 |
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 */ |