diff options
author | Jay Fenlason <fenlason@redhat.com> | 2009-03-05 13:08:40 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-03-24 15:56:49 -0400 |
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) | |||
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 | ||
1245 | struct stream_packet { | ||
1246 | struct fw_packet packet; | ||
1247 | u8 data[0]; | ||
1248 | }; | ||
1249 | |||
1250 | static 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 | |||
1256 | static 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 | |||
1245 | static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { | 1277 | static 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 | ||
1267 | static int dispatch_ioctl(struct client *client, | 1300 | static int dispatch_ioctl(struct client *client, |