diff options
Diffstat (limited to 'drivers/vme/vme.c')
-rw-r--r-- | drivers/vme/vme.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/vme/vme.c b/drivers/vme/vme.c index 6803744978b2..2b79cd2715da 100644 --- a/drivers/vme/vme.c +++ b/drivers/vme/vme.c | |||
@@ -223,6 +223,39 @@ int vme_check_window(u32 aspace, unsigned long long vme_base, | |||
223 | } | 223 | } |
224 | EXPORT_SYMBOL(vme_check_window); | 224 | EXPORT_SYMBOL(vme_check_window); |
225 | 225 | ||
226 | static u32 vme_get_aspace(int am) | ||
227 | { | ||
228 | switch (am) { | ||
229 | case 0x29: | ||
230 | case 0x2D: | ||
231 | return VME_A16; | ||
232 | case 0x38: | ||
233 | case 0x39: | ||
234 | case 0x3A: | ||
235 | case 0x3B: | ||
236 | case 0x3C: | ||
237 | case 0x3D: | ||
238 | case 0x3E: | ||
239 | case 0x3F: | ||
240 | return VME_A24; | ||
241 | case 0x8: | ||
242 | case 0x9: | ||
243 | case 0xA: | ||
244 | case 0xB: | ||
245 | case 0xC: | ||
246 | case 0xD: | ||
247 | case 0xE: | ||
248 | case 0xF: | ||
249 | return VME_A32; | ||
250 | case 0x0: | ||
251 | case 0x1: | ||
252 | case 0x3: | ||
253 | return VME_A64; | ||
254 | } | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
226 | /* | 259 | /* |
227 | * Request a slave image with specific attributes, return some unique | 260 | * Request a slave image with specific attributes, return some unique |
228 | * identifier. | 261 | * identifier. |
@@ -991,14 +1024,14 @@ int vme_dma_free(struct vme_resource *resource) | |||
991 | EXPORT_SYMBOL(vme_dma_free); | 1024 | EXPORT_SYMBOL(vme_dma_free); |
992 | 1025 | ||
993 | void vme_bus_error_handler(struct vme_bridge *bridge, | 1026 | void vme_bus_error_handler(struct vme_bridge *bridge, |
994 | unsigned long long address, u32 attributes) | 1027 | unsigned long long address, int am) |
995 | { | 1028 | { |
996 | struct vme_bus_error *error; | 1029 | struct vme_bus_error *error; |
997 | 1030 | ||
998 | error = kmalloc(sizeof(struct vme_bus_error), GFP_ATOMIC); | 1031 | error = kmalloc(sizeof(struct vme_bus_error), GFP_ATOMIC); |
999 | if (error) { | 1032 | if (error) { |
1033 | error->aspace = vme_get_aspace(am); | ||
1000 | error->address = address; | 1034 | error->address = address; |
1001 | error->attributes = attributes; | ||
1002 | list_add_tail(&error->list, &bridge->vme_errors); | 1035 | list_add_tail(&error->list, &bridge->vme_errors); |
1003 | } else { | 1036 | } else { |
1004 | dev_err(bridge->parent, | 1037 | dev_err(bridge->parent, |
@@ -1019,19 +1052,13 @@ struct vme_bus_error *vme_find_error(struct vme_bridge *bridge, u32 aspace, | |||
1019 | 1052 | ||
1020 | bound = address + count; | 1053 | bound = address + count; |
1021 | 1054 | ||
1022 | /* | ||
1023 | * XXX We are currently not looking at the address space when parsing | ||
1024 | * for errors. This is because parsing the Address Modifier Codes | ||
1025 | * is going to be quite resource intensive to do properly. We | ||
1026 | * should be OK just looking at the addresses and this is certainly | ||
1027 | * much better than what we had before. | ||
1028 | */ | ||
1029 | err_pos = NULL; | 1055 | err_pos = NULL; |
1030 | /* Iterate through errors */ | 1056 | /* Iterate through errors */ |
1031 | list_for_each(err_pos, &bridge->vme_errors) { | 1057 | list_for_each(err_pos, &bridge->vme_errors) { |
1032 | vme_err = list_entry(err_pos, struct vme_bus_error, list); | 1058 | vme_err = list_entry(err_pos, struct vme_bus_error, list); |
1033 | if ((vme_err->address >= address) && | 1059 | if ((vme_err->aspace == aspace) && |
1034 | (vme_err->address < bound)) { | 1060 | (vme_err->address >= address) && |
1061 | (vme_err->address < bound)) { | ||
1035 | 1062 | ||
1036 | valid = vme_err; | 1063 | valid = vme_err; |
1037 | break; | 1064 | break; |
@@ -1054,20 +1081,14 @@ void vme_clear_errors(struct vme_bridge *bridge, u32 aspace, | |||
1054 | 1081 | ||
1055 | bound = address + count; | 1082 | bound = address + count; |
1056 | 1083 | ||
1057 | /* | ||
1058 | * XXX We are currently not looking at the address space when parsing | ||
1059 | * for errors. This is because parsing the Address Modifier Codes | ||
1060 | * is going to be quite resource intensive to do properly. We | ||
1061 | * should be OK just looking at the addresses and this is certainly | ||
1062 | * much better than what we had before. | ||
1063 | */ | ||
1064 | err_pos = NULL; | 1084 | err_pos = NULL; |
1065 | /* Iterate through errors */ | 1085 | /* Iterate through errors */ |
1066 | list_for_each_safe(err_pos, temp, &bridge->vme_errors) { | 1086 | list_for_each_safe(err_pos, temp, &bridge->vme_errors) { |
1067 | vme_err = list_entry(err_pos, struct vme_bus_error, list); | 1087 | vme_err = list_entry(err_pos, struct vme_bus_error, list); |
1068 | 1088 | ||
1069 | if ((vme_err->address >= address) && | 1089 | if ((vme_err->aspace == aspace) && |
1070 | (vme_err->address < bound)) { | 1090 | (vme_err->address >= address) && |
1091 | (vme_err->address < bound)) { | ||
1071 | 1092 | ||
1072 | list_del(err_pos); | 1093 | list_del(err_pos); |
1073 | kfree(vme_err); | 1094 | kfree(vme_err); |