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>
This commit is contained in:
Kristian Høgsberg 2007-05-31 11:16:43 -04:00 committed by Stefan Richter
parent 2aef469a35
commit 1ca31ae7cf
2 changed files with 24 additions and 7 deletions

View file

@ -677,12 +677,21 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
return 0; 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) static int ioctl_queue_iso(struct client *client, void *buffer)
{ {
struct fw_cdev_queue_iso *request = buffer; struct fw_cdev_queue_iso *request = buffer;
struct fw_cdev_iso_packet __user *p, *end, *next; struct fw_cdev_iso_packet __user *p, *end, *next;
struct fw_iso_context *ctx = client->iso_context; struct fw_iso_context *ctx = client->iso_context;
unsigned long payload, buffer_end, header_length; unsigned long payload, buffer_end, header_length;
u32 control;
int count; int count;
struct { struct {
struct fw_iso_packet packet; 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; end = (void __user *)p + request->size;
count = 0; count = 0;
while (p < end) { while (p < end) {
if (__copy_from_user(&u.packet, p, sizeof(*p))) if (get_user(control, &p->control))
return -EFAULT; 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) { if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
header_length = u.packet.header_length; header_length = u.packet.header_length;

View file

@ -198,13 +198,15 @@ struct fw_cdev_create_iso_context {
__u32 handle; __u32 handle;
}; };
#define FW_CDEV_ISO_PAYLOAD_LENGTH(v) (v)
#define FW_CDEV_ISO_INTERRUPT (1 << 16)
#define FW_CDEV_ISO_SKIP (1 << 17)
#define FW_CDEV_ISO_TAG(v) ((v) << 18)
#define FW_CDEV_ISO_SY(v) ((v) << 20)
#define FW_CDEV_ISO_HEADER_LENGTH(v) ((v) << 24)
struct fw_cdev_iso_packet { struct fw_cdev_iso_packet {
__u16 payload_length; /* Length of indirect payload. */ __u32 control;
__u32 interrupt : 1; /* Generate interrupt on this packet */
__u32 skip : 1; /* Set to not send packet at all. */
__u32 tag : 2;
__u32 sy : 4;
__u32 header_length : 8; /* Length of immediate header. */
__u32 header[0]; __u32 header[0];
}; };