diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-01 11:28:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-06-01 11:28:15 -0400 |
commit | f285e3d329ce68cc355fadf4ab2c8f34d7f264cb (patch) | |
tree | a40ae43a277bedeec732fd20eee166990974fb58 /drivers/firewire/fw-cdev.c | |
parent | c1a834dc704763673df10282995257f2de93cbe9 (diff) | |
parent | ca9a7af35f1ce4a990c6c3aace65ed36f89d50bf (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.c | 17 |
1 files changed, 16 insertions, 1 deletions
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) | |||
677 | return 0; | 677 | return 0; |
678 | } | 678 | } |
679 | 679 | ||
680 | /* Macros for decoding the iso packet control header. */ | ||
681 | #define GET_PAYLOAD_LENGTH(v) ((v) & 0xffff) | ||
682 | #define GET_INTERRUPT(v) (((v) >> 16) & 0x01) | ||
683 | #define GET_SKIP(v) (((v) >> 17) & 0x01) | ||
684 | #define GET_TAG(v) (((v) >> 18) & 0x02) | ||
685 | #define GET_SY(v) (((v) >> 20) & 0x04) | ||
686 | #define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff) | ||
687 | |||
680 | static int ioctl_queue_iso(struct client *client, void *buffer) | 688 | static int ioctl_queue_iso(struct client *client, void *buffer) |
681 | { | 689 | { |
682 | struct fw_cdev_queue_iso *request = buffer; | 690 | struct fw_cdev_queue_iso *request = buffer; |
683 | struct fw_cdev_iso_packet __user *p, *end, *next; | 691 | struct fw_cdev_iso_packet __user *p, *end, *next; |
684 | struct fw_iso_context *ctx = client->iso_context; | 692 | struct fw_iso_context *ctx = client->iso_context; |
685 | unsigned long payload, buffer_end, header_length; | 693 | unsigned long payload, buffer_end, header_length; |
694 | u32 control; | ||
686 | int count; | 695 | int count; |
687 | struct { | 696 | struct { |
688 | struct fw_iso_packet packet; | 697 | struct fw_iso_packet packet; |
@@ -717,8 +726,14 @@ static int ioctl_queue_iso(struct client *client, void *buffer) | |||
717 | end = (void __user *)p + request->size; | 726 | end = (void __user *)p + request->size; |
718 | count = 0; | 727 | count = 0; |
719 | while (p < end) { | 728 | while (p < end) { |
720 | if (__copy_from_user(&u.packet, p, sizeof(*p))) | 729 | if (get_user(control, &p->control)) |
721 | return -EFAULT; | 730 | return -EFAULT; |
731 | u.packet.payload_length = GET_PAYLOAD_LENGTH(control); | ||
732 | u.packet.interrupt = GET_INTERRUPT(control); | ||
733 | u.packet.skip = GET_SKIP(control); | ||
734 | u.packet.tag = GET_TAG(control); | ||
735 | u.packet.sy = GET_SY(control); | ||
736 | u.packet.header_length = GET_HEADER_LENGTH(control); | ||
722 | 737 | ||
723 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { | 738 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { |
724 | header_length = u.packet.header_length; | 739 | header_length = u.packet.header_length; |