[RFC] usb: dwc3: ep0: Fix mem corruption on OUT transfers of more than 512 bytes
diff mbox

Message ID 1433860550-25636-1-git-send-email-kishon@ti.com
State New
Headers show

Commit Message

Kishon Vijay Abraham I June 9, 2015, 2:35 p.m. UTC
DWC3 uses bounce buffer to handle non max packet aligned OUT transfers and
the size of bounce buffer is 512 bytes. However if the host initiates OUT
transfers of size more than 512 bytes (and non max packet aligned), the
driver throws a WARN dump but still programs the TRB to receive more than
512 bytes. This will cause bounce buffer to overflow and corrupt the
adjacent memory locations which can be fatal.

Fix it by programming the TRB to receive a maximum of DWC3_EP0_BOUNCE_SIZE
(512) bytes.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Steps to see the issue (before this patch)
1) Insert g_zero in DUT
2) run './testusb -t 14 -c 1 -s 520 -v 1' in host (size should be > 512)

The test should FAIL since bounce buffer can handle only 512 bytes, but the
test PASS. There is a WARN dump in DUT but still there will be memory
corruption since the bounce buffer overflows.

Tested this patch using USB3 Gen X CV (ch9 tests: usb2 and usb3, link layer
testing and MSC tests) and using USB2 X CV (ch9 tests, MSC tests).

After the patch, the tests timeout!
./testusb -t 14 -c 1 -s 514 -v 1
unknown speed	/dev/bus/usb/001/018	0
/dev/bus/usb/001/018 test 14 --> 110 (Connection timed out)

IMO a patch to fix this is required for stable releases too. So If this
patch is alright, I can post the patch cc'ing stable. While the actual fix
would be to have chained TRB, I'm not sure if it can go to stable
releases.
 drivers/usb/dwc3/ep0.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Kishon Vijay Abraham I June 9, 2015, 2:44 p.m. UTC | #1
Hi,

On Tuesday 09 June 2015 08:09 PM, Michael Trimarchi wrote:
> Hi
>
> On Jun 9, 2015 4:36 PM, "Kishon Vijay Abraham I" <kishon@ti.com
> <mailto:kishon@ti.com>> wrote:
>  >
>  > DWC3 uses bounce buffer to handle non max packet aligned OUT transfers and
>  > the size of bounce buffer is 512 bytes. However if the host initiates OUT
>  > transfers of size more than 512 bytes (and non max packet aligned), the
>  > driver throws a WARN dump but still programs the TRB to receive more than
>  > 512 bytes. This will cause bounce buffer to overflow and corrupt the
>  > adjacent memory locations which can be fatal.
>  >
>  > Fix it by programming the TRB to receive a maximum of DWC3_EP0_BOUNCE_SIZE
>  > (512) bytes.
>  >
>  > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com <mailto:kishon@ti.com>>
>  > ---
>  > Steps to see the issue (before this patch)
>  > 1) Insert g_zero in DUT
>  > 2) run './testusb -t 14 -c 1 -s 520 -v 1' in host (size should be > 512)
>  >
>  > The test should FAIL since bounce buffer can handle only 512 bytes, but the
>  > test PASS. There is a WARN dump in DUT but still there will be memory
>  > corruption since the bounce buffer overflows.
>  >
>  > Tested this patch using USB3 Gen X CV (ch9 tests: usb2 and usb3, link layer
>  > testing and MSC tests) and using USB2 X CV (ch9 tests, MSC tests).
>  >
>  > After the patch, the tests timeout!
>  > ./testusb -t 14 -c 1 -s 514 -v 1
>  > unknown speed   /dev/bus/usb/001/018    0
>  > /dev/bus/usb/001/018 test 14 --> 110 (Connection timed out)
>  >
>  > IMO a patch to fix this is required for stable releases too. So If this
>  > patch is alright, I can post the patch cc'ing stable. While the actual fix
>  > would be to have chained TRB, I'm not sure if it can go to stable
>  > releases.
>  >  drivers/usb/dwc3/ep0.c |   12 ++++++++++--
>  >  1 file changed, 10 insertions(+), 2 deletions(-)
>  >
>  > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>  > index 2ef3c8d..8858c60 100644
>  > --- a/drivers/usb/dwc3/ep0.c
>  > +++ b/drivers/usb/dwc3/ep0.c
>  > @@ -816,6 +816,11 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
>  >                 unsigned maxp = ep0->endpoint.maxpacket;
>  >
>  >                 transfer_size += (maxp - (transfer_size % maxp));
>  > +
>  > +               /* Maximum of DWC3_EP0_BOUNCE_SIZE can only be received */
>  > +               if (transfer_size > DWC3_EP0_BOUNCE_SIZE)
>  > +                       transfer_size = DWC3_EP0_BOUNCE_SIZE;
>  > +
>
> Can you just use maxp in the correct way?

what do you mean by correct way? Using roundup() to calculate transfer_size?

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Stern June 9, 2015, 2:59 p.m. UTC | #2
On Tue, 9 Jun 2015, Kishon Vijay Abraham I wrote:

> Hi,
> 
> On Tuesday 09 June 2015 08:09 PM, Michael Trimarchi wrote:
> > Hi
> >
> > On Jun 9, 2015 4:36 PM, "Kishon Vijay Abraham I" <kishon@ti.com
> > <mailto:kishon@ti.com>> wrote:
> >  >
> >  > DWC3 uses bounce buffer to handle non max packet aligned OUT transfers and
> >  > the size of bounce buffer is 512 bytes. However if the host initiates OUT
> >  > transfers of size more than 512 bytes (and non max packet aligned), the
> >  > driver throws a WARN dump but still programs the TRB to receive more than
> >  > 512 bytes. This will cause bounce buffer to overflow and corrupt the
> >  > adjacent memory locations which can be fatal.
> >  >
> >  > Fix it by programming the TRB to receive a maximum of DWC3_EP0_BOUNCE_SIZE
> >  > (512) bytes.
> >  >
> >  > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com <mailto:kishon@ti.com>>
> >  > ---
> >  > Steps to see the issue (before this patch)
> >  > 1) Insert g_zero in DUT
> >  > 2) run './testusb -t 14 -c 1 -s 520 -v 1' in host (size should be > 512)
> >  >
> >  > The test should FAIL since bounce buffer can handle only 512 bytes, but the
> >  > test PASS. There is a WARN dump in DUT but still there will be memory
> >  > corruption since the bounce buffer overflows.
> >  >
> >  > Tested this patch using USB3 Gen X CV (ch9 tests: usb2 and usb3, link layer
> >  > testing and MSC tests) and using USB2 X CV (ch9 tests, MSC tests).
> >  >
> >  > After the patch, the tests timeout!
> >  > ./testusb -t 14 -c 1 -s 514 -v 1
> >  > unknown speed   /dev/bus/usb/001/018    0
> >  > /dev/bus/usb/001/018 test 14 --> 110 (Connection timed out)
> >  >
> >  > IMO a patch to fix this is required for stable releases too. So If this
> >  > patch is alright, I can post the patch cc'ing stable. While the actual fix
> >  > would be to have chained TRB, I'm not sure if it can go to stable
> >  > releases.
> >  >  drivers/usb/dwc3/ep0.c |   12 ++++++++++--
> >  >  1 file changed, 10 insertions(+), 2 deletions(-)
> >  >
> >  > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
> >  > index 2ef3c8d..8858c60 100644
> >  > --- a/drivers/usb/dwc3/ep0.c
> >  > +++ b/drivers/usb/dwc3/ep0.c
> >  > @@ -816,6 +816,11 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
> >  >                 unsigned maxp = ep0->endpoint.maxpacket;
> >  >
> >  >                 transfer_size += (maxp - (transfer_size % maxp));
> >  > +
> >  > +               /* Maximum of DWC3_EP0_BOUNCE_SIZE can only be received */
> >  > +               if (transfer_size > DWC3_EP0_BOUNCE_SIZE)
> >  > +                       transfer_size = DWC3_EP0_BOUNCE_SIZE;
> >  > +
> >
> > Can you just use maxp in the correct way?
> 
> what do you mean by correct way? Using roundup() to calculate transfer_size?

Why not just make the bounce buffer size the same as the maxpacket 
size?  In other words, 1024 bytes instead of 512, for ep0 on a USB-3 
device.

Alan stern

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I June 9, 2015, 3:08 p.m. UTC | #3
Hi,

On Tuesday 09 June 2015 08:29 PM, Alan Stern wrote:
> On Tue, 9 Jun 2015, Kishon Vijay Abraham I wrote:
>
>> Hi,
>>
>> On Tuesday 09 June 2015 08:09 PM, Michael Trimarchi wrote:
>>> Hi
>>>
>>> On Jun 9, 2015 4:36 PM, "Kishon Vijay Abraham I" <kishon@ti.com
>>> <mailto:kishon@ti.com>> wrote:
>>>   >
>>>   > DWC3 uses bounce buffer to handle non max packet aligned OUT transfers and
>>>   > the size of bounce buffer is 512 bytes. However if the host initiates OUT
>>>   > transfers of size more than 512 bytes (and non max packet aligned), the
>>>   > driver throws a WARN dump but still programs the TRB to receive more than
>>>   > 512 bytes. This will cause bounce buffer to overflow and corrupt the
>>>   > adjacent memory locations which can be fatal.
>>>   >
>>>   > Fix it by programming the TRB to receive a maximum of DWC3_EP0_BOUNCE_SIZE
>>>   > (512) bytes.
>>>   >
>>>   > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com <mailto:kishon@ti.com>>
>>>   > ---
>>>   > Steps to see the issue (before this patch)
>>>   > 1) Insert g_zero in DUT
>>>   > 2) run './testusb -t 14 -c 1 -s 520 -v 1' in host (size should be > 512)
>>>   >
>>>   > The test should FAIL since bounce buffer can handle only 512 bytes, but the
>>>   > test PASS. There is a WARN dump in DUT but still there will be memory
>>>   > corruption since the bounce buffer overflows.
>>>   >
>>>   > Tested this patch using USB3 Gen X CV (ch9 tests: usb2 and usb3, link layer
>>>   > testing and MSC tests) and using USB2 X CV (ch9 tests, MSC tests).
>>>   >
>>>   > After the patch, the tests timeout!
>>>   > ./testusb -t 14 -c 1 -s 514 -v 1
>>>   > unknown speed   /dev/bus/usb/001/018    0
>>>   > /dev/bus/usb/001/018 test 14 --> 110 (Connection timed out)
>>>   >
>>>   > IMO a patch to fix this is required for stable releases too. So If this
>>>   > patch is alright, I can post the patch cc'ing stable. While the actual fix
>>>   > would be to have chained TRB, I'm not sure if it can go to stable
>>>   > releases.
>>>   >  drivers/usb/dwc3/ep0.c |   12 ++++++++++--
>>>   >  1 file changed, 10 insertions(+), 2 deletions(-)
>>>   >
>>>   > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>>>   > index 2ef3c8d..8858c60 100644
>>>   > --- a/drivers/usb/dwc3/ep0.c
>>>   > +++ b/drivers/usb/dwc3/ep0.c
>>>   > @@ -816,6 +816,11 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
>>>   >                 unsigned maxp = ep0->endpoint.maxpacket;
>>>   >
>>>   >                 transfer_size += (maxp - (transfer_size % maxp));
>>>   > +
>>>   > +               /* Maximum of DWC3_EP0_BOUNCE_SIZE can only be received */
>>>   > +               if (transfer_size > DWC3_EP0_BOUNCE_SIZE)
>>>   > +                       transfer_size = DWC3_EP0_BOUNCE_SIZE;
>>>   > +
>>>
>>> Can you just use maxp in the correct way?
>>
>> what do you mean by correct way? Using roundup() to calculate transfer_size?
>
> Why not just make the bounce buffer size the same as the maxpacket
> size?  In other words, 1024 bytes instead of 512, for ep0 on a USB-3
> device.

It would still be possible for the host to send data more than 1024 bytes no? 
When working with DFU gadget, I've seen host sends data upto 4KB. Changing the 
bounce buffer size might not be able to fix all the cases IMO. The actual fix 
will be something like [1]

[1] -> http://comments.gmane.org/gmane.linux.kernel/1883688

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Stern June 9, 2015, 3:16 p.m. UTC | #4
On Tue, 9 Jun 2015, Kishon Vijay Abraham I wrote:

> > Why not just make the bounce buffer size the same as the maxpacket
> > size?  In other words, 1024 bytes instead of 512, for ep0 on a USB-3
> > device.
> 
> It would still be possible for the host to send data more than 1024 bytes no? 

Yes.

> When working with DFU gadget, I've seen host sends data upto 4KB. Changing the 
> bounce buffer size might not be able to fix all the cases IMO. The actual fix 
> will be something like [1]
> 
> [1] -> http://comments.gmane.org/gmane.linux.kernel/1883688

But with a bounce buffer that's only 512 bytes long, you can never send
an entire packet's worth of data.  If the bounce buffer is 1024 bytes
then you can send the entire first packet.  When that's done, you can
send the second packet.  And so on.  It wouldn't be quite as fast, but
for ep0 that shouldn't matter.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I June 9, 2015, 4:14 p.m. UTC | #5
Hi,

On Tuesday 09 June 2015 08:46 PM, Alan Stern wrote:
> On Tue, 9 Jun 2015, Kishon Vijay Abraham I wrote:
>
>>> Why not just make the bounce buffer size the same as the maxpacket
>>> size?  In other words, 1024 bytes instead of 512, for ep0 on a USB-3
>>> device.
>>
>> It would still be possible for the host to send data more than 1024 bytes no?
>
> Yes.
>
>> When working with DFU gadget, I've seen host sends data upto 4KB. Changing the
>> bounce buffer size might not be able to fix all the cases IMO. The actual fix
>> will be something like [1]
>>
>> [1] -> http://comments.gmane.org/gmane.linux.kernel/1883688
>
> But with a bounce buffer that's only 512 bytes long, you can never send
> an entire packet's worth of data.  If the bounce buffer is 1024 bytes

for control endpoint, 512 bytes should be sufficient to send entire packet right?
> then you can send the entire first packet.  When that's done, you can
> send the second packet.  And so on.  It wouldn't be quite as fast, but
> for ep0 that shouldn't matter.

right! this is a variant of what I tried to implement in chained TRB [1]. 
$subject tries just to avoid memory corruption instead of actually trying to 
receive all the data.

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Felipe Balbi June 9, 2015, 5:16 p.m. UTC | #6
On Tue, Jun 09, 2015 at 10:59:50AM -0400, Alan Stern wrote:
> On Tue, 9 Jun 2015, Kishon Vijay Abraham I wrote:
> 
> > Hi,
> > 
> > On Tuesday 09 June 2015 08:09 PM, Michael Trimarchi wrote:
> > > Hi
> > >
> > > On Jun 9, 2015 4:36 PM, "Kishon Vijay Abraham I" <kishon@ti.com
> > > <mailto:kishon@ti.com>> wrote:
> > >  >
> > >  > DWC3 uses bounce buffer to handle non max packet aligned OUT transfers and
> > >  > the size of bounce buffer is 512 bytes. However if the host initiates OUT
> > >  > transfers of size more than 512 bytes (and non max packet aligned), the
> > >  > driver throws a WARN dump but still programs the TRB to receive more than
> > >  > 512 bytes. This will cause bounce buffer to overflow and corrupt the
> > >  > adjacent memory locations which can be fatal.
> > >  >
> > >  > Fix it by programming the TRB to receive a maximum of DWC3_EP0_BOUNCE_SIZE
> > >  > (512) bytes.
> > >  >
> > >  > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com <mailto:kishon@ti.com>>
> > >  > ---
> > >  > Steps to see the issue (before this patch)
> > >  > 1) Insert g_zero in DUT
> > >  > 2) run './testusb -t 14 -c 1 -s 520 -v 1' in host (size should be > 512)
> > >  >
> > >  > The test should FAIL since bounce buffer can handle only 512 bytes, but the
> > >  > test PASS. There is a WARN dump in DUT but still there will be memory
> > >  > corruption since the bounce buffer overflows.
> > >  >
> > >  > Tested this patch using USB3 Gen X CV (ch9 tests: usb2 and usb3, link layer
> > >  > testing and MSC tests) and using USB2 X CV (ch9 tests, MSC tests).
> > >  >
> > >  > After the patch, the tests timeout!
> > >  > ./testusb -t 14 -c 1 -s 514 -v 1
> > >  > unknown speed   /dev/bus/usb/001/018    0
> > >  > /dev/bus/usb/001/018 test 14 --> 110 (Connection timed out)
> > >  >
> > >  > IMO a patch to fix this is required for stable releases too. So If this
> > >  > patch is alright, I can post the patch cc'ing stable. While the actual fix
> > >  > would be to have chained TRB, I'm not sure if it can go to stable
> > >  > releases.
> > >  >  drivers/usb/dwc3/ep0.c |   12 ++++++++++--
> > >  >  1 file changed, 10 insertions(+), 2 deletions(-)
> > >  >
> > >  > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
> > >  > index 2ef3c8d..8858c60 100644
> > >  > --- a/drivers/usb/dwc3/ep0.c
> > >  > +++ b/drivers/usb/dwc3/ep0.c
> > >  > @@ -816,6 +816,11 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
> > >  >                 unsigned maxp = ep0->endpoint.maxpacket;
> > >  >
> > >  >                 transfer_size += (maxp - (transfer_size % maxp));
> > >  > +
> > >  > +               /* Maximum of DWC3_EP0_BOUNCE_SIZE can only be received */
> > >  > +               if (transfer_size > DWC3_EP0_BOUNCE_SIZE)
> > >  > +                       transfer_size = DWC3_EP0_BOUNCE_SIZE;
> > >  > +
> > >
> > > Can you just use maxp in the correct way?
> > 
> > what do you mean by correct way? Using roundup() to calculate transfer_size?
> 
> Why not just make the bounce buffer size the same as the maxpacket 
> size?  In other words, 1024 bytes instead of 512, for ep0 on a USB-3 
> device.

EP0 max packet size is 512 on USB3.
Alan Stern June 9, 2015, 5:24 p.m. UTC | #7
On Tue, 9 Jun 2015, Kishon Vijay Abraham I wrote:

> > But with a bounce buffer that's only 512 bytes long, you can never send
> > an entire packet's worth of data.  If the bounce buffer is 1024 bytes
> 
> for control endpoint, 512 bytes should be sufficient to send entire packet right?

Yes, you're right.  I had confused control endpoints with bulk 
endpoints, where the maxpacket size is 1024.  Sorry for the mistake.

> > then you can send the entire first packet.  When that's done, you can
> > send the second packet.  And so on.  It wouldn't be quite as fast, but
> > for ep0 that shouldn't matter.
> 
> right! this is a variant of what I tried to implement in chained TRB [1]. 
> $subject tries just to avoid memory corruption instead of actually trying to 
> receive all the data.

Okay.  If you take the $SUBJECT approach, I think it would be better
for an URB submission to fail than for the host controller to send only
part of the data.

Alan Stern

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Kishon Vijay Abraham I June 10, 2015, 5:33 a.m. UTC | #8
Hi,

On Tuesday 09 June 2015 10:54 PM, Alan Stern wrote:
> On Tue, 9 Jun 2015, Kishon Vijay Abraham I wrote:
>
>>> But with a bounce buffer that's only 512 bytes long, you can never send
>>> an entire packet's worth of data.  If the bounce buffer is 1024 bytes
>>
>> for control endpoint, 512 bytes should be sufficient to send entire packet right?
>
> Yes, you're right.  I had confused control endpoints with bulk
> endpoints, where the maxpacket size is 1024.  Sorry for the mistake.

no problem.
>
>>> then you can send the entire first packet.  When that's done, you can
>>> send the second packet.  And so on.  It wouldn't be quite as fast, but
>>> for ep0 that shouldn't matter.
>>
>> right! this is a variant of what I tried to implement in chained TRB [1].
>> $subject tries just to avoid memory corruption instead of actually trying to
>> receive all the data.
>
> Okay.  If you take the $SUBJECT approach, I think it would be better
> for an URB submission to fail than for the host controller to send only
> part of the data.

Could be but we also want to prevent mem corruption in the case of a faulty 
host to be more robust.

Thanks
Kishon
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Michael Nazzareno Trimarchi June 11, 2015, 6:57 p.m. UTC | #9
Hi

On Tue, Jun 9, 2015 at 3:44 PM, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Hi,
>
> On Tuesday 09 June 2015 08:09 PM, Michael Trimarchi wrote:
>>
>> Hi
>>
>> On Jun 9, 2015 4:36 PM, "Kishon Vijay Abraham I" <kishon@ti.com
>> <mailto:kishon@ti.com>> wrote:
>>  >
>>  > DWC3 uses bounce buffer to handle non max packet aligned OUT transfers
>> and
>>  > the size of bounce buffer is 512 bytes. However if the host initiates
>> OUT
>>  > transfers of size more than 512 bytes (and non max packet aligned), the
>>  > driver throws a WARN dump but still programs the TRB to receive more
>> than
>>  > 512 bytes. This will cause bounce buffer to overflow and corrupt the
>>  > adjacent memory locations which can be fatal.
>>  >
>>  > Fix it by programming the TRB to receive a maximum of
>> DWC3_EP0_BOUNCE_SIZE
>>  > (512) bytes.
>>  >
>>  > Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com
>> <mailto:kishon@ti.com>>
>>
>>  > ---
>>  > Steps to see the issue (before this patch)
>>  > 1) Insert g_zero in DUT
>>  > 2) run './testusb -t 14 -c 1 -s 520 -v 1' in host (size should be >
>> 512)
>>  >
>>  > The test should FAIL since bounce buffer can handle only 512 bytes, but
>> the
>>  > test PASS. There is a WARN dump in DUT but still there will be memory
>>  > corruption since the bounce buffer overflows.
>>  >
>>  > Tested this patch using USB3 Gen X CV (ch9 tests: usb2 and usb3, link
>> layer
>>  > testing and MSC tests) and using USB2 X CV (ch9 tests, MSC tests).
>>  >
>>  > After the patch, the tests timeout!
>>  > ./testusb -t 14 -c 1 -s 514 -v 1
>>  > unknown speed   /dev/bus/usb/001/018    0
>>  > /dev/bus/usb/001/018 test 14 --> 110 (Connection timed out)
>>  >
>>  > IMO a patch to fix this is required for stable releases too. So If this
>>  > patch is alright, I can post the patch cc'ing stable. While the actual
>> fix
>>  > would be to have chained TRB, I'm not sure if it can go to stable
>>  > releases.
>>  >  drivers/usb/dwc3/ep0.c |   12 ++++++++++--
>>  >  1 file changed, 10 insertions(+), 2 deletions(-)
>>  >
>>  > diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
>>  > index 2ef3c8d..8858c60 100644
>>  > --- a/drivers/usb/dwc3/ep0.c
>>  > +++ b/drivers/usb/dwc3/ep0.c
>>  > @@ -816,6 +816,11 @@ static void dwc3_ep0_complete_data(struct dwc3
>> *dwc,
>>  >                 unsigned maxp = ep0->endpoint.maxpacket;
>>  >
>>  >                 transfer_size += (maxp - (transfer_size % maxp));
>>  > +
>>  > +               /* Maximum of DWC3_EP0_BOUNCE_SIZE can only be received
>> */
>>  > +               if (transfer_size > DWC3_EP0_BOUNCE_SIZE)
>>  > +                       transfer_size = DWC3_EP0_BOUNCE_SIZE;
>>  > +
>>
>> Can you just use maxp in the correct way?
>
>
> what do you mean by correct way? Using roundup() to calculate transfer_size?
>

just a max

Michael

> Thanks
> Kishon

Patch
diff mbox

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 2ef3c8d..8858c60 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -816,6 +816,11 @@  static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 		unsigned maxp = ep0->endpoint.maxpacket;
 
 		transfer_size += (maxp - (transfer_size % maxp));
+
+		/* Maximum of DWC3_EP0_BOUNCE_SIZE can only be received */
+		if (transfer_size > DWC3_EP0_BOUNCE_SIZE)
+			transfer_size = DWC3_EP0_BOUNCE_SIZE;
+
 		transferred = min_t(u32, ur->length,
 				transfer_size - length);
 		memcpy(ur->buf, dwc->ep0_bounce, transferred);
@@ -937,11 +942,14 @@  static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 			return;
 		}
 
-		WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE);
-
 		maxpacket = dep->endpoint.maxpacket;
 		transfer_size = roundup(req->request.length, maxpacket);
 
+		if (transfer_size > DWC3_EP0_BOUNCE_SIZE) {
+			dev_WARN(dwc->dev, "bounce buf can't handle req len\n");
+			transfer_size = DWC3_EP0_BOUNCE_SIZE;
+		}
+
 		dwc->ep0_bounced = true;
 
 		/*