aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/core-cdev.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2010-02-21 11:56:21 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2010-02-24 14:36:55 -0500
commit6e95dea728f4af36c033fcf2318529bd46dae540 (patch)
tree611870be19f96a4937cadf349e5a4e12723283fb /drivers/firewire/core-cdev.c
parente94b6d7736107c07b1b089797651d02994d268c7 (diff)
firewire: core: change type of a data buffer
from array of char to union of structs. I already used a union to size the buffer which holds ioctl arguments; more consequent is to define it as an instance of this union in the first place. Also rename several local variables from "request" to "a"(rgument) since the term request can be mistaken to mean a transaction subaction, e.g. an instance of struct fw_request. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/core-cdev.c')
-rw-r--r--drivers/firewire/core-cdev.c325
1 files changed, 152 insertions, 173 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index a4aa477b9b2c..d7de17a0f250 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -368,39 +368,56 @@ void fw_device_cdev_remove(struct fw_device *device)
368 for_each_client(device, wake_up_client); 368 for_each_client(device, wake_up_client);
369} 369}
370 370
371static int ioctl_get_info(struct client *client, void *buffer) 371union ioctl_arg {
372 struct fw_cdev_get_info get_info;
373 struct fw_cdev_send_request send_request;
374 struct fw_cdev_allocate allocate;
375 struct fw_cdev_deallocate deallocate;
376 struct fw_cdev_send_response send_response;
377 struct fw_cdev_initiate_bus_reset initiate_bus_reset;
378 struct fw_cdev_add_descriptor add_descriptor;
379 struct fw_cdev_remove_descriptor remove_descriptor;
380 struct fw_cdev_create_iso_context create_iso_context;
381 struct fw_cdev_queue_iso queue_iso;
382 struct fw_cdev_start_iso start_iso;
383 struct fw_cdev_stop_iso stop_iso;
384 struct fw_cdev_get_cycle_timer get_cycle_timer;
385 struct fw_cdev_allocate_iso_resource allocate_iso_resource;
386 struct fw_cdev_send_stream_packet send_stream_packet;
387 struct fw_cdev_get_cycle_timer2 get_cycle_timer2;
388};
389
390static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
372{ 391{
373 struct fw_cdev_get_info *get_info = buffer; 392 struct fw_cdev_get_info *a = &arg->get_info;
374 struct fw_cdev_event_bus_reset bus_reset; 393 struct fw_cdev_event_bus_reset bus_reset;
375 unsigned long ret = 0; 394 unsigned long ret = 0;
376 395
377 client->version = get_info->version; 396 client->version = a->version;
378 get_info->version = FW_CDEV_VERSION; 397 a->version = FW_CDEV_VERSION;
379 get_info->card = client->device->card->index; 398 a->card = client->device->card->index;
380 399
381 down_read(&fw_device_rwsem); 400 down_read(&fw_device_rwsem);
382 401
383 if (get_info->rom != 0) { 402 if (a->rom != 0) {
384 void __user *uptr = u64_to_uptr(get_info->rom); 403 size_t want = a->rom_length;
385 size_t want = get_info->rom_length;
386 size_t have = client->device->config_rom_length * 4; 404 size_t have = client->device->config_rom_length * 4;
387 405
388 ret = copy_to_user(uptr, client->device->config_rom, 406 ret = copy_to_user(u64_to_uptr(a->rom),
389 min(want, have)); 407 client->device->config_rom, min(want, have));
390 } 408 }
391 get_info->rom_length = client->device->config_rom_length * 4; 409 a->rom_length = client->device->config_rom_length * 4;
392 410
393 up_read(&fw_device_rwsem); 411 up_read(&fw_device_rwsem);
394 412
395 if (ret != 0) 413 if (ret != 0)
396 return -EFAULT; 414 return -EFAULT;
397 415
398 client->bus_reset_closure = get_info->bus_reset_closure; 416 client->bus_reset_closure = a->bus_reset_closure;
399 if (get_info->bus_reset != 0) { 417 if (a->bus_reset != 0) {
400 void __user *uptr = u64_to_uptr(get_info->bus_reset);
401
402 fill_bus_reset_event(&bus_reset, client); 418 fill_bus_reset_event(&bus_reset, client);
403 if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) 419 if (copy_to_user(u64_to_uptr(a->bus_reset),
420 &bus_reset, sizeof(bus_reset)))
404 return -EFAULT; 421 return -EFAULT;
405 } 422 }
406 423
@@ -571,11 +588,9 @@ static int init_request(struct client *client,
571 return ret; 588 return ret;
572} 589}
573 590
574static int ioctl_send_request(struct client *client, void *buffer) 591static int ioctl_send_request(struct client *client, union ioctl_arg *arg)
575{ 592{
576 struct fw_cdev_send_request *request = buffer; 593 switch (arg->send_request.tcode) {
577
578 switch (request->tcode) {
579 case TCODE_WRITE_QUADLET_REQUEST: 594 case TCODE_WRITE_QUADLET_REQUEST:
580 case TCODE_WRITE_BLOCK_REQUEST: 595 case TCODE_WRITE_BLOCK_REQUEST:
581 case TCODE_READ_QUADLET_REQUEST: 596 case TCODE_READ_QUADLET_REQUEST:
@@ -592,7 +607,7 @@ static int ioctl_send_request(struct client *client, void *buffer)
592 return -EINVAL; 607 return -EINVAL;
593 } 608 }
594 609
595 return init_request(client, request, client->device->node_id, 610 return init_request(client, &arg->send_request, client->device->node_id,
596 client->device->max_speed); 611 client->device->max_speed);
597} 612}
598 613
@@ -683,9 +698,9 @@ static void release_address_handler(struct client *client,
683 kfree(r); 698 kfree(r);
684} 699}
685 700
686static int ioctl_allocate(struct client *client, void *buffer) 701static int ioctl_allocate(struct client *client, union ioctl_arg *arg)
687{ 702{
688 struct fw_cdev_allocate *request = buffer; 703 struct fw_cdev_allocate *a = &arg->allocate;
689 struct address_handler_resource *r; 704 struct address_handler_resource *r;
690 struct fw_address_region region; 705 struct fw_address_region region;
691 int ret; 706 int ret;
@@ -694,13 +709,13 @@ static int ioctl_allocate(struct client *client, void *buffer)
694 if (r == NULL) 709 if (r == NULL)
695 return -ENOMEM; 710 return -ENOMEM;
696 711
697 region.start = request->offset; 712 region.start = a->offset;
698 region.end = request->offset + request->length; 713 region.end = a->offset + a->length;
699 r->handler.length = request->length; 714 r->handler.length = a->length;
700 r->handler.address_callback = handle_request; 715 r->handler.address_callback = handle_request;
701 r->handler.callback_data = r; 716 r->handler.callback_data = r;
702 r->closure = request->closure; 717 r->closure = a->closure;
703 r->client = client; 718 r->client = client;
704 719
705 ret = fw_core_add_address_handler(&r->handler, &region); 720 ret = fw_core_add_address_handler(&r->handler, &region);
706 if (ret < 0) { 721 if (ret < 0) {
@@ -714,27 +729,25 @@ static int ioctl_allocate(struct client *client, void *buffer)
714 release_address_handler(client, &r->resource); 729 release_address_handler(client, &r->resource);
715 return ret; 730 return ret;
716 } 731 }
717 request->handle = r->resource.handle; 732 a->handle = r->resource.handle;
718 733
719 return 0; 734 return 0;
720} 735}
721 736
722static int ioctl_deallocate(struct client *client, void *buffer) 737static int ioctl_deallocate(struct client *client, union ioctl_arg *arg)
723{ 738{
724 struct fw_cdev_deallocate *request = buffer; 739 return release_client_resource(client, arg->deallocate.handle,
725
726 return release_client_resource(client, request->handle,
727 release_address_handler, NULL); 740 release_address_handler, NULL);
728} 741}
729 742
730static int ioctl_send_response(struct client *client, void *buffer) 743static int ioctl_send_response(struct client *client, union ioctl_arg *arg)
731{ 744{
732 struct fw_cdev_send_response *request = buffer; 745 struct fw_cdev_send_response *a = &arg->send_response;
733 struct client_resource *resource; 746 struct client_resource *resource;
734 struct inbound_transaction_resource *r; 747 struct inbound_transaction_resource *r;
735 int ret = 0; 748 int ret = 0;
736 749
737 if (release_client_resource(client, request->handle, 750 if (release_client_resource(client, a->handle,
738 release_request, &resource) < 0) 751 release_request, &resource) < 0)
739 return -EINVAL; 752 return -EINVAL;
740 753
@@ -743,28 +756,24 @@ static int ioctl_send_response(struct client *client, void *buffer)
743 if (is_fcp_request(r->request)) 756 if (is_fcp_request(r->request))
744 goto out; 757 goto out;
745 758
746 if (request->length < r->length) 759 if (a->length < r->length)
747 r->length = request->length; 760 r->length = a->length;
748 if (copy_from_user(r->data, u64_to_uptr(request->data), r->length)) { 761 if (copy_from_user(r->data, u64_to_uptr(a->data), r->length)) {
749 ret = -EFAULT; 762 ret = -EFAULT;
750 kfree(r->request); 763 kfree(r->request);
751 goto out; 764 goto out;
752 } 765 }
753 fw_send_response(client->device->card, r->request, request->rcode); 766 fw_send_response(client->device->card, r->request, a->rcode);
754 out: 767 out:
755 kfree(r); 768 kfree(r);
756 769
757 return ret; 770 return ret;
758} 771}
759 772
760static int ioctl_initiate_bus_reset(struct client *client, void *buffer) 773static int ioctl_initiate_bus_reset(struct client *client, union ioctl_arg *arg)
761{ 774{
762 struct fw_cdev_initiate_bus_reset *request = buffer; 775 return fw_core_initiate_bus_reset(client->device->card,
763 int short_reset; 776 arg->initiate_bus_reset.type == FW_CDEV_SHORT_RESET);
764
765 short_reset = (request->type == FW_CDEV_SHORT_RESET);
766
767 return fw_core_initiate_bus_reset(client->device->card, short_reset);
768} 777}
769 778
770static void release_descriptor(struct client *client, 779static void release_descriptor(struct client *client,
@@ -777,9 +786,9 @@ static void release_descriptor(struct client *client,
777 kfree(r); 786 kfree(r);
778} 787}
779 788
780static int ioctl_add_descriptor(struct client *client, void *buffer) 789static int ioctl_add_descriptor(struct client *client, union ioctl_arg *arg)
781{ 790{
782 struct fw_cdev_add_descriptor *request = buffer; 791 struct fw_cdev_add_descriptor *a = &arg->add_descriptor;
783 struct descriptor_resource *r; 792 struct descriptor_resource *r;
784 int ret; 793 int ret;
785 794
@@ -787,22 +796,21 @@ static int ioctl_add_descriptor(struct client *client, void *buffer)
787 if (!client->device->is_local) 796 if (!client->device->is_local)
788 return -ENOSYS; 797 return -ENOSYS;
789 798
790 if (request->length > 256) 799 if (a->length > 256)
791 return -EINVAL; 800 return -EINVAL;
792 801
793 r = kmalloc(sizeof(*r) + request->length * 4, GFP_KERNEL); 802 r = kmalloc(sizeof(*r) + a->length * 4, GFP_KERNEL);
794 if (r == NULL) 803 if (r == NULL)
795 return -ENOMEM; 804 return -ENOMEM;
796 805
797 if (copy_from_user(r->data, 806 if (copy_from_user(r->data, u64_to_uptr(a->data), a->length * 4)) {
798 u64_to_uptr(request->data), request->length * 4)) {
799 ret = -EFAULT; 807 ret = -EFAULT;
800 goto failed; 808 goto failed;
801 } 809 }
802 810
803 r->descriptor.length = request->length; 811 r->descriptor.length = a->length;
804 r->descriptor.immediate = request->immediate; 812 r->descriptor.immediate = a->immediate;
805 r->descriptor.key = request->key; 813 r->descriptor.key = a->key;
806 r->descriptor.data = r->data; 814 r->descriptor.data = r->data;
807 815
808 ret = fw_core_add_descriptor(&r->descriptor); 816 ret = fw_core_add_descriptor(&r->descriptor);
@@ -815,7 +823,7 @@ static int ioctl_add_descriptor(struct client *client, void *buffer)
815 fw_core_remove_descriptor(&r->descriptor); 823 fw_core_remove_descriptor(&r->descriptor);
816 goto failed; 824 goto failed;
817 } 825 }
818 request->handle = r->resource.handle; 826 a->handle = r->resource.handle;
819 827
820 return 0; 828 return 0;
821 failed: 829 failed:
@@ -824,11 +832,9 @@ static int ioctl_add_descriptor(struct client *client, void *buffer)
824 return ret; 832 return ret;
825} 833}
826 834
827static int ioctl_remove_descriptor(struct client *client, void *buffer) 835static int ioctl_remove_descriptor(struct client *client, union ioctl_arg *arg)
828{ 836{
829 struct fw_cdev_remove_descriptor *request = buffer; 837 return release_client_resource(client, arg->remove_descriptor.handle,
830
831 return release_client_resource(client, request->handle,
832 release_descriptor, NULL); 838 release_descriptor, NULL);
833} 839}
834 840
@@ -851,49 +857,44 @@ static void iso_callback(struct fw_iso_context *context, u32 cycle,
851 sizeof(e->interrupt) + header_length, NULL, 0); 857 sizeof(e->interrupt) + header_length, NULL, 0);
852} 858}
853 859
854static int ioctl_create_iso_context(struct client *client, void *buffer) 860static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
855{ 861{
856 struct fw_cdev_create_iso_context *request = buffer; 862 struct fw_cdev_create_iso_context *a = &arg->create_iso_context;
857 struct fw_iso_context *context; 863 struct fw_iso_context *context;
858 864
859 /* We only support one context at this time. */ 865 /* We only support one context at this time. */
860 if (client->iso_context != NULL) 866 if (client->iso_context != NULL)
861 return -EBUSY; 867 return -EBUSY;
862 868
863 if (request->channel > 63) 869 if (a->channel > 63)
864 return -EINVAL; 870 return -EINVAL;
865 871
866 switch (request->type) { 872 switch (a->type) {
867 case FW_ISO_CONTEXT_RECEIVE: 873 case FW_ISO_CONTEXT_RECEIVE:
868 if (request->header_size < 4 || (request->header_size & 3)) 874 if (a->header_size < 4 || (a->header_size & 3))
869 return -EINVAL; 875 return -EINVAL;
870
871 break; 876 break;
872 877
873 case FW_ISO_CONTEXT_TRANSMIT: 878 case FW_ISO_CONTEXT_TRANSMIT:
874 if (request->speed > SCODE_3200) 879 if (a->speed > SCODE_3200)
875 return -EINVAL; 880 return -EINVAL;
876
877 break; 881 break;
878 882
879 default: 883 default:
880 return -EINVAL; 884 return -EINVAL;
881 } 885 }
882 886
883 context = fw_iso_context_create(client->device->card, 887 context = fw_iso_context_create(client->device->card, a->type,
884 request->type, 888 a->channel, a->speed, a->header_size,
885 request->channel, 889 iso_callback, client);
886 request->speed,
887 request->header_size,
888 iso_callback, client);
889 if (IS_ERR(context)) 890 if (IS_ERR(context))
890 return PTR_ERR(context); 891 return PTR_ERR(context);
891 892
892 client->iso_closure = request->closure; 893 client->iso_closure = a->closure;
893 client->iso_context = context; 894 client->iso_context = context;
894 895
895 /* We only support one context at this time. */ 896 /* We only support one context at this time. */
896 request->handle = 0; 897 a->handle = 0;
897 898
898 return 0; 899 return 0;
899} 900}
@@ -906,9 +907,9 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
906#define GET_SY(v) (((v) >> 20) & 0x0f) 907#define GET_SY(v) (((v) >> 20) & 0x0f)
907#define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff) 908#define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
908 909
909static int ioctl_queue_iso(struct client *client, void *buffer) 910static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
910{ 911{
911 struct fw_cdev_queue_iso *request = buffer; 912 struct fw_cdev_queue_iso *a = &arg->queue_iso;
912 struct fw_cdev_iso_packet __user *p, *end, *next; 913 struct fw_cdev_iso_packet __user *p, *end, *next;
913 struct fw_iso_context *ctx = client->iso_context; 914 struct fw_iso_context *ctx = client->iso_context;
914 unsigned long payload, buffer_end, header_length; 915 unsigned long payload, buffer_end, header_length;
@@ -919,7 +920,7 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
919 u8 header[256]; 920 u8 header[256];
920 } u; 921 } u;
921 922
922 if (ctx == NULL || request->handle != 0) 923 if (ctx == NULL || a->handle != 0)
923 return -EINVAL; 924 return -EINVAL;
924 925
925 /* 926 /*
@@ -929,23 +930,23 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
929 * set them both to 0, which will still let packets with 930 * set them both to 0, which will still let packets with
930 * payload_length == 0 through. In other words, if no packets 931 * payload_length == 0 through. In other words, if no packets
931 * use the indirect payload, the iso buffer need not be mapped 932 * use the indirect payload, the iso buffer need not be mapped
932 * and the request->data pointer is ignored. 933 * and the a->data pointer is ignored.
933 */ 934 */
934 935
935 payload = (unsigned long)request->data - client->vm_start; 936 payload = (unsigned long)a->data - client->vm_start;
936 buffer_end = client->buffer.page_count << PAGE_SHIFT; 937 buffer_end = client->buffer.page_count << PAGE_SHIFT;
937 if (request->data == 0 || client->buffer.pages == NULL || 938 if (a->data == 0 || client->buffer.pages == NULL ||
938 payload >= buffer_end) { 939 payload >= buffer_end) {
939 payload = 0; 940 payload = 0;
940 buffer_end = 0; 941 buffer_end = 0;
941 } 942 }
942 943
943 p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(request->packets); 944 p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(a->packets);
944 945
945 if (!access_ok(VERIFY_READ, p, request->size)) 946 if (!access_ok(VERIFY_READ, p, a->size))
946 return -EFAULT; 947 return -EFAULT;
947 948
948 end = (void __user *)p + request->size; 949 end = (void __user *)p + a->size;
949 count = 0; 950 count = 0;
950 while (p < end) { 951 while (p < end) {
951 if (get_user(control, &p->control)) 952 if (get_user(control, &p->control))
@@ -995,45 +996,41 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
995 count++; 996 count++;
996 } 997 }
997 998
998 request->size -= uptr_to_u64(p) - request->packets; 999 a->size -= uptr_to_u64(p) - a->packets;
999 request->packets = uptr_to_u64(p); 1000 a->packets = uptr_to_u64(p);
1000 request->data = client->vm_start + payload; 1001 a->data = client->vm_start + payload;
1001 1002
1002 return count; 1003 return count;
1003} 1004}
1004 1005
1005static int ioctl_start_iso(struct client *client, void *buffer) 1006static int ioctl_start_iso(struct client *client, union ioctl_arg *arg)
1006{ 1007{
1007 struct fw_cdev_start_iso *request = buffer; 1008 struct fw_cdev_start_iso *a = &arg->start_iso;
1008 1009
1009 if (client->iso_context == NULL || request->handle != 0) 1010 if (client->iso_context == NULL || a->handle != 0)
1010 return -EINVAL; 1011 return -EINVAL;
1011 1012
1012 if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) { 1013 if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE &&
1013 if (request->tags == 0 || request->tags > 15) 1014 (a->tags == 0 || a->tags > 15 || a->sync > 15))
1014 return -EINVAL; 1015 return -EINVAL;
1015
1016 if (request->sync > 15)
1017 return -EINVAL;
1018 }
1019 1016
1020 return fw_iso_context_start(client->iso_context, request->cycle, 1017 return fw_iso_context_start(client->iso_context,
1021 request->sync, request->tags); 1018 a->cycle, a->sync, a->tags);
1022} 1019}
1023 1020
1024static int ioctl_stop_iso(struct client *client, void *buffer) 1021static int ioctl_stop_iso(struct client *client, union ioctl_arg *arg)
1025{ 1022{
1026 struct fw_cdev_stop_iso *request = buffer; 1023 struct fw_cdev_stop_iso *a = &arg->stop_iso;
1027 1024
1028 if (client->iso_context == NULL || request->handle != 0) 1025 if (client->iso_context == NULL || a->handle != 0)
1029 return -EINVAL; 1026 return -EINVAL;
1030 1027
1031 return fw_iso_context_stop(client->iso_context); 1028 return fw_iso_context_stop(client->iso_context);
1032} 1029}
1033 1030
1034static int ioctl_get_cycle_timer2(struct client *client, void *buffer) 1031static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
1035{ 1032{
1036 struct fw_cdev_get_cycle_timer2 *request = buffer; 1033 struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2;
1037 struct fw_card *card = client->device->card; 1034 struct fw_card *card = client->device->card;
1038 struct timespec ts = {0, 0}; 1035 struct timespec ts = {0, 0};
1039 u32 cycle_time; 1036 u32 cycle_time;
@@ -1043,7 +1040,7 @@ static int ioctl_get_cycle_timer2(struct client *client, void *buffer)
1043 1040
1044 cycle_time = card->driver->get_cycle_time(card); 1041 cycle_time = card->driver->get_cycle_time(card);
1045 1042
1046 switch (request->clk_id) { 1043 switch (a->clk_id) {
1047 case CLOCK_REALTIME: getnstimeofday(&ts); break; 1044 case CLOCK_REALTIME: getnstimeofday(&ts); break;
1048 case CLOCK_MONOTONIC: do_posix_clock_monotonic_gettime(&ts); break; 1045 case CLOCK_MONOTONIC: do_posix_clock_monotonic_gettime(&ts); break;
1049 case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break; 1046 case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break;
@@ -1053,24 +1050,23 @@ static int ioctl_get_cycle_timer2(struct client *client, void *buffer)
1053 1050
1054 local_irq_enable(); 1051 local_irq_enable();
1055 1052
1056 request->tv_sec = ts.tv_sec; 1053 a->tv_sec = ts.tv_sec;
1057 request->tv_nsec = ts.tv_nsec; 1054 a->tv_nsec = ts.tv_nsec;
1058 request->cycle_timer = cycle_time; 1055 a->cycle_timer = cycle_time;
1059 1056
1060 return ret; 1057 return ret;
1061} 1058}
1062 1059
1063static int ioctl_get_cycle_timer(struct client *client, void *buffer) 1060static int ioctl_get_cycle_timer(struct client *client, union ioctl_arg *arg)
1064{ 1061{
1065 struct fw_cdev_get_cycle_timer *request = buffer; 1062 struct fw_cdev_get_cycle_timer *a = &arg->get_cycle_timer;
1066 struct fw_cdev_get_cycle_timer2 ct2; 1063 struct fw_cdev_get_cycle_timer2 ct2;
1067 1064
1068 ct2.clk_id = CLOCK_REALTIME; 1065 ct2.clk_id = CLOCK_REALTIME;
1069 ioctl_get_cycle_timer2(client, &ct2); 1066 ioctl_get_cycle_timer2(client, (union ioctl_arg *)&ct2);
1070 1067
1071 request->local_time = ct2.tv_sec * USEC_PER_SEC + 1068 a->local_time = ct2.tv_sec * USEC_PER_SEC + ct2.tv_nsec / NSEC_PER_USEC;
1072 ct2.tv_nsec / NSEC_PER_USEC; 1069 a->cycle_timer = ct2.cycle_timer;
1073 request->cycle_timer = ct2.cycle_timer;
1074 1070
1075 return 0; 1071 return 0;
1076} 1072}
@@ -1242,33 +1238,32 @@ static int init_iso_resource(struct client *client,
1242 return ret; 1238 return ret;
1243} 1239}
1244 1240
1245static int ioctl_allocate_iso_resource(struct client *client, void *buffer) 1241static int ioctl_allocate_iso_resource(struct client *client,
1242 union ioctl_arg *arg)
1246{ 1243{
1247 struct fw_cdev_allocate_iso_resource *request = buffer; 1244 return init_iso_resource(client,
1248 1245 &arg->allocate_iso_resource, ISO_RES_ALLOC);
1249 return init_iso_resource(client, request, ISO_RES_ALLOC);
1250} 1246}
1251 1247
1252static int ioctl_deallocate_iso_resource(struct client *client, void *buffer) 1248static int ioctl_deallocate_iso_resource(struct client *client,
1249 union ioctl_arg *arg)
1253{ 1250{
1254 struct fw_cdev_deallocate *request = buffer; 1251 return release_client_resource(client,
1255 1252 arg->deallocate.handle, release_iso_resource, NULL);
1256 return release_client_resource(client, request->handle,
1257 release_iso_resource, NULL);
1258} 1253}
1259 1254
1260static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer) 1255static int ioctl_allocate_iso_resource_once(struct client *client,
1256 union ioctl_arg *arg)
1261{ 1257{
1262 struct fw_cdev_allocate_iso_resource *request = buffer; 1258 return init_iso_resource(client,
1263 1259 &arg->allocate_iso_resource, ISO_RES_ALLOC_ONCE);
1264 return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE);
1265} 1260}
1266 1261
1267static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer) 1262static int ioctl_deallocate_iso_resource_once(struct client *client,
1263 union ioctl_arg *arg)
1268{ 1264{
1269 struct fw_cdev_allocate_iso_resource *request = buffer; 1265 return init_iso_resource(client,
1270 1266 &arg->allocate_iso_resource, ISO_RES_DEALLOC_ONCE);
1271 return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE);
1272} 1267}
1273 1268
1274/* 1269/*
@@ -1276,16 +1271,17 @@ static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffe
1276 * limited by the device's link speed, the local node's link speed, 1271 * limited by the device's link speed, the local node's link speed,
1277 * and all PHY port speeds between the two links. 1272 * and all PHY port speeds between the two links.
1278 */ 1273 */
1279static int ioctl_get_speed(struct client *client, void *buffer) 1274static int ioctl_get_speed(struct client *client, union ioctl_arg *arg)
1280{ 1275{
1281 return client->device->max_speed; 1276 return client->device->max_speed;
1282} 1277}
1283 1278
1284static int ioctl_send_broadcast_request(struct client *client, void *buffer) 1279static int ioctl_send_broadcast_request(struct client *client,
1280 union ioctl_arg *arg)
1285{ 1281{
1286 struct fw_cdev_send_request *request = buffer; 1282 struct fw_cdev_send_request *a = &arg->send_request;
1287 1283
1288 switch (request->tcode) { 1284 switch (a->tcode) {
1289 case TCODE_WRITE_QUADLET_REQUEST: 1285 case TCODE_WRITE_QUADLET_REQUEST:
1290 case TCODE_WRITE_BLOCK_REQUEST: 1286 case TCODE_WRITE_BLOCK_REQUEST:
1291 break; 1287 break;
@@ -1294,36 +1290,36 @@ static int ioctl_send_broadcast_request(struct client *client, void *buffer)
1294 } 1290 }
1295 1291
1296 /* Security policy: Only allow accesses to Units Space. */ 1292 /* Security policy: Only allow accesses to Units Space. */
1297 if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END) 1293 if (a->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END)
1298 return -EACCES; 1294 return -EACCES;
1299 1295
1300 return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100); 1296 return init_request(client, a, LOCAL_BUS | 0x3f, SCODE_100);
1301} 1297}
1302 1298
1303static int ioctl_send_stream_packet(struct client *client, void *buffer) 1299static int ioctl_send_stream_packet(struct client *client, union ioctl_arg *arg)
1304{ 1300{
1305 struct fw_cdev_send_stream_packet *p = buffer; 1301 struct fw_cdev_send_stream_packet *a = &arg->send_stream_packet;
1306 struct fw_cdev_send_request request; 1302 struct fw_cdev_send_request request;
1307 int dest; 1303 int dest;
1308 1304
1309 if (p->speed > client->device->card->link_speed || 1305 if (a->speed > client->device->card->link_speed ||
1310 p->length > 1024 << p->speed) 1306 a->length > 1024 << a->speed)
1311 return -EIO; 1307 return -EIO;
1312 1308
1313 if (p->tag > 3 || p->channel > 63 || p->sy > 15) 1309 if (a->tag > 3 || a->channel > 63 || a->sy > 15)
1314 return -EINVAL; 1310 return -EINVAL;
1315 1311
1316 dest = fw_stream_packet_destination_id(p->tag, p->channel, p->sy); 1312 dest = fw_stream_packet_destination_id(a->tag, a->channel, a->sy);
1317 request.tcode = TCODE_STREAM_DATA; 1313 request.tcode = TCODE_STREAM_DATA;
1318 request.length = p->length; 1314 request.length = a->length;
1319 request.closure = p->closure; 1315 request.closure = a->closure;
1320 request.data = p->data; 1316 request.data = a->data;
1321 request.generation = p->generation; 1317 request.generation = a->generation;
1322 1318
1323 return init_request(client, &request, dest, p->speed); 1319 return init_request(client, &request, dest, a->speed);
1324} 1320}
1325 1321
1326static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { 1322static int (* const ioctl_handlers[])(struct client *, union ioctl_arg *) = {
1327 ioctl_get_info, 1323 ioctl_get_info,
1328 ioctl_send_request, 1324 ioctl_send_request,
1329 ioctl_allocate, 1325 ioctl_allocate,
@@ -1350,24 +1346,7 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
1350static int dispatch_ioctl(struct client *client, 1346static int dispatch_ioctl(struct client *client,
1351 unsigned int cmd, void __user *arg) 1347 unsigned int cmd, void __user *arg)
1352{ 1348{
1353 char buffer[sizeof(union { 1349 union ioctl_arg buffer;
1354 struct fw_cdev_get_info _00;
1355 struct fw_cdev_send_request _01;
1356 struct fw_cdev_allocate _02;
1357 struct fw_cdev_deallocate _03;
1358 struct fw_cdev_send_response _04;
1359 struct fw_cdev_initiate_bus_reset _05;
1360 struct fw_cdev_add_descriptor _06;
1361 struct fw_cdev_remove_descriptor _07;
1362 struct fw_cdev_create_iso_context _08;
1363 struct fw_cdev_queue_iso _09;
1364 struct fw_cdev_start_iso _0a;
1365 struct fw_cdev_stop_iso _0b;
1366 struct fw_cdev_get_cycle_timer _0c;
1367 struct fw_cdev_allocate_iso_resource _0d;
1368 struct fw_cdev_send_stream_packet _13;
1369 struct fw_cdev_get_cycle_timer2 _14;
1370 })];
1371 int ret; 1350 int ret;
1372 1351
1373 if (_IOC_TYPE(cmd) != '#' || 1352 if (_IOC_TYPE(cmd) != '#' ||
@@ -1376,17 +1355,17 @@ static int dispatch_ioctl(struct client *client,
1376 1355
1377 if (_IOC_DIR(cmd) & _IOC_WRITE) { 1356 if (_IOC_DIR(cmd) & _IOC_WRITE) {
1378 if (_IOC_SIZE(cmd) > sizeof(buffer) || 1357 if (_IOC_SIZE(cmd) > sizeof(buffer) ||
1379 copy_from_user(buffer, arg, _IOC_SIZE(cmd))) 1358 copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
1380 return -EFAULT; 1359 return -EFAULT;
1381 } 1360 }
1382 1361
1383 ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer); 1362 ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer);
1384 if (ret < 0) 1363 if (ret < 0)
1385 return ret; 1364 return ret;
1386 1365
1387 if (_IOC_DIR(cmd) & _IOC_READ) { 1366 if (_IOC_DIR(cmd) & _IOC_READ) {
1388 if (_IOC_SIZE(cmd) > sizeof(buffer) || 1367 if (_IOC_SIZE(cmd) > sizeof(buffer) ||
1389 copy_to_user(arg, buffer, _IOC_SIZE(cmd))) 1368 copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
1390 return -EFAULT; 1369 return -EFAULT;
1391 } 1370 }
1392 1371