diff options
author | Jay Fenlason, Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-01-04 10:23:29 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-03-24 15:56:44 -0400 |
commit | acfe8333572cad5dc70fce18ac966be0446548d7 (patch) | |
tree | 7402f2c6759465c351d735855990620e24a644e2 /drivers/firewire/fw-cdev.c | |
parent | 33580a3ef5ba3bc0ee1b520df82a24bb37ce28f0 (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.c | 74 |
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 | ||
521 | static int ioctl_send_request(struct client *client, void *buffer) | 521 | static 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 | ||
571 | static 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 | |||
592 | static void release_request(struct client *client, | 596 | static 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 | ||
1236 | static 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 | |||
1232 | static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { | 1251 | static 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 | ||
1253 | static int dispatch_ioctl(struct client *client, | 1273 | static int dispatch_ioctl(struct client *client, |