diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2005-06-27 19:28:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-27 21:03:18 -0400 |
commit | 22916638b124e859b595099bd0c86a1e09e767fb (patch) | |
tree | eb72f33295a0e7806c13df8f1bbf8b340a739326 | |
parent | 5085cb26503a662a5cfdf53ce96fd606c1fbe9ba (diff) |
[PATCH] pcmcia: update resource database adjust routines to use unsigned long values
Make adjust_io and adjust_memory independent of adjust_t to allow for IO
resources > x86's IO_SPACE_LIMIT.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 89 |
1 files changed, 38 insertions, 51 deletions
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 9a0b835d612b..6b463609a3aa 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -683,27 +683,23 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num, | |||
683 | } | 683 | } |
684 | 684 | ||
685 | 685 | ||
686 | static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj) | 686 | static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) |
687 | { | 687 | { |
688 | u_long base, num; | ||
689 | struct socket_data *data = s->resource_data; | 688 | struct socket_data *data = s->resource_data; |
690 | int ret; | 689 | unsigned long size = end - start + 1; |
691 | 690 | int ret = 0; | |
692 | base = adj->resource.memory.Base; | ||
693 | num = adj->resource.memory.Size; | ||
694 | if ((num == 0) || (base+num-1 < base)) | ||
695 | return CS_BAD_SIZE; | ||
696 | 691 | ||
697 | ret = CS_SUCCESS; | 692 | if (end <= start) |
693 | return -EINVAL; | ||
698 | 694 | ||
699 | down(&rsrc_sem); | 695 | down(&rsrc_sem); |
700 | switch (adj->Action) { | 696 | switch (action) { |
701 | case ADD_MANAGED_RESOURCE: | 697 | case ADD_MANAGED_RESOURCE: |
702 | ret = add_interval(&data->mem_db, base, num); | 698 | ret = add_interval(&data->mem_db, start, size); |
703 | break; | 699 | break; |
704 | case REMOVE_MANAGED_RESOURCE: | 700 | case REMOVE_MANAGED_RESOURCE: |
705 | ret = sub_interval(&data->mem_db, base, num); | 701 | ret = sub_interval(&data->mem_db, start, size); |
706 | if (ret == CS_SUCCESS) { | 702 | if (!ret) { |
707 | struct pcmcia_socket *socket; | 703 | struct pcmcia_socket *socket; |
708 | down_read(&pcmcia_socket_list_rwsem); | 704 | down_read(&pcmcia_socket_list_rwsem); |
709 | list_for_each_entry(socket, &pcmcia_socket_list, socket_list) | 705 | list_for_each_entry(socket, &pcmcia_socket_list, socket_list) |
@@ -712,7 +708,7 @@ static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj) | |||
712 | } | 708 | } |
713 | break; | 709 | break; |
714 | default: | 710 | default: |
715 | ret = CS_UNSUPPORTED_FUNCTION; | 711 | ret = -EINVAL; |
716 | } | 712 | } |
717 | up(&rsrc_sem); | 713 | up(&rsrc_sem); |
718 | 714 | ||
@@ -720,36 +716,35 @@ static int adjust_memory(struct pcmcia_socket *s, adjust_t *adj) | |||
720 | } | 716 | } |
721 | 717 | ||
722 | 718 | ||
723 | static int adjust_io(struct pcmcia_socket *s, adjust_t *adj) | 719 | static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) |
724 | { | 720 | { |
725 | struct socket_data *data = s->resource_data; | 721 | struct socket_data *data = s->resource_data; |
726 | kio_addr_t base, num; | 722 | unsigned long size = end - start + 1; |
727 | int ret = CS_SUCCESS; | 723 | int ret = 0; |
728 | 724 | ||
729 | base = adj->resource.io.BasePort; | 725 | if (end <= start) |
730 | num = adj->resource.io.NumPorts; | 726 | return -EINVAL; |
731 | if ((base < 0) || (base > 0xffff)) | 727 | |
732 | return CS_BAD_BASE; | 728 | if (end > IO_SPACE_LIMIT) |
733 | if ((num <= 0) || (base+num > 0x10000) || (base+num <= base)) | 729 | return -EINVAL; |
734 | return CS_BAD_SIZE; | ||
735 | 730 | ||
736 | down(&rsrc_sem); | 731 | down(&rsrc_sem); |
737 | switch (adj->Action) { | 732 | switch (action) { |
738 | case ADD_MANAGED_RESOURCE: | 733 | case ADD_MANAGED_RESOURCE: |
739 | if (add_interval(&data->io_db, base, num) != 0) { | 734 | if (add_interval(&data->io_db, start, size) != 0) { |
740 | ret = CS_IN_USE; | 735 | ret = -EBUSY; |
741 | break; | 736 | break; |
742 | } | 737 | } |
743 | #ifdef CONFIG_PCMCIA_PROBE | 738 | #ifdef CONFIG_PCMCIA_PROBE |
744 | if (probe_io) | 739 | if (probe_io) |
745 | do_io_probe(s, base, num); | 740 | do_io_probe(s, start, size); |
746 | #endif | 741 | #endif |
747 | break; | 742 | break; |
748 | case REMOVE_MANAGED_RESOURCE: | 743 | case REMOVE_MANAGED_RESOURCE: |
749 | sub_interval(&data->io_db, base, num); | 744 | sub_interval(&data->io_db, start, size); |
750 | break; | 745 | break; |
751 | default: | 746 | default: |
752 | ret = CS_UNSUPPORTED_FUNCTION; | 747 | ret = -EINVAL; |
753 | break; | 748 | break; |
754 | } | 749 | } |
755 | up(&rsrc_sem); | 750 | up(&rsrc_sem); |
@@ -760,11 +755,15 @@ static int adjust_io(struct pcmcia_socket *s, adjust_t *adj) | |||
760 | 755 | ||
761 | static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj) | 756 | static int nonstatic_adjust_resource_info(struct pcmcia_socket *s, adjust_t *adj) |
762 | { | 757 | { |
758 | unsigned long end; | ||
759 | |||
763 | switch (adj->Resource) { | 760 | switch (adj->Resource) { |
764 | case RES_MEMORY_RANGE: | 761 | case RES_MEMORY_RANGE: |
765 | return adjust_memory(s, adj); | 762 | end = adj->resource.memory.Base + adj->resource.memory.Size - 1; |
763 | return adjust_memory(s, adj->Action, adj->resource.memory.Base, end); | ||
766 | case RES_IO_RANGE: | 764 | case RES_IO_RANGE: |
767 | return adjust_io(s, adj); | 765 | end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1; |
766 | return adjust_io(s, adj->Action, adj->resource.io.BasePort, end); | ||
768 | } | 767 | } |
769 | return CS_UNSUPPORTED_FUNCTION; | 768 | return CS_UNSUPPORTED_FUNCTION; |
770 | } | 769 | } |
@@ -845,17 +844,16 @@ static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size | |||
845 | { | 844 | { |
846 | struct pcmcia_socket *s = class_get_devdata(class_dev); | 845 | struct pcmcia_socket *s = class_get_devdata(class_dev); |
847 | unsigned long start_addr, end_addr; | 846 | unsigned long start_addr, end_addr; |
848 | unsigned int add = 1; | 847 | unsigned int add = ADD_MANAGED_RESOURCE; |
849 | adjust_t adj; | ||
850 | ssize_t ret = 0; | 848 | ssize_t ret = 0; |
851 | 849 | ||
852 | ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr); | 850 | ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr); |
853 | if (ret != 2) { | 851 | if (ret != 2) { |
854 | ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr); | 852 | ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr); |
855 | add = 0; | 853 | add = REMOVE_MANAGED_RESOURCE; |
856 | if (ret != 2) { | 854 | if (ret != 2) { |
857 | ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr); | 855 | ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr); |
858 | add = 1; | 856 | add = ADD_MANAGED_RESOURCE; |
859 | if (ret != 2) | 857 | if (ret != 2) |
860 | return -EINVAL; | 858 | return -EINVAL; |
861 | } | 859 | } |
@@ -863,12 +861,7 @@ static ssize_t store_io_db(struct class_device *class_dev, const char *buf, size | |||
863 | if (end_addr <= start_addr) | 861 | if (end_addr <= start_addr) |
864 | return -EINVAL; | 862 | return -EINVAL; |
865 | 863 | ||
866 | adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE; | 864 | ret = adjust_io(s, add, start_addr, end_addr); |
867 | adj.Resource = RES_IO_RANGE; | ||
868 | adj.resource.io.BasePort = start_addr; | ||
869 | adj.resource.io.NumPorts = end_addr - start_addr + 1; | ||
870 | |||
871 | ret = adjust_io(s, &adj); | ||
872 | 865 | ||
873 | return ret ? ret : count; | 866 | return ret ? ret : count; |
874 | } | 867 | } |
@@ -901,17 +894,16 @@ static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, siz | |||
901 | { | 894 | { |
902 | struct pcmcia_socket *s = class_get_devdata(class_dev); | 895 | struct pcmcia_socket *s = class_get_devdata(class_dev); |
903 | unsigned long start_addr, end_addr; | 896 | unsigned long start_addr, end_addr; |
904 | unsigned int add = 1; | 897 | unsigned int add = ADD_MANAGED_RESOURCE; |
905 | adjust_t adj; | ||
906 | ssize_t ret = 0; | 898 | ssize_t ret = 0; |
907 | 899 | ||
908 | ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr); | 900 | ret = sscanf (buf, "+ 0x%lx - 0x%lx", &start_addr, &end_addr); |
909 | if (ret != 2) { | 901 | if (ret != 2) { |
910 | ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr); | 902 | ret = sscanf (buf, "- 0x%lx - 0x%lx", &start_addr, &end_addr); |
911 | add = 0; | 903 | add = REMOVE_MANAGED_RESOURCE; |
912 | if (ret != 2) { | 904 | if (ret != 2) { |
913 | ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr); | 905 | ret = sscanf (buf, "0x%lx - 0x%lx", &start_addr, &end_addr); |
914 | add = 1; | 906 | add = ADD_MANAGED_RESOURCE; |
915 | if (ret != 2) | 907 | if (ret != 2) |
916 | return -EINVAL; | 908 | return -EINVAL; |
917 | } | 909 | } |
@@ -919,12 +911,7 @@ static ssize_t store_mem_db(struct class_device *class_dev, const char *buf, siz | |||
919 | if (end_addr <= start_addr) | 911 | if (end_addr <= start_addr) |
920 | return -EINVAL; | 912 | return -EINVAL; |
921 | 913 | ||
922 | adj.Action = add ? ADD_MANAGED_RESOURCE : REMOVE_MANAGED_RESOURCE; | 914 | ret = adjust_memory(s, add, start_addr, end_addr); |
923 | adj.Resource = RES_MEMORY_RANGE; | ||
924 | adj.resource.memory.Base = start_addr; | ||
925 | adj.resource.memory.Size = end_addr - start_addr + 1; | ||
926 | |||
927 | ret = adjust_memory(s, &adj); | ||
928 | 915 | ||
929 | return ret ? ret : count; | 916 | return ret ? ret : count; |
930 | } | 917 | } |