From b2fb47f1873ae812ce33129996a22b11a36d0aa9 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 15 Dec 2011 08:40:51 -0700 Subject: USB: Use (get|put)_unaligned for accessing wMaxPacketSize In 9792987721c7980453fe6447c3fa6593b44f8458 Stefan describes a usecase where the previous behavior of leaving wMaxPacketSize be unaligned caused fatal problems. The initial fix for this problem was incomplete however as it showed another cases of non-aligned access that previously worked implicitly. This switches to making sure that all access of wMaxPacketSize are done via (get|put)_unaligned. In order to maintain a level of readability to the code in some cases we now use a variable for the value of wMaxPacketSize and in others, a macro. Cc: Minkyu Kang Cc: Remy Bohmer OpenRISC: Tested-by: Stefan Kristiansson Beagleboard xM, Pandaboard run-tested, s5p_goni build-tested. Signed-off-by: Tom Rini --- drivers/usb/gadget/epautoconf.c | 8 +++++--- drivers/usb/gadget/s3c_udc_otg.c | 10 ++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/usb') diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 1896489..5b8776e 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "gadget_chips.h" #define isdigit(c) ('0' <= (c) && (c) <= '9') @@ -127,7 +128,7 @@ static int ep_matches( * where it's an output parameter representing the full speed limit. * the usb spec fixes high speed bulk maxpacket at 512 bytes. */ - max = 0x7ff & le16_to_cpu(desc->wMaxPacketSize); + max = 0x7ff & le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)); switch (type) { case USB_ENDPOINT_XFER_INT: /* INT: limit 64 bytes full speed, 1024 high speed */ @@ -143,7 +144,8 @@ static int ep_matches( return 0; /* BOTH: "high bandwidth" works only at high speed */ - if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) { + if ((get_unaligned(&desc->wMaxPacketSize) & + __constant_cpu_to_le16(3<<11))) { if (!gadget->is_dualspeed) return 0; /* configure your hardware with enough buffering!! */ @@ -176,7 +178,7 @@ static int ep_matches( /* min() doesn't work on bitfields with gcc-3.5 */ if (size > 64) size = 64; - desc->wMaxPacketSize = cpu_to_le16(size); + put_unaligned(cpu_to_le16(size), &desc->wMaxPacketSize); } return 1; } diff --git a/drivers/usb/gadget/s3c_udc_otg.c b/drivers/usb/gadget/s3c_udc_otg.c index 5a3ac78..901fac9 100644 --- a/drivers/usb/gadget/s3c_udc_otg.c +++ b/drivers/usb/gadget/s3c_udc_otg.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -586,7 +587,8 @@ static int s3c_ep_enable(struct usb_ep *_ep, if (!_ep || !desc || ep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || ep->bEndpointAddress != desc->bEndpointAddress - || ep_maxpacket(ep) < le16_to_cpu(desc->wMaxPacketSize)) { + || ep_maxpacket(ep) < + le16_to_cpu(get_unaligned(&desc->wMaxPacketSize))) { DEBUG("%s: bad ep or descriptor\n", __func__); return -EINVAL; @@ -603,8 +605,8 @@ static int s3c_ep_enable(struct usb_ep *_ep, /* hardware _could_ do smaller, but driver doesn't */ if ((desc->bmAttributes == USB_ENDPOINT_XFER_BULK - && le16_to_cpu(desc->wMaxPacketSize) != ep_maxpacket(ep)) - || !desc->wMaxPacketSize) { + && le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)) != + ep_maxpacket(ep)) || !get_unaligned(&desc->wMaxPacketSize)) { DEBUG("%s: bad %s maxpacket\n", __func__, _ep->name); return -ERANGE; @@ -620,7 +622,7 @@ static int s3c_ep_enable(struct usb_ep *_ep, ep->stopped = 0; ep->desc = desc; ep->pio_irqs = 0; - ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); + ep->ep.maxpacket = le16_to_cpu(get_unaligned(&desc->wMaxPacketSize)); /* Reset halt state */ s3c_udc_set_nak(ep); -- cgit v1.1