aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-device-cdev.c
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@redhat.com>2007-02-16 17:34:40 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2007-03-09 16:02:58 -0500
commit295e3feb92e5073ec32a3c626302d4b92c4c8a95 (patch)
tree58c581080526c4b27401d3c2f4e52595d78cc4e8 /drivers/firewire/fw-device-cdev.c
parent30200739e612932739cc34baf588b39bacc2f427 (diff)
firewire: Implement basic isochronous receive functionality.
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.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/drivers/firewire/fw-device-cdev.c b/drivers/firewire/fw-device-cdev.c
index 6284375c6390..1101ccd9b9c1 100644
--- a/drivers/firewire/fw-device-cdev.c
+++ b/drivers/firewire/fw-device-cdev.c
@@ -406,8 +406,12 @@ static int ioctl_create_iso_context(struct client *client, void __user *arg)
406 if (copy_from_user(&request, arg, sizeof request)) 406 if (copy_from_user(&request, arg, sizeof request))
407 return -EFAULT; 407 return -EFAULT;
408 408
409 if (request.type > FW_ISO_CONTEXT_RECEIVE)
410 return -EINVAL;
411
409 client->iso_context = fw_iso_context_create(client->device->card, 412 client->iso_context = fw_iso_context_create(client->device->card,
410 FW_ISO_CONTEXT_TRANSMIT, 413 request.type,
414 request.header_size,
411 iso_callback, client); 415 iso_callback, client);
412 if (IS_ERR(client->iso_context)) 416 if (IS_ERR(client->iso_context))
413 return PTR_ERR(client->iso_context); 417 return PTR_ERR(client->iso_context);
@@ -419,7 +423,7 @@ static int ioctl_queue_iso(struct client *client, void __user *arg)
419{ 423{
420 struct fw_cdev_queue_iso request; 424 struct fw_cdev_queue_iso request;
421 struct fw_cdev_iso_packet __user *p, *end, *next; 425 struct fw_cdev_iso_packet __user *p, *end, *next;
422 unsigned long payload, payload_end; 426 unsigned long payload, payload_end, header_length;
423 int count; 427 int count;
424 struct { 428 struct {
425 struct fw_iso_packet packet; 429 struct fw_iso_packet packet;
@@ -456,12 +460,23 @@ static int ioctl_queue_iso(struct client *client, void __user *arg)
456 while (p < end) { 460 while (p < end) {
457 if (__copy_from_user(&u.packet, p, sizeof *p)) 461 if (__copy_from_user(&u.packet, p, sizeof *p))
458 return -EFAULT; 462 return -EFAULT;
463
464 if (client->iso_context->type == FW_ISO_CONTEXT_TRANSMIT) {
465 header_length = u.packet.header_length;
466 } else {
467 /* We require that header_length is a multiple of
468 * the fixed header size, ctx->header_size */
469 if (u.packet.header_length % client->iso_context->header_size != 0)
470 return -EINVAL;
471 header_length = 0;
472 }
473
459 next = (struct fw_cdev_iso_packet __user *) 474 next = (struct fw_cdev_iso_packet __user *)
460 &p->header[u.packet.header_length / 4]; 475 &p->header[header_length / 4];
461 if (next > end) 476 if (next > end)
462 return -EINVAL; 477 return -EINVAL;
463 if (__copy_from_user 478 if (__copy_from_user
464 (u.packet.header, p->header, u.packet.header_length)) 479 (u.packet.header, p->header, header_length))
465 return -EFAULT; 480 return -EFAULT;
466 if (u.packet.skip && 481 if (u.packet.skip &&
467 u.packet.header_length + u.packet.payload_length > 0) 482 u.packet.header_length + u.packet.payload_length > 0)