diff options
author | Jay Fenlason <fenlason@redhat.com> | 2009-03-05 19:08:40 +0100 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-03-24 20:56:49 +0100 |
commit | f8c2287c65f8f72000102fc058232669e4540bc4 (patch) | |
tree | a82393fbdd3a2b20f8e499537b10eb9e61dae941 /drivers/firewire/fw-cdev.c | |
parent | ba27e1f7bf220799cd3d7503f82bda71b8ebe8c5 (diff) |
firewire: implement asynchronous stream transmission
Allow userspace and other firewire drivers (fw-ipv4 I'm looking at
you!) to send Asynchronous Transmit Streams as described in 7.8.3 of
release 1.1 of the 1394 Open Host Controller Interface Specification.
Signed-off-by: Jay Fenlason <fenlason@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (tweaks)
Diffstat (limited to 'drivers/firewire/fw-cdev.c')
-rw-r--r-- | drivers/firewire/fw-cdev.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index 214e534efee5..539dae5eb5b2 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c @@ -1242,6 +1242,38 @@ static int ioctl_send_broadcast_request(struct client *client, void *buffer) return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100); } +struct stream_packet { + struct fw_packet packet; + u8 data[0]; +}; + +static void send_stream_packet_done(struct fw_packet *packet, + struct fw_card *card, int status) +{ + kfree(container_of(packet, struct stream_packet, packet)); +} + +static int ioctl_send_stream_packet(struct client *client, void *buffer) +{ + struct fw_cdev_send_stream_packet *request = buffer; + struct stream_packet *p; + + p = kmalloc(sizeof(*p) + request->size, GFP_KERNEL); + if (p == NULL) + return -ENOMEM; + + if (request->data && + copy_from_user(p->data, u64_to_uptr(request->data), request->size)) { + kfree(p); + return -EFAULT; + } + fw_send_stream_packet(client->device->card, &p->packet, + request->generation, request->speed, + request->channel, request->sy, request->tag, + p->data, request->size, send_stream_packet_done); + return 0; +} + static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { ioctl_get_info, ioctl_send_request, @@ -1262,6 +1294,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { ioctl_deallocate_iso_resource_once, ioctl_get_speed, ioctl_send_broadcast_request, + ioctl_send_stream_packet, }; static int dispatch_ioctl(struct client *client, |