diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-03 11:08:44 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-03 11:08:44 -0500 |
commit | c1dcb4bb1e3e16e9baee578d9bb040e5fba1063e (patch) | |
tree | 1bba995740aed8ef9a47111c1ee6ceeda84af836 /drivers/firewire | |
parent | 60f8a8d4c6c46bb080e8e65d30be31b172a39a78 (diff) | |
parent | 6fdb2ee243404c7cbf530387bf904ad1841ebf5b (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6: (23 commits)
firewire: ohci: extend initialization log message
firewire: ohci: fix IR/IT context mask mixup
firewire: ohci: add module parameter to activate quirk fixes
firewire: ohci: use an ID table for quirks detection
firewire: ohci: reorder struct fw_ohci for better cache efficiency
firewire: ohci: remove unused dualbuffer IR code
firewire: core: combine a bit of repeated code
firewire: core: change type of a data buffer
firewire: cdev: increment ABI version number
firewire: cdev: add more flexible cycle timer ioctl
firewire: core: rename an internal function
firewire: core: fix an information leak
firewire: core: increase stack size of config ROM reader
firewire: core: don't fail device creation in case of too large config ROM blocks
firewire: core: fix "giving up on config rom" with Panasonic AG-DV2500
firewire: remove incomplete Bus_Time CSR support
firewire: get_cycle_timer optimization and cleanup
firewire: ohci: enable cycle timer fix on ALi and NEC controllers
firewire: ohci: work around cycle timer bugs on VIA controllers
firewire: make PCI device id constant
...
Diffstat (limited to 'drivers/firewire')
-rw-r--r-- | drivers/firewire/core-cdev.c | 368 | ||||
-rw-r--r-- | drivers/firewire/core-device.c | 198 | ||||
-rw-r--r-- | drivers/firewire/core-transaction.c | 17 | ||||
-rw-r--r-- | drivers/firewire/core.h | 2 | ||||
-rw-r--r-- | drivers/firewire/ohci.c | 364 | ||||
-rw-r--r-- | drivers/firewire/sbp2.c | 5 |
6 files changed, 447 insertions, 507 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 4eeaed57e219..8be720b278b7 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,7 +33,6 @@ | |||
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/spinlock.h> | 37 | #include <linux/spinlock.h> |
38 | #include <linux/string.h> | 38 | #include <linux/string.h> |
@@ -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 | ||
371 | static int ioctl_get_info(struct client *client, void *buffer) | 371 | union 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 | |||
390 | static 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 | ||
574 | static int ioctl_send_request(struct client *client, void *buffer) | 591 | static 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 | ||
686 | static int ioctl_allocate(struct client *client, void *buffer) | 701 | static 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, ®ion); | 720 | ret = fw_core_add_address_handler(&r->handler, ®ion); |
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 | ||
722 | static int ioctl_deallocate(struct client *client, void *buffer) | 737 | static 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 | ||
730 | static int ioctl_send_response(struct client *client, void *buffer) | 743 | static 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 | ||
760 | static int ioctl_initiate_bus_reset(struct client *client, void *buffer) | 773 | static 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 | ||
770 | static void release_descriptor(struct client *client, | 779 | static 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 | ||
780 | static int ioctl_add_descriptor(struct client *client, void *buffer) | 789 | static 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 | ||
827 | static int ioctl_remove_descriptor(struct client *client, void *buffer) | 835 | static 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 | ||
854 | static int ioctl_create_iso_context(struct client *client, void *buffer) | 860 | static 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 | ||
909 | static int ioctl_queue_iso(struct client *client, void *buffer) | 910 | static 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,61 +996,78 @@ 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 | ||
1005 | static int ioctl_start_iso(struct client *client, void *buffer) | 1006 | static 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 | ||
1024 | static int ioctl_stop_iso(struct client *client, void *buffer) | 1021 | static 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 | ||
1034 | static int ioctl_get_cycle_timer(struct client *client, void *buffer) | 1031 | static int ioctl_get_cycle_timer2(struct client *client, union ioctl_arg *arg) |
1035 | { | 1032 | { |
1036 | struct fw_cdev_get_cycle_timer *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 | unsigned long long bus_time; | 1035 | struct timespec ts = {0, 0}; |
1039 | struct timeval tv; | 1036 | u32 cycle_time; |
1040 | unsigned long flags; | 1037 | int ret = 0; |
1038 | |||
1039 | local_irq_disable(); | ||
1040 | |||
1041 | cycle_time = card->driver->get_cycle_time(card); | ||
1041 | 1042 | ||
1042 | preempt_disable(); | 1043 | switch (a->clk_id) { |
1043 | local_irq_save(flags); | 1044 | case CLOCK_REALTIME: getnstimeofday(&ts); break; |
1045 | case CLOCK_MONOTONIC: do_posix_clock_monotonic_gettime(&ts); break; | ||
1046 | case CLOCK_MONOTONIC_RAW: getrawmonotonic(&ts); break; | ||
1047 | default: | ||
1048 | ret = -EINVAL; | ||
1049 | } | ||
1044 | 1050 | ||
1045 | bus_time = card->driver->get_bus_time(card); | 1051 | local_irq_enable(); |
1046 | do_gettimeofday(&tv); | ||
1047 | 1052 | ||
1048 | local_irq_restore(flags); | 1053 | a->tv_sec = ts.tv_sec; |
1049 | preempt_enable(); | 1054 | a->tv_nsec = ts.tv_nsec; |
1055 | a->cycle_timer = cycle_time; | ||
1056 | |||
1057 | return ret; | ||
1058 | } | ||
1059 | |||
1060 | static int ioctl_get_cycle_timer(struct client *client, union ioctl_arg *arg) | ||
1061 | { | ||
1062 | struct fw_cdev_get_cycle_timer *a = &arg->get_cycle_timer; | ||
1063 | struct fw_cdev_get_cycle_timer2 ct2; | ||
1064 | |||
1065 | ct2.clk_id = CLOCK_REALTIME; | ||
1066 | ioctl_get_cycle_timer2(client, (union ioctl_arg *)&ct2); | ||
1067 | |||
1068 | a->local_time = ct2.tv_sec * USEC_PER_SEC + ct2.tv_nsec / NSEC_PER_USEC; | ||
1069 | a->cycle_timer = ct2.cycle_timer; | ||
1050 | 1070 | ||
1051 | request->local_time = tv.tv_sec * 1000000ULL + tv.tv_usec; | ||
1052 | request->cycle_timer = bus_time & 0xffffffff; | ||
1053 | return 0; | 1071 | return 0; |
1054 | } | 1072 | } |
1055 | 1073 | ||
@@ -1220,33 +1238,32 @@ static int init_iso_resource(struct client *client, | |||
1220 | return ret; | 1238 | return ret; |
1221 | } | 1239 | } |
1222 | 1240 | ||
1223 | static int ioctl_allocate_iso_resource(struct client *client, void *buffer) | 1241 | static int ioctl_allocate_iso_resource(struct client *client, |
1242 | union ioctl_arg *arg) | ||
1224 | { | 1243 | { |
1225 | struct fw_cdev_allocate_iso_resource *request = buffer; | 1244 | return init_iso_resource(client, |
1226 | 1245 | &arg->allocate_iso_resource, ISO_RES_ALLOC); | |
1227 | return init_iso_resource(client, request, ISO_RES_ALLOC); | ||
1228 | } | 1246 | } |
1229 | 1247 | ||
1230 | static int ioctl_deallocate_iso_resource(struct client *client, void *buffer) | 1248 | static int ioctl_deallocate_iso_resource(struct client *client, |
1249 | union ioctl_arg *arg) | ||
1231 | { | 1250 | { |
1232 | struct fw_cdev_deallocate *request = buffer; | 1251 | return release_client_resource(client, |
1233 | 1252 | arg->deallocate.handle, release_iso_resource, NULL); | |
1234 | return release_client_resource(client, request->handle, | ||
1235 | release_iso_resource, NULL); | ||
1236 | } | 1253 | } |
1237 | 1254 | ||
1238 | static int ioctl_allocate_iso_resource_once(struct client *client, void *buffer) | 1255 | static int ioctl_allocate_iso_resource_once(struct client *client, |
1256 | union ioctl_arg *arg) | ||
1239 | { | 1257 | { |
1240 | struct fw_cdev_allocate_iso_resource *request = buffer; | 1258 | return init_iso_resource(client, |
1241 | 1259 | &arg->allocate_iso_resource, ISO_RES_ALLOC_ONCE); | |
1242 | return init_iso_resource(client, request, ISO_RES_ALLOC_ONCE); | ||
1243 | } | 1260 | } |
1244 | 1261 | ||
1245 | static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffer) | 1262 | static int ioctl_deallocate_iso_resource_once(struct client *client, |
1263 | union ioctl_arg *arg) | ||
1246 | { | 1264 | { |
1247 | struct fw_cdev_allocate_iso_resource *request = buffer; | 1265 | return init_iso_resource(client, |
1248 | 1266 | &arg->allocate_iso_resource, ISO_RES_DEALLOC_ONCE); | |
1249 | return init_iso_resource(client, request, ISO_RES_DEALLOC_ONCE); | ||
1250 | } | 1267 | } |
1251 | 1268 | ||
1252 | /* | 1269 | /* |
@@ -1254,16 +1271,17 @@ static int ioctl_deallocate_iso_resource_once(struct client *client, void *buffe | |||
1254 | * 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, |
1255 | * and all PHY port speeds between the two links. | 1272 | * and all PHY port speeds between the two links. |
1256 | */ | 1273 | */ |
1257 | static int ioctl_get_speed(struct client *client, void *buffer) | 1274 | static int ioctl_get_speed(struct client *client, union ioctl_arg *arg) |
1258 | { | 1275 | { |
1259 | return client->device->max_speed; | 1276 | return client->device->max_speed; |
1260 | } | 1277 | } |
1261 | 1278 | ||
1262 | static int ioctl_send_broadcast_request(struct client *client, void *buffer) | 1279 | static int ioctl_send_broadcast_request(struct client *client, |
1280 | union ioctl_arg *arg) | ||
1263 | { | 1281 | { |
1264 | struct fw_cdev_send_request *request = buffer; | 1282 | struct fw_cdev_send_request *a = &arg->send_request; |
1265 | 1283 | ||
1266 | switch (request->tcode) { | 1284 | switch (a->tcode) { |
1267 | case TCODE_WRITE_QUADLET_REQUEST: | 1285 | case TCODE_WRITE_QUADLET_REQUEST: |
1268 | case TCODE_WRITE_BLOCK_REQUEST: | 1286 | case TCODE_WRITE_BLOCK_REQUEST: |
1269 | break; | 1287 | break; |
@@ -1272,36 +1290,36 @@ static int ioctl_send_broadcast_request(struct client *client, void *buffer) | |||
1272 | } | 1290 | } |
1273 | 1291 | ||
1274 | /* Security policy: Only allow accesses to Units Space. */ | 1292 | /* Security policy: Only allow accesses to Units Space. */ |
1275 | if (request->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END) | 1293 | if (a->offset < CSR_REGISTER_BASE + CSR_CONFIG_ROM_END) |
1276 | return -EACCES; | 1294 | return -EACCES; |
1277 | 1295 | ||
1278 | return init_request(client, request, LOCAL_BUS | 0x3f, SCODE_100); | 1296 | return init_request(client, a, LOCAL_BUS | 0x3f, SCODE_100); |
1279 | } | 1297 | } |
1280 | 1298 | ||
1281 | static int ioctl_send_stream_packet(struct client *client, void *buffer) | 1299 | static int ioctl_send_stream_packet(struct client *client, union ioctl_arg *arg) |
1282 | { | 1300 | { |
1283 | struct fw_cdev_send_stream_packet *p = buffer; | 1301 | struct fw_cdev_send_stream_packet *a = &arg->send_stream_packet; |
1284 | struct fw_cdev_send_request request; | 1302 | struct fw_cdev_send_request request; |
1285 | int dest; | 1303 | int dest; |
1286 | 1304 | ||
1287 | if (p->speed > client->device->card->link_speed || | 1305 | if (a->speed > client->device->card->link_speed || |
1288 | p->length > 1024 << p->speed) | 1306 | a->length > 1024 << a->speed) |
1289 | return -EIO; | 1307 | return -EIO; |
1290 | 1308 | ||
1291 | if (p->tag > 3 || p->channel > 63 || p->sy > 15) | 1309 | if (a->tag > 3 || a->channel > 63 || a->sy > 15) |
1292 | return -EINVAL; | 1310 | return -EINVAL; |
1293 | 1311 | ||
1294 | 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); |
1295 | request.tcode = TCODE_STREAM_DATA; | 1313 | request.tcode = TCODE_STREAM_DATA; |
1296 | request.length = p->length; | 1314 | request.length = a->length; |
1297 | request.closure = p->closure; | 1315 | request.closure = a->closure; |
1298 | request.data = p->data; | 1316 | request.data = a->data; |
1299 | request.generation = p->generation; | 1317 | request.generation = a->generation; |
1300 | 1318 | ||
1301 | return init_request(client, &request, dest, p->speed); | 1319 | return init_request(client, &request, dest, a->speed); |
1302 | } | 1320 | } |
1303 | 1321 | ||
1304 | static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { | 1322 | static int (* const ioctl_handlers[])(struct client *, union ioctl_arg *) = { |
1305 | ioctl_get_info, | 1323 | ioctl_get_info, |
1306 | ioctl_send_request, | 1324 | ioctl_send_request, |
1307 | ioctl_allocate, | 1325 | ioctl_allocate, |
@@ -1322,47 +1340,35 @@ static int (* const ioctl_handlers[])(struct client *client, void *buffer) = { | |||
1322 | ioctl_get_speed, | 1340 | ioctl_get_speed, |
1323 | ioctl_send_broadcast_request, | 1341 | ioctl_send_broadcast_request, |
1324 | ioctl_send_stream_packet, | 1342 | ioctl_send_stream_packet, |
1343 | ioctl_get_cycle_timer2, | ||
1325 | }; | 1344 | }; |
1326 | 1345 | ||
1327 | static int dispatch_ioctl(struct client *client, | 1346 | static int dispatch_ioctl(struct client *client, |
1328 | unsigned int cmd, void __user *arg) | 1347 | unsigned int cmd, void __user *arg) |
1329 | { | 1348 | { |
1330 | char buffer[sizeof(union { | 1349 | union ioctl_arg buffer; |
1331 | struct fw_cdev_get_info _00; | ||
1332 | struct fw_cdev_send_request _01; | ||
1333 | struct fw_cdev_allocate _02; | ||
1334 | struct fw_cdev_deallocate _03; | ||
1335 | struct fw_cdev_send_response _04; | ||
1336 | struct fw_cdev_initiate_bus_reset _05; | ||
1337 | struct fw_cdev_add_descriptor _06; | ||
1338 | struct fw_cdev_remove_descriptor _07; | ||
1339 | struct fw_cdev_create_iso_context _08; | ||
1340 | struct fw_cdev_queue_iso _09; | ||
1341 | struct fw_cdev_start_iso _0a; | ||
1342 | struct fw_cdev_stop_iso _0b; | ||
1343 | struct fw_cdev_get_cycle_timer _0c; | ||
1344 | struct fw_cdev_allocate_iso_resource _0d; | ||
1345 | struct fw_cdev_send_stream_packet _13; | ||
1346 | })]; | ||
1347 | int ret; | 1350 | int ret; |
1348 | 1351 | ||
1352 | if (fw_device_is_shutdown(client->device)) | ||
1353 | return -ENODEV; | ||
1354 | |||
1349 | if (_IOC_TYPE(cmd) != '#' || | 1355 | if (_IOC_TYPE(cmd) != '#' || |
1350 | _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers)) | 1356 | _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers)) |
1351 | return -EINVAL; | 1357 | return -EINVAL; |
1352 | 1358 | ||
1353 | if (_IOC_DIR(cmd) & _IOC_WRITE) { | 1359 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
1354 | if (_IOC_SIZE(cmd) > sizeof(buffer) || | 1360 | if (_IOC_SIZE(cmd) > sizeof(buffer) || |
1355 | copy_from_user(buffer, arg, _IOC_SIZE(cmd))) | 1361 | copy_from_user(&buffer, arg, _IOC_SIZE(cmd))) |
1356 | return -EFAULT; | 1362 | return -EFAULT; |
1357 | } | 1363 | } |
1358 | 1364 | ||
1359 | ret = ioctl_handlers[_IOC_NR(cmd)](client, buffer); | 1365 | ret = ioctl_handlers[_IOC_NR(cmd)](client, &buffer); |
1360 | if (ret < 0) | 1366 | if (ret < 0) |
1361 | return ret; | 1367 | return ret; |
1362 | 1368 | ||
1363 | if (_IOC_DIR(cmd) & _IOC_READ) { | 1369 | if (_IOC_DIR(cmd) & _IOC_READ) { |
1364 | if (_IOC_SIZE(cmd) > sizeof(buffer) || | 1370 | if (_IOC_SIZE(cmd) > sizeof(buffer) || |
1365 | copy_to_user(arg, buffer, _IOC_SIZE(cmd))) | 1371 | copy_to_user(arg, &buffer, _IOC_SIZE(cmd))) |
1366 | return -EFAULT; | 1372 | return -EFAULT; |
1367 | } | 1373 | } |
1368 | 1374 | ||
@@ -1372,24 +1378,14 @@ static int dispatch_ioctl(struct client *client, | |||
1372 | static long fw_device_op_ioctl(struct file *file, | 1378 | static long fw_device_op_ioctl(struct file *file, |
1373 | unsigned int cmd, unsigned long arg) | 1379 | unsigned int cmd, unsigned long arg) |
1374 | { | 1380 | { |
1375 | struct client *client = file->private_data; | 1381 | return dispatch_ioctl(file->private_data, cmd, (void __user *)arg); |
1376 | |||
1377 | if (fw_device_is_shutdown(client->device)) | ||
1378 | return -ENODEV; | ||
1379 | |||
1380 | return dispatch_ioctl(client, cmd, (void __user *) arg); | ||
1381 | } | 1382 | } |
1382 | 1383 | ||
1383 | #ifdef CONFIG_COMPAT | 1384 | #ifdef CONFIG_COMPAT |
1384 | static long fw_device_op_compat_ioctl(struct file *file, | 1385 | static long fw_device_op_compat_ioctl(struct file *file, |
1385 | unsigned int cmd, unsigned long arg) | 1386 | unsigned int cmd, unsigned long arg) |
1386 | { | 1387 | { |
1387 | struct client *client = file->private_data; | 1388 | return dispatch_ioctl(file->private_data, cmd, compat_ptr(arg)); |
1388 | |||
1389 | if (fw_device_is_shutdown(client->device)) | ||
1390 | return -ENODEV; | ||
1391 | |||
1392 | return dispatch_ioctl(client, cmd, compat_ptr(arg)); | ||
1393 | } | 1389 | } |
1394 | #endif | 1390 | #endif |
1395 | 1391 | ||
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9d0dfcbe2c1c..014cabd3afda 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/bug.h> | ||
21 | #include <linux/ctype.h> | 22 | #include <linux/ctype.h> |
22 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
23 | #include <linux/device.h> | 24 | #include <linux/device.h> |
@@ -43,7 +44,7 @@ | |||
43 | 44 | ||
44 | #include "core.h" | 45 | #include "core.h" |
45 | 46 | ||
46 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 * p) | 47 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p) |
47 | { | 48 | { |
48 | ci->p = p + 1; | 49 | ci->p = p + 1; |
49 | ci->end = ci->p + (p[0] >> 16); | 50 | ci->end = ci->p + (p[0] >> 16); |
@@ -59,9 +60,76 @@ int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value) | |||
59 | } | 60 | } |
60 | EXPORT_SYMBOL(fw_csr_iterator_next); | 61 | EXPORT_SYMBOL(fw_csr_iterator_next); |
61 | 62 | ||
63 | static const u32 *search_leaf(const u32 *directory, int search_key) | ||
64 | { | ||
65 | struct fw_csr_iterator ci; | ||
66 | int last_key = 0, key, value; | ||
67 | |||
68 | fw_csr_iterator_init(&ci, directory); | ||
69 | while (fw_csr_iterator_next(&ci, &key, &value)) { | ||
70 | if (last_key == search_key && | ||
71 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | ||
72 | return ci.p - 1 + value; | ||
73 | |||
74 | last_key = key; | ||
75 | } | ||
76 | |||
77 | return NULL; | ||
78 | } | ||
79 | |||
80 | static int textual_leaf_to_string(const u32 *block, char *buf, size_t size) | ||
81 | { | ||
82 | unsigned int quadlets, i; | ||
83 | char c; | ||
84 | |||
85 | if (!size || !buf) | ||
86 | return -EINVAL; | ||
87 | |||
88 | quadlets = min(block[0] >> 16, 256U); | ||
89 | if (quadlets < 2) | ||
90 | return -ENODATA; | ||
91 | |||
92 | if (block[1] != 0 || block[2] != 0) | ||
93 | /* unknown language/character set */ | ||
94 | return -ENODATA; | ||
95 | |||
96 | block += 3; | ||
97 | quadlets -= 2; | ||
98 | for (i = 0; i < quadlets * 4 && i < size - 1; i++) { | ||
99 | c = block[i / 4] >> (24 - 8 * (i % 4)); | ||
100 | if (c == '\0') | ||
101 | break; | ||
102 | buf[i] = c; | ||
103 | } | ||
104 | buf[i] = '\0'; | ||
105 | |||
106 | return i; | ||
107 | } | ||
108 | |||
109 | /** | ||
110 | * fw_csr_string - reads a string from the configuration ROM | ||
111 | * @directory: e.g. root directory or unit directory | ||
112 | * @key: the key of the preceding directory entry | ||
113 | * @buf: where to put the string | ||
114 | * @size: size of @buf, in bytes | ||
115 | * | ||
116 | * The string is taken from a minimal ASCII text descriptor leaf after | ||
117 | * the immediate entry with @key. The string is zero-terminated. | ||
118 | * Returns strlen(buf) or a negative error code. | ||
119 | */ | ||
120 | int fw_csr_string(const u32 *directory, int key, char *buf, size_t size) | ||
121 | { | ||
122 | const u32 *leaf = search_leaf(directory, key); | ||
123 | if (!leaf) | ||
124 | return -ENOENT; | ||
125 | |||
126 | return textual_leaf_to_string(leaf, buf, size); | ||
127 | } | ||
128 | EXPORT_SYMBOL(fw_csr_string); | ||
129 | |||
62 | static bool is_fw_unit(struct device *dev); | 130 | static bool is_fw_unit(struct device *dev); |
63 | 131 | ||
64 | static int match_unit_directory(u32 *directory, u32 match_flags, | 132 | static int match_unit_directory(const u32 *directory, u32 match_flags, |
65 | const struct ieee1394_device_id *id) | 133 | const struct ieee1394_device_id *id) |
66 | { | 134 | { |
67 | struct fw_csr_iterator ci; | 135 | struct fw_csr_iterator ci; |
@@ -195,7 +263,7 @@ static ssize_t show_immediate(struct device *dev, | |||
195 | struct config_rom_attribute *attr = | 263 | struct config_rom_attribute *attr = |
196 | container_of(dattr, struct config_rom_attribute, attr); | 264 | container_of(dattr, struct config_rom_attribute, attr); |
197 | struct fw_csr_iterator ci; | 265 | struct fw_csr_iterator ci; |
198 | u32 *dir; | 266 | const u32 *dir; |
199 | int key, value, ret = -ENOENT; | 267 | int key, value, ret = -ENOENT; |
200 | 268 | ||
201 | down_read(&fw_device_rwsem); | 269 | down_read(&fw_device_rwsem); |
@@ -226,10 +294,10 @@ static ssize_t show_text_leaf(struct device *dev, | |||
226 | { | 294 | { |
227 | struct config_rom_attribute *attr = | 295 | struct config_rom_attribute *attr = |
228 | container_of(dattr, struct config_rom_attribute, attr); | 296 | container_of(dattr, struct config_rom_attribute, attr); |
229 | struct fw_csr_iterator ci; | 297 | const u32 *dir; |
230 | u32 *dir, *block = NULL, *p, *end; | 298 | size_t bufsize; |
231 | int length, key, value, last_key = 0, ret = -ENOENT; | 299 | char dummy_buf[2]; |
232 | char *b; | 300 | int ret; |
233 | 301 | ||
234 | down_read(&fw_device_rwsem); | 302 | down_read(&fw_device_rwsem); |
235 | 303 | ||
@@ -238,40 +306,23 @@ static ssize_t show_text_leaf(struct device *dev, | |||
238 | else | 306 | else |
239 | dir = fw_device(dev)->config_rom + 5; | 307 | dir = fw_device(dev)->config_rom + 5; |
240 | 308 | ||
241 | fw_csr_iterator_init(&ci, dir); | 309 | if (buf) { |
242 | while (fw_csr_iterator_next(&ci, &key, &value)) { | 310 | bufsize = PAGE_SIZE - 1; |
243 | if (attr->key == last_key && | 311 | } else { |
244 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | 312 | buf = dummy_buf; |
245 | block = ci.p - 1 + value; | 313 | bufsize = 1; |
246 | last_key = key; | ||
247 | } | 314 | } |
248 | 315 | ||
249 | if (block == NULL) | 316 | ret = fw_csr_string(dir, attr->key, buf, bufsize); |
250 | goto out; | ||
251 | |||
252 | length = min(block[0] >> 16, 256U); | ||
253 | if (length < 3) | ||
254 | goto out; | ||
255 | |||
256 | if (block[1] != 0 || block[2] != 0) | ||
257 | /* Unknown encoding. */ | ||
258 | goto out; | ||
259 | 317 | ||
260 | if (buf == NULL) { | 318 | if (ret >= 0) { |
261 | ret = length * 4; | 319 | /* Strip trailing whitespace and add newline. */ |
262 | goto out; | 320 | while (ret > 0 && isspace(buf[ret - 1])) |
321 | ret--; | ||
322 | strcpy(buf + ret, "\n"); | ||
323 | ret++; | ||
263 | } | 324 | } |
264 | 325 | ||
265 | b = buf; | ||
266 | end = &block[length + 1]; | ||
267 | for (p = &block[3]; p < end; p++, b += 4) | ||
268 | * (u32 *) b = (__force u32) __cpu_to_be32(*p); | ||
269 | |||
270 | /* Strip trailing whitespace and add newline. */ | ||
271 | while (b--, (isspace(*b) || *b == '\0') && b > buf); | ||
272 | strcpy(b + 1, "\n"); | ||
273 | ret = b + 2 - buf; | ||
274 | out: | ||
275 | up_read(&fw_device_rwsem); | 326 | up_read(&fw_device_rwsem); |
276 | 327 | ||
277 | return ret; | 328 | return ret; |
@@ -371,7 +422,7 @@ static ssize_t guid_show(struct device *dev, | |||
371 | return ret; | 422 | return ret; |
372 | } | 423 | } |
373 | 424 | ||
374 | static int units_sprintf(char *buf, u32 *directory) | 425 | static int units_sprintf(char *buf, const u32 *directory) |
375 | { | 426 | { |
376 | struct fw_csr_iterator ci; | 427 | struct fw_csr_iterator ci; |
377 | int key, value; | 428 | int key, value; |
@@ -441,28 +492,29 @@ static int read_rom(struct fw_device *device, | |||
441 | return rcode; | 492 | return rcode; |
442 | } | 493 | } |
443 | 494 | ||
444 | #define READ_BIB_ROM_SIZE 256 | 495 | #define MAX_CONFIG_ROM_SIZE 256 |
445 | #define READ_BIB_STACK_SIZE 16 | ||
446 | 496 | ||
447 | /* | 497 | /* |
448 | * Read the bus info block, perform a speed probe, and read all of the rest of | 498 | * Read the bus info block, perform a speed probe, and read all of the rest of |
449 | * the config ROM. We do all this with a cached bus generation. If the bus | 499 | * the config ROM. We do all this with a cached bus generation. If the bus |
450 | * generation changes under us, read_bus_info_block will fail and get retried. | 500 | * generation changes under us, read_config_rom will fail and get retried. |
451 | * It's better to start all over in this case because the node from which we | 501 | * It's better to start all over in this case because the node from which we |
452 | * are reading the ROM may have changed the ROM during the reset. | 502 | * are reading the ROM may have changed the ROM during the reset. |
453 | */ | 503 | */ |
454 | static int read_bus_info_block(struct fw_device *device, int generation) | 504 | static int read_config_rom(struct fw_device *device, int generation) |
455 | { | 505 | { |
456 | u32 *rom, *stack, *old_rom, *new_rom; | 506 | const u32 *old_rom, *new_rom; |
507 | u32 *rom, *stack; | ||
457 | u32 sp, key; | 508 | u32 sp, key; |
458 | int i, end, length, ret = -1; | 509 | int i, end, length, ret = -1; |
459 | 510 | ||
460 | rom = kmalloc(sizeof(*rom) * READ_BIB_ROM_SIZE + | 511 | rom = kmalloc(sizeof(*rom) * MAX_CONFIG_ROM_SIZE + |
461 | sizeof(*stack) * READ_BIB_STACK_SIZE, GFP_KERNEL); | 512 | sizeof(*stack) * MAX_CONFIG_ROM_SIZE, GFP_KERNEL); |
462 | if (rom == NULL) | 513 | if (rom == NULL) |
463 | return -ENOMEM; | 514 | return -ENOMEM; |
464 | 515 | ||
465 | stack = &rom[READ_BIB_ROM_SIZE]; | 516 | stack = &rom[MAX_CONFIG_ROM_SIZE]; |
517 | memset(rom, 0, sizeof(*rom) * MAX_CONFIG_ROM_SIZE); | ||
466 | 518 | ||
467 | device->max_speed = SCODE_100; | 519 | device->max_speed = SCODE_100; |
468 | 520 | ||
@@ -529,40 +581,54 @@ static int read_bus_info_block(struct fw_device *device, int generation) | |||
529 | */ | 581 | */ |
530 | key = stack[--sp]; | 582 | key = stack[--sp]; |
531 | i = key & 0xffffff; | 583 | i = key & 0xffffff; |
532 | if (i >= READ_BIB_ROM_SIZE) | 584 | if (WARN_ON(i >= MAX_CONFIG_ROM_SIZE)) |
533 | /* | ||
534 | * The reference points outside the standard | ||
535 | * config rom area, something's fishy. | ||
536 | */ | ||
537 | goto out; | 585 | goto out; |
538 | 586 | ||
539 | /* Read header quadlet for the block to get the length. */ | 587 | /* Read header quadlet for the block to get the length. */ |
540 | if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) | 588 | if (read_rom(device, generation, i, &rom[i]) != RCODE_COMPLETE) |
541 | goto out; | 589 | goto out; |
542 | end = i + (rom[i] >> 16) + 1; | 590 | end = i + (rom[i] >> 16) + 1; |
543 | i++; | 591 | if (end > MAX_CONFIG_ROM_SIZE) { |
544 | if (end > READ_BIB_ROM_SIZE) | ||
545 | /* | 592 | /* |
546 | * This block extends outside standard config | 593 | * This block extends outside the config ROM which is |
547 | * area (and the array we're reading it | 594 | * a firmware bug. Ignore this whole block, i.e. |
548 | * into). That's broken, so ignore this | 595 | * simply set a fake block length of 0. |
549 | * device. | ||
550 | */ | 596 | */ |
551 | goto out; | 597 | fw_error("skipped invalid ROM block %x at %llx\n", |
598 | rom[i], | ||
599 | i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM); | ||
600 | rom[i] = 0; | ||
601 | end = i; | ||
602 | } | ||
603 | i++; | ||
552 | 604 | ||
553 | /* | 605 | /* |
554 | * Now read in the block. If this is a directory | 606 | * Now read in the block. If this is a directory |
555 | * block, check the entries as we read them to see if | 607 | * block, check the entries as we read them to see if |
556 | * it references another block, and push it in that case. | 608 | * it references another block, and push it in that case. |
557 | */ | 609 | */ |
558 | while (i < end) { | 610 | for (; i < end; i++) { |
559 | if (read_rom(device, generation, i, &rom[i]) != | 611 | if (read_rom(device, generation, i, &rom[i]) != |
560 | RCODE_COMPLETE) | 612 | RCODE_COMPLETE) |
561 | goto out; | 613 | goto out; |
562 | if ((key >> 30) == 3 && (rom[i] >> 30) > 1 && | 614 | |
563 | sp < READ_BIB_STACK_SIZE) | 615 | if ((key >> 30) != 3 || (rom[i] >> 30) < 2) |
564 | stack[sp++] = i + rom[i]; | 616 | continue; |
565 | i++; | 617 | /* |
618 | * Offset points outside the ROM. May be a firmware | ||
619 | * bug or an Extended ROM entry (IEEE 1212-2001 clause | ||
620 | * 7.7.18). Simply overwrite this pointer here by a | ||
621 | * fake immediate entry so that later iterators over | ||
622 | * the ROM don't have to check offsets all the time. | ||
623 | */ | ||
624 | if (i + (rom[i] & 0xffffff) >= MAX_CONFIG_ROM_SIZE) { | ||
625 | fw_error("skipped unsupported ROM entry %x at %llx\n", | ||
626 | rom[i], | ||
627 | i * 4 | CSR_REGISTER_BASE | CSR_CONFIG_ROM); | ||
628 | rom[i] = 0; | ||
629 | continue; | ||
630 | } | ||
631 | stack[sp++] = i + rom[i]; | ||
566 | } | 632 | } |
567 | if (length < i) | 633 | if (length < i) |
568 | length = i; | 634 | length = i; |
@@ -905,7 +971,7 @@ static void fw_device_init(struct work_struct *work) | |||
905 | * device. | 971 | * device. |
906 | */ | 972 | */ |
907 | 973 | ||
908 | if (read_bus_info_block(device, device->generation) < 0) { | 974 | if (read_config_rom(device, device->generation) < 0) { |
909 | if (device->config_rom_retries < MAX_RETRIES && | 975 | if (device->config_rom_retries < MAX_RETRIES && |
910 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 976 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
911 | device->config_rom_retries++; | 977 | device->config_rom_retries++; |
@@ -1022,7 +1088,7 @@ enum { | |||
1022 | }; | 1088 | }; |
1023 | 1089 | ||
1024 | /* Reread and compare bus info block and header of root directory */ | 1090 | /* Reread and compare bus info block and header of root directory */ |
1025 | static int reread_bus_info_block(struct fw_device *device, int generation) | 1091 | static int reread_config_rom(struct fw_device *device, int generation) |
1026 | { | 1092 | { |
1027 | u32 q; | 1093 | u32 q; |
1028 | int i; | 1094 | int i; |
@@ -1048,7 +1114,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
1048 | struct fw_card *card = device->card; | 1114 | struct fw_card *card = device->card; |
1049 | int node_id = device->node_id; | 1115 | int node_id = device->node_id; |
1050 | 1116 | ||
1051 | switch (reread_bus_info_block(device, device->generation)) { | 1117 | switch (reread_config_rom(device, device->generation)) { |
1052 | case REREAD_BIB_ERROR: | 1118 | case REREAD_BIB_ERROR: |
1053 | if (device->config_rom_retries < MAX_RETRIES / 2 && | 1119 | if (device->config_rom_retries < MAX_RETRIES / 2 && |
1054 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 1120 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
@@ -1082,7 +1148,7 @@ static void fw_device_refresh(struct work_struct *work) | |||
1082 | */ | 1148 | */ |
1083 | device_for_each_child(&device->device, NULL, shutdown_unit); | 1149 | device_for_each_child(&device->device, NULL, shutdown_unit); |
1084 | 1150 | ||
1085 | if (read_bus_info_block(device, device->generation) < 0) { | 1151 | if (read_config_rom(device, device->generation) < 0) { |
1086 | if (device->config_rom_retries < MAX_RETRIES && | 1152 | if (device->config_rom_retries < MAX_RETRIES && |
1087 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { | 1153 | atomic_read(&device->state) == FW_DEVICE_INITIALIZING) { |
1088 | device->config_rom_retries++; | 1154 | device->config_rom_retries++; |
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 495849eb13cc..673b03f8b4ec 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -921,23 +921,15 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
921 | void *payload, size_t length, void *callback_data) | 921 | void *payload, size_t length, void *callback_data) |
922 | { | 922 | { |
923 | int reg = offset & ~CSR_REGISTER_BASE; | 923 | int reg = offset & ~CSR_REGISTER_BASE; |
924 | unsigned long long bus_time; | ||
925 | __be32 *data = payload; | 924 | __be32 *data = payload; |
926 | int rcode = RCODE_COMPLETE; | 925 | int rcode = RCODE_COMPLETE; |
927 | 926 | ||
928 | switch (reg) { | 927 | switch (reg) { |
929 | case CSR_CYCLE_TIME: | 928 | case CSR_CYCLE_TIME: |
930 | case CSR_BUS_TIME: | 929 | if (TCODE_IS_READ_REQUEST(tcode) && length == 4) |
931 | if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) { | 930 | *data = cpu_to_be32(card->driver->get_cycle_time(card)); |
932 | rcode = RCODE_TYPE_ERROR; | ||
933 | break; | ||
934 | } | ||
935 | |||
936 | bus_time = card->driver->get_bus_time(card); | ||
937 | if (reg == CSR_CYCLE_TIME) | ||
938 | *data = cpu_to_be32(bus_time); | ||
939 | else | 931 | else |
940 | *data = cpu_to_be32(bus_time >> 25); | 932 | rcode = RCODE_TYPE_ERROR; |
941 | break; | 933 | break; |
942 | 934 | ||
943 | case CSR_BROADCAST_CHANNEL: | 935 | case CSR_BROADCAST_CHANNEL: |
@@ -968,6 +960,9 @@ static void handle_registers(struct fw_card *card, struct fw_request *request, | |||
968 | case CSR_BUSY_TIMEOUT: | 960 | case CSR_BUSY_TIMEOUT: |
969 | /* FIXME: Implement this. */ | 961 | /* FIXME: Implement this. */ |
970 | 962 | ||
963 | case CSR_BUS_TIME: | ||
964 | /* Useless without initialization by the bus manager. */ | ||
965 | |||
971 | default: | 966 | default: |
972 | rcode = RCODE_ADDRESS_ERROR; | 967 | rcode = RCODE_ADDRESS_ERROR; |
973 | break; | 968 | break; |
diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index ed3b1a765c00..fb0321300cce 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h | |||
@@ -70,7 +70,7 @@ struct fw_card_driver { | |||
70 | int (*enable_phys_dma)(struct fw_card *card, | 70 | int (*enable_phys_dma)(struct fw_card *card, |
71 | int node_id, int generation); | 71 | int node_id, int generation); |
72 | 72 | ||
73 | u64 (*get_bus_time)(struct fw_card *card); | 73 | u32 (*get_cycle_time)(struct fw_card *card); |
74 | 74 | ||
75 | struct fw_iso_context * | 75 | struct fw_iso_context * |
76 | (*allocate_iso_context)(struct fw_card *card, | 76 | (*allocate_iso_context)(struct fw_card *card, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 43ebf337b131..75dc6988cffd 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <linux/spinlock.h> | 38 | #include <linux/spinlock.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | 40 | ||
41 | #include <asm/atomic.h> | ||
42 | #include <asm/byteorder.h> | 41 | #include <asm/byteorder.h> |
43 | #include <asm/page.h> | 42 | #include <asm/page.h> |
44 | #include <asm/system.h> | 43 | #include <asm/system.h> |
@@ -73,20 +72,6 @@ struct descriptor { | |||
73 | __le16 transfer_status; | 72 | __le16 transfer_status; |
74 | } __attribute__((aligned(16))); | 73 | } __attribute__((aligned(16))); |
75 | 74 | ||
76 | struct db_descriptor { | ||
77 | __le16 first_size; | ||
78 | __le16 control; | ||
79 | __le16 second_req_count; | ||
80 | __le16 first_req_count; | ||
81 | __le32 branch_address; | ||
82 | __le16 second_res_count; | ||
83 | __le16 first_res_count; | ||
84 | __le32 reserved0; | ||
85 | __le32 first_buffer; | ||
86 | __le32 second_buffer; | ||
87 | __le32 reserved1; | ||
88 | } __attribute__((aligned(16))); | ||
89 | |||
90 | #define CONTROL_SET(regs) (regs) | 75 | #define CONTROL_SET(regs) (regs) |
91 | #define CONTROL_CLEAR(regs) ((regs) + 4) | 76 | #define CONTROL_CLEAR(regs) ((regs) + 4) |
92 | #define COMMAND_PTR(regs) ((regs) + 12) | 77 | #define COMMAND_PTR(regs) ((regs) + 12) |
@@ -181,31 +166,16 @@ struct fw_ohci { | |||
181 | struct fw_card card; | 166 | struct fw_card card; |
182 | 167 | ||
183 | __iomem char *registers; | 168 | __iomem char *registers; |
184 | dma_addr_t self_id_bus; | ||
185 | __le32 *self_id_cpu; | ||
186 | struct tasklet_struct bus_reset_tasklet; | ||
187 | int node_id; | 169 | int node_id; |
188 | int generation; | 170 | int generation; |
189 | int request_generation; /* for timestamping incoming requests */ | 171 | int request_generation; /* for timestamping incoming requests */ |
190 | atomic_t bus_seconds; | 172 | unsigned quirks; |
191 | |||
192 | bool use_dualbuffer; | ||
193 | bool old_uninorth; | ||
194 | bool bus_reset_packet_quirk; | ||
195 | 173 | ||
196 | /* | 174 | /* |
197 | * Spinlock for accessing fw_ohci data. Never call out of | 175 | * Spinlock for accessing fw_ohci data. Never call out of |
198 | * this driver with this lock held. | 176 | * this driver with this lock held. |
199 | */ | 177 | */ |
200 | spinlock_t lock; | 178 | spinlock_t lock; |
201 | u32 self_id_buffer[512]; | ||
202 | |||
203 | /* Config rom buffers */ | ||
204 | __be32 *config_rom; | ||
205 | dma_addr_t config_rom_bus; | ||
206 | __be32 *next_config_rom; | ||
207 | dma_addr_t next_config_rom_bus; | ||
208 | __be32 next_header; | ||
209 | 179 | ||
210 | struct ar_context ar_request_ctx; | 180 | struct ar_context ar_request_ctx; |
211 | struct ar_context ar_response_ctx; | 181 | struct ar_context ar_response_ctx; |
@@ -217,6 +187,18 @@ struct fw_ohci { | |||
217 | u64 ir_context_channels; | 187 | u64 ir_context_channels; |
218 | u32 ir_context_mask; | 188 | u32 ir_context_mask; |
219 | struct iso_context *ir_context_list; | 189 | struct iso_context *ir_context_list; |
190 | |||
191 | __be32 *config_rom; | ||
192 | dma_addr_t config_rom_bus; | ||
193 | __be32 *next_config_rom; | ||
194 | dma_addr_t next_config_rom_bus; | ||
195 | __be32 next_header; | ||
196 | |||
197 | __le32 *self_id_cpu; | ||
198 | dma_addr_t self_id_bus; | ||
199 | struct tasklet_struct bus_reset_tasklet; | ||
200 | |||
201 | u32 self_id_buffer[512]; | ||
220 | }; | 202 | }; |
221 | 203 | ||
222 | static inline struct fw_ohci *fw_ohci(struct fw_card *card) | 204 | static inline struct fw_ohci *fw_ohci(struct fw_card *card) |
@@ -249,6 +231,30 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
249 | 231 | ||
250 | static char ohci_driver_name[] = KBUILD_MODNAME; | 232 | static char ohci_driver_name[] = KBUILD_MODNAME; |
251 | 233 | ||
234 | #define QUIRK_CYCLE_TIMER 1 | ||
235 | #define QUIRK_RESET_PACKET 2 | ||
236 | #define QUIRK_BE_HEADERS 4 | ||
237 | |||
238 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | ||
239 | static const struct { | ||
240 | unsigned short vendor, device, flags; | ||
241 | } ohci_quirks[] = { | ||
242 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | ||
243 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
244 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
245 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | ||
246 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, | ||
247 | }; | ||
248 | |||
249 | /* This overrides anything that was found in ohci_quirks[]. */ | ||
250 | static int param_quirks; | ||
251 | module_param_named(quirks, param_quirks, int, 0644); | ||
252 | MODULE_PARM_DESC(quirks, "Chip quirks (default = 0" | ||
253 | ", nonatomic cycle timer = " __stringify(QUIRK_CYCLE_TIMER) | ||
254 | ", reset packet generation = " __stringify(QUIRK_RESET_PACKET) | ||
255 | ", AR/selfID endianess = " __stringify(QUIRK_BE_HEADERS) | ||
256 | ")"); | ||
257 | |||
252 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG | 258 | #ifdef CONFIG_FIREWIRE_OHCI_DEBUG |
253 | 259 | ||
254 | #define OHCI_PARAM_DEBUG_AT_AR 1 | 260 | #define OHCI_PARAM_DEBUG_AT_AR 1 |
@@ -275,7 +281,7 @@ static void log_irqs(u32 evt) | |||
275 | !(evt & OHCI1394_busReset)) | 281 | !(evt & OHCI1394_busReset)) |
276 | return; | 282 | return; |
277 | 283 | ||
278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, | 284 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, |
279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", | 285 | evt & OHCI1394_selfIDComplete ? " selfID" : "", |
280 | evt & OHCI1394_RQPkt ? " AR_req" : "", | 286 | evt & OHCI1394_RQPkt ? " AR_req" : "", |
281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", | 287 | evt & OHCI1394_RSPkt ? " AR_resp" : "", |
@@ -285,7 +291,6 @@ static void log_irqs(u32 evt) | |||
285 | evt & OHCI1394_isochTx ? " IT" : "", | 291 | evt & OHCI1394_isochTx ? " IT" : "", |
286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", | 292 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", |
287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", | 293 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", |
288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", | ||
289 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", | 294 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", |
290 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", | 295 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", |
291 | evt & OHCI1394_busReset ? " busReset" : "", | 296 | evt & OHCI1394_busReset ? " busReset" : "", |
@@ -293,8 +298,7 @@ static void log_irqs(u32 evt) | |||
293 | OHCI1394_RSPkt | OHCI1394_reqTxComplete | | 298 | OHCI1394_RSPkt | OHCI1394_reqTxComplete | |
294 | OHCI1394_respTxComplete | OHCI1394_isochRx | | 299 | OHCI1394_respTxComplete | OHCI1394_isochRx | |
295 | OHCI1394_isochTx | OHCI1394_postedWriteErr | | 300 | OHCI1394_isochTx | OHCI1394_postedWriteErr | |
296 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | | 301 | OHCI1394_cycleTooLong | OHCI1394_cycleInconsistent | |
297 | OHCI1394_cycleInconsistent | | ||
298 | OHCI1394_regAccessFail | OHCI1394_busReset) | 302 | OHCI1394_regAccessFail | OHCI1394_busReset) |
299 | ? " ?" : ""); | 303 | ? " ?" : ""); |
300 | } | 304 | } |
@@ -524,7 +528,7 @@ static void ar_context_release(struct ar_context *ctx) | |||
524 | 528 | ||
525 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | 529 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) |
526 | #define cond_le32_to_cpu(v) \ | 530 | #define cond_le32_to_cpu(v) \ |
527 | (ohci->old_uninorth ? (__force __u32)(v) : le32_to_cpu(v)) | 531 | (ohci->quirks & QUIRK_BE_HEADERS ? (__force __u32)(v) : le32_to_cpu(v)) |
528 | #else | 532 | #else |
529 | #define cond_le32_to_cpu(v) le32_to_cpu(v) | 533 | #define cond_le32_to_cpu(v) le32_to_cpu(v) |
530 | #endif | 534 | #endif |
@@ -605,7 +609,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
605 | * at a slightly incorrect time (in bus_reset_tasklet). | 609 | * at a slightly incorrect time (in bus_reset_tasklet). |
606 | */ | 610 | */ |
607 | if (evt == OHCI1394_evt_bus_reset) { | 611 | if (evt == OHCI1394_evt_bus_reset) { |
608 | if (!ohci->bus_reset_packet_quirk) | 612 | if (!(ohci->quirks & QUIRK_RESET_PACKET)) |
609 | ohci->request_generation = (p.header[2] >> 16) & 0xff; | 613 | ohci->request_generation = (p.header[2] >> 16) & 0xff; |
610 | } else if (ctx == &ohci->ar_request_ctx) { | 614 | } else if (ctx == &ohci->ar_request_ctx) { |
611 | fw_core_handle_request(&ohci->card, &p); | 615 | fw_core_handle_request(&ohci->card, &p); |
@@ -1329,7 +1333,7 @@ static void bus_reset_tasklet(unsigned long data) | |||
1329 | context_stop(&ohci->at_response_ctx); | 1333 | context_stop(&ohci->at_response_ctx); |
1330 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); | 1334 | reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset); |
1331 | 1335 | ||
1332 | if (ohci->bus_reset_packet_quirk) | 1336 | if (ohci->quirks & QUIRK_RESET_PACKET) |
1333 | ohci->request_generation = generation; | 1337 | ohci->request_generation = generation; |
1334 | 1338 | ||
1335 | /* | 1339 | /* |
@@ -1384,7 +1388,7 @@ static void bus_reset_tasklet(unsigned long data) | |||
1384 | static irqreturn_t irq_handler(int irq, void *data) | 1388 | static irqreturn_t irq_handler(int irq, void *data) |
1385 | { | 1389 | { |
1386 | struct fw_ohci *ohci = data; | 1390 | struct fw_ohci *ohci = data; |
1387 | u32 event, iso_event, cycle_time; | 1391 | u32 event, iso_event; |
1388 | int i; | 1392 | int i; |
1389 | 1393 | ||
1390 | event = reg_read(ohci, OHCI1394_IntEventClear); | 1394 | event = reg_read(ohci, OHCI1394_IntEventClear); |
@@ -1454,12 +1458,6 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1454 | fw_notify("isochronous cycle inconsistent\n"); | 1458 | fw_notify("isochronous cycle inconsistent\n"); |
1455 | } | 1459 | } |
1456 | 1460 | ||
1457 | if (event & OHCI1394_cycle64Seconds) { | ||
1458 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
1459 | if ((cycle_time & 0x80000000) == 0) | ||
1460 | atomic_inc(&ohci->bus_seconds); | ||
1461 | } | ||
1462 | |||
1463 | return IRQ_HANDLED; | 1461 | return IRQ_HANDLED; |
1464 | } | 1462 | } |
1465 | 1463 | ||
@@ -1553,8 +1551,7 @@ static int ohci_enable(struct fw_card *card, | |||
1553 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | 1551 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | |
1554 | OHCI1394_isochRx | OHCI1394_isochTx | | 1552 | OHCI1394_isochRx | OHCI1394_isochTx | |
1555 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | | 1553 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | |
1556 | OHCI1394_cycleInconsistent | | 1554 | OHCI1394_cycleInconsistent | OHCI1394_regAccessFail | |
1557 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | | ||
1558 | OHCI1394_masterIntEnable); | 1555 | OHCI1394_masterIntEnable); |
1559 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1556 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
1560 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); | 1557 | reg_write(ohci, OHCI1394_IntMaskSet, OHCI1394_busReset); |
@@ -1794,16 +1791,61 @@ static int ohci_enable_phys_dma(struct fw_card *card, | |||
1794 | #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */ | 1791 | #endif /* CONFIG_FIREWIRE_OHCI_REMOTE_DMA */ |
1795 | } | 1792 | } |
1796 | 1793 | ||
1797 | static u64 ohci_get_bus_time(struct fw_card *card) | 1794 | static u32 cycle_timer_ticks(u32 cycle_timer) |
1798 | { | 1795 | { |
1799 | struct fw_ohci *ohci = fw_ohci(card); | 1796 | u32 ticks; |
1800 | u32 cycle_time; | ||
1801 | u64 bus_time; | ||
1802 | 1797 | ||
1803 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1798 | ticks = cycle_timer & 0xfff; |
1804 | bus_time = ((u64)atomic_read(&ohci->bus_seconds) << 32) | cycle_time; | 1799 | ticks += 3072 * ((cycle_timer >> 12) & 0x1fff); |
1800 | ticks += (3072 * 8000) * (cycle_timer >> 25); | ||
1801 | |||
1802 | return ticks; | ||
1803 | } | ||
1804 | |||
1805 | /* | ||
1806 | * Some controllers exhibit one or more of the following bugs when updating the | ||
1807 | * iso cycle timer register: | ||
1808 | * - When the lowest six bits are wrapping around to zero, a read that happens | ||
1809 | * at the same time will return garbage in the lowest ten bits. | ||
1810 | * - When the cycleOffset field wraps around to zero, the cycleCount field is | ||
1811 | * not incremented for about 60 ns. | ||
1812 | * - Occasionally, the entire register reads zero. | ||
1813 | * | ||
1814 | * To catch these, we read the register three times and ensure that the | ||
1815 | * difference between each two consecutive reads is approximately the same, i.e. | ||
1816 | * less than twice the other. Furthermore, any negative difference indicates an | ||
1817 | * error. (A PCI read should take at least 20 ticks of the 24.576 MHz timer to | ||
1818 | * execute, so we have enough precision to compute the ratio of the differences.) | ||
1819 | */ | ||
1820 | static u32 ohci_get_cycle_time(struct fw_card *card) | ||
1821 | { | ||
1822 | struct fw_ohci *ohci = fw_ohci(card); | ||
1823 | u32 c0, c1, c2; | ||
1824 | u32 t0, t1, t2; | ||
1825 | s32 diff01, diff12; | ||
1826 | int i; | ||
1805 | 1827 | ||
1806 | return bus_time; | 1828 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
1829 | |||
1830 | if (ohci->quirks & QUIRK_CYCLE_TIMER) { | ||
1831 | i = 0; | ||
1832 | c1 = c2; | ||
1833 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
1834 | do { | ||
1835 | c0 = c1; | ||
1836 | c1 = c2; | ||
1837 | c2 = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | ||
1838 | t0 = cycle_timer_ticks(c0); | ||
1839 | t1 = cycle_timer_ticks(c1); | ||
1840 | t2 = cycle_timer_ticks(c2); | ||
1841 | diff01 = t1 - t0; | ||
1842 | diff12 = t2 - t1; | ||
1843 | } while ((diff01 <= 0 || diff12 <= 0 || | ||
1844 | diff01 / diff12 >= 2 || diff12 / diff01 >= 2) | ||
1845 | && i++ < 20); | ||
1846 | } | ||
1847 | |||
1848 | return c2; | ||
1807 | } | 1849 | } |
1808 | 1850 | ||
1809 | static void copy_iso_headers(struct iso_context *ctx, void *p) | 1851 | static void copy_iso_headers(struct iso_context *ctx, void *p) |
@@ -1828,52 +1870,6 @@ static void copy_iso_headers(struct iso_context *ctx, void *p) | |||
1828 | ctx->header_length += ctx->base.header_size; | 1870 | ctx->header_length += ctx->base.header_size; |
1829 | } | 1871 | } |
1830 | 1872 | ||
1831 | static int handle_ir_dualbuffer_packet(struct context *context, | ||
1832 | struct descriptor *d, | ||
1833 | struct descriptor *last) | ||
1834 | { | ||
1835 | struct iso_context *ctx = | ||
1836 | container_of(context, struct iso_context, context); | ||
1837 | struct db_descriptor *db = (struct db_descriptor *) d; | ||
1838 | __le32 *ir_header; | ||
1839 | size_t header_length; | ||
1840 | void *p, *end; | ||
1841 | |||
1842 | if (db->first_res_count != 0 && db->second_res_count != 0) { | ||
1843 | if (ctx->excess_bytes <= le16_to_cpu(db->second_req_count)) { | ||
1844 | /* This descriptor isn't done yet, stop iteration. */ | ||
1845 | return 0; | ||
1846 | } | ||
1847 | ctx->excess_bytes -= le16_to_cpu(db->second_req_count); | ||
1848 | } | ||
1849 | |||
1850 | header_length = le16_to_cpu(db->first_req_count) - | ||
1851 | le16_to_cpu(db->first_res_count); | ||
1852 | |||
1853 | p = db + 1; | ||
1854 | end = p + header_length; | ||
1855 | while (p < end) { | ||
1856 | copy_iso_headers(ctx, p); | ||
1857 | ctx->excess_bytes += | ||
1858 | (le32_to_cpu(*(__le32 *)(p + 4)) >> 16) & 0xffff; | ||
1859 | p += max(ctx->base.header_size, (size_t)8); | ||
1860 | } | ||
1861 | |||
1862 | ctx->excess_bytes -= le16_to_cpu(db->second_req_count) - | ||
1863 | le16_to_cpu(db->second_res_count); | ||
1864 | |||
1865 | if (le16_to_cpu(db->control) & DESCRIPTOR_IRQ_ALWAYS) { | ||
1866 | ir_header = (__le32 *) (db + 1); | ||
1867 | ctx->base.callback(&ctx->base, | ||
1868 | le32_to_cpu(ir_header[0]) & 0xffff, | ||
1869 | ctx->header_length, ctx->header, | ||
1870 | ctx->base.callback_data); | ||
1871 | ctx->header_length = 0; | ||
1872 | } | ||
1873 | |||
1874 | return 1; | ||
1875 | } | ||
1876 | |||
1877 | static int handle_ir_packet_per_buffer(struct context *context, | 1873 | static int handle_ir_packet_per_buffer(struct context *context, |
1878 | struct descriptor *d, | 1874 | struct descriptor *d, |
1879 | struct descriptor *last) | 1875 | struct descriptor *last) |
@@ -1960,10 +1956,7 @@ static struct fw_iso_context *ohci_allocate_iso_context(struct fw_card *card, | |||
1960 | channels = &ohci->ir_context_channels; | 1956 | channels = &ohci->ir_context_channels; |
1961 | mask = &ohci->ir_context_mask; | 1957 | mask = &ohci->ir_context_mask; |
1962 | list = ohci->ir_context_list; | 1958 | list = ohci->ir_context_list; |
1963 | if (ohci->use_dualbuffer) | 1959 | callback = handle_ir_packet_per_buffer; |
1964 | callback = handle_ir_dualbuffer_packet; | ||
1965 | else | ||
1966 | callback = handle_ir_packet_per_buffer; | ||
1967 | } | 1960 | } |
1968 | 1961 | ||
1969 | spin_lock_irqsave(&ohci->lock, flags); | 1962 | spin_lock_irqsave(&ohci->lock, flags); |
@@ -2026,8 +2019,6 @@ static int ohci_start_iso(struct fw_iso_context *base, | |||
2026 | } else { | 2019 | } else { |
2027 | index = ctx - ohci->ir_context_list; | 2020 | index = ctx - ohci->ir_context_list; |
2028 | control = IR_CONTEXT_ISOCH_HEADER; | 2021 | control = IR_CONTEXT_ISOCH_HEADER; |
2029 | if (ohci->use_dualbuffer) | ||
2030 | control |= IR_CONTEXT_DUAL_BUFFER_MODE; | ||
2031 | match = (tags << 28) | (sync << 8) | ctx->base.channel; | 2022 | match = (tags << 28) | (sync << 8) | ctx->base.channel; |
2032 | if (cycle >= 0) { | 2023 | if (cycle >= 0) { |
2033 | match |= (cycle & 0x07fff) << 12; | 2024 | match |= (cycle & 0x07fff) << 12; |
@@ -2188,92 +2179,6 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base, | |||
2188 | return 0; | 2179 | return 0; |
2189 | } | 2180 | } |
2190 | 2181 | ||
2191 | static int ohci_queue_iso_receive_dualbuffer(struct fw_iso_context *base, | ||
2192 | struct fw_iso_packet *packet, | ||
2193 | struct fw_iso_buffer *buffer, | ||
2194 | unsigned long payload) | ||
2195 | { | ||
2196 | struct iso_context *ctx = container_of(base, struct iso_context, base); | ||
2197 | struct db_descriptor *db = NULL; | ||
2198 | struct descriptor *d; | ||
2199 | struct fw_iso_packet *p; | ||
2200 | dma_addr_t d_bus, page_bus; | ||
2201 | u32 z, header_z, length, rest; | ||
2202 | int page, offset, packet_count, header_size; | ||
2203 | |||
2204 | /* | ||
2205 | * FIXME: Cycle lost behavior should be configurable: lose | ||
2206 | * packet, retransmit or terminate.. | ||
2207 | */ | ||
2208 | |||
2209 | p = packet; | ||
2210 | z = 2; | ||
2211 | |||
2212 | /* | ||
2213 | * The OHCI controller puts the isochronous header and trailer in the | ||
2214 | * buffer, so we need at least 8 bytes. | ||
2215 | */ | ||
2216 | packet_count = p->header_length / ctx->base.header_size; | ||
2217 | header_size = packet_count * max(ctx->base.header_size, (size_t)8); | ||
2218 | |||
2219 | /* Get header size in number of descriptors. */ | ||
2220 | header_z = DIV_ROUND_UP(header_size, sizeof(*d)); | ||
2221 | page = payload >> PAGE_SHIFT; | ||
2222 | offset = payload & ~PAGE_MASK; | ||
2223 | rest = p->payload_length; | ||
2224 | /* | ||
2225 | * The controllers I've tested have not worked correctly when | ||
2226 | * second_req_count is zero. Rather than do something we know won't | ||
2227 | * work, return an error | ||
2228 | */ | ||
2229 | if (rest == 0) | ||
2230 | return -EINVAL; | ||
2231 | |||
2232 | while (rest > 0) { | ||
2233 | d = context_get_descriptors(&ctx->context, | ||
2234 | z + header_z, &d_bus); | ||
2235 | if (d == NULL) | ||
2236 | return -ENOMEM; | ||
2237 | |||
2238 | db = (struct db_descriptor *) d; | ||
2239 | db->control = cpu_to_le16(DESCRIPTOR_STATUS | | ||
2240 | DESCRIPTOR_BRANCH_ALWAYS); | ||
2241 | db->first_size = | ||
2242 | cpu_to_le16(max(ctx->base.header_size, (size_t)8)); | ||
2243 | if (p->skip && rest == p->payload_length) { | ||
2244 | db->control |= cpu_to_le16(DESCRIPTOR_WAIT); | ||
2245 | db->first_req_count = db->first_size; | ||
2246 | } else { | ||
2247 | db->first_req_count = cpu_to_le16(header_size); | ||
2248 | } | ||
2249 | db->first_res_count = db->first_req_count; | ||
2250 | db->first_buffer = cpu_to_le32(d_bus + sizeof(*db)); | ||
2251 | |||
2252 | if (p->skip && rest == p->payload_length) | ||
2253 | length = 4; | ||
2254 | else if (offset + rest < PAGE_SIZE) | ||
2255 | length = rest; | ||
2256 | else | ||
2257 | length = PAGE_SIZE - offset; | ||
2258 | |||
2259 | db->second_req_count = cpu_to_le16(length); | ||
2260 | db->second_res_count = db->second_req_count; | ||
2261 | page_bus = page_private(buffer->pages[page]); | ||
2262 | db->second_buffer = cpu_to_le32(page_bus + offset); | ||
2263 | |||
2264 | if (p->interrupt && length == rest) | ||
2265 | db->control |= cpu_to_le16(DESCRIPTOR_IRQ_ALWAYS); | ||
2266 | |||
2267 | context_append(&ctx->context, d, z, header_z); | ||
2268 | offset = (offset + length) & ~PAGE_MASK; | ||
2269 | rest -= length; | ||
2270 | if (offset == 0) | ||
2271 | page++; | ||
2272 | } | ||
2273 | |||
2274 | return 0; | ||
2275 | } | ||
2276 | |||
2277 | static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, | 2182 | static int ohci_queue_iso_receive_packet_per_buffer(struct fw_iso_context *base, |
2278 | struct fw_iso_packet *packet, | 2183 | struct fw_iso_packet *packet, |
2279 | struct fw_iso_buffer *buffer, | 2184 | struct fw_iso_buffer *buffer, |
@@ -2364,9 +2269,6 @@ static int ohci_queue_iso(struct fw_iso_context *base, | |||
2364 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); | 2269 | spin_lock_irqsave(&ctx->context.ohci->lock, flags); |
2365 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) | 2270 | if (base->type == FW_ISO_CONTEXT_TRANSMIT) |
2366 | ret = ohci_queue_iso_transmit(base, packet, buffer, payload); | 2271 | ret = ohci_queue_iso_transmit(base, packet, buffer, payload); |
2367 | else if (ctx->context.ohci->use_dualbuffer) | ||
2368 | ret = ohci_queue_iso_receive_dualbuffer(base, packet, | ||
2369 | buffer, payload); | ||
2370 | else | 2272 | else |
2371 | ret = ohci_queue_iso_receive_packet_per_buffer(base, packet, | 2273 | ret = ohci_queue_iso_receive_packet_per_buffer(base, packet, |
2372 | buffer, payload); | 2274 | buffer, payload); |
@@ -2383,7 +2285,7 @@ static const struct fw_card_driver ohci_driver = { | |||
2383 | .send_response = ohci_send_response, | 2285 | .send_response = ohci_send_response, |
2384 | .cancel_packet = ohci_cancel_packet, | 2286 | .cancel_packet = ohci_cancel_packet, |
2385 | .enable_phys_dma = ohci_enable_phys_dma, | 2287 | .enable_phys_dma = ohci_enable_phys_dma, |
2386 | .get_bus_time = ohci_get_bus_time, | 2288 | .get_cycle_time = ohci_get_cycle_time, |
2387 | 2289 | ||
2388 | .allocate_iso_context = ohci_allocate_iso_context, | 2290 | .allocate_iso_context = ohci_allocate_iso_context, |
2389 | .free_iso_context = ohci_free_iso_context, | 2291 | .free_iso_context = ohci_free_iso_context, |
@@ -2421,17 +2323,13 @@ static void ohci_pmac_off(struct pci_dev *dev) | |||
2421 | #define ohci_pmac_off(dev) | 2323 | #define ohci_pmac_off(dev) |
2422 | #endif /* CONFIG_PPC_PMAC */ | 2324 | #endif /* CONFIG_PPC_PMAC */ |
2423 | 2325 | ||
2424 | #define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT | ||
2425 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | ||
2426 | #define PCI_DEVICE_ID_TI_TSB43AB23 0x8024 | ||
2427 | |||
2428 | static int __devinit pci_probe(struct pci_dev *dev, | 2326 | static int __devinit pci_probe(struct pci_dev *dev, |
2429 | const struct pci_device_id *ent) | 2327 | const struct pci_device_id *ent) |
2430 | { | 2328 | { |
2431 | struct fw_ohci *ohci; | 2329 | struct fw_ohci *ohci; |
2432 | u32 bus_options, max_receive, link_speed, version; | 2330 | u32 bus_options, max_receive, link_speed, version; |
2433 | u64 guid; | 2331 | u64 guid; |
2434 | int err; | 2332 | int i, err, n_ir, n_it; |
2435 | size_t size; | 2333 | size_t size; |
2436 | 2334 | ||
2437 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); | 2335 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); |
@@ -2472,36 +2370,15 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2472 | goto fail_iomem; | 2370 | goto fail_iomem; |
2473 | } | 2371 | } |
2474 | 2372 | ||
2475 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; | 2373 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) |
2476 | #if 0 | 2374 | if (ohci_quirks[i].vendor == dev->vendor && |
2477 | /* FIXME: make it a context option or remove dual-buffer mode */ | 2375 | (ohci_quirks[i].device == dev->device || |
2478 | ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; | 2376 | ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { |
2479 | #endif | 2377 | ohci->quirks = ohci_quirks[i].flags; |
2480 | 2378 | break; | |
2481 | /* dual-buffer mode is broken if more than one IR context is active */ | 2379 | } |
2482 | if (dev->vendor == PCI_VENDOR_ID_AGERE && | 2380 | if (param_quirks) |
2483 | dev->device == PCI_DEVICE_ID_AGERE_FW643) | 2381 | ohci->quirks = param_quirks; |
2484 | ohci->use_dualbuffer = false; | ||
2485 | |||
2486 | /* dual-buffer mode is broken */ | ||
2487 | if (dev->vendor == PCI_VENDOR_ID_RICOH && | ||
2488 | dev->device == PCI_DEVICE_ID_RICOH_R5C832) | ||
2489 | ohci->use_dualbuffer = false; | ||
2490 | |||
2491 | /* x86-32 currently doesn't use highmem for dma_alloc_coherent */ | ||
2492 | #if !defined(CONFIG_X86_32) | ||
2493 | /* dual-buffer mode is broken with descriptor addresses above 2G */ | ||
2494 | if (dev->vendor == PCI_VENDOR_ID_TI && | ||
2495 | (dev->device == PCI_DEVICE_ID_TI_TSB43AB22 || | ||
2496 | dev->device == PCI_DEVICE_ID_TI_TSB43AB23)) | ||
2497 | ohci->use_dualbuffer = false; | ||
2498 | #endif | ||
2499 | |||
2500 | #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) | ||
2501 | ohci->old_uninorth = dev->vendor == PCI_VENDOR_ID_APPLE && | ||
2502 | dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW; | ||
2503 | #endif | ||
2504 | ohci->bus_reset_packet_quirk = dev->vendor == PCI_VENDOR_ID_TI; | ||
2505 | 2382 | ||
2506 | ar_context_init(&ohci->ar_request_ctx, ohci, | 2383 | ar_context_init(&ohci->ar_request_ctx, ohci, |
2507 | OHCI1394_AsReqRcvContextControlSet); | 2384 | OHCI1394_AsReqRcvContextControlSet); |
@@ -2516,17 +2393,19 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2516 | OHCI1394_AsRspTrContextControlSet, handle_at_packet); | 2393 | OHCI1394_AsRspTrContextControlSet, handle_at_packet); |
2517 | 2394 | ||
2518 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); | 2395 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); |
2519 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); | 2396 | ohci->ir_context_channels = ~0ULL; |
2397 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); | ||
2520 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); | 2398 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); |
2521 | size = sizeof(struct iso_context) * hweight32(ohci->it_context_mask); | 2399 | n_ir = hweight32(ohci->ir_context_mask); |
2522 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); | 2400 | size = sizeof(struct iso_context) * n_ir; |
2401 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); | ||
2523 | 2402 | ||
2524 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); | 2403 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); |
2525 | ohci->ir_context_channels = ~0ULL; | 2404 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); |
2526 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); | ||
2527 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); | 2405 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); |
2528 | size = sizeof(struct iso_context) * hweight32(ohci->ir_context_mask); | 2406 | n_it = hweight32(ohci->it_context_mask); |
2529 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); | 2407 | size = sizeof(struct iso_context) * n_it; |
2408 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); | ||
2530 | 2409 | ||
2531 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { | 2410 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { |
2532 | err = -ENOMEM; | 2411 | err = -ENOMEM; |
@@ -2553,8 +2432,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2553 | if (err) | 2432 | if (err) |
2554 | goto fail_self_id; | 2433 | goto fail_self_id; |
2555 | 2434 | ||
2556 | fw_notify("Added fw-ohci device %s, OHCI version %x.%x\n", | 2435 | version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; |
2557 | dev_name(&dev->dev), version >> 16, version & 0xff); | 2436 | fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " |
2437 | "%d IR + %d IT contexts, quirks 0x%x\n", | ||
2438 | dev_name(&dev->dev), version >> 16, version & 0xff, | ||
2439 | n_ir, n_it, ohci->quirks); | ||
2558 | 2440 | ||
2559 | return 0; | 2441 | return 0; |
2560 | 2442 | ||
@@ -2662,7 +2544,7 @@ static int pci_resume(struct pci_dev *dev) | |||
2662 | } | 2544 | } |
2663 | #endif | 2545 | #endif |
2664 | 2546 | ||
2665 | static struct pci_device_id pci_table[] = { | 2547 | static const struct pci_device_id pci_table[] = { |
2666 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, | 2548 | { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_FIREWIRE_OHCI, ~0) }, |
2667 | { } | 2549 | { } |
2668 | }; | 2550 | }; |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 70fef40cd22f..ca264f2fdf0c 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -1014,7 +1014,8 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) | |||
1014 | return 0; | 1014 | return 0; |
1015 | } | 1015 | } |
1016 | 1016 | ||
1017 | static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory) | 1017 | static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, |
1018 | const u32 *directory) | ||
1018 | { | 1019 | { |
1019 | struct fw_csr_iterator ci; | 1020 | struct fw_csr_iterator ci; |
1020 | int key, value; | 1021 | int key, value; |
@@ -1027,7 +1028,7 @@ static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory) | |||
1027 | return 0; | 1028 | return 0; |
1028 | } | 1029 | } |
1029 | 1030 | ||
1030 | static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory, | 1031 | static int sbp2_scan_unit_dir(struct sbp2_target *tgt, const u32 *directory, |
1031 | u32 *model, u32 *firmware_revision) | 1032 | u32 *model, u32 *firmware_revision) |
1032 | { | 1033 | { |
1033 | struct fw_csr_iterator ci; | 1034 | struct fw_csr_iterator ci; |