Commit acfe8333572cad5dc70fce18ac966be0446548d7

Authored by Jay Fenlason, Stefan Richter
Committed by Stefan Richter
1 parent 33580a3ef5

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 *