Commit acfe8333 authored by Jay Fenlason, Stefan Richter's avatar Jay Fenlason, Stefan Richter Committed by Stefan Richter

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: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent 33580a3e
...@@ -518,10 +518,10 @@ static void complete_transaction(struct fw_card *card, int rcode, ...@@ -518,10 +518,10 @@ static void complete_transaction(struct fw_card *card, int rcode,
client_put(client); 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; struct outbound_transaction_event *e;
int ret; int ret;
...@@ -544,24 +544,6 @@ static int ioctl_send_request(struct client *client, void *buffer) ...@@ -544,24 +544,6 @@ static int ioctl_send_request(struct client *client, void *buffer)
goto failed; 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; e->r.resource.release = release_transaction;
ret = add_client_resource(client, &e->r.resource, GFP_KERNEL); ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
if (ret < 0) if (ret < 0)
...@@ -570,12 +552,9 @@ static int ioctl_send_request(struct client *client, void *buffer) ...@@ -570,12 +552,9 @@ static int ioctl_send_request(struct client *client, void *buffer)
/* Get a reference for the transaction callback */ /* Get a reference for the transaction callback */
client_get(client); client_get(client);
fw_send_request(device->card, &e->r.transaction, fw_send_request(client->device->card, &e->r.transaction,
request->tcode & 0x1f, request->tcode & 0x1f, destination_id,
device->node->node_id, request->generation, speed, request->offset,
request->generation,
device->max_speed,
request->offset,
e->response.data, request->length, e->response.data, request->length,
complete_transaction, e); complete_transaction, e);
...@@ -589,6 +568,31 @@ static int ioctl_send_request(struct client *client, void *buffer) ...@@ -589,6 +568,31 @@ static int ioctl_send_request(struct client *client, void *buffer)
return ret; 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, static void release_request(struct client *client,
struct client_resource *resource) struct client_resource *resource)
{ {
...@@ -1229,6 +1233,21 @@ static int ioctl_get_speed(struct client *client, void *buffer) ...@@ -1229,6 +1233,21 @@ static int ioctl_get_speed(struct client *client, void *buffer)
return 0; 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) = { static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_get_info, ioctl_get_info,
ioctl_send_request, ioctl_send_request,
...@@ -1248,6 +1267,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { ...@@ -1248,6 +1267,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
ioctl_allocate_iso_resource_once, ioctl_allocate_iso_resource_once,
ioctl_deallocate_iso_resource_once, ioctl_deallocate_iso_resource_once,
ioctl_get_speed, ioctl_get_speed,
ioctl_send_broadcast_request,
}; };
static int dispatch_ioctl(struct client *client, static int dispatch_ioctl(struct client *client,
......
...@@ -230,6 +230,7 @@ union fw_cdev_event { ...@@ -230,6 +230,7 @@ union fw_cdev_event {
#define FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x0f, struct fw_cdev_allocate_iso_resource) #define FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x0f, struct fw_cdev_allocate_iso_resource)
#define FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x10, struct fw_cdev_allocate_iso_resource) #define FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x10, struct fw_cdev_allocate_iso_resource)
#define FW_CDEV_IOC_GET_SPEED _IOR('#', 0x11, struct fw_cdev_get_speed) #define FW_CDEV_IOC_GET_SPEED _IOR('#', 0x11, struct fw_cdev_get_speed)
#define FW_CDEV_IOC_SEND_BROADCAST_REQUEST _IOW('#', 0x12, struct fw_cdev_send_request)
/* FW_CDEV_VERSION History /* FW_CDEV_VERSION History
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment