aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-cdev.c
diff options
context:
space:
mode:
authorJay Fenlason, Stefan Richter <stefanr@s5r6.in-berlin.de>2009-01-04 10:23:29 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-24 15:56:44 -0400
commitacfe8333572cad5dc70fce18ac966be0446548d7 (patch)
tree7402f2c6759465c351d735855990620e24a644e2 /drivers/firewire/fw-cdev.c
parent33580a3ef5ba3bc0ee1b520df82a24bb37ce28f0 (diff)
firewire: cdev: add ioctl for broadcast write requests
Write transactions to the broadcast node ID are a convenient way to trigger functions of multiple nodes at once. IIDC is a protocol which can make use of this if multiple cameras with same command_regs_base are connected at the same bus. Based on Date: Wed, 10 Sep 2008 11:32:16 -0400 From: Jay Fenlason <fenlason@redhat.com> Subject: [patch] SEND_BROADCAST_REQUEST Changes: ioctl_send_request() and ioctl_send_broadcast_request() now share code. Broadcast speed corrected to S100. Check for proper tcode. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-cdev.c')
-rw-r--r--drivers/firewire/fw-cdev.c74
1 files changed, 47 insertions, 27 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 05ad2a8f286c..a1637a86da3d 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -518,10 +518,10 @@ static void complete_transaction(struct fw_card *card, int rcode,
518 client_put(client); 518 client_put(client);
519} 519}
520 520
521static int ioctl_send_request(struct client *client, void *buffer) 521static int init_request(struct client *client,
522 struct fw_cdev_send_request *request,
523 int destination_id, int speed)
522{ 524{
523 struct fw_device *device = client->device;
524 struct fw_cdev_send_request *request = buffer;
525 struct outbound_transaction_event *e; 525 struct outbound_transaction_event *e;
526 int ret; 526 int ret;
527 527
@@ -544,24 +544,6 @@ static int ioctl_send_request(struct client *client, void *buffer)
544 goto failed; 544 goto failed;
545 } 545 }
546 546
547 switch (request->tcode) {
548 case TCODE_WRITE_QUADLET_REQUEST:
549 case TCODE_WRITE_BLOCK_REQUEST:
550 case TCODE_READ_QUADLET_REQUEST:
551 case TCODE_READ_BLOCK_REQUEST:
552 case TCODE_LOCK_MASK_SWAP:
553 case TCODE_LOCK_COMPARE_SWAP:
554 case TCODE_LOCK_FETCH_ADD:
555 case TCODE_LOCK_LITTLE_ADD:
556 case TCODE_LOCK_BOUNDED_ADD:
557 case TCODE_LOCK_WRAP_ADD:
558 case TCODE_LOCK_VENDOR_DEPENDENT:
559 break;
560 default:
561 ret = -EINVAL;
562 goto failed;
563 }
564
565 e->r.resource.release = release_transaction; 547 e->r.resource.release = release_transaction;
566 ret = add_client_resource(client, &e->r.resource, GFP_KERNEL); 548 ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
567 if (ret < 0) 549 if (ret < 0)
@@ -570,12 +552,9 @@ static int ioctl_send_request(struct client *client, void *buffer)
570 /* Get a reference for the transaction callback */ 552 /* Get a reference for the transaction callback */
571 client_get(client); 553 client_get(client);
572 554
573 fw_send_request(device->card, &e->r.transaction, 555 fw_send_request(client->device->card, &e->r.transaction,
574 request->tcode & 0x1f, 556 request->tcode & 0x1f, destination_id,
575 device->node->node_id, 557 request->generation, speed, request->offset,
576 request->generation,
577 device->max_speed,
578 request->offset,
579 e->response.data, request->length, 558 e->response.data, request->length,
580 complete_transaction, e); 559 complete_transaction, e);
581 560
@@ -589,6 +568,31 @@ static int ioctl_send_request(struct client *client, void *buffer)
589 return ret; 568 return ret;
590} 569}
591 570
571static int ioctl_send_request(struct client *client, void *buffer)
572{
573 struct fw_cdev_send_request *request = buffer;
574
575 switch (request->tcode) {
576 case TCODE_WRITE_QUADLET_REQUEST:
577 case TCODE_WRITE_BLOCK_REQUEST:
578 case TCODE_READ_QUADLET_REQUEST:
579 case TCODE_READ_BLOCK_REQUEST:
580 case TCODE_LOCK_MASK_SWAP:
581 case TCODE_LOCK_COMPARE_SWAP:
582 case TCODE_LOCK_FETCH_ADD:
583 case TCODE_LOCK_LITTLE_ADD:
584 case TCODE_LOCK_BOUNDED_ADD:
585 case TCODE_LOCK_WRAP_ADD:
586 case TCODE_LOCK_VENDOR_DEPENDENT:
587 break;
588 default:
589 return -EINVAL;
590 }
591
592 return init_request(client, request, client->device->node->node_id,
593 client->device->max_speed);
594}
595
592static void release_request(struct client *client, 596static void release_request(struct client *client,
593 struct client_resource *resource) 597 struct client_resource *resource)
594{ 598{
@@ -1229,6 +1233,21 @@ static int ioctl_get_speed(struct client *client, void *buffer)
1229 return 0; 1233 return 0;
1230} 1234}
1231 1235
1236static int ioctl_send_broadcast_request(struct client *client, void *buffer)
1237{
1238 struct fw_cdev_send_request *request = buffer;
1239
1240 switch (request->tcode) {
1241 case TCODE_WRITE_QUADLET_REQUEST:
1242 case TCODE_WRITE_BLOCK_REQUEST:
1243 break;
1244 default:
1245 return -EINVAL;
1246 }
1247
1248 return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
1249}
1250
1232static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { 1251static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
1233 ioctl_get_info, 1252 ioctl_get_info,
1234 ioctl_send_request, 1253 ioctl_send_request,
@@ -1248,6 +1267,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
1248 ioctl_allocate_iso_resource_once, 1267 ioctl_allocate_iso_resource_once,
1249 ioctl_deallocate_iso_resource_once, 1268 ioctl_deallocate_iso_resource_once,
1250 ioctl_get_speed, 1269 ioctl_get_speed,
1270 ioctl_send_broadcast_request,
1251}; 1271};
1252 1272
1253static int dispatch_ioctl(struct client *client, 1273static int dispatch_ioctl(struct client *client,