aboutsummaryrefslogtreecommitdiff
path: root/drivers/firewire/fw-cdev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-01 08:28:15 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-06-01 08:28:15 -0700
commitf285e3d329ce68cc355fadf4ab2c8f34d7f264cb (patch)
treea40ae43a277bedeec732fd20eee166990974fb58 /drivers/firewire/fw-cdev.c
parentc1a834dc704763673df10282995257f2de93cbe9 (diff)
parentca9a7af35f1ce4a990c6c3aace65ed36f89d50bf (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: firewire: Install firewire-constants.h and firewire-cdev.h for userspace. firewire: Change struct fw_cdev_iso_packet to not use bitfields. firewire: Implement suspend/resume PCI driver hooks. firewire: add to MAINTAINERS firewire: fw-sbp2: implement sysfs ieee1394_id ieee1394: sbp2: offer SAM-conforming target port ID in sysfs ieee1394: fix calculation of sysfs attribute "address"
Diffstat (limited to 'drivers/firewire/fw-cdev.c')
-rw-r--r--drivers/firewire/fw-cdev.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 3ab3585d360..5d402d63799 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;