aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/core-cdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/core-cdev.c')
-rw-r--r--drivers/firewire/core-cdev.c500
1 files changed, 274 insertions, 226 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 5089331544ed..14a34d99eea2 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -25,6 +25,7 @@
25#include <linux/firewire.h> 25#include <linux/firewire.h>
26#include <linux/firewire-cdev.h> 26#include <linux/firewire-cdev.h>
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <linux/irqflags.h>
28#include <linux/jiffies.h> 29#include <linux/jiffies.h>
29#include <linux/kernel.h> 30#include <linux/kernel.h>
30#include <linux/kref.h> 31#include <linux/kref.h>
@@ -32,9 +33,10 @@
32#include <linux/module.h> 33#include <linux/module.h>
33#include <linux/mutex.h> 34#include <linux/mutex.h>
34#include <linux/poll.h> 35#include <linux/poll.h>
35#include <linux/preempt.h>
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/slab.h>
37#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <linux/string.h>
38#include <linux/time.h> 40#include <linux/time.h>
39#include <linux/uaccess.h> 41#include <linux/uaccess.h>
40#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
@@ -130,9 +132,22 @@ struct iso_resource {
130 struct iso_resource_event *e_alloc, *e_dealloc; 132 struct iso_resource_event *e_alloc, *e_dealloc;
131}; 133};
132 134
133static void schedule_iso_resource(struct iso_resource *);
134static void release_iso_resource(struct client *, struct client_resource *); 135static void release_iso_resource(struct client *, struct client_resource *);
135 136
137static void schedule_iso_resource(struct iso_resource *r, unsigned long delay)
138{
139 client_get(r->client);
140 if (!schedule_delayed_work(&r->work, delay))
141 client_put(r->client);
142}
143
144static void schedule_if_iso_resource(struct client_resource *resource)
145{
146 if (resource->release == release_iso_resource)
147 schedule_iso_resource(container_of(resource,
148 struct iso_resource, resource), 0);
149}
150
136/* 151/*
137 * dequeue_event() just kfree()'s the event, so the event has to be 152 * dequeue_event() just kfree()'s the event, so the event has to be
138 * the first field in a struct XYZ_event. 153 * the first field in a struct XYZ_event.
@@ -166,7 +181,7 @@ struct iso_interrupt_event {
166 181
167struct iso_resource_event { 182struct iso_resource_event {
168 struct event event; 183 struct event event;
169 struct fw_cdev_event_iso_resource resource; 184 struct fw_cdev_event_iso_resource iso_resource;
170}; 185};
171 186
172static inline void __user *u64_to_uptr(__u64 value) 187static inline void __user *u64_to_uptr(__u64 value)
@@ -314,11 +329,8 @@ static void for_each_client(struct fw_device *device,
314 329
315static int schedule_reallocations(int id, void *p, void *data) 330static int schedule_reallocations(int id, void *p, void *data)
316{ 331{
317 struct client_resource *r = p; 332 schedule_if_iso_resource(p);
318 333
319 if (r->release == release_iso_resource)
320 schedule_iso_resource(container_of(r,
321 struct iso_resource, resource));
322 return 0; 334 return 0;
323} 335}
324 336
@@ -357,39 +369,56 @@ void fw_device_cdev_remove(struct fw_device *device)
357 for_each_client(device, wake_up_client); 369 for_each_client(device, wake_up_client);
358} 370}
359 371
360static int ioctl_get_info(struct client *client, void *buffer) 372union ioctl_arg {
373 struct fw_cdev_get_info get_info;
374 struct fw_cdev_send_request send_request;
375 struct fw_cdev_allocate allocate;
376 struct fw_cdev_deallocate deallocate;
377 struct fw_cdev_send_response send_response;
378 struct fw_cdev_initiate_bus_reset initiate_bus_reset;
379 struct fw_cdev_add_descriptor add_descriptor;
380 struct fw_cdev_remove_descriptor remove_descriptor;
381 struct fw_cdev_create_iso_context create_iso_context;
382 struct fw_cdev_queue_iso queue_iso;
383 struct fw_cdev_start_iso start_iso;
384 struct fw_cdev_stop_iso stop_iso;
385 struct fw_cdev_get_cycle_timer get_cycle_timer;
386 struct fw_cdev_allocate_iso_resource allocate_iso_resource;
387 struct fw_cdev_send_stream_packet send_stream_packet;
388 struct fw_cdev_get_cycle_timer2 get_cycle_timer2;
389};
390
391static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
361{ 392{
362 struct fw_cdev_get_info *get_info = buffer; 393 struct fw_cdev_get_info *a = &arg->get_info;
363 struct fw_cdev_event_bus_reset bus_reset; 394 struct fw_cdev_event_bus_reset bus_reset;
364 unsigned long ret = 0; 395 unsigned long ret = 0;
365 396
366 client->version = get_info->version; 397 client->version = a->version;
367 get_info->version = FW_CDEV_VERSION; 398 a->version = FW_CDEV_VERSION;
368 get_info->card = client->device->card->index; 399 a->card = client->device->card->index;
369 400
370 down_read(&fw_device_rwsem); 401 down_read(&fw_device_rwsem);
371 402
372 if (get_info->rom != 0) { 403 if (a->rom != 0) {
373 void __user *uptr = u64_to_uptr(get_info->rom); 404 size_t want = a->rom_length;
374 size_t want = get_info->rom_length;
375 size_t have = client->device->config_rom_length * 4; 405 size_t have = client->device->config_rom_length * 4;
376 406
377 ret = copy_to_user(uptr, client->device->config_rom, 407 ret = copy_to_user(u64_to_uptr(a->rom),
378 min(want, have)); 408 client->device->config_rom, min(want, have));
379 } 409 }
380 get_info->rom_length = client->device->config_rom_length * 4; 410 a->rom_length = client->device->config_rom_length * 4;
381 411
382 up_read(&fw_device_rwsem); 412 up_read(&fw_device_rwsem);
383 413
384 if (ret != 0) 414 if (ret != 0)
385 return -EFAULT; 415 return -EFAULT;
386 416
387 client->bus_reset_closure = get_info->bus_reset_closure; 417 client->bus_reset_closure = a->bus_reset_closure;
388 if (get_info->bus_reset != 0) { 418 if (a->bus_reset != 0) {
389 void __user *uptr = u64_to_uptr(get_info->bus_reset);
390
391 fill_bus_reset_event(&bus_reset, client); 419 fill_bus_reset_event(&bus_reset, client);
392 if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) 420 if (copy_to_user(u64_to_uptr(a->bus_reset),
421 &bus_reset, sizeof(bus_reset)))
393 return -EFAULT; 422 return -EFAULT;
394 } 423 }
395 424
@@ -414,9 +443,7 @@ static int add_client_resource(struct client *client,
414 &resource->handle); 443 &resource->handle);
415 if (ret >= 0) { 444 if (ret >= 0) {
416 client_get(client); 445 client_get(client);
417 if (resource->release == release_iso_resource) 446 schedule_if_iso_resource(resource);
418 schedule_iso_resource(container_of(resource,
419 struct iso_resource, resource));
420 } 447 }
421 spin_unlock_irqrestore(&client->lock, flags); 448 spin_unlock_irqrestore(&client->lock, flags);
422 449
@@ -428,26 +455,26 @@ static int add_client_resource(struct client *client,
428 455
429static int release_client_resource(struct client *client, u32 handle, 456static int release_client_resource(struct client *client, u32 handle,
430 client_resource_release_fn_t release, 457 client_resource_release_fn_t release,
431 struct client_resource **resource) 458 struct client_resource **return_resource)
432{ 459{
433 struct client_resource *r; 460 struct client_resource *resource;
434 461
435 spin_lock_irq(&client->lock); 462 spin_lock_irq(&client->lock);
436 if (client->in_shutdown) 463 if (client->in_shutdown)
437 r = NULL; 464 resource = NULL;
438 else 465 else
439 r = idr_find(&client->resource_idr, handle); 466 resource = idr_find(&client->resource_idr, handle);
440 if (r && r->release == release) 467 if (resource && resource->release == release)
441 idr_remove(&client->resource_idr, handle); 468 idr_remove(&client->resource_idr, handle);
442 spin_unlock_irq(&client->lock); 469 spin_unlock_irq(&client->lock);
443 470
444 if (!(r && r->release == release)) 471 if (!(resource && resource->release == release))
445 return -EINVAL; 472 return -EINVAL;
446 473
447 if (resource) 474 if (return_resource)
448 *resource = r; 475 *return_resource = resource;
449 else 476 else
450 r->release(client, r); 477 resource->release(client, resource);
451 478
452 client_put(client); 479 client_put(client);
453 480
@@ -562,11 +589,9 @@ static int init_request(struct client *client,
562 return ret; 589 return ret;
563} 590}
564 591
565static int ioctl_send_request(struct client *client, void *buffer) 592static int ioctl_send_request(struct client *client, union ioctl_arg *arg)
566{ 593{
567 struct fw_cdev_send_request *request = buffer; 594 switch (arg->send_request.tcode) {
568
569 switch (request->tcode) {
570 case TCODE_WRITE_QUADLET_REQUEST: 595 case TCODE_WRITE_QUADLET_REQUEST:
571 case TCODE_WRITE_BLOCK_REQUEST: 596 case TCODE_WRITE_BLOCK_REQUEST:
572 case TCODE_READ_QUADLET_REQUEST: 597 case TCODE_READ_QUADLET_REQUEST:
@@ -583,18 +608,26 @@ static int ioctl_send_request(struct client *client, void *buffer)
583 return -EINVAL; 608 return -EINVAL;
584 } 609 }
585 610
586 return init_request(client, request, client->device->node_id, 611 return init_request(client, &arg->send_request, client->device->node_id,
587 client->device->max_speed); 612 client->device->max_speed);
588} 613}
589 614
615static inline bool is_fcp_request(struct fw_request *request)
616{
617 return request == NULL;
618}
619
590static void release_request(struct client *client, 620static void release_request(struct client *client,
591 struct client_resource *resource) 621 struct client_resource *resource)
592{ 622{
593 struct inbound_transaction_resource *r = container_of(resource, 623 struct inbound_transaction_resource *r = container_of(resource,
594 struct inbound_transaction_resource, resource); 624 struct inbound_transaction_resource, resource);
595 625
596 fw_send_response(client->device->card, r->request, 626 if (is_fcp_request(r->request))
597 RCODE_CONFLICT_ERROR); 627 kfree(r->data);
628 else
629 fw_send_response(client->device->card, r->request,
630 RCODE_CONFLICT_ERROR);
598 kfree(r); 631 kfree(r);
599} 632}
600 633
@@ -607,6 +640,7 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
607 struct address_handler_resource *handler = callback_data; 640 struct address_handler_resource *handler = callback_data;
608 struct inbound_transaction_resource *r; 641 struct inbound_transaction_resource *r;
609 struct inbound_transaction_event *e; 642 struct inbound_transaction_event *e;
643 void *fcp_frame = NULL;
610 int ret; 644 int ret;
611 645
612 r = kmalloc(sizeof(*r), GFP_ATOMIC); 646 r = kmalloc(sizeof(*r), GFP_ATOMIC);
@@ -618,6 +652,18 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
618 r->data = payload; 652 r->data = payload;
619 r->length = length; 653 r->length = length;
620 654
655 if (is_fcp_request(request)) {
656 /*
657 * FIXME: Let core-transaction.c manage a
658 * single reference-counted copy?
659 */
660 fcp_frame = kmemdup(payload, length, GFP_ATOMIC);
661 if (fcp_frame == NULL)
662 goto failed;
663
664 r->data = fcp_frame;
665 }
666
621 r->resource.release = release_request; 667 r->resource.release = release_request;
622 ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC); 668 ret = add_client_resource(handler->client, &r->resource, GFP_ATOMIC);
623 if (ret < 0) 669 if (ret < 0)
@@ -631,13 +677,16 @@ static void handle_request(struct fw_card *card, struct fw_request *request,
631 e->request.closure = handler->closure; 677 e->request.closure = handler->closure;
632 678
633 queue_event(handler->client, &e->event, 679 queue_event(handler->client, &e->event,
634 &e->request, sizeof(e->request), payload, length); 680 &e->request, sizeof(e->request), r->data, length);
635 return; 681 return;
636 682
637 failed: 683 failed:
638 kfree(r); 684 kfree(r);
639 kfree(e); 685 kfree(e);
640 fw_send_response(card, request, RCODE_CONFLICT_ERROR); 686 kfree(fcp_frame);
687
688 if (!is_fcp_request(request))
689 fw_send_response(card, request, RCODE_CONFLICT_ERROR);
641} 690}
642 691
643static void release_address_handler(struct client *client, 692static void release_address_handler(struct client *client,
@@ -650,9 +699,9 @@ static void release_address_handler(struct client *client,
650 kfree(r); 699 kfree(r);
651} 700}
652 701
653static int ioctl_allocate(struct client *client, void *buffer) 702static int ioctl_allocate(struct client *client, union ioctl_arg *arg)
654{ 703{
655 struct fw_cdev_allocate *request = buffer; 704 struct fw_cdev_allocate *a = &arg->allocate;
656 struct address_handler_resource *r; 705 struct address_handler_resource *r;
657 struct fw_address_region region; 706 struct fw_address_region region;
658 int ret; 707 int ret;
@@ -661,13 +710,13 @@ static int ioctl_allocate(struct client *client, void *buffer)
661 if (r == NULL) 710 if (r == NULL)
662 return -ENOMEM; 711 return -ENOMEM;
663 712
664 region.start = request->offset; 713 region.start = a->offset;
665 region.end = request->offset + request->length; 714 region.end = a->offset + a->length;
666 r->handler.length = request->length; 715 r->handler.length = a->length;
667 r->handler.address_callback = handle_request; 716 r->handler.address_callback = handle_request;
668 r->handler.callback_data = r; 717 r->handler.callback_data = r;
669 r->closure = request->closure; 718 r->closure = a->closure;
670 r->client = client; 719 r->client = client;
671 720
672 ret = fw_core_add_address_handler(&r->handler, &region); 721 ret = fw_core_add_address_handler(&r->handler, &region);
673 if (ret < 0) { 722 if (ret < 0) {
@@ -681,50 +730,51 @@ static int ioctl_allocate(struct client *client, void *buffer)
681 release_address_handler(client, &r->resource); 730 release_address_handler(client, &r->resource);
682 return ret; 731 return ret;
683 } 732 }
684 request->handle = r->resource.handle; 733 a->handle = r->resource.handle;
685 734
686 return 0; 735 return 0;
687} 736}
688 737
689static int ioctl_deallocate(struct client *client, void *buffer) 738static int ioctl_deallocate(struct client *client, union ioctl_arg *arg)
690{ 739{
691 struct fw_cdev_deallocate *request = buffer; 740 return release_client_resource(client, arg->deallocate.handle,
692
693 return release_client_resource(client, request->handle,
694 release_address_handler, NULL); 741 release_address_handler, NULL);
695} 742}
696 743
697static int ioctl_send_response(struct client *client, void *buffer) 744static int ioctl_send_response(struct client *client, union ioctl_arg *arg)
698{ 745{
699 struct fw_cdev_send_response *request = buffer; 746 struct fw_cdev_send_response *a = &arg->send_response;
700 struct client_resource *resource; 747 struct client_resource *resource;
701 struct inbound_transaction_resource *r; 748 struct inbound_transaction_resource *r;
749 int ret = 0;
702 750
703 if (release_client_resource(client, request->handle, 751 if (release_client_resource(client, a->handle,
704 release_request, &resource) < 0) 752 release_request, &resource) < 0)
705 return -EINVAL; 753 return -EINVAL;
706 754
707 r = container_of(resource, struct inbound_transaction_resource, 755 r = container_of(resource, struct inbound_transaction_resource,
708 resource); 756 resource);
709 if (request->length < r->length) 757 if (is_fcp_request(r->request))
710 r->length = request->length; 758 goto out;
711 if (copy_from_user(r->data, u64_to_uptr(request->data), r->length))
712 return -EFAULT;
713 759
714 fw_send_response(client->device->card, r->request, request->rcode); 760 if (a->length < r->length)
761 r->length = a->length;
762 if (copy_from_user(r->data, u64_to_uptr(a->data), r->length)) {
763 ret = -EFAULT;
764 kfree(r->request);
765 goto out;
766 }
767 fw_send_response(client->device->card, r->request, a->rcode);
768 out:
715 kfree(r); 769 kfree(r);
716 770
717 return 0; 771 return ret;
718} 772}
719 773
720static int ioctl_initiate_bus_reset(struct client *client, void *buffer) 774static int ioctl_initiate_bus_reset(struct client *client, union ioctl_arg *arg)
721{ 775{
722 struct fw_cdev_initiate_bus_reset *request = buffer; 776 return fw_core_initiate_bus_reset(client->device->card,
723 int short_reset; 777 arg->initiate_bus_reset.type == FW_CDEV_SHORT_RESET);
724
725 short_reset = (request->type == FW_CDEV_SHORT_RESET);
726
727 return fw_core_initiate_bus_reset(client->device->card, short_reset);
728} 778}
729 779
730static void release_descriptor(struct client *client, 780static void release_descriptor(struct client *client,
@@ -737,9 +787,9 @@ static void release_descriptor(struct client *client,
737 kfree(r); 787 kfree(r);
738} 788}
739 789
740static int ioctl_add_descriptor(struct client *client, void *buffer) 790static int ioctl_add_descriptor(struct client *client, union ioctl_arg *arg)
741{ 791{
742 struct fw_cdev_add_descriptor *request = buffer; 792 struct fw_cdev_add_descriptor *a = &arg->add_descriptor;
743 struct descriptor_resource *r; 793 struct descriptor_resource *r;
744 int ret; 794 int ret;
745 795
@@ -747,22 +797,21 @@ static int ioctl_add_descriptor(struct client *client, void *buffer)
747 if (!client->device->is_local) 797 if (!client->device->is_local)
748 return -ENOSYS; 798 return -ENOSYS;
749 799
750 if (request->length > 256) 800 if (a->length > 256)
751 return -EINVAL; 801 return -EINVAL;
752 802
753 r = kmalloc(sizeof(*r) + request->length * 4, GFP_KERNEL); 803 r = kmalloc(sizeof(*r) + a->length * 4, GFP_KERNEL);
754 if (r == NULL) 804 if (r == NULL)
755 return -ENOMEM; 805 return -ENOMEM;
756 806
757 if (copy_from_user(r->data, 807 if (copy_from_user(r->data, u64_to_uptr(a->data), a->length * 4)) {
758 u64_to_uptr(request->data), request->length * 4)) {
759 ret = -EFAULT; 808 ret = -EFAULT;
760 goto failed; 809 goto failed;
761 } 810 }
762 811
763 r->descriptor.length = request->length; 812 r->descriptor.length = a->length;
764 r->descriptor.immediate = request->immediate; 813 r->descriptor.immediate = a->immediate;
765 r->descriptor.key = request->key; 814 r->descriptor.key = a->key;
766 r->descriptor.data = r->data; 815 r->descriptor.data = r->data;
767 816
768 ret = fw_core_add_descriptor(&r->descriptor); 817 ret = fw_core_add_descriptor(&r->descriptor);
@@ -775,7 +824,7 @@ static int ioctl_add_descriptor(struct client *client, void *buffer)
775 fw_core_remove_descriptor(&r->descriptor); 824 fw_core_remove_descriptor(&r->descriptor);
776 goto failed; 825 goto failed;
777 } 826 }
778 request->handle = r->resource.handle; 827 a->handle = r->resource.handle;
779 828
780 return 0; 829 return 0;
781 failed: 830 failed:
@@ -784,11 +833,9 @@ static int ioctl_add_descriptor(struct client *client, void *buffer)
784 return ret; 833 return ret;
785} 834}
786 835
787static int ioctl_remove_descriptor(struct client *client, void *buffer) 836static int ioctl_remove_descriptor(struct client *client, union ioctl_arg *arg)
788{ 837{
789 struct fw_cdev_remove_descriptor *request = buffer; 838 return release_client_resource(client, arg->remove_descriptor.handle,
790
791 return release_client_resource(client, request->handle,
792 release_descriptor, NULL); 839 release_descriptor, NULL);
793} 840}
794 841
@@ -811,49 +858,44 @@ static void iso_callback(struct fw_iso_context *context, u32 cycle,
811 sizeof(e->interrupt) + header_length, NULL, 0); 858 sizeof(e->interrupt) + header_length, NULL, 0);
812} 859}
813 860
814static int ioctl_create_iso_context(struct client *client, void *buffer) 861static int ioctl_create_iso_context(struct client *client, union ioctl_arg *arg)
815{ 862{
816 struct fw_cdev_create_iso_context *request = buffer; 863 struct fw_cdev_create_iso_context *a = &arg->create_iso_context;
817 struct fw_iso_context *context; 864 struct fw_iso_context *context;
818 865
819 /* We only support one context at this time. */ 866 /* We only support one context at this time. */
820 if (client->iso_context != NULL) 867 if (client->iso_context != NULL)
821 return -EBUSY; 868 return -EBUSY;
822 869
823 if (request->channel > 63) 870 if (a->channel > 63)
824 return -EINVAL; 871 return -EINVAL;
825 872
826 switch (request->type) { 873 switch (a->type) {
827 case FW_ISO_CONTEXT_RECEIVE: 874 case FW_ISO_CONTEXT_RECEIVE:
828 if (request->header_size < 4 || (request->header_size & 3)) 875 if (a->header_size < 4 || (a->header_size & 3))
829 return -EINVAL; 876 return -EINVAL;
830
831 break; 877 break;
832 878
833 case FW_ISO_CONTEXT_TRANSMIT: 879 case FW_ISO_CONTEXT_TRANSMIT:
834 if (request->speed > SCODE_3200) 880 if (a->speed > SCODE_3200)
835 return -EINVAL; 881 return -EINVAL;
836
837 break; 882 break;
838 883
839 default: 884 default:
840 return -EINVAL; 885 return -EINVAL;
841 } 886 }
842 887
843 context = fw_iso_context_create(client->device->card, 888 context = fw_iso_context_create(client->device->card, a->type,
844 request->type, 889 a->channel, a->speed, a->header_size,
845 request->channel, 890 iso_callback, client);
846 request->speed,
847 request->header_size,
848 iso_callback, client);
849 if (IS_ERR(context)) 891 if (IS_ERR(context))
850 return PTR_ERR(context); 892 return PTR_ERR(context);
851 893
852 client->iso_closure = request->closure; 894 client->iso_closure = a->closure;
853 client->iso_context = context; 895 client->iso_context = context;
854 896
855 /* We only support one context at this time. */ 897 /* We only support one context at this time. */
856 request->handle = 0; 898 a->handle = 0;
857 899
858 return 0; 900 return 0;
859} 901}
@@ -866,9 +908,9 @@ static int ioctl_create_iso_context(struct client *client, void *buffer)
866#define GET_SY(v) (((v) >> 20) & 0x0f) 908#define GET_SY(v) (((v) >> 20) & 0x0f)
867#define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff) 909#define GET_HEADER_LENGTH(v) (((v) >> 24) & 0xff)
868 910
869static int ioctl_queue_iso(struct client *client, void *buffer) 911static int ioctl_queue_iso(struct client *client, union ioctl_arg *arg)
870{ 912{
871 struct fw_cdev_queue_iso *request = buffer; 913 struct fw_cdev_queue_iso *a = &arg->queue_iso;
872 struct fw_cdev_iso_packet __user *p, *end, *next; 914 struct fw_cdev_iso_packet __user *p, *end, *next;
873 struct fw_iso_context *ctx = client->iso_context; 915 struct fw_iso_context *ctx = client->iso_context;
874 unsigned long payload, buffer_end, header_length; 916 unsigned long payload, buffer_end, header_length;
@@ -879,7 +921,7 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
879 u8 header[256]; 921 u8 header[256];
880 } u; 922 } u;
881 923
882 if (ctx == NULL || request->handle != 0) 924 if (ctx == NULL || a->handle != 0)
883 return -EINVAL; 925 return -EINVAL;
884 926
885 /* 927 /*
@@ -889,23 +931,23 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
889 * set them both to 0, which will still let packets with 931 * set them both to 0, which will still let packets with
890 * payload_length == 0 through. In other words, if no packets 932 * payload_length == 0 through. In other words, if no packets
891 * use the indirect payload, the iso buffer need not be mapped 933 * use the indirect payload, the iso buffer need not be mapped
892 * and the request->data pointer is ignored. 934 * and the a->data pointer is ignored.
893 */ 935 */
894 936
895 payload = (unsigned long)request->data - client->vm_start; 937 payload = (unsigned long)a->data - client->vm_start;
896 buffer_end = client->buffer.page_count << PAGE_SHIFT; 938 buffer_end = client->buffer.page_count << PAGE_SHIFT;
897 if (request->data == 0 || client->buffer.pages == NULL || 939 if (a->data == 0 || client->buffer.pages == NULL ||
898 payload >= buffer_end) { 940 payload >= buffer_end) {
899 payload = 0; 941 payload = 0;
900 buffer_end = 0; 942 buffer_end = 0;
901 } 943 }
902 944
903 p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(request->packets); 945 p = (struct fw_cdev_iso_packet __user *)u64_to_uptr(a->packets);
904 946
905 if (!access_ok(VERIFY_READ, p, request->size)) 947 if (!access_ok(VERIFY_READ, p, a->size))
906 return -EFAULT; 948 return -EFAULT;
907 949
908 end = (void __user *)p + request->size; 950 end = (void __user *)p + a->size;
909 count = 0; 951 count = 0;
910 while (p < end) { 952 while (p < end) {
911 if (get_user(control, &p->control)) 953 if (get_user(control, &p->control))
@@ -918,6 +960,8 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
918 u.packet.header_length = GET_HEADER_LENGTH(control); 960 u.packet.header_length = GET_HEADER_LENGTH(control);
919 961
920 if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) { 962 if (ctx->type == FW_ISO_CONTEXT_TRANSMIT) {
963 if (u.packet.header_length % 4 != 0)
964 return -EINVAL;
921 header_length = u.packet.header_length; 965 header_length = u.packet.header_length;
922 } else { 966 } else {
923 /* 967 /*
@@ -927,7 +971,8 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
927 if (ctx->header_size == 0) { 971 if (ctx->header_size == 0) {
928 if (u.packet.header_length > 0) 972 if (u.packet.header_length > 0)
929 return -EINVAL; 973 return -EINVAL;
930 } else if (u.packet.header_length % ctx->header_size != 0) { 974 } else if (u.packet.header_length == 0 ||
975 u.packet.header_length % ctx->header_size != 0) {
931 return -EINVAL; 976 return -EINVAL;
932 } 977 }
933 header_length = 0; 978 header_length = 0;
@@ -955,61 +1000,78 @@ static int ioctl_queue_iso(struct client *client, void *buffer)
955 count++; 1000 count++;
956 } 1001 }
957 1002
958 request->size -= uptr_to_u64(p) - request->packets; 1003 a->size -= uptr_to_u64(p) - a->packets;
959 request->packets = uptr_to_u64(p); 1004 a->packets = uptr_to_u64(p);
960 request->data = client->vm_start + payload; 1005 a->data = client->vm_start + payload;
961 1006
962 return count; 1007 return count;
963} 1008}
964 1009
965static int ioctl_start_iso(struct client *client, void *buffer) 1010static int ioctl_start_iso(struct client *client, union ioctl_arg *arg)
966{ 1011{
967 struct fw_cdev_start_iso *request = buffer; 1012 struct fw_cdev_start_iso *a = &arg->start_iso;
968 1013
969 if (client->iso_context == NULL || request->handle != 0) 1014 if (client->iso_context == NULL || a->handle != 0)
970 return -EINVAL; 1015 return -EINVAL;
971 1016
972 if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE) { 1017 if (client->iso_context->type == FW_ISO_CONTEXT_RECEIVE &&
973 if (request->tags == 0 || request->tags > 15) 1018 (a->tags == 0 || a->tags > 15 || a->sync > 15))
974 return -EINVAL; 1019 return -EINVAL;
975
976 if (request->sync > 15)
977 return -EINVAL;
978 }
979 1020
980 return fw_iso_context_start(client->iso_context, request->cycle, 1021 return fw_iso_context_start(client->iso_context,
981 request->sync, request->tags); 1022 a->cycle, a->sync, a->tags);
982} 1023}
983 1024
984static int ioctl_stop_iso(struct client *client, void *buffer) 1025static int ioctl_stop_iso(struct client *client, union ioctl_arg *arg)
985{ 1026{
986 struct fw_cdev_stop_iso *request = buffer; 1027 struct fw_cdev_stop_iso *a = &arg->stop_iso;
987 1028
988 if (client->iso_context == NULL || request->handle != 0) 1029 if (client->iso_context == NULL || a->handle != 0)
989 return -EINVAL; 1030 return -EINVAL;
990 1031
991 return fw_iso_context_stop(client->iso_context); 1032 return fw_iso_context_stop(client->iso_context);
992} 1033}
993 1034
994static int ioctl_get_cycle_timer(struct client *client, void *buffer) 1035static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg)
995{ 1036{
996 struct fw_cdev_get_cycle_timer *request = buffer; 1037 struct fw_cdev_get_cycle_timer2 *a = &arg->get_cycle_timer2;
997 struct fw_card *card = client->device->card; 1038 struct fw_card *card = client->device->card;
998 unsigned long long bus_time; 1039 struct timespec ts = {0, 0};
999 struct timeval tv; 1040 u32 cycle_time;
1000 unsigned long flags; 1041 int ret = 0;
1042
1043 local_irq_disable();
1044
1045 cycle_time = card->driver->get_cycle_time(card);
1046
1047 switch (a->clk_id) {
1048 case CLOCK_REALTIME: getnstimeofday(&ts); break;
1049 case CLOCK_MONOTONIC: do_posix_clock_monotonic_gettime(&ts); break;
1050 case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break;
1051 default:
1052 ret = -EINVAL;
1053 }
1054
1055 local_irq_enable();
1056
1057 a->tv_sec = ts.tv_sec;
1058 a->tv_nsec = ts.tv_nsec;
1059 a->cycle_timer = cycle_time;
1001 1060
1002 preempt_disable(); 1061 return ret;
1003 local_irq_save(flags); 1062}
1004 1063
1005 bus_time = card->driver->get_bus_time(card); 1064static int ioctl_get_cycle_timer(struct client *client, union ioctl_arg *arg)
1006 do_gettimeofday(&tv); 1065{
1066 struct fw_cdev_get_cycle_timer *a = &arg->get_cycle_timer;
1067 struct fw_cdev_get_cycle_timer2 ct2;
1007 1068
1008 local_irq_restore(flags); 1069 ct2.clk_id = CLOCK_REALTIME;
1009 preempt_enable(); 1070 ioctl_get_cycle_timer2(client, (union ioctl_arg *)&ct2);
1071
1072 a->local_time = ct2.tv_sec * USEC_PER_SEC + ct2.tv_nsec / NSEC_PER_USEC;
1073 a->cycle_timer = ct2.cycle_timer;
1010 1074
1011 request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
1012 request->cycle_timer = bus_time & 0xffffffff;
1013 return 0; 1075 return 0;
1014} 1076}
1015 1077
@@ -1028,8 +1090,7 @@ static void iso_resource_work(struct work_struct *work)
1028 /* Allow 1000ms grace period for other reallocations. */ 1090 /* Allow 1000ms grace period for other reallocations. */
1029 if (todo == ISO_RES_ALLOC && 1091 if (todo == ISO_RES_ALLOC &&
1030 time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) { 1092 time_is_after_jiffies(client->device->card->reset_jiffies + HZ)) {
1031 if (schedule_delayed_work(&r->work, DIV_ROUND_UP(HZ, 3))) 1093 schedule_iso_resource(r, DIV_ROUND_UP(HZ, 3));
1032 client_get(client);
1033 skip = true; 1094 skip = true;
1034 } else { 1095 } else {
1035 /* We could be called twice within the same generation. */ 1096 /* We could be called twice within the same generation. */
@@ -1097,12 +1158,12 @@ static void iso_resource_work(struct work_struct *work)
1097 e = r->e_dealloc; 1158 e = r->e_dealloc;
1098 r->e_dealloc = NULL; 1159 r->e_dealloc = NULL;
1099 } 1160 }
1100 e->resource.handle = r->resource.handle; 1161 e->iso_resource.handle = r->resource.handle;
1101 e->resource.channel = channel; 1162 e->iso_resource.channel = channel;
1102 e->resource.bandwidth = bandwidth; 1163 e->iso_resource.bandwidth = bandwidth;
1103 1164
1104 queue_event(client, &e->event, 1165 queue_event(client, &e->event,
1105 &e->resource, sizeof(e->resource), NULL, 0); 1166 &e->iso_resource, sizeof(e->iso_resource), NULL, 0);
1106 1167
1107 if (free) { 1168 if (free) {
1108 cancel_delayed_work(&r->work); 1169 cancel_delayed_work(&r->work);
@@ -1114,13 +1175,6 @@ static void iso_resource_work(struct work_struct *work)
1114 client_put(client); 1175 client_put(client);
1115} 1176}
1116 1177
1117static void schedule_iso_resource(struct iso_resource *r)
1118{
1119 client_get(r->client);
1120 if (!schedule_delayed_work(&r->work, 0))
1121 client_put(r->client);
1122}
1123
1124static void release_iso_resource(struct client *client, 1178static void release_iso_resource(struct client *client,
1125 struct client_resource *resource) 1179 struct client_resource *resource)
1126{ 1180{
@@ -1129,7 +1183,7 @@ static void release_iso_resource(struct client *client,
1129 1183
1130 spin_lock_irq(&client->lock); 1184 spin_lock_irq(&client->lock);
1131 r->todo = ISO_RES_DEALLOC; 1185 r->todo = ISO_RES_DEALLOC;
1132 schedule_iso_resource(r); 1186 schedule_iso_resource(r, 0);
1133 spin_unlock_irq(&client->lock); 1187 spin_unlock_irq(&client->lock);
1134} 1188}
1135 1189
@@ -1162,10 +1216,10 @@ static int init_iso_resource(struct client *client,
1162 r->e_alloc = e1; 1216 r->e_alloc = e1;
1163 r->e_dealloc = e2; 1217 r->e_dealloc = e2;
1164 1218
1165 e1->resource.closure = request->closure; 1219 e1->iso_resource.closure = request->closure;
1166 e1->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED; 1220 e1->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_ALLOCATED;
1167 e2->resource.closure = request->closure; 1221 e2->iso_resource.closure = request->closure;
1168 e2->resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED; 1222 e2->iso_resource.type = FW_CDEV_EVENT_ISO_RESOURCE_DEALLOCATED;
1169 1223
1170 if (todo == ISO_RES_ALLOC) { 1224 if (todo == ISO_RES_ALLOC) {
1171 r->resource.release = release_iso_resource; 1225 r->resource.release = release_iso_resource;
@@ -1175,7 +1229,7 @@ static int init_iso_resource(struct client *client,
1175 } else { 1229 } else {
1176 r->resource.release = NULL; 1230 r->resource.release = NULL;
1177 r->resource.handle = -1; 1231 r->resource.handle = -1;
1178 schedule_iso_resource(r); 1232 schedule_iso_resource(r, 0);
1179 } 1233 }
1180 request->handle = r->resource.handle; 1234 request->handle = r->resource.handle;
1181 1235
@@ -1188,33 +1242,32 @@ static int init_iso_resource(struct client *client,
1188 return ret; 1242 return ret;
1189} 1243}
1190 1244
1191static int ioctl_allocate_iso_resource(struct client *client, void *buffer) 1245static int ioctl_allocate_iso_resource(struct client *client,
1246 union ioctl_arg *arg)
1192{ 1247{
1193 struct fw_cdev_allocate_iso_resource *request = buffer; 1248 return init_iso_resource(client,
1194 1249 &arg->allocate_iso_resource, ISO_RES_ALLOC);
1195 return init_iso_resource(client, request, ISO_RES_ALLOC);
1196} 1250}
1197 1251
1198static int ioctl_deallocate_iso_resource(struct client *client, void *buffer) 1252static int ioctl_deallocate_iso_resource(struct client *client,
1253 union ioctl_arg *arg)
1199{ 1254{
1200 struct fw_cdev_deallocate *request = buffer; 1255 return release_client_resource(client,
1201 1256 arg->deallocate.handle, release_iso_resource, NULL);
1202 return release_client_resource(client, request->handle,
1203 release_iso_resource, NULL);
1204} 1257}
1205 1258
1206static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer) 1259static int ioctl_allocate_iso_resource_once(struct client *client,
1260 union ioctl_arg *arg)
1207{ 1261{
1208 struct fw_cdev_allocate_iso_resource *request = buffer; 1262 return init_iso_resource(client,
1209 1263 &arg->allocate_iso_resource, ISO_RES_ALLOC_ONCE);
1210 return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE);
1211} 1264}
1212 1265
1213static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer) 1266static int ioctl_deallocate_iso_resource_once(struct client *client,
1267 union ioctl_arg *arg)
1214{ 1268{
1215 struct fw_cdev_allocate_iso_resource *request = buffer; 1269 return init_iso_resource(client,
1216 1270 &arg->allocate_iso_resource, ISO_RES_DEALLOC_ONCE);
1217 return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE);
1218} 1271}
1219 1272
1220/* 1273/*
@@ -1222,16 +1275,17 @@ static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffe
1222 * limited by the device's link speed, the local node's link speed, 1275 * limited by the device's link speed, the local node's link speed,
1223 * and all PHY port speeds between the two links. 1276 * and all PHY port speeds between the two links.
1224 */ 1277 */
1225static int ioctl_get_speed(struct client *client, void *buffer) 1278static int ioctl_get_speed(struct client *client, union ioctl_arg *arg)
1226{ 1279{
1227 return client->device->max_speed; 1280 return client->device->max_speed;
1228} 1281}
1229 1282
1230static int ioctl_send_broadcast_request(struct client *client, void *buffer) 1283static int ioctl_send_broadcast_request(struct client *client,
1284 union ioctl_arg *arg)
1231{ 1285{
1232 struct fw_cdev_send_request *request = buffer; 1286 struct fw_cdev_send_request *a = &arg->send_request;
1233 1287
1234 switch (request->tcode) { 1288 switch (a->tcode) {
1235 case TCODE_WRITE_QUADLET_REQUEST: 1289 case TCODE_WRITE_QUADLET_REQUEST:
1236 case TCODE_WRITE_BLOCK_REQUEST: 1290 case TCODE_WRITE_BLOCK_REQUEST:
1237 break; 1291 break;
@@ -1240,36 +1294,36 @@ static int ioctl_send_broadcast_request(struct client *client, void *buffer)
1240 } 1294 }
1241 1295
1242 /* Security policy: Only allow accesses to Units Space. */ 1296 /* Security policy: Only allow accesses to Units Space. */
1243 if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END) 1297 if (a->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END)
1244 return -EACCES; 1298 return -EACCES;
1245 1299
1246 return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100); 1300 return init_request(client, a, LOCAL_BUS | 0x3f, SCODE_100);
1247} 1301}
1248 1302
1249static int ioctl_send_stream_packet(struct client *client, void *buffer) 1303static int ioctl_send_stream_packet(struct client *client, union ioctl_arg *arg)
1250{ 1304{
1251 struct fw_cdev_send_stream_packet *p = buffer; 1305 struct fw_cdev_send_stream_packet *a = &arg->send_stream_packet;
1252 struct fw_cdev_send_request request; 1306 struct fw_cdev_send_request request;
1253 int dest; 1307 int dest;
1254 1308
1255 if (p->speed > client->device->card->link_speed || 1309 if (a->speed > client->device->card->link_speed ||
1256 p->length > 1024 << p->speed) 1310 a->length > 1024 << a->speed)
1257 return -EIO; 1311 return -EIO;
1258 1312
1259 if (p->tag > 3 || p->channel > 63 || p->sy > 15) 1313 if (a->tag > 3 || a->channel > 63 || a->sy > 15)
1260 return -EINVAL; 1314 return -EINVAL;
1261 1315
1262 dest = fw_stream_packet_destination_id(p->tag, p->channel, p->sy); 1316 dest = fw_stream_packet_destination_id(a->tag, a->channel, a->sy);
1263 request.tcode = TCODE_STREAM_DATA; 1317 request.tcode = TCODE_STREAM_DATA;
1264 request.length = p->length; 1318 request.length = a->length;
1265 request.closure = p->closure; 1319 request.closure = a->closure;
1266 request.data = p->data; 1320 request.data = a->data;
1267 request.generation = p->generation; 1321 request.generation = a->generation;
1268 1322
1269 return init_request(client, &request, dest, p->speed); 1323 return init_request(client, &request, dest, a->speed);
1270} 1324}
1271 1325
1272static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { 1326static int (* const ioctl_handlers[])(struct client *, union ioctl_arg *) = {
1273 ioctl_get_info, 1327 ioctl_get_info,
1274 ioctl_send_request, 1328 ioctl_send_request,
1275 ioctl_allocate, 1329 ioctl_allocate,
@@ -1290,33 +1344,37 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = {
1290 ioctl_get_speed, 1344 ioctl_get_speed,
1291 ioctl_send_broadcast_request, 1345 ioctl_send_broadcast_request,
1292 ioctl_send_stream_packet, 1346 ioctl_send_stream_packet,
1347 ioctl_get_cycle_timer2,
1293}; 1348};
1294 1349
1295static int dispatch_ioctl(struct client *client, 1350static int dispatch_ioctl(struct client *client,
1296 unsigned int cmd, void __user *arg) 1351 unsigned int cmd, void __user *arg)
1297{ 1352{
1298 char buffer[256]; 1353 union ioctl_arg buffer;
1299 int ret; 1354 int ret;
1300 1355
1356 if (fw_device_is_shutdown(client->device))
1357 return -ENODEV;
1358
1301 if (_IOC_TYPE(cmd) != '#' || 1359 if (_IOC_TYPE(cmd) != '#' ||
1302 _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers)) 1360 _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) ||
1361 _IOC_SIZE(cmd) > sizeof(buffer))
1303 return -EINVAL; 1362 return -EINVAL;
1304 1363
1305 if (_IOC_DIR(cmd) & _IOC_WRITE) { 1364 if (_IOC_DIR(cmd) == _IOC_READ)
1306 if (_IOC_SIZE(cmd) > sizeof(buffer) || 1365 memset(&buffer, 0, _IOC_SIZE(cmd));
1307 copy_from_user(buffer, arg, _IOC_SIZE(cmd))) 1366
1367 if (_IOC_DIR(cmd) & _IOC_WRITE)
1368 if (copy_from_user(&buffer, arg, _IOC_SIZE(cmd)))
1308 return -EFAULT; 1369 return -EFAULT;
1309 }
1310 1370
1311 ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer); 1371 ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer);
1312 if (ret < 0) 1372 if (ret < 0)
1313 return ret; 1373 return ret;
1314 1374
1315 if (_IOC_DIR(cmd) & _IOC_READ) { 1375 if (_IOC_DIR(cmd) & _IOC_READ)
1316 if (_IOC_SIZE(cmd) > sizeof(buffer) || 1376 if (copy_to_user(arg, &buffer, _IOC_SIZE(cmd)))
1317 copy_to_user(arg, buffer, _IOC_SIZE(cmd)))
1318 return -EFAULT; 1377 return -EFAULT;
1319 }
1320 1378
1321 return ret; 1379 return ret;
1322} 1380}
@@ -1324,24 +1382,14 @@ static int dispatch_ioctl(struct client *client,
1324static long fw_device_op_ioctl(struct file *file, 1382static long fw_device_op_ioctl(struct file *file,
1325 unsigned int cmd, unsigned long arg) 1383 unsigned int cmd, unsigned long arg)
1326{ 1384{
1327 struct client *client = file->private_data; 1385 return dispatch_ioctl(file->private_data, cmd, (void __user *)arg);
1328
1329 if (fw_device_is_shutdown(client->device))
1330 return -ENODEV;
1331
1332 return dispatch_ioctl(client, cmd, (void __user *) arg);
1333} 1386}
1334 1387
1335#ifdef CONFIG_COMPAT 1388#ifdef CONFIG_COMPAT
1336static long fw_device_op_compat_ioctl(struct file *file, 1389static long fw_device_op_compat_ioctl(struct file *file,
1337 unsigned int cmd, unsigned long arg) 1390 unsigned int cmd, unsigned long arg)
1338{ 1391{
1339 struct client *client = file->private_data; 1392 return dispatch_ioctl(file->private_data, cmd, compat_ptr(arg));
1340
1341 if (fw_device_is_shutdown(client->device))
1342 return -ENODEV;
1343
1344 return dispatch_ioctl(client, cmd, compat_ptr(arg));
1345} 1393}
1346#endif 1394#endif
1347 1395
@@ -1390,10 +1438,10 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
1390 1438
1391static int shutdown_resource(int id, void *p, void *data) 1439static int shutdown_resource(int id, void *p, void *data)
1392{ 1440{
1393 struct client_resource *r = p; 1441 struct client_resource *resource = p;
1394 struct client *client = data; 1442 struct client *client = data;
1395 1443
1396 r->release(client, r); 1444 resource->release(client, resource);
1397 client_put(client); 1445 client_put(client);
1398 1446
1399 return 0; 1447 return 0;
@@ -1402,7 +1450,7 @@ static int shutdown_resource(int id, void *p, void *data)
1402static int fw_device_op_release(struct inode *inode, struct file *file) 1450static int fw_device_op_release(struct inode *inode, struct file *file)
1403{ 1451{
1404 struct client *client = file->private_data; 1452 struct client *client = file->private_data;
1405 struct event *e, *next_e; 1453 struct event *event, *next_event;
1406 1454
1407 mutex_lock(&client->device->client_list_mutex); 1455 mutex_lock(&client->device->client_list_mutex);
1408 list_del(&client->link); 1456 list_del(&client->link);
@@ -1423,8 +1471,8 @@ static int fw_device_op_release(struct inode *inode, struct file *file)
1423 idr_remove_all(&client->resource_idr); 1471 idr_remove_all(&client->resource_idr);
1424 idr_destroy(&client->resource_idr); 1472 idr_destroy(&client->resource_idr);
1425 1473
1426 list_for_each_entry_safe(e, next_e, &client->event_list, link) 1474 list_for_each_entry_safe(event, next_event, &client->event_list, link)
1427 kfree(e); 1475 kfree(event);
1428 1476
1429 client_put(client); 1477 client_put(client);
1430 1478