Commit acfe8333572cad5dc70fce18ac966be0446548d7
Committed by
Stefan Richter
1 parent
33580a3ef5
Exists in
master
and in
7 other branches
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>
Showing 2 changed files with 48 additions and 27 deletions Side-by-side Diff
drivers/firewire/fw-cdev.c
... | ... | @@ -518,10 +518,10 @@ |
518 | 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 | 525 | struct outbound_transaction_event *e; |
526 | 526 | int ret; |
527 | 527 | |
... | ... | @@ -544,24 +544,6 @@ |
544 | 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 | 547 | e->r.resource.release = release_transaction; |
566 | 548 | ret = add_client_resource(client, &e->r.resource, GFP_KERNEL); |
567 | 549 | if (ret < 0) |
... | ... | @@ -570,12 +552,9 @@ |
570 | 552 | /* Get a reference for the transaction callback */ |
571 | 553 | client_get(client); |
572 | 554 | |
573 | - fw_send_request(device->card, &e->r.transaction, | |
574 | - request->tcode & 0x1f, | |
575 | - device->node->node_id, | |
576 | - request->generation, | |
577 | - device->max_speed, | |
578 | - request->offset, | |
555 | + fw_send_request(client->device->card, &e->r.transaction, | |
556 | + request->tcode & 0x1f, destination_id, | |
557 | + request->generation, speed, request->offset, | |
579 | 558 | e->response.data, request->length, |
580 | 559 | complete_transaction, e); |
581 | 560 | |
... | ... | @@ -589,6 +568,31 @@ |
589 | 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 | 596 | static void release_request(struct client *client, |
593 | 597 | struct client_resource *resource) |
594 | 598 | { |
... | ... | @@ -1229,6 +1233,21 @@ |
1229 | 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 | 1251 | static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { |
1233 | 1252 | ioctl_get_info, |
1234 | 1253 | ioctl_send_request, |
... | ... | @@ -1248,6 +1267,7 @@ |
1248 | 1267 | ioctl_allocate_iso_resource_once, |
1249 | 1268 | ioctl_deallocate_iso_resource_once, |
1250 | 1269 | ioctl_get_speed, |
1270 | + ioctl_send_broadcast_request, | |
1251 | 1271 | }; |
1252 | 1272 | |
1253 | 1273 | static int dispatch_ioctl(struct client *client, |
include/linux/firewire-cdev.h
... | ... | @@ -230,6 +230,7 @@ |
230 | 230 | #define FW_CDEV_IOC_ALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x0f, struct fw_cdev_allocate_iso_resource) |
231 | 231 | #define FW_CDEV_IOC_DEALLOCATE_ISO_RESOURCE_ONCE _IOW('#', 0x10, struct fw_cdev_allocate_iso_resource) |
232 | 232 | #define FW_CDEV_IOC_GET_SPEED _IOR('#', 0x11, struct fw_cdev_get_speed) |
233 | +#define FW_CDEV_IOC_SEND_BROADCAST_REQUEST _IOW('#', 0x12, struct fw_cdev_send_request) | |
233 | 234 | |
234 | 235 | /* FW_CDEV_VERSION History |
235 | 236 | * |