Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.6-rc3 235 lines 6.4 kB view raw
1#include "amd64_edac.h" 2 3static ssize_t amd64_inject_section_show(struct device *dev, 4 struct device_attribute *mattr, 5 char *buf) 6{ 7 struct mem_ctl_info *mci = to_mci(dev); 8 struct amd64_pvt *pvt = mci->pvt_info; 9 return sprintf(buf, "0x%x\n", pvt->injection.section); 10} 11 12/* 13 * store error injection section value which refers to one of 4 16-byte sections 14 * within a 64-byte cacheline 15 * 16 * range: 0..3 17 */ 18static ssize_t amd64_inject_section_store(struct device *dev, 19 struct device_attribute *mattr, 20 const char *data, size_t count) 21{ 22 struct mem_ctl_info *mci = to_mci(dev); 23 struct amd64_pvt *pvt = mci->pvt_info; 24 unsigned long value; 25 int ret = 0; 26 27 ret = strict_strtoul(data, 10, &value); 28 if (ret != -EINVAL) { 29 30 if (value > 3) { 31 amd64_warn("%s: invalid section 0x%lx\n", __func__, value); 32 return -EINVAL; 33 } 34 35 pvt->injection.section = (u32) value; 36 return count; 37 } 38 return ret; 39} 40 41static ssize_t amd64_inject_word_show(struct device *dev, 42 struct device_attribute *mattr, 43 char *buf) 44{ 45 struct mem_ctl_info *mci = to_mci(dev); 46 struct amd64_pvt *pvt = mci->pvt_info; 47 return sprintf(buf, "0x%x\n", pvt->injection.word); 48} 49 50/* 51 * store error injection word value which refers to one of 9 16-bit word of the 52 * 16-byte (128-bit + ECC bits) section 53 * 54 * range: 0..8 55 */ 56static ssize_t amd64_inject_word_store(struct device *dev, 57 struct device_attribute *mattr, 58 const char *data, size_t count) 59{ 60 struct mem_ctl_info *mci = to_mci(dev); 61 struct amd64_pvt *pvt = mci->pvt_info; 62 unsigned long value; 63 int ret = 0; 64 65 ret = strict_strtoul(data, 10, &value); 66 if (ret != -EINVAL) { 67 68 if (value > 8) { 69 amd64_warn("%s: invalid word 0x%lx\n", __func__, value); 70 return -EINVAL; 71 } 72 73 pvt->injection.word = (u32) value; 74 return count; 75 } 76 return ret; 77} 78 79static ssize_t amd64_inject_ecc_vector_show(struct device *dev, 80 struct device_attribute *mattr, 81 char *buf) 82{ 83 struct mem_ctl_info *mci = to_mci(dev); 84 struct amd64_pvt *pvt = mci->pvt_info; 85 return sprintf(buf, "0x%x\n", pvt->injection.bit_map); 86} 87 88/* 89 * store 16 bit error injection vector which enables injecting errors to the 90 * corresponding bit within the error injection word above. When used during a 91 * DRAM ECC read, it holds the contents of the of the DRAM ECC bits. 92 */ 93static ssize_t amd64_inject_ecc_vector_store(struct device *dev, 94 struct device_attribute *mattr, 95 const char *data, size_t count) 96{ 97 struct mem_ctl_info *mci = to_mci(dev); 98 struct amd64_pvt *pvt = mci->pvt_info; 99 unsigned long value; 100 int ret = 0; 101 102 ret = strict_strtoul(data, 16, &value); 103 if (ret != -EINVAL) { 104 105 if (value & 0xFFFF0000) { 106 amd64_warn("%s: invalid EccVector: 0x%lx\n", 107 __func__, value); 108 return -EINVAL; 109 } 110 111 pvt->injection.bit_map = (u32) value; 112 return count; 113 } 114 return ret; 115} 116 117/* 118 * Do a DRAM ECC read. Assemble staged values in the pvt area, format into 119 * fields needed by the injection registers and read the NB Array Data Port. 120 */ 121static ssize_t amd64_inject_read_store(struct device *dev, 122 struct device_attribute *mattr, 123 const char *data, size_t count) 124{ 125 struct mem_ctl_info *mci = to_mci(dev); 126 struct amd64_pvt *pvt = mci->pvt_info; 127 unsigned long value; 128 u32 section, word_bits; 129 int ret = 0; 130 131 ret = strict_strtoul(data, 10, &value); 132 if (ret != -EINVAL) { 133 134 /* Form value to choose 16-byte section of cacheline */ 135 section = F10_NB_ARRAY_DRAM_ECC | 136 SET_NB_ARRAY_ADDRESS(pvt->injection.section); 137 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); 138 139 word_bits = SET_NB_DRAM_INJECTION_READ(pvt->injection.word, 140 pvt->injection.bit_map); 141 142 /* Issue 'word' and 'bit' along with the READ request */ 143 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); 144 145 edac_dbg(0, "section=0x%x word_bits=0x%x\n", 146 section, word_bits); 147 148 return count; 149 } 150 return ret; 151} 152 153/* 154 * Do a DRAM ECC write. Assemble staged values in the pvt area and format into 155 * fields needed by the injection registers. 156 */ 157static ssize_t amd64_inject_write_store(struct device *dev, 158 struct device_attribute *mattr, 159 const char *data, size_t count) 160{ 161 struct mem_ctl_info *mci = to_mci(dev); 162 struct amd64_pvt *pvt = mci->pvt_info; 163 unsigned long value; 164 u32 section, word_bits; 165 int ret = 0; 166 167 ret = strict_strtoul(data, 10, &value); 168 if (ret != -EINVAL) { 169 170 /* Form value to choose 16-byte section of cacheline */ 171 section = F10_NB_ARRAY_DRAM_ECC | 172 SET_NB_ARRAY_ADDRESS(pvt->injection.section); 173 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_ADDR, section); 174 175 word_bits = SET_NB_DRAM_INJECTION_WRITE(pvt->injection.word, 176 pvt->injection.bit_map); 177 178 /* Issue 'word' and 'bit' along with the READ request */ 179 amd64_write_pci_cfg(pvt->F3, F10_NB_ARRAY_DATA, word_bits); 180 181 edac_dbg(0, "section=0x%x word_bits=0x%x\n", 182 section, word_bits); 183 184 return count; 185 } 186 return ret; 187} 188 189/* 190 * update NUM_INJ_ATTRS in case you add new members 191 */ 192 193static DEVICE_ATTR(inject_section, S_IRUGO | S_IWUSR, 194 amd64_inject_section_show, amd64_inject_section_store); 195static DEVICE_ATTR(inject_word, S_IRUGO | S_IWUSR, 196 amd64_inject_word_show, amd64_inject_word_store); 197static DEVICE_ATTR(inject_ecc_vector, S_IRUGO | S_IWUSR, 198 amd64_inject_ecc_vector_show, amd64_inject_ecc_vector_store); 199static DEVICE_ATTR(inject_write, S_IRUGO | S_IWUSR, 200 NULL, amd64_inject_write_store); 201static DEVICE_ATTR(inject_read, S_IRUGO | S_IWUSR, 202 NULL, amd64_inject_read_store); 203 204 205int amd64_create_sysfs_inject_files(struct mem_ctl_info *mci) 206{ 207 int rc; 208 209 rc = device_create_file(&mci->dev, &dev_attr_inject_section); 210 if (rc < 0) 211 return rc; 212 rc = device_create_file(&mci->dev, &dev_attr_inject_word); 213 if (rc < 0) 214 return rc; 215 rc = device_create_file(&mci->dev, &dev_attr_inject_ecc_vector); 216 if (rc < 0) 217 return rc; 218 rc = device_create_file(&mci->dev, &dev_attr_inject_write); 219 if (rc < 0) 220 return rc; 221 rc = device_create_file(&mci->dev, &dev_attr_inject_read); 222 if (rc < 0) 223 return rc; 224 225 return 0; 226} 227 228void amd64_remove_sysfs_inject_files(struct mem_ctl_info *mci) 229{ 230 device_remove_file(&mci->dev, &dev_attr_inject_section); 231 device_remove_file(&mci->dev, &dev_attr_inject_word); 232 device_remove_file(&mci->dev, &dev_attr_inject_ecc_vector); 233 device_remove_file(&mci->dev, &dev_attr_inject_write); 234 device_remove_file(&mci->dev, &dev_attr_inject_read); 235}