summaryrefslogtreecommitdiffstats
path: root/drivers/vme/vme.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/vme/vme.c')
-rw-r--r--drivers/vme/vme.c61
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}
224EXPORT_SYMBOL(vme_check_window); 224EXPORT_SYMBOL(vme_check_window);
225 225
226static 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)
991EXPORT_SYMBOL(vme_dma_free); 1024EXPORT_SYMBOL(vme_dma_free);
992 1025
993void vme_bus_error_handler(struct vme_bridge *bridge, 1026void 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);