Commit 1ca31ae7cfed3e2a8e48fbf6ed6cac06495b6158
Committed by
Stefan Richter
1 parent
2aef469a35
Exists in
master
and in
7 other branches
firewire: Change struct fw_cdev_iso_packet to not use bitfields.
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>
Showing 2 changed files with 24 additions and 7 deletions Side-by-side Diff
drivers/firewire/fw-cdev.c
... | ... | @@ -677,12 +677,21 @@ |
677 | 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 | 688 | static int ioctl_queue_iso(struct client *client, void *buffer) |
681 | 689 | { |
682 | 690 | struct fw_cdev_queue_iso *request = buffer; |
683 | 691 | struct fw_cdev_iso_packet __user *p, *end, *next; |
684 | 692 | struct fw_iso_context *ctx = client->iso_context; |
685 | 693 | unsigned long payload, buffer_end, header_length; |
694 | + u32 control; | |
686 | 695 | int count; |
687 | 696 | struct { |
688 | 697 | struct fw_iso_packet packet; |
689 | 698 | |
... | ... | @@ -717,8 +726,14 @@ |
717 | 726 | end = (void __user *)p + request->size; |
718 | 727 | count = 0; |
719 | 728 | while (p < end) { |
720 | - if (__copy_from_user(&u.packet, p, sizeof(*p))) | |
729 | + if (get_user(control, &p->control)) | |
721 | 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 | 738 | if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { |
724 | 739 | header_length = u.packet.header_length; |
include/linux/firewire-cdev.h
... | ... | @@ -198,13 +198,15 @@ |
198 | 198 | __u32 handle; |
199 | 199 | }; |
200 | 200 | |
201 | +#define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v) | |
202 | +#define FW_CDEV_ISO_INTERRUPT (1 << 16) | |
203 | +#define FW_CDEV_ISO_SKIP (1 << 17) | |
204 | +#define FW_CDEV_ISO_TAG(v) ((v) << 18) | |
205 | +#define FW_CDEV_ISO_SY(v) ((v) << 20) | |
206 | +#define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24) | |
207 | + | |
201 | 208 | struct fw_cdev_iso_packet { |
202 | - __u16 payload_length; /* Length of indirect payload. */ | |
203 | - __u32 interrupt : 1; /* Generate interrupt on this packet */ | |
204 | - __u32 skip : 1; /* Set to not send packet at all. */ | |
205 | - __u32 tag : 2; | |
206 | - __u32 sy : 4; | |
207 | - __u32 header_length : 8; /* Length of immediate header. */ | |
209 | + __u32 control; | |
208 | 210 | __u32 header[0]; |
209 | 211 | }; |
210 | 212 |