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>
This commit is contained in:
parent
33580a3ef5
commit
acfe833357
|
@ -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,6 +544,34 @@ static int ioctl_send_request(struct client *client, void *buffer)
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e->r.resource.release = release_transaction;
|
||||||
|
ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
|
||||||
|
if (ret < 0)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* Get a reference for the transaction callback */
|
||||||
|
client_get(client);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (request->data)
|
||||||
|
return sizeof(request) + request->length;
|
||||||
|
else
|
||||||
|
return sizeof(request);
|
||||||
|
failed:
|
||||||
|
kfree(e);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ioctl_send_request(struct client *client, void *buffer)
|
||||||
|
{
|
||||||
|
struct fw_cdev_send_request *request = buffer;
|
||||||
|
|
||||||
switch (request->tcode) {
|
switch (request->tcode) {
|
||||||
case TCODE_WRITE_QUADLET_REQUEST:
|
case TCODE_WRITE_QUADLET_REQUEST:
|
||||||
case TCODE_WRITE_BLOCK_REQUEST:
|
case TCODE_WRITE_BLOCK_REQUEST:
|
||||||
|
@ -558,35 +586,11 @@ static int ioctl_send_request(struct client *client, void *buffer)
|
||||||
case TCODE_LOCK_VENDOR_DEPENDENT:
|
case TCODE_LOCK_VENDOR_DEPENDENT:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
return -EINVAL;
|
||||||
goto failed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e->r.resource.release = release_transaction;
|
return init_request(client, request, client->device->node->node_id,
|
||||||
ret = add_client_resource(client, &e->r.resource, GFP_KERNEL);
|
client->device->max_speed);
|
||||||
if (ret < 0)
|
|
||||||
goto failed;
|
|
||||||
|
|
||||||
/* 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,
|
|
||||||
e->response.data, request->length,
|
|
||||||
complete_transaction, e);
|
|
||||||
|
|
||||||
if (request->data)
|
|
||||||
return sizeof(request) + request->length;
|
|
||||||
else
|
|
||||||
return sizeof(request);
|
|
||||||
failed:
|
|
||||||
kfree(e);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_request(struct client *client,
|
static void release_request(struct client *client,
|
||||||
|
@ -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) = {
|
||||||
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 {
|
||||||
#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
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue