* Fix big-endian application issue for MUSB gadget
@ 2018-07-26 12:52 Alexey Spirkov
0 siblings, 0 replies; 3+ messages in thread
From: Alexey Spirkov @ 2018-07-26 12:52 UTC (permalink / raw)
To: Bin Liu, Greg Kroah-Hartman, linux-usb@vger.kernel.org; +Cc: andrew@ncrmnt.org
Existing code is not applicable to big-endian machines
ctrlrequest fields received in USB endian - i.e. in little-endian
and should be converted to cpu endianness before usage.
Signed-off-by: Alexey Spirkov <alexeis@astrosoft.ru>
---
drivers/usb/musb/musb_gadget_ep0.c | 33 ++++++++++++++++++++-------------
1 file changed, 20 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
index 91a5027..5d5c933 100644
--- a/drivers/usb/musb/musb_gadget_ep0.c
+++ b/drivers/usb/musb/musb_gadget_ep0.c
@@ -82,7 +82,7 @@ static int service_tx_status_request(
u16 tmp;
void __iomem *regs;
- epnum = (u8) ctrlrequest->wIndex;
+ epnum = (u8) le16_to_cpu(ctrlrequest->wIndex);
if (!epnum) {
result[0] = 0;
break;
@@ -217,14 +217,15 @@ __acquires(musb->lock)
case USB_REQ_SET_ADDRESS:
/* change it after the status stage */
musb->set_address = true;
- musb->address = (u8) (ctrlrequest->wValue & 0x7f);
+ musb->address = (u8) (le16_to_cpu(ctrlrequest->wValue) &
+ 0x7f);
handled = 1;
break;
case USB_REQ_CLEAR_FEATURE:
switch (recip) {
case USB_RECIP_DEVICE:
- if (ctrlrequest->wValue
+ if (le16_to_cpu(ctrlrequest->wValue)
!= USB_DEVICE_REMOTE_WAKEUP)
break;
musb->may_wakeup = 0;
@@ -234,7 +235,7 @@ __acquires(musb->lock)
break;
case USB_RECIP_ENDPOINT:{
const u8 epnum =
- ctrlrequest->wIndex & 0x0f;
+ le16_to_cpu(ctrlrequest->wIndex) & 0x0f;
struct musb_ep *musb_ep;
struct musb_hw_ep *ep;
struct musb_request *request;
@@ -243,12 +244,14 @@ __acquires(musb->lock)
u16 csr;
if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
- ctrlrequest->wValue != USB_ENDPOINT_HALT)
+ le16_to_cpu(ctrlrequest->wValue)
+ != USB_ENDPOINT_HALT)
break;
ep = musb->endpoints + epnum;
regs = ep->regs;
- is_in = ctrlrequest->wIndex & USB_DIR_IN;
+ is_in = le16_to_cpu(ctrlrequest->wIndex) &
+ USB_DIR_IN;
if (is_in)
musb_ep = &ep->ep_in;
else
@@ -300,17 +303,19 @@ __acquires(musb->lock)
switch (recip) {
case USB_RECIP_DEVICE:
handled = 1;
- switch (ctrlrequest->wValue) {
+ switch (le16_to_cpu(ctrlrequest->wValue)) {
case USB_DEVICE_REMOTE_WAKEUP:
musb->may_wakeup = 1;
break;
case USB_DEVICE_TEST_MODE:
if (musb->g.speed != USB_SPEED_HIGH)
goto stall;
- if (ctrlrequest->wIndex & 0xff)
+ if (le16_to_cpu(ctrlrequest->wIndex) &
+ 0xff)
goto stall;
- switch (ctrlrequest->wIndex >> 8) {
+ switch (le16_to_cpu(ctrlrequest->wIndex)
+ >> 8) {
case 1:
pr_debug("TEST_J\n");
/* TEST_J */
@@ -399,7 +404,7 @@ __acquires(musb->lock)
case USB_RECIP_ENDPOINT:{
const u8 epnum =
- ctrlrequest->wIndex & 0x0f;
+ le16_to_cpu(ctrlrequest->wIndex) & 0x0f;
struct musb_ep *musb_ep;
struct musb_hw_ep *ep;
void __iomem *regs;
@@ -407,12 +412,14 @@ __acquires(musb->lock)
u16 csr;
if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
- ctrlrequest->wValue != USB_ENDPOINT_HALT)
+ le16_to_cpu(ctrlrequest->wValue)
+ != USB_ENDPOINT_HALT)
break;
ep = musb->endpoints + epnum;
regs = ep->regs;
- is_in = ctrlrequest->wIndex & USB_DIR_IN;
+ is_in = le16_to_cpu(ctrlrequest->wIndex) &
+ USB_DIR_IN;
if (is_in)
musb_ep = &ep->ep_in;
else
@@ -608,7 +615,7 @@ musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req)
*/
musb->set_address = false;
musb->ackpend = MUSB_CSR0_P_SVDRXPKTRDY;
- if (req->wLength == 0) {
+ if (le16_to_cpu(req->wLength) == 0) {
if (req->bRequestType & USB_DIR_IN)
musb->ackpend |= MUSB_CSR0_TXPKTRDY;
musb->ep0_state = MUSB_EP0_STAGE_ACKWAIT;
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Fix big-endian application issue for MUSB gadget
@ 2018-08-02 16:44 Bin Liu
0 siblings, 0 replies; 3+ messages in thread
From: Bin Liu @ 2018-08-02 16:44 UTC (permalink / raw)
To: Alexey Spirkov
Cc: Greg Kroah-Hartman, linux-usb@vger.kernel.org, andrew@ncrmnt.org
Hi,
On Thu, Jul 26, 2018 at 12:52:53PM +0000, Alexey Spirkov wrote:
> Existing code is not applicable to big-endian machines
> ctrlrequest fields received in USB endian - i.e. in little-endian
> and should be converted to cpu endianness before usage.
>
> Signed-off-by: Alexey Spirkov <alexeis@astrosoft.ru>
> ---
> drivers/usb/musb/musb_gadget_ep0.c | 33 ++++++++++++++++++++-------------
> 1 file changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
> index 91a5027..5d5c933 100644
> --- a/drivers/usb/musb/musb_gadget_ep0.c
> +++ b/drivers/usb/musb/musb_gadget_ep0.c
> @@ -82,7 +82,7 @@ static int service_tx_status_request(
> u16 tmp;
> void __iomem *regs;
>
> - epnum = (u8) ctrlrequest->wIndex;
> + epnum = (u8) le16_to_cpu(ctrlrequest->wIndex);
> if (!epnum) {
> result[0] = 0;
> break;
> @@ -217,14 +217,15 @@ __acquires(musb->lock)
> case USB_REQ_SET_ADDRESS:
> /* change it after the status stage */
> musb->set_address = true;
> - musb->address = (u8) (ctrlrequest->wValue & 0x7f);
> + musb->address = (u8) (le16_to_cpu(ctrlrequest->wValue) &
> + 0x7f);
> handled = 1;
> break;
>
> case USB_REQ_CLEAR_FEATURE:
> switch (recip) {
> case USB_RECIP_DEVICE:
> - if (ctrlrequest->wValue
> + if (le16_to_cpu(ctrlrequest->wValue)
> != USB_DEVICE_REMOTE_WAKEUP)
> break;
> musb->may_wakeup = 0;
> @@ -234,7 +235,7 @@ __acquires(musb->lock)
> break;
> case USB_RECIP_ENDPOINT:{
> const u8 epnum =
> - ctrlrequest->wIndex & 0x0f;
> + le16_to_cpu(ctrlrequest->wIndex) & 0x0f;
> struct musb_ep *musb_ep;
> struct musb_hw_ep *ep;
> struct musb_request *request;
> @@ -243,12 +244,14 @@ __acquires(musb->lock)
> u16 csr;
>
> if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
> - ctrlrequest->wValue != USB_ENDPOINT_HALT)
> + le16_to_cpu(ctrlrequest->wValue)
> + != USB_ENDPOINT_HALT)
> break;
>
> ep = musb->endpoints + epnum;
> regs = ep->regs;
> - is_in = ctrlrequest->wIndex & USB_DIR_IN;
> + is_in = le16_to_cpu(ctrlrequest->wIndex) &
> + USB_DIR_IN;
> if (is_in)
> musb_ep = &ep->ep_in;
> else
> @@ -300,17 +303,19 @@ __acquires(musb->lock)
> switch (recip) {
> case USB_RECIP_DEVICE:
> handled = 1;
> - switch (ctrlrequest->wValue) {
> + switch (le16_to_cpu(ctrlrequest->wValue)) {
> case USB_DEVICE_REMOTE_WAKEUP:
> musb->may_wakeup = 1;
> break;
> case USB_DEVICE_TEST_MODE:
> if (musb->g.speed != USB_SPEED_HIGH)
> goto stall;
> - if (ctrlrequest->wIndex & 0xff)
> + if (le16_to_cpu(ctrlrequest->wIndex) &
> + 0xff)
> goto stall;
>
> - switch (ctrlrequest->wIndex >> 8) {
> + switch (le16_to_cpu(ctrlrequest->wIndex)
> + >> 8) {
> case 1:
> pr_debug("TEST_J\n");
> /* TEST_J */
> @@ -399,7 +404,7 @@ __acquires(musb->lock)
>
> case USB_RECIP_ENDPOINT:{
> const u8 epnum =
> - ctrlrequest->wIndex & 0x0f;
> + le16_to_cpu(ctrlrequest->wIndex) & 0x0f;
> struct musb_ep *musb_ep;
> struct musb_hw_ep *ep;
> void __iomem *regs;
> @@ -407,12 +412,14 @@ __acquires(musb->lock)
> u16 csr;
>
> if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
> - ctrlrequest->wValue != USB_ENDPOINT_HALT)
> + le16_to_cpu(ctrlrequest->wValue)
> + != USB_ENDPOINT_HALT)
> break;
>
> ep = musb->endpoints + epnum;
> regs = ep->regs;
> - is_in = ctrlrequest->wIndex & USB_DIR_IN;
> + is_in = le16_to_cpu(ctrlrequest->wIndex) &
> + USB_DIR_IN;
> if (is_in)
> musb_ep = &ep->ep_in;
> else
Since this function uses ctrlrequest->wIndex and ctrlrequest->wValue
many times, can you please create local vars for them, then we don't
have to call le16_to_cpu() on them in every instance?
> @@ -608,7 +615,7 @@ musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req)
> */
> musb->set_address = false;
> musb->ackpend = MUSB_CSR0_P_SVDRXPKTRDY;
> - if (req->wLength == 0) {
> + if (le16_to_cpu(req->wLength) == 0) {
> if (req->bRequestType & USB_DIR_IN)
> musb->ackpend |= MUSB_CSR0_TXPKTRDY;
> musb->ep0_state = MUSB_EP0_STAGE_ACKWAIT;
Regards,
-Bin.
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread
* Fix big-endian application issue for MUSB gadget
@ 2018-08-02 16:51 Bin Liu
0 siblings, 0 replies; 3+ messages in thread
From: Bin Liu @ 2018-08-02 16:51 UTC (permalink / raw)
To: Alexey Spirkov, Greg Kroah-Hartman, linux-usb@vger.kernel.org,
andrew@ncrmnt.org
On Thu, Aug 02, 2018 at 11:44:00AM -0500, Bin Liu wrote:
> Hi,
>
> On Thu, Jul 26, 2018 at 12:52:53PM +0000, Alexey Spirkov wrote:
> > Existing code is not applicable to big-endian machines
> > ctrlrequest fields received in USB endian - i.e. in little-endian
> > and should be converted to cpu endianness before usage.
> >
> > Signed-off-by: Alexey Spirkov <alexeis@astrosoft.ru>
> > ---
> > drivers/usb/musb/musb_gadget_ep0.c | 33 ++++++++++++++++++++-------------
> > 1 file changed, 20 insertions(+), 13 deletions(-)
> >
> > diff --git a/drivers/usb/musb/musb_gadget_ep0.c b/drivers/usb/musb/musb_gadget_ep0.c
> > index 91a5027..5d5c933 100644
> > --- a/drivers/usb/musb/musb_gadget_ep0.c
> > +++ b/drivers/usb/musb/musb_gadget_ep0.c
> > @@ -82,7 +82,7 @@ static int service_tx_status_request(
> > u16 tmp;
> > void __iomem *regs;
> >
> > - epnum = (u8) ctrlrequest->wIndex;
> > + epnum = (u8) le16_to_cpu(ctrlrequest->wIndex);
> > if (!epnum) {
> > result[0] = 0;
> > break;
> > @@ -217,14 +217,15 @@ __acquires(musb->lock)
> > case USB_REQ_SET_ADDRESS:
> > /* change it after the status stage */
> > musb->set_address = true;
> > - musb->address = (u8) (ctrlrequest->wValue & 0x7f);
> > + musb->address = (u8) (le16_to_cpu(ctrlrequest->wValue) &
> > + 0x7f);
> > handled = 1;
> > break;
> >
> > case USB_REQ_CLEAR_FEATURE:
> > switch (recip) {
> > case USB_RECIP_DEVICE:
> > - if (ctrlrequest->wValue
> > + if (le16_to_cpu(ctrlrequest->wValue)
> > != USB_DEVICE_REMOTE_WAKEUP)
> > break;
> > musb->may_wakeup = 0;
> > @@ -234,7 +235,7 @@ __acquires(musb->lock)
> > break;
> > case USB_RECIP_ENDPOINT:{
> > const u8 epnum =
> > - ctrlrequest->wIndex & 0x0f;
> > + le16_to_cpu(ctrlrequest->wIndex) & 0x0f;
> > struct musb_ep *musb_ep;
> > struct musb_hw_ep *ep;
> > struct musb_request *request;
> > @@ -243,12 +244,14 @@ __acquires(musb->lock)
> > u16 csr;
> >
> > if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
> > - ctrlrequest->wValue != USB_ENDPOINT_HALT)
> > + le16_to_cpu(ctrlrequest->wValue)
> > + != USB_ENDPOINT_HALT)
> > break;
> >
> > ep = musb->endpoints + epnum;
> > regs = ep->regs;
> > - is_in = ctrlrequest->wIndex & USB_DIR_IN;
> > + is_in = le16_to_cpu(ctrlrequest->wIndex) &
> > + USB_DIR_IN;
> > if (is_in)
> > musb_ep = &ep->ep_in;
> > else
> > @@ -300,17 +303,19 @@ __acquires(musb->lock)
> > switch (recip) {
> > case USB_RECIP_DEVICE:
> > handled = 1;
> > - switch (ctrlrequest->wValue) {
> > + switch (le16_to_cpu(ctrlrequest->wValue)) {
> > case USB_DEVICE_REMOTE_WAKEUP:
> > musb->may_wakeup = 1;
> > break;
> > case USB_DEVICE_TEST_MODE:
> > if (musb->g.speed != USB_SPEED_HIGH)
> > goto stall;
> > - if (ctrlrequest->wIndex & 0xff)
> > + if (le16_to_cpu(ctrlrequest->wIndex) &
> > + 0xff)
> > goto stall;
> >
> > - switch (ctrlrequest->wIndex >> 8) {
> > + switch (le16_to_cpu(ctrlrequest->wIndex)
> > + >> 8) {
> > case 1:
> > pr_debug("TEST_J\n");
> > /* TEST_J */
> > @@ -399,7 +404,7 @@ __acquires(musb->lock)
> >
> > case USB_RECIP_ENDPOINT:{
> > const u8 epnum =
> > - ctrlrequest->wIndex & 0x0f;
> > + le16_to_cpu(ctrlrequest->wIndex) & 0x0f;
> > struct musb_ep *musb_ep;
> > struct musb_hw_ep *ep;
> > void __iomem *regs;
> > @@ -407,12 +412,14 @@ __acquires(musb->lock)
> > u16 csr;
> >
> > if (epnum == 0 || epnum >= MUSB_C_NUM_EPS ||
> > - ctrlrequest->wValue != USB_ENDPOINT_HALT)
> > + le16_to_cpu(ctrlrequest->wValue)
> > + != USB_ENDPOINT_HALT)
> > break;
> >
> > ep = musb->endpoints + epnum;
> > regs = ep->regs;
> > - is_in = ctrlrequest->wIndex & USB_DIR_IN;
> > + is_in = le16_to_cpu(ctrlrequest->wIndex) &
> > + USB_DIR_IN;
> > if (is_in)
> > musb_ep = &ep->ep_in;
> > else
>
> Since this function uses ctrlrequest->wIndex and ctrlrequest->wValue
> many times, can you please create local vars for them, then we don't
> have to call le16_to_cpu() on them in every instance?
>
> > @@ -608,7 +615,7 @@ musb_read_setup(struct musb *musb, struct usb_ctrlrequest *req)
> > */
> > musb->set_address = false;
> > musb->ackpend = MUSB_CSR0_P_SVDRXPKTRDY;
> > - if (req->wLength == 0) {
> > + if (le16_to_cpu(req->wLength) == 0) {
> > if (req->bRequestType & USB_DIR_IN)
> > musb->ackpend |= MUSB_CSR0_TXPKTRDY;
> > musb->ep0_state = MUSB_EP0_STAGE_ACKWAIT;
Please also fix the patch subject to "usb: musb: gadget: ..." in your
v2.
Regards,
-Bin.
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-08-02 16:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-02 16:44 Fix big-endian application issue for MUSB gadget Bin Liu
-- strict thread matches above, loose matches on Subject: below --
2018-08-02 16:51 Bin Liu
2018-07-26 12:52 Alexey Spirkov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).