aboutsummaryrefslogtreecommitdiffstats
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.c46
1 files changed, 19 insertions, 27 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 95a207545eb3..7eb6594cc3e5 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -522,7 +522,8 @@ static int init_request(struct client *client,
522 struct outbound_transaction_event *e; 522 struct outbound_transaction_event *e;
523 int ret; 523 int ret;
524 524
525 if (request->length > 4096 || request->length > 512 << speed) 525 if (request->tcode != TCODE_STREAM_DATA &&
526 (request->length > 4096 || request->length > 512 << speed))
526 return -EIO; 527 return -EIO;
527 528
528 e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL); 529 e = kmalloc(sizeof(*e) + request->length, GFP_KERNEL);
@@ -1247,36 +1248,27 @@ static int ioctl_send_broadcast_request(struct client *client, void *buffer)
1247 return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100); 1248 return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
1248} 1249}
1249 1250
1250struct stream_packet {
1251 struct fw_packet packet;
1252 u8 data[0];
1253};
1254
1255static void send_stream_packet_done(struct fw_packet *packet,
1256 struct fw_card *card, int status)
1257{
1258 kfree(container_of(packet, struct stream_packet, packet));
1259}
1260
1261static int ioctl_send_stream_packet(struct client *client, void *buffer) 1251static int ioctl_send_stream_packet(struct client *client, void *buffer)
1262{ 1252{
1263 struct fw_cdev_send_stream_packet *request = buffer; 1253 struct fw_cdev_send_stream_packet *p = buffer;
1264 struct stream_packet *p; 1254 struct fw_cdev_send_request request;
1255 int dest;
1265 1256
1266 p = kmalloc(sizeof(*p) + request->size, GFP_KERNEL); 1257 if (p->speed > client->device->card->link_speed ||
1267 if (p == NULL) 1258 p->length > 1024 << p->speed)
1268 return -ENOMEM; 1259 return -EIO;
1269 1260
1270 if (request->data && 1261 if (p->tag > 3 || p->channel > 63 || p->sy > 15)
1271 copy_from_user(p->data, u64_to_uptr(request->data), request->size)) { 1262 return -EINVAL;
1272 kfree(p); 1263
1273 return -EFAULT; 1264 dest = fw_stream_packet_destination_id(p->tag, p->channel, p->sy);
1274 } 1265 request.tcode = TCODE_STREAM_DATA;
1275 fw_send_stream_packet(client->device->card, &p->packet, 1266 request.length = p->length;
1276 request->generation, request->speed, 1267 request.closure = p->closure;
1277 request->channel, request->sy, request->tag, 1268 request.data = p->data;
1278 p->data, request->size, send_stream_packet_done); 1269 request.generation = p->generation;
1279 return 0; 1270
1271 return init_request(client, &request, dest, p->speed);
1280} 1272}
1281 1273
1282static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { 1274static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {