summaryrefslogtreecommitdiff
path: root/drivers/firewire
diff options
context:
space:
mode:
authorJay Fenlason, Stefan Richter <stefanr@s5r6.in-berlin.de>2009-01-04 16:23:29 +0100
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-03-24 20:56:44 +0100
commitacfe8333572cad5dc70fce18ac966be0446548d7 (patch)
tree7402f2c6759465c351d735855990620e24a644e2 /drivers/firewire
parent33580a3ef5ba3bc0ee1b520df82a24bb37ce28f0 (diff)
downloadlinux-3.10-acfe8333572cad5dc70fce18ac966be0446548d7.tar.gz
linux-3.10-acfe8333572cad5dc70fce18ac966be0446548d7.tar.bz2
linux-3.10-acfe8333572cad5dc70fce18ac966be0446548d7.zip
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')
-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 05ad2a8f286..a1637a86da3 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,
client_put(client);
}
-static int ioctl_send_request(struct client *client, void *buffer)
+static int init_request(struct client *client,
+ struct fw_cdev_send_request *request,
+ int destination_id, int speed)
{
- struct fw_device *device = client->device;
- struct fw_cdev_send_request *request = buffer;
struct outbound_transaction_event *e;
int ret;
@@ -544,24 +544,6 @@ static int ioctl_send_request(struct client *client, void *buffer)
goto failed;
}
- switch (request->tcode) {
- case TCODE_WRITE_QUADLET_REQUEST:
- case TCODE_WRITE_BLOCK_REQUEST:
- case TCODE_READ_QUADLET_REQUEST:
- case TCODE_READ_BLOCK_REQUEST:
- case TCODE_LOCK_MASK_SWAP:
- case TCODE_LOCK_COMPARE_SWAP:
- case TCODE_LOCK_FETCH_ADD:
- case TCODE_LOCK_LITTLE_ADD:
- case TCODE_LOCK_BOUNDED_ADD:
- case TCODE_LOCK_WRAP_ADD:
- case TCODE_LOCK_VENDOR_DEPENDENT:
- break;
- default:
- ret = -EINVAL;
- goto failed;
- }
-
e->r.resource.release = release_transaction;
ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
if (ret < 0)
@@ -570,12 +552,9 @@ static int ioctl_send_request(struct client *client, void *buffer)
/* Get a reference for the transaction callback */
client_get(client);
- fw_send_request(device->card, &e->r.transaction,
- request->tcode & 0x1f,
- device->node->node_id,
- request->generation,
- device->max_speed,
- request->offset,
+ fw_send_request(client->device->card, &e->r.transaction,
+ request->tcode & 0x1f, destination_id,
+ request->generation, speed, request->offset,
e->response.data, request->length,
complete_transaction, e);
@@ -589,6 +568,31 @@ static int ioctl_send_request(struct client *client, void *buffer)
return ret;
}
+static int ioctl_send_request(struct client *client, void *buffer)
+{
+ struct fw_cdev_send_request *request = buffer;
+
+ switch (request->tcode) {
+ case TCODE_WRITE_QUADLET_REQUEST:
+ case TCODE_WRITE_BLOCK_REQUEST:
+ case TCODE_READ_QUADLET_REQUEST:
+ case TCODE_READ_BLOCK_REQUEST:
+ case TCODE_LOCK_MASK_SWAP:
+ case TCODE_LOCK_COMPARE_SWAP:
+ case TCODE_LOCK_FETCH_ADD:
+ case TCODE_LOCK_LITTLE_ADD:
+ case TCODE_LOCK_BOUNDED_ADD:
+ case TCODE_LOCK_WRAP_ADD:
+ case TCODE_LOCK_VENDOR_DEPENDENT:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return init_request(client, request, client->device->node->node_id,
+ client->device->max_speed);
+}
+
static void release_request(struct client *client,
struct client_resource *resource)
{
@@ -1229,6 +1233,21 @@ static int ioctl_get_speed(struct client *client, void *buffer)
return 0;
}
+static int ioctl_send_broadcast_request(struct client *client, void *buffer)
+{
+ struct fw_cdev_send_request *request = buffer;
+
+ switch (request->tcode) {
+ case TCODE_WRITE_QUADLET_REQUEST:
+ case TCODE_WRITE_BLOCK_REQUEST:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100);
+}
+
static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_get_info,
ioctl_send_request,
@@ -1248,6 +1267,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_allocate_iso_resource_once,
ioctl_deallocate_iso_resource_once,
ioctl_get_speed,
+ ioctl_send_broadcast_request,
};
static int dispatch_ioctl(struct client *client,