usb: gadget: f_mtp: Make RX buffer size aligned to EP's MTU
Synopsys USB3 Controller (DWC3) has a restriction where size of OUT requests (TRB) queued to the controller must be aligned with the endpoint's max packet size. Generally, MTP userspace module submits RX requests aligned to 512 bytes which works fine in High speed mode. But, fails in Super-speed mode where max packet size can be 1024 bytes. To overcome this just change the size of RX request buffer while submitting to DCD as the buffers are already allocated with the size of 16KB. Change-Id: I68c32ef3d08b2cf943b52a7269785d0a00146953 Signed-off-by: Manu Gautam <mgautam@codeaurora.org>
This commit is contained in:
parent
2142069a88
commit
f5bf2e9314
1 changed files with 17 additions and 5 deletions
|
@ -478,8 +478,7 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
|
|||
struct mtp_dev *dev = fp->private_data;
|
||||
struct usb_composite_dev *cdev = dev->cdev;
|
||||
struct usb_request *req;
|
||||
ssize_t r = count;
|
||||
unsigned xfer;
|
||||
ssize_t xfer, r = count;
|
||||
int ret = 0;
|
||||
|
||||
DBG(cdev, "mtp_read(%zu)\n", count);
|
||||
|
@ -487,6 +486,10 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
|
|||
if (count > MTP_BULK_BUFFER_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (!IS_ALIGNED(count, dev->ep_out->maxpacket))
|
||||
DBG(cdev, "%s - count(%zu) not multiple of mtu(%d)\n", __func__,
|
||||
count, dev->ep_out->maxpacket);
|
||||
|
||||
/* we will block until we're online */
|
||||
DBG(cdev, "mtp_read: waiting for online state\n");
|
||||
ret = wait_event_interruptible(dev->read_wq,
|
||||
|
@ -508,7 +511,7 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
|
|||
requeue_req:
|
||||
/* queue a request */
|
||||
req = dev->rx_req[0];
|
||||
req->length = count;
|
||||
req->length = MTP_BULK_BUFFER_SIZE;
|
||||
dev->rx_done = 0;
|
||||
ret = usb_ep_queue(dev->ep_out, req, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
|
@ -773,6 +776,9 @@ static void receive_file_work(struct work_struct *data)
|
|||
count = dev->xfer_file_length;
|
||||
|
||||
DBG(cdev, "receive_file_work(%lld)\n", count);
|
||||
if (!IS_ALIGNED(count, dev->ep_out->maxpacket))
|
||||
DBG(cdev, "%s- count(%lld) not multiple of mtu(%d)\n", __func__,
|
||||
count, dev->ep_out->maxpacket);
|
||||
|
||||
while (count > 0 || write_req) {
|
||||
if (count > 0) {
|
||||
|
@ -780,8 +786,9 @@ static void receive_file_work(struct work_struct *data)
|
|||
read_req = dev->rx_req[cur_buf];
|
||||
cur_buf = (cur_buf + 1) % RX_REQ_MAX;
|
||||
|
||||
read_req->length = (count > MTP_BULK_BUFFER_SIZE
|
||||
? MTP_BULK_BUFFER_SIZE : count);
|
||||
/* some h/w expects size to be aligned to ep's MTU */
|
||||
read_req->length = MTP_BULK_BUFFER_SIZE;
|
||||
|
||||
dev->rx_done = 0;
|
||||
ret = usb_ep_queue(dev->ep_out, read_req, GFP_KERNEL);
|
||||
if (ret < 0) {
|
||||
|
@ -814,6 +821,11 @@ static void receive_file_work(struct work_struct *data)
|
|||
usb_ep_dequeue(dev->ep_out, read_req);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if we aligned the size due to MTU constraint */
|
||||
if (count < read_req->length)
|
||||
read_req->actual = (read_req->actual > count ?
|
||||
count : read_req->actual);
|
||||
/* if xfer_file_length is 0xFFFFFFFF, then we read until
|
||||
* we get a zero length packet
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue