Skip to contentSkip to conversation

Video/UVC: Fix unaligned exceptions in uvc video driver.

PATCH In review Bryan Wu 3 participants 5 messages Nov 6, 2008 – Nov 11, 2008 Media (V4L/DVB)

lore
Share & tools
lore

Bryan Wu

author
#0 lore raw

PATCH 1/1 Video/UVC: Fix unaligned exceptions in uvc video driver.

From: Michael Hennerich <[email protected]>

buffer can be odd aligned on some NOMMU machine such as Blackfin

---
 drivers/media/video/uvc/uvc_driver.c |   37 +++++++++++++++++----------------
 1 files changed, 19 insertions(+), 18 deletions(-)
drivers/media/video/uvc/uvc_driver.c +19 -18
index d7ad060..9b4f469 100644
@@ -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];
Signature · 1 line
1.5.6.3
#1 lore raw

Hi Bryan, Michael,

Thanks for the patch.

Quoted 3 lines · Bryan Wu

From: Michael Hennerich <[email protected]>

buffer can be odd aligned on some NOMMU machine such as Blackfin

The comment is a bit misleading. Buffers can be odd-aligned independently off the machine type. The issue comes from machines that can't access unaligned memory. Something like "Fix access to unaligned memory" would be better.

Quoted 20 lines
---
 drivers/media/video/uvc/uvc_driver.c |   37

+++++++++++++++++---------------- 1 files changed, 19 insertions(+), 18 deletions(-)

(quoted diff) +0 -0

b/drivers/media/video/uvc/uvc_driver.c index d7ad060..9b4f469 100644

drivers/media/video/uvc/uvc_driver.c +1 -0
@@ -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>

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device *dev, · line 436

Quoted 8 lines
drivers/media/video/uvc/uvc_driver.c +1 -4
@@ -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]));

What about using get_unaligned_le16 and get_unaligned_le32 directly ? Lines would be shorter and could be kept behind the 80 columns limit more easily.

Tell me if you want to resubmit or if I should make the modification myself (including the patch description).

Quoted 92 lines
drivers/media/video/uvc/uvc_driver.c +10 -7
+		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. */
drivers/media/video/uvc/uvc_driver.c +6 -6
 		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);

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 1085

Quoted 8 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
@@ -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];

Cheers,

Laurent Pinchart

author
#2 lore raw
Quoted 45 lines · Laurent Pinchart

Hi Bryan, Michael,

Thanks for the patch.

Quoted 3 lines · Bryan Wu

From: Michael Hennerich <[email protected]>

buffer can be odd aligned on some NOMMU machine such as Blackfin

The comment is a bit misleading. Buffers can be odd-aligned independently off the machine type. The issue comes from machines that can't access unaligned memory. Something like "Fix access to unaligned memory" would be better.

Quoted 20 lines
---
 drivers/media/video/uvc/uvc_driver.c |   37

+++++++++++++++++---------------- 1 files changed, 19 insertions(+), 18 deletions(-)

(quoted diff) +0 -0

b/drivers/media/video/uvc/uvc_driver.c index d7ad060..9b4f469 100644

drivers/media/video/uvc/uvc_driver.c +1 -0
@@ -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>

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device *dev, · line 436

Quoted 8 lines
drivers/media/video/uvc/uvc_driver.c +1 -4
@@ -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]));

What about using get_unaligned_le16 and get_unaligned_le32 directly ? Lines would be shorter and could be kept behind the 80 columns limit more easily.

Quoted 3 lines

Tell me if you want to resubmit or if I should make the modification myself (including the patch description).

I guess Michael will update this patch according to you review. Then we will resubmit it.

Thanks a lot
-Bryan

#3 lore raw
In reply to Laurent Pinchart
Quoted 7 lines

-----Original Message-----
From: Laurent Pinchart [mailto:[email protected]]
Sent: Sunday, November 09, 2008 1:55 PM
To: Bryan Wu
Cc: [email protected]; [email protected];

linux-

Quoted 6 lines

[email protected]; Michael Hennerich
Subject: Re: [PATCH] Video/UVC: Fix unaligned exceptions in uvc video driver.

Hi Bryan, Michael,

Quoted 8 lines

Thanks for the patch.

Quoted 3 lines · Bryan Wu

From: Michael Hennerich <[email protected]>

buffer can be odd aligned on some NOMMU machine such as Blackfin

The comment is a bit misleading. Buffers can be odd-aligned

independently

Quoted 2 lines

off
the machine type. The issue comes from machines that can't access

unaligned

Quoted 1 line

memory. Something like "Fix access to unaligned memory" would be

better.

Quoted 6 lines
Quoted 6 lines
---
 drivers/media/video/uvc/uvc_driver.c |   37

+++++++++++++++++---------------- 1 files changed, 19 insertions(+),

18

Quoted 13 lines
Quoted 13 lines

deletions(-)

(quoted diff) +0 -0

b/drivers/media/video/uvc/uvc_driver.c index d7ad060..9b4f469 100644

drivers/media/video/uvc/uvc_driver.c +1 -0
@@ -31,6 +31,7 @@
 #include <linux/videodev2.h>
 #include <linux/vmalloc.h>
 #include <linux/wait.h>
+#include <asm/unaligned.h>
 #include <asm/atomic.h>
 
Quoted 2 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 #include <media/v4l2-common.h>
@@ -432,20 +433,20 @@ static int uvc_parse_format(struct uvc_device

*dev,

Quoted 6 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device *dev,

Quoted 6 lines
drivers/media/video/uvc/uvc_driver.c +0 -3
 		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]);

Quoted 1 line

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device · line 437

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +0 -1
-		frame->dwMaxBitRate = le32_to_cpup((__le32

*)&buffer[13]);

Quoted 4 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device · line 435

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +1 -0
+		frame->wWidth = le16_to_cpu(get_unaligned((__le16 *)

&buffer[5]));

What about using get_unaligned_le16 and get_unaligned_le32 directly ?

Lines

Quoted 1 line

would be shorter and could be kept behind the 80 columns limit more

easily.

Quoted 2 lines

Tell me if you want to resubmit or if I should make the modification

myself

Quoted 1 line

(including the patch description).

Laurent,

Well - I just used the same style already used in various other places in the uvc driver. - Just wanted to be consistent.

If you don't mind doing the changes (including the patch description), please go ahead.

Thanks and best regards,
Michael

Quoted 4 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device · line 436

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +1 -0
+		frame->wHeight = le16_to_cpu(get_unaligned((__le16 *)

&buffer[7]));

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device · line 437

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +1 -0
+		frame->dwMinBitRate = le32_to_cpu(get_unaligned((__le32

*)

Quoted 2 lines

&buffer[9]));

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device · line 438

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +1 -0
+		frame->dwMaxBitRate = le32_to_cpu(get_unaligned((__le32

*)

Quoted 4 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device *dev,

Quoted 4 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 &buffer[13])); if (ftype != VS_FRAME_FRAME_BASED) {
 			frame->dwMaxVideoFrameBufferSize =
-				le32_to_cpup((__le32 *)&buffer[17]);
+				le32_to_cpu(get_unaligned((__le32 *)

&buffer[17]));

Quoted 3 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device *dev,

Quoted 3 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 			frame->dwDefaultFrameInterval =
-				le32_to_cpup((__le32 *)&buffer[21]);
+				le32_to_cpu(get_unaligned((__le32 *)

&buffer[21]));

Quoted 6 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device *dev,

Quoted 6 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 			frame->bFrameIntervalType = buffer[25];
 		} else {
 			frame->dwMaxVideoFrameBufferSize = 0;
 			frame->dwDefaultFrameInterval =
-				le32_to_cpup((__le32 *)&buffer[17]);
+				le32_to_cpu(get_unaligned((__le32 *)

&buffer[17]));

Quoted 4 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device

Quoted 4 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 			frame->bFrameIntervalType = buffer[21];
 		}
 		frame->dwFrameInterval = *intervals;
@@ -468,7 +469,7 @@ static int uvc_parse_format(struct uvc_device

*dev,

Quoted 4 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device *dev,

Quoted 4 lines
drivers/media/video/uvc/uvc_driver.c +0 -1
 		 * some other divisions by zero which could happen.
 		 */
 		for (i = 0; i < n; ++i) {
-			interval = le32_to_cpup((__le32

*)&buffer[26+4*i]);

Quoted 6 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_format(struct uvc_device · line 472

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +1 -0
+			interval = le32_to_cpu(get_unaligned((__le32 *)

&buffer[26+4*i]));

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_vendor_control(struct

Quoted 4 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 			*(*intervals)++ = interval ? interval : 1;
 		}
 
@@ -814,7 +815,7 @@ static int uvc_parse_vendor_control(struct

uvc_device

Quoted 5 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_vendor_control(struct uvc_device *dev,

Quoted 5 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 *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]));

Quoted 1 line

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_vendor_control(struct · line 819

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +0 -0
 		unit->extension.baSourceID = (__u8 *)unit + sizeof

*unit;

Quoted 9 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct

Quoted 3 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 		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

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct uvc_device *dev,

Quoted 5 lines
drivers/media/video/uvc/uvc_driver.c +0 -2
 *dev, return -EINVAL;
 		}
 
-		dev->uvc_version = le16_to_cpup((__le16 *)&buffer[3]);
-		dev->clock_frequency = le32_to_cpup((__le32

*)&buffer[7]);

Quoted 3 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 862

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +1 -0
+		dev->uvc_version = le16_to_cpu(get_unaligned((__le16 *)

&buffer[3]));

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 863

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +1 -0
+		dev->clock_frequency = le32_to_cpu(get_unaligned((__le32

*)

Quoted 11 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct

Quoted 5 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 &buffer[7]));
 
 		/* Parse all USB Video Streaming interfaces. */
drivers/media/video/uvc/uvc_driver.c +0 -0
 		for (i = 0; i < n; ++i) {
@@ -886,7 +887,7 @@ static int uvc_parse_standard_control(struct

uvc_device

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct uvc_device *dev,

Quoted 5 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 *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]));

Quoted 2 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 892

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 		if ((type & 0xff00) == 0) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d

videocontrol "

Quoted 1 line

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 893

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +0 -0
 				"interface %d INPUT_TERMINAL %d has

invalid "

Quoted 3 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 930

Quoted 3 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
@@ -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;

Quoted 3 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct uvc_device *dev,

Quoted 3 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 			term->camera.wObjectiveFocalLengthMin =
-				le16_to_cpup((__le16 *)&buffer[8]);
+				le16_to_cpu(get_unaligned((__le16 *)

&buffer[8]));

Quoted 3 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct uvc_device *dev,

Quoted 3 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 			term->camera.wObjectiveFocalLengthMax =
-				le16_to_cpup((__le16 *)&buffer[10]);
+				le16_to_cpu(get_unaligned((__le16 *)

&buffer[10]));

Quoted 3 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct uvc_device *dev,

Quoted 3 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 			term->camera.wOcularFocalLength =
-				le16_to_cpup((__le16 *)&buffer[12]);
+				le16_to_cpu(get_unaligned((__le16 *)

&buffer[12]));

Quoted 2 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 938

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 			memcpy(term->camera.bmControls, &buffer[15], n);
 		} else if (UVC_ENTITY_TYPE(term) ==

ITT_MEDIA_TRANSPORT_INPUT)

Quoted 9 lines

{

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 			term->media.bControlSize = n;
@@ -968,7 +969,7 @@ static int uvc_parse_standard_control(struct

uvc_device

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct uvc_device *dev,

Quoted 5 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 *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]));

Quoted 2 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 974

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 		if ((type & 0xff00) == 0) {
 			uvc_trace(UVC_TRACE_DESCR, "device %d

videocontrol "

Quoted 1 line

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 975

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +0 -0
 				"interface %d OUTPUT_TERMINAL %d has

invalid "

Quoted 6 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 1046

Quoted 6 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
@@ -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]));

Quoted 2 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 1048

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 		unit->processing.bControlSize = buffer[7];
 		unit->processing.bmControls = (__u8 *)unit + sizeof

*unit;

Quoted 3 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 1079

Quoted 3 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 		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],

Quoted 5 lines

16);

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_vendor_control(struct uvc_device *dev,

Quoted 4 lines
drivers/media/video/uvc/uvc_driver.c +1 -1
 		unit->extension.bNumControls = buffer[20];
 		unit->extension.bNrInPins =
-			le16_to_cpup((__le16 *)&buffer[21]);
+			le16_to_cpu(get_unaligned((__le16 *)

&buffer[21]));

Quoted 1 line

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 1083

Quoted 1 line
drivers/media/video/uvc/uvc_driver.c +0 -0
 		unit->extension.baSourceID = (__u8 *)unit + sizeof

*unit;

Quoted 6 lines

drivers/media/video/uvc/uvc_driver.c static int uvc_parse_standard_control(struct · line 1085

Quoted 2 lines
drivers/media/video/uvc/uvc_driver.c +0 -0
 		memcpy(unit->extension.baSourceID, &buffer[22], p);
 		unit->extension.bControlSize = buffer[22+p];

Cheers,

Laurent Pinchart

#4 lore raw
Quoted 22 lines · Michael
Quoted 22 lines

-----Original Message-----
From: Laurent Pinchart [mailto:[email protected]]
Sent: Sunday, November 09, 2008 1:55 PM
To: Bryan Wu
Cc: [email protected]; [email protected]; [email protected]; Michael Hennerich
Subject: Re: [PATCH] Video/UVC: Fix unaligned exceptions in uvc video driver.

Hi Bryan, Michael,

Thanks for the patch.

Quoted 3 lines · Bryan Wu

From: Michael Hennerich <[email protected]>

buffer can be odd aligned on some NOMMU machine such as Blackfin

The comment is a bit misleading. Buffers can be odd-aligned independently off the machine type. The issue comes from machines that can't access unaligned memory. Something like "Fix access to unaligned memory" would be better.

[snip]

Quoted 10 lines
Quoted 5 lines

What about using get_unaligned_le16 and get_unaligned_le32 directly ? Lines would be shorter and could be kept behind the 80 columns limit more easily.
Tell me if you want to resubmit or if I should make the modification myself (including the patch description).

Laurent,

Well - I just used the same style already used in various other places in the uvc driver. - Just wanted to be consistent.

No worries. get_unaligned_le{16|32} has been introduced in the kernel recently and I haven't updated the uvcvideo driver like I should have. I'll fix that.

Quoted 2 lines

If you don't mind doing the changes (including the patch description), please go ahead.

Ok I'll fix and submit the patch.

Best regards,

Laurent Pinchart

--
video4linux-list mailing list
Unsubscribe mailto:[email protected]?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list