aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-cdev.c
diff options
context:
space:
mode:
authorJay Fenlason <fenlason@redhat.com>2009-03-05 13:08:40 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-24 15:56:49 -0400
commitf8c2287c65f8f72000102fc058232669e4540bc4 (patch)
treea82393fbdd3a2b20f8e499537b10eb9e61dae941 /drivers/firewire/fw-cdev.c
parentba27e1f7bf220799cd3d7503f82bda71b8ebe8c5 (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.c33
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)
1242 return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100); 1242 return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
1243} 1243}
1244 1244
1245struct stream_packet {
1246 struct fw_packet packet;
1247 u8 data[0];
1248};
1249
1250static void send_stream_packet_done(struct fw_packet *packet,
1251 struct fw_card *card, int status)
1252{
1253 kfree(container_of(packet, struct stream_packet, packet));
1254}
1255
1256static int ioctl_send_stream_packet(struct client *client, void *buffer)
1257{
1258 struct fw_cdev_send_stream_packet *request = buffer;
1259 struct stream_packet *p;
1260
1261 p = kmalloc(sizeof(*p) + request->size, GFP_KERNEL);
1262 if (p == NULL)
1263 return -ENOMEM;
1264
1265 if (request->data &&
1266 copy_from_user(p->data, u64_to_uptr(request->data), request->size)) {
1267 kfree(p);
1268 return -EFAULT;
1269 }
1270 fw_send_stream_packet(client->device->card, &p->packet,
1271 request->generation, request->speed,
1272 request->channel, request->sy, request->tag,
1273 p->data, request->size, send_stream_packet_done);
1274 return 0;
1275}
1276
1245static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { 1277static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
1246 ioctl_get_info, 1278 ioctl_get_info,
1247 ioctl_send_request, 1279 ioctl_send_request,
@@ -1262,6 +1294,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
1262 ioctl_deallocate_iso_resource_once, 1294 ioctl_deallocate_iso_resource_once,
1263 ioctl_get_speed, 1295 ioctl_get_speed,
1264 ioctl_send_broadcast_request, 1296 ioctl_send_broadcast_request,
1297 ioctl_send_stream_packet,
1265}; 1298};
1266 1299
1267static int dispatch_ioctl(struct client *client, 1300static int dispatch_ioctl(struct client *client,