diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/edac/amd64_edac.h | 17 | ||||
-rw-r--r-- | drivers/edac/amd64_edac_inj.c | 112 |
2 files changed, 60 insertions, 69 deletions
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 8c4139647efc..19a12a4fbf45 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -267,18 +267,19 @@ | |||
267 | #define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7) | 267 | #define online_spare_bad_dramcs(pvt, c) (((pvt)->online_spare >> (4 + 4 * (c))) & 0x7) |
268 | 268 | ||
269 | #define F10_NB_ARRAY_ADDR 0xB8 | 269 | #define F10_NB_ARRAY_ADDR 0xB8 |
270 | #define F10_NB_ARRAY_DRAM_ECC BIT(31) | 270 | #define F10_NB_ARRAY_DRAM BIT(31) |
271 | 271 | ||
272 | /* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */ | 272 | /* Bits [2:1] are used to select 16-byte section within a 64-byte cacheline */ |
273 | #define SET_NB_ARRAY_ADDRESS(section) (((section) & 0x3) << 1) | 273 | #define SET_NB_ARRAY_ADDR(section) (((section) & 0x3) << 1) |
274 | 274 | ||
275 | #define F10_NB_ARRAY_DATA 0xBC | 275 | #define F10_NB_ARRAY_DATA 0xBC |
276 | #define SET_NB_DRAM_INJECTION_WRITE(word, bits) \ | 276 | #define SET_NB_DRAM_INJECTION_WRITE(inj) \ |
277 | (BIT(((word) & 0xF) + 20) | \ | 277 | (BIT(((inj.word) & 0xF) + 20) | \ |
278 | BIT(17) | bits) | 278 | BIT(17) | inj.bit_map) |
279 | #define SET_NB_DRAM_INJECTION_READ(word, bits) \ | 279 | #define SET_NB_DRAM_INJECTION_READ(inj) \ |
280 | (BIT(((word) & 0xF) + 20) | \ | 280 | (BIT(((inj.word) & 0xF) + 20) | \ |
281 | BIT(16) | bits) | 281 | BIT(16) | inj.bit_map) |
282 | |||
282 | 283 | ||
283 | #define NBCAP 0xE8 | 284 | #define NBCAP 0xE8 |
284 | #define NBCAP_CHIPKILL BIT(4) | 285 | #define NBCAP_CHIPKILL BIT(4) |
diff --git a/drivers/edac/amd64_edac_inj.c b/drivers/edac/amd64_edac_inj.c index 53d972e00dfb..8977e2fa61da 100644 --- a/drivers/edac/amd64_edac_inj.c +++ b/drivers/edac/amd64_edac_inj.c | |||
@@ -22,20 +22,19 @@ static ssize_t amd64_inject_section_store(struct device *dev, | |||
22 | struct mem_ctl_info *mci = to_mci(dev); | 22 | struct mem_ctl_info *mci = to_mci(dev); |
23 | struct amd64_pvt *pvt = mci->pvt_info; | 23 | struct amd64_pvt *pvt = mci->pvt_info; |
24 | unsigned long value; | 24 | unsigned long value; |
25 | int ret = 0; | 25 | int ret; |
26 | 26 | ||
27 | ret = strict_strtoul(data, 10, &value); | 27 | ret = strict_strtoul(data, 10, &value); |
28 | if (ret != -EINVAL) { | 28 | if (ret < 0) |
29 | return ret; | ||
29 | 30 | ||
30 | if (value > 3) { | 31 | if (value > 3) { |
31 | amd64_warn("%s: invalid section 0x%lx\n", __func__, value); | 32 | amd64_warn("%s: invalid section 0x%lx\n", __func__, value); |
32 | return -EINVAL; | 33 | return -EINVAL; |
33 | } | ||
34 | |||
35 | pvt->injection.section = (u32) value; | ||
36 | return count; | ||
37 | } | 34 | } |
38 | return ret; | 35 | |
36 | pvt->injection.section = (u32) value; | ||
37 | return count; | ||
39 | } | 38 | } |
40 | 39 | ||
41 | static ssize_t amd64_inject_word_show(struct device *dev, | 40 | static ssize_t amd64_inject_word_show(struct device *dev, |
@@ -60,20 +59,19 @@ static ssize_t amd64_inject_word_store(struct device *dev, | |||
60 | struct mem_ctl_info *mci = to_mci(dev); | 59 | struct mem_ctl_info *mci = to_mci(dev); |
61 | struct amd64_pvt *pvt = mci->pvt_info; | 60 | struct amd64_pvt *pvt = mci->pvt_info; |
62 | unsigned long value; | 61 | unsigned long value; |
63 | int ret = 0; | 62 | int ret; |
64 | 63 | ||
65 | ret = strict_strtoul(data, 10, &value); | 64 | ret = strict_strtoul(data, 10, &value); |
66 | if (ret != -EINVAL) { | 65 | if (ret < 0) |
67 | 66 | return ret; | |
68 | if (value > 8) { | ||
69 | amd64_warn("%s: invalid word 0x%lx\n", __func__, value); | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | 67 | ||
73 | pvt->injection.word = (u32) value; | 68 | if (value > 8) { |
74 | return count; | 69 | amd64_warn("%s: invalid word 0x%lx\n", __func__, value); |
70 | return -EINVAL; | ||
75 | } | 71 | } |
76 | return ret; | 72 | |
73 | pvt->injection.word = (u32) value; | ||
74 | return count; | ||
77 | } | 75 | } |
78 | 76 | ||
79 | static ssize_t amd64_inject_ecc_vector_show(struct device *dev, | 77 | static ssize_t amd64_inject_ecc_vector_show(struct device *dev, |
@@ -97,21 +95,19 @@ static ssize_t amd64_inject_ecc_vector_store(struct device *dev, | |||
97 | struct mem_ctl_info *mci = to_mci(dev); | 95 | struct mem_ctl_info *mci = to_mci(dev); |
98 | struct amd64_pvt *pvt = mci->pvt_info; | 96 | struct amd64_pvt *pvt = mci->pvt_info; |
99 | unsigned long value; | 97 | unsigned long value; |
100 | int ret = 0; | 98 | int ret; |
101 | 99 | ||
102 | ret = strict_strtoul(data, 16, &value); | 100 | ret = strict_strtoul(data, 16, &value); |
103 | if (ret != -EINVAL) { | 101 | if (ret < 0) |
104 | 102 | return ret; | |
105 | if (value & 0xFFFF0000) { | ||
106 | amd64_warn("%s: invalid EccVector: 0x%lx\n", | ||
107 | __func__, value); | ||
108 | return -EINVAL; | ||
109 | } | ||
110 | 103 | ||
111 | pvt->injection.bit_map = (u32) value; | 104 | if (value & 0xFFFF0000) { |
112 | return count; | 105 | amd64_warn("%s: invalid EccVector: 0x%lx\n", __func__, value); |
106 | return -EINVAL; | ||
113 | } | 107 | } |
114 | return ret; | 108 | |
109 | pvt->injection.bit_map = (u32) value; | ||
110 | return count; | ||
115 | } | 111 | } |
116 | 112 | ||
117 | /* | 113 | /* |
@@ -126,28 +122,25 @@ static ssize_t amd64_inject_read_store(struct device *dev, | |||
126 | struct amd64_pvt *pvt = mci->pvt_info; | 122 | struct amd64_pvt *pvt = mci->pvt_info; |
127 | unsigned long value; | 123 | unsigned long value; |
128 | u32 section, word_bits; | 124 | u32 section, word_bits; |
129 | int ret = 0; | 125 | int ret; |
130 | 126 | ||
131 | ret = strict_strtoul(data, 10, &value); | 127 | ret = strict_strtoul(data, 10, &value); |
132 | if (ret != -EINVAL) { | 128 | if (ret < 0) |
129 | return ret; | ||
133 | 130 | ||
134 | /* Form value to choose 16-byte section of cacheline */ | 131 | /* Form value to choose 16-byte section of cacheline */ |
135 | section = F10_NB_ARRAY_DRAM_ECC | | 132 | section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section); |
136 | SET_NB_ARRAY_ADDRESS(pvt->injection.section); | ||
137 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); | ||
138 | 133 | ||
139 | word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word, | 134 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); |
140 | pvt->injection.bit_map); | ||
141 | 135 | ||
142 | /* Issue 'word' and 'bit' along with the READ request */ | 136 | word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection); |
143 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); | ||
144 | 137 | ||
145 | edac_dbg(0, "section=0x%x word_bits=0x%x\n", | 138 | /* Issue 'word' and 'bit' along with the READ request */ |
146 | section, word_bits); | 139 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); |
147 | 140 | ||
148 | return count; | 141 | edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits); |
149 | } | 142 | |
150 | return ret; | 143 | return count; |
151 | } | 144 | } |
152 | 145 | ||
153 | /* | 146 | /* |
@@ -162,28 +155,25 @@ static ssize_t amd64_inject_write_store(struct device *dev, | |||
162 | struct amd64_pvt *pvt = mci->pvt_info; | 155 | struct amd64_pvt *pvt = mci->pvt_info; |
163 | unsigned long value; | 156 | unsigned long value; |
164 | u32 section, word_bits; | 157 | u32 section, word_bits; |
165 | int ret = 0; | 158 | int ret; |
166 | 159 | ||
167 | ret = strict_strtoul(data, 10, &value); | 160 | ret = strict_strtoul(data, 10, &value); |
168 | if (ret != -EINVAL) { | 161 | if (ret < 0) |
162 | return ret; | ||
169 | 163 | ||
170 | /* Form value to choose 16-byte section of cacheline */ | 164 | /* Form value to choose 16-byte section of cacheline */ |
171 | section = F10_NB_ARRAY_DRAM_ECC | | 165 | section = F10_NB_ARRAY_DRAM | SET_NB_ARRAY_ADDR(pvt->injection.section); |
172 | SET_NB_ARRAY_ADDRESS(pvt->injection.section); | ||
173 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); | ||
174 | 166 | ||
175 | word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word, | 167 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); |
176 | pvt->injection.bit_map); | ||
177 | 168 | ||
178 | /* Issue 'word' and 'bit' along with the READ request */ | 169 | word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection); |
179 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); | ||
180 | 170 | ||
181 | edac_dbg(0, "section=0x%x word_bits=0x%x\n", | 171 | /* Issue 'word' and 'bit' along with the READ request */ |
182 | section, word_bits); | 172 | amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); |
183 | 173 | ||
184 | return count; | 174 | edac_dbg(0, "section=0x%x word_bits=0x%x\n", section, word_bits); |
185 | } | 175 | |
186 | return ret; | 176 | return count; |
187 | } | 177 | } |
188 | 178 | ||
189 | /* | 179 | /* |