diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c index a09d52fcae99..32efcf2e59c4 100644 --- a/drivers/usb/gadget/function/f_accessory.c +++ b/drivers/usb/gadget/function/f_accessory.c @@ -643,6 +643,7 @@ static ssize_t acc_read(struct file *fp, char __user *buf, struct acc_dev *dev = fp->private_data; struct usb_request *req; ssize_t r = count; + ssize_t data_length; unsigned xfer; int ret = 0; @@ -664,6 +665,15 @@ static ssize_t acc_read(struct file *fp, char __user *buf, goto done; } + /* + * Calculate the data length by considering termination character. + * Then compansite the difference of rounding up to + * integer multiple of maxpacket size. + */ + data_length = count; + data_length += dev->ep_out->maxpacket - 1; + data_length -= data_length % dev->ep_out->maxpacket; + if (dev->rx_done) { // last req cancelled. try to get it. req = dev->rx_req[0]; @@ -673,7 +683,7 @@ static ssize_t acc_read(struct file *fp, char __user *buf, requeue_req: /* queue a request */ req = dev->rx_req[0]; - req->length = count; + req->length = data_length; dev->rx_done = 0; ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL); if (ret < 0) {