From: Bryan Wu <cooloney@kernel.org>
To: laurent.pinchart@skynet.be, linux-uvc-devel@lists.berlios.de,
video4linux-list@redhat.com
Cc: linux-kernel@vger.kernel.org,
Michael Hennerich <michael.hennerich@analog.com>,
Bryan Wu <cooloney@kernel.org>
Subject: [PATCH] Video/UVC: Fix unaligned exceptions in uvc video driver.
Date: Thu, 6 Nov 2008 17:17:32 +0800 [thread overview]
Message-ID: <1225963052-6657-1-git-send-email-cooloney@kernel.org> (raw)
From: Michael Hennerich <michael.hennerich@analog.com>
buffer can be odd aligned on some NOMMU machine such as Blackfin
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
---
drivers/media/video/uvc/uvc_driver.c | 37 +++++++++++++++++----------------
1 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index d7ad060..9b4f469 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -31,6 +31,7 @@
#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/wait.h>
+#include <asm/unaligned.h>
#include <asm/atomic.h>
#include <media/v4l2-common.h>
@@ -432,20 +433,20 @@ static int uvc_parse_format(struct uvc_device *dev,
frame->bFrameIndex = buffer[3];
frame->bmCapabilities = buffer[4];
- frame->wWidth = le16_to_cpup((__le16 *)&buffer[5]);
- frame->wHeight = le16_to_cpup((__le16 *)&buffer[7]);
- frame->dwMinBitRate = le32_to_cpup((__le32 *)&buffer[9]);
- frame->dwMaxBitRate = le32_to_cpup((__le32 *)&buffer[13]);
+ frame->wWidth = le16_to_cpu(get_unaligned((__le16 *) &buffer[5]));
+ frame->wHeight = le16_to_cpu(get_unaligned((__le16 *) &buffer[7]));
+ frame->dwMinBitRate = le32_to_cpu(get_unaligned((__le32 *) &buffer[9]));
+ frame->dwMaxBitRate = le32_to_cpu(get_unaligned((__le32 *) &buffer[13]));
if (ftype != VS_FRAME_FRAME_BASED) {
frame->dwMaxVideoFrameBufferSize =
- le32_to_cpup((__le32 *)&buffer[17]);
+ le32_to_cpu(get_unaligned((__le32 *) &buffer[17]));
frame->dwDefaultFrameInterval =
- le32_to_cpup((__le32 *)&buffer[21]);
+ le32_to_cpu(get_unaligned((__le32 *) &buffer[21]));
frame->bFrameIntervalType = buffer[25];
} else {
frame->dwMaxVideoFrameBufferSize = 0;
frame->dwDefaultFrameInterval =
- le32_to_cpup((__le32 *)&buffer[17]);
+ le32_to_cpu(get_unaligned((__le32 *) &buffer[17]));
frame->bFrameIntervalType = buffer[21];
}
frame->dwFrameInterval = *intervals;
@@ -468,7 +469,7 @@ static int uvc_parse_format(struct uvc_device *dev,
* some other divisions by zero which could happen.
*/
for (i = 0; i < n; ++i) {
- interval = le32_to_cpup((__le32 *)&buffer[26+4*i]);
+ interval = le32_to_cpu(get_unaligned((__le32 *) &buffer[26+4*i]));
*(*intervals)++ = interval ? interval : 1;
}
@@ -814,7 +815,7 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
unit->extension.bNumControls = buffer[20];
unit->extension.bNrInPins =
- le16_to_cpup((__le16 *)&buffer[21]);
+ le16_to_cpu(get_unaligned((__le16 *) &buffer[21]));
unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
memcpy(unit->extension.baSourceID, &buffer[22], p);
unit->extension.bControlSize = buffer[22+p];
@@ -858,8 +859,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}
- dev->uvc_version = le16_to_cpup((__le16 *)&buffer[3]);
- dev->clock_frequency = le32_to_cpup((__le32 *)&buffer[7]);
+ dev->uvc_version = le16_to_cpu(get_unaligned((__le16 *) &buffer[3]));
+ dev->clock_frequency = le32_to_cpu(get_unaligned((__le32 *) &buffer[7]));
/* Parse all USB Video Streaming interfaces. */
for (i = 0; i < n; ++i) {
@@ -886,7 +887,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
/* Make sure the terminal type MSB is not null, otherwise it
* could be confused with a unit.
*/
- type = le16_to_cpup((__le16 *)&buffer[4]);
+ type = le16_to_cpu(get_unaligned((__le16 *) &buffer[4]));
if ((type & 0xff00) == 0) {
uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
"interface %d INPUT_TERMINAL %d has invalid "
@@ -928,11 +929,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
term->camera.bControlSize = n;
term->camera.bmControls = (__u8 *)term + sizeof *term;
term->camera.wObjectiveFocalLengthMin =
- le16_to_cpup((__le16 *)&buffer[8]);
+ le16_to_cpu(get_unaligned((__le16 *) &buffer[8]));
term->camera.wObjectiveFocalLengthMax =
- le16_to_cpup((__le16 *)&buffer[10]);
+ le16_to_cpu(get_unaligned((__le16 *) &buffer[10]));
term->camera.wOcularFocalLength =
- le16_to_cpup((__le16 *)&buffer[12]);
+ le16_to_cpu(get_unaligned((__le16 *) &buffer[12]));
memcpy(term->camera.bmControls, &buffer[15], n);
} else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) {
term->media.bControlSize = n;
@@ -968,7 +969,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
/* Make sure the terminal type MSB is not null, otherwise it
* could be confused with a unit.
*/
- type = le16_to_cpup((__le16 *)&buffer[4]);
+ type = le16_to_cpu(get_unaligned((__le16 *) &buffer[4]));
if ((type & 0xff00) == 0) {
uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
"interface %d OUTPUT_TERMINAL %d has invalid "
@@ -1042,7 +1043,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
unit->type = buffer[2];
unit->processing.bSourceID = buffer[4];
unit->processing.wMaxMultiplier =
- le16_to_cpup((__le16 *)&buffer[5]);
+ le16_to_cpu(get_unaligned((__le16 *) &buffer[5]));
unit->processing.bControlSize = buffer[7];
unit->processing.bmControls = (__u8 *)unit + sizeof *unit;
memcpy(unit->processing.bmControls, &buffer[8], n);
@@ -1078,7 +1079,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
unit->extension.bNumControls = buffer[20];
unit->extension.bNrInPins =
- le16_to_cpup((__le16 *)&buffer[21]);
+ le16_to_cpu(get_unaligned((__le16 *) &buffer[21]));
unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
memcpy(unit->extension.baSourceID, &buffer[22], p);
unit->extension.bControlSize = buffer[22+p];
--
1.5.6.3
next reply other threads:[~2008-11-06 9:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-06 9:17 Bryan Wu [this message]
2008-11-09 12:55 ` Laurent Pinchart
2008-11-10 2:07 ` Bryan Wu
2008-11-10 10:51 ` Hennerich, Michael
2008-11-11 17:11 ` Laurent Pinchart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1225963052-6657-1-git-send-email-cooloney@kernel.org \
--to=cooloney@kernel.org \
--cc=laurent.pinchart@skynet.be \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-uvc-devel@lists.berlios.de \
--cc=michael.hennerich@analog.com \
--cc=video4linux-list@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®