From 1ca31ae7cfed3e2a8e48fbf6ed6cac06495b6158 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= <krh@redhat.com>
Date: Thu, 31 May 2007 11:16:43 -0400
Subject: firewire: Change struct fw_cdev_iso_packet to not use bitfields.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The struct is part of the userspace interface and can not use
bitfields.  This patch replaces the bitfields with a __u32 'control'
word and provides access macros to set the bits.

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
---
 drivers/firewire/fw-cdev.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

(limited to 'drivers/firewire')

diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 3ab3585d3601..5d402d63799f 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -677,12 +677,21 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
 	return 0;
 }
 
+/* Macros for decoding the iso packet control header. */
+#define GET_PAYLOAD_LENGTH(v)	((v) & 0xffff)
+#define GET_INTERRUPT(v)	(((v) >> 16) & 0x01)
+#define GET_SKIP(v)		(((v) >> 17) & 0x01)
+#define GET_TAG(v)		(((v) >> 18) & 0x02)
+#define GET_SY(v)		(((v) >> 20) & 0x04)
+#define GET_HEADER_LENGTH(v)	(((v) >> 24) & 0xff)
+
 static int ioctl_queue_iso(struct client *client, void *buffer)
 {
 	struct fw_cdev_queue_iso *request = buffer;
 	struct fw_cdev_iso_packet __user *p, *end, *next;
 	struct fw_iso_context *ctx = client->iso_context;
 	unsigned long payload, buffer_end, header_length;
+	u32 control;
 	int count;
 	struct {
 		struct fw_iso_packet packet;
@@ -717,8 +726,14 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
 	end = (void __user *)p + request->size;
 	count = 0;
 	while (p < end) {
-		if (__copy_from_user(&u.packet, p, sizeof(*p)))
+		if (get_user(control, &p->control))
 			return -EFAULT;
+		u.packet.payload_length = GET_PAYLOAD_LENGTH(control);
+		u.packet.interrupt = GET_INTERRUPT(control);
+		u.packet.skip = GET_SKIP(control);
+		u.packet.tag = GET_TAG(control);
+		u.packet.sy = GET_SY(control);
+		u.packet.header_length = GET_HEADER_LENGTH(control);
 
 		if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
 			header_length = u.packet.header_length;
-- 
cgit v1.2.3