diff options
| -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 | ||||
| -rw-r--r-- | drivers/media/dvb/firewire/firedtv-fw.c | 39 | ||||
| -rw-r--r-- | include/linux/firewire-cdev.h | 40 | ||||
| -rw-r--r-- | include/linux/firewire.h | 11 | ||||
| -rw-r--r-- | include/linux/pci_ids.h | 1 |
10 files changed, 493 insertions, 552 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; |
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c index 7a3de16fba06..75afe4f81e33 100644 --- a/drivers/media/dvb/firewire/firedtv-fw.c +++ b/drivers/media/dvb/firewire/firedtv-fw.c | |||
| @@ -239,47 +239,18 @@ static const struct fw_address_region fcp_region = { | |||
| 239 | }; | 239 | }; |
| 240 | 240 | ||
| 241 | /* Adjust the template string if models with longer names appear. */ | 241 | /* Adjust the template string if models with longer names appear. */ |
| 242 | #define MAX_MODEL_NAME_LEN ((int)DIV_ROUND_UP(sizeof("FireDTV ????"), 4)) | 242 | #define MAX_MODEL_NAME_LEN sizeof("FireDTV ????") |
| 243 | |||
| 244 | static size_t model_name(u32 *directory, __be32 *buffer) | ||
| 245 | { | ||
| 246 | struct fw_csr_iterator ci; | ||
| 247 | int i, length, key, value, last_key = 0; | ||
| 248 | u32 *block = NULL; | ||
| 249 | |||
| 250 | fw_csr_iterator_init(&ci, directory); | ||
| 251 | while (fw_csr_iterator_next(&ci, &key, &value)) { | ||
| 252 | if (last_key == CSR_MODEL && | ||
| 253 | key == (CSR_DESCRIPTOR | CSR_LEAF)) | ||
| 254 | block = ci.p - 1 + value; | ||
| 255 | last_key = key; | ||
| 256 | } | ||
| 257 | |||
| 258 | if (block == NULL) | ||
| 259 | return 0; | ||
| 260 | |||
| 261 | length = min((int)(block[0] >> 16) - 2, MAX_MODEL_NAME_LEN); | ||
| 262 | if (length <= 0) | ||
| 263 | return 0; | ||
| 264 | |||
| 265 | /* fast-forward to text string */ | ||
| 266 | block += 3; | ||
| 267 | |||
| 268 | for (i = 0; i < length; i++) | ||
| 269 | buffer[i] = cpu_to_be32(block[i]); | ||
| 270 | |||
| 271 | return length * 4; | ||
| 272 | } | ||
| 273 | 243 | ||
| 274 | static int node_probe(struct device *dev) | 244 | static int node_probe(struct device *dev) |
| 275 | { | 245 | { |
| 276 | struct firedtv *fdtv; | 246 | struct firedtv *fdtv; |
| 277 | __be32 name[MAX_MODEL_NAME_LEN]; | 247 | char name[MAX_MODEL_NAME_LEN]; |
| 278 | int name_len, err; | 248 | int name_len, err; |
| 279 | 249 | ||
| 280 | name_len = model_name(fw_unit(dev)->directory, name); | 250 | name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL, |
| 251 | name, sizeof(name)); | ||
| 281 | 252 | ||
| 282 | fdtv = fdtv_alloc(dev, &backend, (char *)name, name_len); | 253 | fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0); |
| 283 | if (!fdtv) | 254 | if (!fdtv) |
| 284 | return -ENOMEM; | 255 | return -ENOMEM; |
| 285 | 256 | ||
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 520ecf86cbb3..40b11013408e 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h | |||
| @@ -248,13 +248,20 @@ union fw_cdev_event { | |||
| 248 | #define FW_CDEV_IOC_SEND_BROADCAST_REQUEST _IOW('#', 0x12, struct fw_cdev_send_request) | 248 | #define FW_CDEV_IOC_SEND_BROADCAST_REQUEST _IOW('#', 0x12, struct fw_cdev_send_request) |
| 249 | #define FW_CDEV_IOC_SEND_STREAM_PACKET _IOW('#', 0x13, struct fw_cdev_send_stream_packet) | 249 | #define FW_CDEV_IOC_SEND_STREAM_PACKET _IOW('#', 0x13, struct fw_cdev_send_stream_packet) |
| 250 | 250 | ||
| 251 | /* available since kernel version 2.6.34 */ | ||
| 252 | #define FW_CDEV_IOC_GET_CYCLE_TIMER2 _IOWR('#', 0x14, struct fw_cdev_get_cycle_timer2) | ||
| 253 | |||
| 251 | /* | 254 | /* |
| 252 | * FW_CDEV_VERSION History | 255 | * FW_CDEV_VERSION History |
| 253 | * 1 (2.6.22) - initial version | 256 | * 1 (2.6.22) - initial version |
| 254 | * 2 (2.6.30) - changed &fw_cdev_event_iso_interrupt.header if | 257 | * 2 (2.6.30) - changed &fw_cdev_event_iso_interrupt.header if |
| 255 | * &fw_cdev_create_iso_context.header_size is 8 or more | 258 | * &fw_cdev_create_iso_context.header_size is 8 or more |
| 259 | * (2.6.32) - added time stamp to xmit &fw_cdev_event_iso_interrupt | ||
| 260 | * (2.6.33) - IR has always packet-per-buffer semantics now, not one of | ||
| 261 | * dual-buffer or packet-per-buffer depending on hardware | ||
| 262 | * 3 (2.6.34) - made &fw_cdev_get_cycle_timer reliable | ||
| 256 | */ | 263 | */ |
| 257 | #define FW_CDEV_VERSION 2 | 264 | #define FW_CDEV_VERSION 3 |
| 258 | 265 | ||
| 259 | /** | 266 | /** |
| 260 | * struct fw_cdev_get_info - General purpose information ioctl | 267 | * struct fw_cdev_get_info - General purpose information ioctl |
| @@ -544,14 +551,18 @@ struct fw_cdev_stop_iso { | |||
| 544 | /** | 551 | /** |
| 545 | * struct fw_cdev_get_cycle_timer - read cycle timer register | 552 | * struct fw_cdev_get_cycle_timer - read cycle timer register |
| 546 | * @local_time: system time, in microseconds since the Epoch | 553 | * @local_time: system time, in microseconds since the Epoch |
| 547 | * @cycle_timer: isochronous cycle timer, as per OHCI 1.1 clause 5.13 | 554 | * @cycle_timer: Cycle Time register contents |
| 548 | * | 555 | * |
| 549 | * The %FW_CDEV_IOC_GET_CYCLE_TIMER ioctl reads the isochronous cycle timer | 556 | * The %FW_CDEV_IOC_GET_CYCLE_TIMER ioctl reads the isochronous cycle timer |
| 550 | * and also the system clock. This allows to express the receive time of an | 557 | * and also the system clock (%CLOCK_REALTIME). This allows to express the |
| 551 | * isochronous packet as a system time with microsecond accuracy. | 558 | * receive time of an isochronous packet as a system time. |
| 552 | * | 559 | * |
| 553 | * @cycle_timer consists of 7 bits cycleSeconds, 13 bits cycleCount, and | 560 | * @cycle_timer consists of 7 bits cycleSeconds, 13 bits cycleCount, and |
| 554 | * 12 bits cycleOffset, in host byte order. | 561 | * 12 bits cycleOffset, in host byte order. Cf. the Cycle Time register |
| 562 | * per IEEE 1394 or Isochronous Cycle Timer register per OHCI-1394. | ||
| 563 | * | ||
| 564 | * In version 1 and 2 of the ABI, this ioctl returned unreliable (non- | ||
| 565 | * monotonic) @cycle_timer values on certain controllers. | ||
| 555 | */ | 566 | */ |
| 556 | struct fw_cdev_get_cycle_timer { | 567 | struct fw_cdev_get_cycle_timer { |
| 557 | __u64 local_time; | 568 | __u64 local_time; |
| @@ -559,6 +570,25 @@ struct fw_cdev_get_cycle_timer { | |||
| 559 | }; | 570 | }; |
| 560 | 571 | ||
| 561 | /** | 572 | /** |
| 573 | * struct fw_cdev_get_cycle_timer2 - read cycle timer register | ||
| 574 | * @tv_sec: system time, seconds | ||
| 575 | * @tv_nsec: system time, sub-seconds part in nanoseconds | ||
| 576 | * @clk_id: input parameter, clock from which to get the system time | ||
| 577 | * @cycle_timer: Cycle Time register contents | ||
| 578 | * | ||
| 579 | * The %FW_CDEV_IOC_GET_CYCLE_TIMER2 works like | ||
| 580 | * %FW_CDEV_IOC_GET_CYCLE_TIMER but lets you choose a clock like with POSIX' | ||
| 581 | * clock_gettime function. Supported @clk_id values are POSIX' %CLOCK_REALTIME | ||
| 582 | * and %CLOCK_MONOTONIC and Linux' %CLOCK_MONOTONIC_RAW. | ||
| 583 | */ | ||
| 584 | struct fw_cdev_get_cycle_timer2 { | ||
| 585 | __s64 tv_sec; | ||
| 586 | __s32 tv_nsec; | ||
| 587 | __s32 clk_id; | ||
| 588 | __u32 cycle_timer; | ||
| 589 | }; | ||
| 590 | |||
| 591 | /** | ||
| 562 | * struct fw_cdev_allocate_iso_resource - (De)allocate a channel or bandwidth | 592 | * struct fw_cdev_allocate_iso_resource - (De)allocate a channel or bandwidth |
| 563 | * @closure: Passed back to userspace in correponding iso resource events | 593 | * @closure: Passed back to userspace in correponding iso resource events |
| 564 | * @channels: Isochronous channels of which one is to be (de)allocated | 594 | * @channels: Isochronous channels of which one is to be (de)allocated |
diff --git a/include/linux/firewire.h b/include/linux/firewire.h index a0e67150a729..4bd94bf5e739 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h | |||
| @@ -65,12 +65,13 @@ | |||
| 65 | #define CSR_DIRECTORY_ID 0x20 | 65 | #define CSR_DIRECTORY_ID 0x20 |
| 66 | 66 | ||
| 67 | struct fw_csr_iterator { | 67 | struct fw_csr_iterator { |
| 68 | u32 *p; | 68 | const u32 *p; |
| 69 | u32 *end; | 69 | const u32 *end; |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, u32 *p); | 72 | void fw_csr_iterator_init(struct fw_csr_iterator *ci, const u32 *p); |
| 73 | int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value); | 73 | int fw_csr_iterator_next(struct fw_csr_iterator *ci, int *key, int *value); |
| 74 | int fw_csr_string(const u32 *directory, int key, char *buf, size_t size); | ||
| 74 | 75 | ||
| 75 | extern struct bus_type fw_bus_type; | 76 | extern struct bus_type fw_bus_type; |
| 76 | 77 | ||
| @@ -162,7 +163,7 @@ struct fw_device { | |||
| 162 | struct mutex client_list_mutex; | 163 | struct mutex client_list_mutex; |
| 163 | struct list_head client_list; | 164 | struct list_head client_list; |
| 164 | 165 | ||
| 165 | u32 *config_rom; | 166 | const u32 *config_rom; |
| 166 | size_t config_rom_length; | 167 | size_t config_rom_length; |
| 167 | int config_rom_retries; | 168 | int config_rom_retries; |
| 168 | unsigned is_local:1; | 169 | unsigned is_local:1; |
| @@ -204,7 +205,7 @@ int fw_device_enable_phys_dma(struct fw_device *device); | |||
| 204 | */ | 205 | */ |
| 205 | struct fw_unit { | 206 | struct fw_unit { |
| 206 | struct device device; | 207 | struct device device; |
| 207 | u32 *directory; | 208 | const u32 *directory; |
| 208 | struct fw_attribute_group attribute_group; | 209 | struct fw_attribute_group attribute_group; |
| 209 | }; | 210 | }; |
| 210 | 211 | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0be824320580..c0e207c0c45a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -770,7 +770,6 @@ | |||
| 770 | #define PCI_VENDOR_ID_TI 0x104c | 770 | #define PCI_VENDOR_ID_TI 0x104c |
| 771 | #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 | 771 | #define PCI_DEVICE_ID_TI_TVP4020 0x3d07 |
| 772 | #define PCI_DEVICE_ID_TI_4450 0x8011 | 772 | #define PCI_DEVICE_ID_TI_4450 0x8011 |
| 773 | #define PCI_DEVICE_ID_TI_TSB43AB22 0x8023 | ||
| 774 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 | 773 | #define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 |
| 775 | #define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 | 774 | #define PCI_DEVICE_ID_TI_XX21_XX11_FM 0x8033 |
| 776 | #define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 | 775 | #define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 |
