diff options
Diffstat (limited to 'drivers/edac/i82860_edac.c')
-rw-r--r-- | drivers/edac/i82860_edac.c | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/drivers/edac/i82860_edac.c b/drivers/edac/i82860_edac.c index e2c3b8bc097b..d196dcc850a8 100644 --- a/drivers/edac/i82860_edac.c +++ b/drivers/edac/i82860_edac.c | |||
@@ -133,15 +133,50 @@ static void i82860_check(struct mem_ctl_info *mci) | |||
133 | i82860_process_error_info(mci, &info, 1); | 133 | i82860_process_error_info(mci, &info, 1); |
134 | } | 134 | } |
135 | 135 | ||
136 | static int i82860_probe1(struct pci_dev *pdev, int dev_idx) | 136 | static void i82860_init_csrows(struct mem_ctl_info *mci, struct pci_dev *pdev) |
137 | { | 137 | { |
138 | int rc = -ENODEV; | ||
139 | int index; | ||
140 | struct mem_ctl_info *mci = NULL; | ||
141 | unsigned long last_cumul_size; | 138 | unsigned long last_cumul_size; |
142 | struct i82860_error_info discard; | 139 | u16 mchcfg_ddim; /* DRAM Data Integrity Mode 0=none, 2=edac */ |
140 | u16 value; | ||
141 | u32 cumul_size; | ||
142 | struct csrow_info *csrow; | ||
143 | int index; | ||
144 | |||
145 | pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim); | ||
146 | mchcfg_ddim = mchcfg_ddim & 0x180; | ||
147 | last_cumul_size = 0; | ||
148 | |||
149 | /* The group row boundary (GRA) reg values are boundary address | ||
150 | * for each DRAM row with a granularity of 16MB. GRA regs are | ||
151 | * cumulative; therefore GRA15 will contain the total memory contained | ||
152 | * in all eight rows. | ||
153 | */ | ||
154 | for (index = 0; index < mci->nr_csrows; index++) { | ||
155 | csrow = &mci->csrows[index]; | ||
156 | pci_read_config_word(pdev, I82860_GBA + index * 2, &value); | ||
157 | cumul_size = (value & I82860_GBA_MASK) << | ||
158 | (I82860_GBA_SHIFT - PAGE_SHIFT); | ||
159 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, | ||
160 | cumul_size); | ||
161 | |||
162 | if (cumul_size == last_cumul_size) | ||
163 | continue; /* not populated */ | ||
143 | 164 | ||
144 | u16 mchcfg_ddim; /* DRAM Data Integrity Mode 0=none,2=edac */ | 165 | csrow->first_page = last_cumul_size; |
166 | csrow->last_page = cumul_size - 1; | ||
167 | csrow->nr_pages = cumul_size - last_cumul_size; | ||
168 | last_cumul_size = cumul_size; | ||
169 | csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */ | ||
170 | csrow->mtype = MEM_RMBS; | ||
171 | csrow->dtype = DEV_UNKNOWN; | ||
172 | csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | static int i82860_probe1(struct pci_dev *pdev, int dev_idx) | ||
177 | { | ||
178 | struct mem_ctl_info *mci; | ||
179 | struct i82860_error_info discard; | ||
145 | 180 | ||
146 | /* RDRAM has channels but these don't map onto the abstractions that | 181 | /* RDRAM has channels but these don't map onto the abstractions that |
147 | edac uses. | 182 | edac uses. |
@@ -159,53 +194,15 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) | |||
159 | debugf3("%s(): init mci\n", __func__); | 194 | debugf3("%s(): init mci\n", __func__); |
160 | mci->dev = &pdev->dev; | 195 | mci->dev = &pdev->dev; |
161 | mci->mtype_cap = MEM_FLAG_DDR; | 196 | mci->mtype_cap = MEM_FLAG_DDR; |
162 | |||
163 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; | 197 | mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; |
164 | /* I"m not sure about this but I think that all RDRAM is SECDED */ | 198 | /* I"m not sure about this but I think that all RDRAM is SECDED */ |
165 | mci->edac_cap = EDAC_FLAG_SECDED; | 199 | mci->edac_cap = EDAC_FLAG_SECDED; |
166 | /* adjust FLAGS */ | ||
167 | |||
168 | mci->mod_name = EDAC_MOD_STR; | 200 | mci->mod_name = EDAC_MOD_STR; |
169 | mci->mod_ver = I82860_REVISION; | 201 | mci->mod_ver = I82860_REVISION; |
170 | mci->ctl_name = i82860_devs[dev_idx].ctl_name; | 202 | mci->ctl_name = i82860_devs[dev_idx].ctl_name; |
171 | mci->edac_check = i82860_check; | 203 | mci->edac_check = i82860_check; |
172 | mci->ctl_page_to_phys = NULL; | 204 | mci->ctl_page_to_phys = NULL; |
173 | 205 | i82860_init_csrows(mci, pdev); | |
174 | pci_read_config_word(pdev, I82860_MCHCFG, &mchcfg_ddim); | ||
175 | mchcfg_ddim = mchcfg_ddim & 0x180; | ||
176 | |||
177 | /* | ||
178 | * The group row boundary (GRA) reg values are boundary address | ||
179 | * for each DRAM row with a granularity of 16MB. GRA regs are | ||
180 | * cumulative; therefore GRA15 will contain the total memory contained | ||
181 | * in all eight rows. | ||
182 | */ | ||
183 | for (last_cumul_size = index = 0; index < mci->nr_csrows; index++) { | ||
184 | u16 value; | ||
185 | u32 cumul_size; | ||
186 | struct csrow_info *csrow = &mci->csrows[index]; | ||
187 | |||
188 | pci_read_config_word(pdev, I82860_GBA + index * 2, | ||
189 | &value); | ||
190 | |||
191 | cumul_size = (value & I82860_GBA_MASK) << | ||
192 | (I82860_GBA_SHIFT - PAGE_SHIFT); | ||
193 | debugf3("%s(): (%d) cumul_size 0x%x\n", __func__, index, | ||
194 | cumul_size); | ||
195 | |||
196 | if (cumul_size == last_cumul_size) | ||
197 | continue; /* not populated */ | ||
198 | |||
199 | csrow->first_page = last_cumul_size; | ||
200 | csrow->last_page = cumul_size - 1; | ||
201 | csrow->nr_pages = cumul_size - last_cumul_size; | ||
202 | last_cumul_size = cumul_size; | ||
203 | csrow->grain = 1 << 12; /* I82860_EAP has 4KiB reolution */ | ||
204 | csrow->mtype = MEM_RMBS; | ||
205 | csrow->dtype = DEV_UNKNOWN; | ||
206 | csrow->edac_mode = mchcfg_ddim ? EDAC_SECDED : EDAC_NONE; | ||
207 | } | ||
208 | |||
209 | i82860_get_error_info(mci, &discard); /* clear counters */ | 206 | i82860_get_error_info(mci, &discard); /* clear counters */ |
210 | 207 | ||
211 | /* Here we assume that we will never see multiple instances of this | 208 | /* Here we assume that we will never see multiple instances of this |
@@ -213,14 +210,17 @@ static int i82860_probe1(struct pci_dev *pdev, int dev_idx) | |||
213 | */ | 210 | */ |
214 | if (edac_mc_add_mc(mci,0)) { | 211 | if (edac_mc_add_mc(mci,0)) { |
215 | debugf3("%s(): failed edac_mc_add_mc()\n", __func__); | 212 | debugf3("%s(): failed edac_mc_add_mc()\n", __func__); |
216 | edac_mc_free(mci); | 213 | goto fail; |
217 | } else { | ||
218 | /* get this far and it's successful */ | ||
219 | debugf3("%s(): success\n", __func__); | ||
220 | rc = 0; | ||
221 | } | 214 | } |
222 | 215 | ||
223 | return rc; | 216 | /* get this far and it's successful */ |
217 | debugf3("%s(): success\n", __func__); | ||
218 | |||
219 | return 0; | ||
220 | |||
221 | fail: | ||
222 | edac_mc_free(mci); | ||
223 | return -ENODEV; | ||
224 | } | 224 | } |
225 | 225 | ||
226 | /* returns count (>= 0), or negative on error */ | 226 | /* returns count (>= 0), or negative on error */ |