summaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device-cdev.c
diff options
context:
space:
mode:
authorKristian Høgsberg2007-02-16 23:34:44 +0100
committerStefan Richter2007-03-09 22:03:00 +0100
commit9b32d5f3074e9b1afaa39a360a59fd77a2214783 (patch)
tree441cde033cc8a55b7bc9715684c42554fa259cc4 /drivers/firewire/fw-device-cdev.c
parentfirewire: Log OHCI chipset version in PCI probe. (diff)
downloadkernel-qcow2-linux-9b32d5f3074e9b1afaa39a360a59fd77a2214783.tar.gz
kernel-qcow2-linux-9b32d5f3074e9b1afaa39a360a59fd77a2214783.tar.xz
kernel-qcow2-linux-9b32d5f3074e9b1afaa39a360a59fd77a2214783.zip
firewire: Acummulate received iso headers and send them back to user space.
Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-device-cdev.c')
-rw-r--r--drivers/firewire/fw-device-cdev.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/firewire/fw-device-cdev.c b/drivers/firewire/fw-device-cdev.c
index 1ce33d4f91a3..6545fb8214d8 100644
--- a/drivers/firewire/fw-device-cdev.c
+++ b/drivers/firewire/fw-device-cdev.c
@@ -383,20 +383,24 @@ static int ioctl_send_response(struct client *client, void __user *arg)
}
static void
-iso_callback(struct fw_iso_context *context, int status, u32 cycle, void *data)
+iso_callback(struct fw_iso_context *context, u32 cycle,
+ size_t header_length, void *header, void *data)
{
struct client *client = data;
struct iso_interrupt *interrupt;
- interrupt = kzalloc(sizeof *interrupt, GFP_ATOMIC);
+ interrupt = kzalloc(sizeof *interrupt + header_length, GFP_ATOMIC);
if (interrupt == NULL)
return;
interrupt->interrupt.type = FW_CDEV_EVENT_ISO_INTERRUPT;
interrupt->interrupt.closure = 0;
interrupt->interrupt.cycle = cycle;
+ interrupt->interrupt.header_length = header_length;
+ memcpy(interrupt->interrupt.header, header, header_length);
queue_event(client, &interrupt->event,
- &interrupt->interrupt, sizeof interrupt->interrupt, NULL, 0);
+ &interrupt->interrupt,
+ sizeof interrupt->interrupt + header_length, NULL, 0);
}
static int ioctl_create_iso_context(struct client *client, void __user *arg)
@@ -423,6 +427,7 @@ static int ioctl_queue_iso(struct client *client, void __user *arg)
{
struct fw_cdev_queue_iso request;
struct fw_cdev_iso_packet __user *p, *end, *next;
+ struct fw_iso_context *ctx = client->iso_context;
unsigned long payload, payload_end, header_length;
int count;
struct {
@@ -430,7 +435,7 @@ static int ioctl_queue_iso(struct client *client, void __user *arg)
u8 header[256];
} u;
- if (client->iso_context == NULL)
+ if (ctx == NULL)
return -EINVAL;
if (copy_from_user(&request, arg, sizeof request))
return -EFAULT;
@@ -461,13 +466,17 @@ static int ioctl_queue_iso(struct client *client, void __user *arg)
if (__copy_from_user(&u.packet, p, sizeof *p))
return -EFAULT;
- if (client->iso_context->type == FW_ISO_CONTEXT_TRANSMIT) {
+ if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
header_length = u.packet.header_length;
} else {
/* We require that header_length is a multiple of
* the fixed header size, ctx->header_size */
- if (u.packet.header_length % client->iso_context->header_size != 0)
+ if (ctx->header_size == 0) {
+ if (u.packet.header_length > 0)
+ return -EINVAL;
+ } else if (u.packet.header_length % ctx->header_size != 0) {
return -EINVAL;
+ }
header_length = 0;
}
@@ -484,8 +493,8 @@ static int ioctl_queue_iso(struct client *client, void __user *arg)
if (payload + u.packet.payload_length > payload_end)
return -EINVAL;
- if (fw_iso_context_queue(client->iso_context,
- &u.packet, &client->buffer, payload))
+ if (fw_iso_context_queue(ctx, &u.packet,
+ &client->buffer, payload))
break;
p = next;