diff options
author | Martyn Welch <martyn.welch@gefanuc.com> | 2009-10-29 12:35:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-12-11 15:23:18 -0500 |
commit | 59c2290428dd93a4117aa453fc4c2be38da288c0 (patch) | |
tree | fdbe6cd402c95f81f2c0c00861144720e7a63d3c /drivers/staging/vme | |
parent | 70d7aa889f7c107a768d07389998e4fd89a7103d (diff) |
Staging: vme: Allow size of 0 when disabling a window
The TSI148 driver currently does not allow a size of zero to be passed to a
window. Zero is a valid value if the window is being disabled. Allow
windows to be disabled and their registers cleared.
Signed-off-by: Martyn Welch <martyn.welch@gefanuc.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/vme')
-rw-r--r-- | drivers/staging/vme/bridges/vme_tsi148.c | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 5b5c73ec103..03eb48e4d8f 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c | |||
@@ -846,7 +846,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, | |||
846 | image->pci_resource.start); | 846 | image->pci_resource.start); |
847 | 847 | ||
848 | /* If the existing size is OK, return */ | 848 | /* If the existing size is OK, return */ |
849 | if (existing_size == (size - 1)) | 849 | if ((size != 0) && (existing_size == (size - 1))) |
850 | return 0; | 850 | return 0; |
851 | 851 | ||
852 | if (existing_size != 0) { | 852 | if (existing_size != 0) { |
@@ -858,6 +858,11 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, | |||
858 | memset(&(image->pci_resource), 0, sizeof(struct resource)); | 858 | memset(&(image->pci_resource), 0, sizeof(struct resource)); |
859 | } | 859 | } |
860 | 860 | ||
861 | /* Exit here if size is zero */ | ||
862 | if (size == 0) { | ||
863 | return 0; | ||
864 | } | ||
865 | |||
861 | if (image->pci_resource.name == NULL) { | 866 | if (image->pci_resource.name == NULL) { |
862 | image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); | 867 | image->pci_resource.name = kmalloc(VMENAMSIZ+3, GFP_KERNEL); |
863 | if (image->pci_resource.name == NULL) { | 868 | if (image->pci_resource.name == NULL) { |
@@ -936,12 +941,13 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, | |||
936 | 941 | ||
937 | /* Verify input data */ | 942 | /* Verify input data */ |
938 | if (vme_base & 0xFFFF) { | 943 | if (vme_base & 0xFFFF) { |
939 | printk("Invalid VME Window alignment\n"); | 944 | printk(KERN_ERR "Invalid VME Window alignment\n"); |
940 | retval = -EINVAL; | 945 | retval = -EINVAL; |
941 | goto err_window; | 946 | goto err_window; |
942 | } | 947 | } |
943 | if (size < 0x10000) { | 948 | |
944 | printk("Invalid VME Window size\n"); | 949 | if ((size == 0) && (enabled != 0)) { |
950 | printk(KERN_ERR "Size must be non-zero for enabled windows\n"); | ||
945 | retval = -EINVAL; | 951 | retval = -EINVAL; |
946 | goto err_window; | 952 | goto err_window; |
947 | } | 953 | } |
@@ -949,26 +955,31 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, | |||
949 | spin_lock(&(image->lock)); | 955 | spin_lock(&(image->lock)); |
950 | 956 | ||
951 | /* Let's allocate the resource here rather than further up the stack as | 957 | /* Let's allocate the resource here rather than further up the stack as |
952 | * it avoids pushing loads of bus dependant stuff up the stack | 958 | * it avoids pushing loads of bus dependant stuff up the stack. If size |
959 | * is zero, any existing resource will be freed. | ||
953 | */ | 960 | */ |
954 | retval = tsi148_alloc_resource(image, size); | 961 | retval = tsi148_alloc_resource(image, size); |
955 | if (retval) { | 962 | if (retval) { |
956 | spin_unlock(&(image->lock)); | 963 | spin_unlock(&(image->lock)); |
957 | printk(KERN_ERR "Unable to allocate memory for resource " | 964 | printk(KERN_ERR "Unable to allocate memory for " |
958 | "name\n"); | 965 | "resource\n"); |
959 | retval = -ENOMEM; | ||
960 | goto err_res; | 966 | goto err_res; |
961 | } | 967 | } |
962 | 968 | ||
963 | pci_base = (unsigned long long)image->pci_resource.start; | 969 | if (size == 0) { |
964 | 970 | pci_base = 0; | |
971 | pci_bound = 0; | ||
972 | vme_offset = 0; | ||
973 | } else { | ||
974 | pci_base = (unsigned long long)image->pci_resource.start; | ||
965 | 975 | ||
966 | /* | 976 | /* |
967 | * Bound address is a valid address for the window, adjust | 977 | * Bound address is a valid address for the window, adjust |
968 | * according to window granularity. | 978 | * according to window granularity. |
969 | */ | 979 | */ |
970 | pci_bound = pci_base + (size - 0x10000); | 980 | pci_bound = pci_base + (size - 0x10000); |
971 | vme_offset = vme_base - pci_base; | 981 | vme_offset = vme_base - pci_base; |
982 | } | ||
972 | 983 | ||
973 | /* Convert 64-bit variables to 2x 32-bit variables */ | 984 | /* Convert 64-bit variables to 2x 32-bit variables */ |
974 | reg_split(pci_base, &pci_base_high, &pci_base_low); | 985 | reg_split(pci_base, &pci_base_high, &pci_base_low); |
@@ -977,19 +988,19 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, | |||
977 | 988 | ||
978 | if (pci_base_low & 0xFFFF) { | 989 | if (pci_base_low & 0xFFFF) { |
979 | spin_unlock(&(image->lock)); | 990 | spin_unlock(&(image->lock)); |
980 | printk("Invalid PCI base alignment\n"); | 991 | printk(KERN_ERR "Invalid PCI base alignment\n"); |
981 | retval = -EINVAL; | 992 | retval = -EINVAL; |
982 | goto err_gran; | 993 | goto err_gran; |
983 | } | 994 | } |
984 | if (pci_bound_low & 0xFFFF) { | 995 | if (pci_bound_low & 0xFFFF) { |
985 | spin_unlock(&(image->lock)); | 996 | spin_unlock(&(image->lock)); |
986 | printk("Invalid PCI bound alignment\n"); | 997 | printk(KERN_ERR "Invalid PCI bound alignment\n"); |
987 | retval = -EINVAL; | 998 | retval = -EINVAL; |
988 | goto err_gran; | 999 | goto err_gran; |
989 | } | 1000 | } |
990 | if (vme_offset_low & 0xFFFF) { | 1001 | if (vme_offset_low & 0xFFFF) { |
991 | spin_unlock(&(image->lock)); | 1002 | spin_unlock(&(image->lock)); |
992 | printk("Invalid VME Offset alignment\n"); | 1003 | printk(KERN_ERR "Invalid VME Offset alignment\n"); |
993 | retval = -EINVAL; | 1004 | retval = -EINVAL; |
994 | goto err_gran; | 1005 | goto err_gran; |
995 | } | 1006 | } |
@@ -1049,7 +1060,8 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, | |||
1049 | temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST; | 1060 | temp_ctl |= TSI148_LCSR_OTAT_TM_2eSST; |
1050 | } | 1061 | } |
1051 | if (cycle & VME_2eSSTB) { | 1062 | if (cycle & VME_2eSSTB) { |
1052 | printk("Currently not setting Broadcast Select Registers\n"); | 1063 | printk(KERN_WARNING "Currently not setting Broadcast Select " |
1064 | "Registers\n"); | ||
1053 | temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; | 1065 | temp_ctl &= ~TSI148_LCSR_OTAT_TM_M; |
1054 | temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB; | 1066 | temp_ctl |= TSI148_LCSR_OTAT_TM_2eSSTB; |
1055 | } | 1067 | } |
@@ -1065,7 +1077,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, | |||
1065 | break; | 1077 | break; |
1066 | default: | 1078 | default: |
1067 | spin_unlock(&(image->lock)); | 1079 | spin_unlock(&(image->lock)); |
1068 | printk("Invalid data width\n"); | 1080 | printk(KERN_ERR "Invalid data width\n"); |
1069 | retval = -EINVAL; | 1081 | retval = -EINVAL; |
1070 | goto err_dwidth; | 1082 | goto err_dwidth; |
1071 | } | 1083 | } |
@@ -1102,7 +1114,7 @@ int tsi148_master_set( struct vme_master_resource *image, int enabled, | |||
1102 | break; | 1114 | break; |
1103 | default: | 1115 | default: |
1104 | spin_unlock(&(image->lock)); | 1116 | spin_unlock(&(image->lock)); |
1105 | printk("Invalid address space\n"); | 1117 | printk(KERN_ERR "Invalid address space\n"); |
1106 | retval = -EINVAL; | 1118 | retval = -EINVAL; |
1107 | goto err_aspace; | 1119 | goto err_aspace; |
1108 | break; | 1120 | break; |