aboutsummaryrefslogtreecommitdiff
path: root/drivers/firewire/fw-cdev.c
diff options
context:
space:
mode:
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 214e534efee..539dae5eb5b 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,