1*424fb153SAndroid Build Coastguard Worker // Copyright 2008 Google Inc. All Rights Reserved.
2*424fb153SAndroid Build Coastguard Worker
3*424fb153SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*424fb153SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*424fb153SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*424fb153SAndroid Build Coastguard Worker
7*424fb153SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*424fb153SAndroid Build Coastguard Worker
9*424fb153SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*424fb153SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*424fb153SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*424fb153SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*424fb153SAndroid Build Coastguard Worker // limitations under the License.
14*424fb153SAndroid Build Coastguard Worker
15*424fb153SAndroid Build Coastguard Worker // error_diag.cc: Collects device errors for analysis to more accurately
16*424fb153SAndroid Build Coastguard Worker // pin-point failed component.
17*424fb153SAndroid Build Coastguard Worker
18*424fb153SAndroid Build Coastguard Worker #include <set>
19*424fb153SAndroid Build Coastguard Worker #include <list>
20*424fb153SAndroid Build Coastguard Worker #include <map>
21*424fb153SAndroid Build Coastguard Worker
22*424fb153SAndroid Build Coastguard Worker // This file must work with autoconf on its public version,
23*424fb153SAndroid Build Coastguard Worker // so these includes are correct.
24*424fb153SAndroid Build Coastguard Worker #include "error_diag.h"
25*424fb153SAndroid Build Coastguard Worker #include "sattypes.h"
26*424fb153SAndroid Build Coastguard Worker
27*424fb153SAndroid Build Coastguard Worker
28*424fb153SAndroid Build Coastguard Worker // DeviceTree constructor.
DeviceTree(string name)29*424fb153SAndroid Build Coastguard Worker DeviceTree::DeviceTree(string name)
30*424fb153SAndroid Build Coastguard Worker : parent_(0), name_(name) {
31*424fb153SAndroid Build Coastguard Worker pthread_mutex_init(&device_tree_mutex_, NULL);
32*424fb153SAndroid Build Coastguard Worker }
33*424fb153SAndroid Build Coastguard Worker
34*424fb153SAndroid Build Coastguard Worker // DeviceTree destructor.
~DeviceTree()35*424fb153SAndroid Build Coastguard Worker DeviceTree::~DeviceTree() {
36*424fb153SAndroid Build Coastguard Worker // Deallocate subtree devices.
37*424fb153SAndroid Build Coastguard Worker for (std::map<string, DeviceTree*>::iterator itr = subdevices_.begin();
38*424fb153SAndroid Build Coastguard Worker itr != subdevices_.end();
39*424fb153SAndroid Build Coastguard Worker ++itr) {
40*424fb153SAndroid Build Coastguard Worker delete itr->second;
41*424fb153SAndroid Build Coastguard Worker }
42*424fb153SAndroid Build Coastguard Worker // Deallocate device errors.
43*424fb153SAndroid Build Coastguard Worker for (std::list<ErrorInstance*>::iterator itr = errors_.begin();
44*424fb153SAndroid Build Coastguard Worker itr != errors_.end();
45*424fb153SAndroid Build Coastguard Worker ++itr) {
46*424fb153SAndroid Build Coastguard Worker delete (*itr);
47*424fb153SAndroid Build Coastguard Worker }
48*424fb153SAndroid Build Coastguard Worker pthread_mutex_destroy(&device_tree_mutex_);
49*424fb153SAndroid Build Coastguard Worker }
50*424fb153SAndroid Build Coastguard Worker
51*424fb153SAndroid Build Coastguard Worker // Atomically find named device in sub device tree.
52*424fb153SAndroid Build Coastguard Worker // Returns 0 if not found
FindInSubTree(string name)53*424fb153SAndroid Build Coastguard Worker DeviceTree *DeviceTree::FindInSubTree(string name) {
54*424fb153SAndroid Build Coastguard Worker DeviceTree *ret;
55*424fb153SAndroid Build Coastguard Worker pthread_mutex_lock(&device_tree_mutex_);
56*424fb153SAndroid Build Coastguard Worker ret = UnlockedFindInSubTree(name);
57*424fb153SAndroid Build Coastguard Worker pthread_mutex_unlock(&device_tree_mutex_);
58*424fb153SAndroid Build Coastguard Worker return ret;
59*424fb153SAndroid Build Coastguard Worker }
60*424fb153SAndroid Build Coastguard Worker
61*424fb153SAndroid Build Coastguard Worker // Find named device in sub device tree (Non-atomic).
62*424fb153SAndroid Build Coastguard Worker // Returns 0 if not found
UnlockedFindInSubTree(string name)63*424fb153SAndroid Build Coastguard Worker DeviceTree *DeviceTree::UnlockedFindInSubTree(string name) {
64*424fb153SAndroid Build Coastguard Worker std::map<string, DeviceTree*>::iterator itr = subdevices_.find(name);
65*424fb153SAndroid Build Coastguard Worker if (itr != subdevices_.end()) {
66*424fb153SAndroid Build Coastguard Worker return itr->second;
67*424fb153SAndroid Build Coastguard Worker } else {
68*424fb153SAndroid Build Coastguard Worker // Search sub-tree.
69*424fb153SAndroid Build Coastguard Worker for (std::map<string, DeviceTree*>::iterator itr = subdevices_.begin();
70*424fb153SAndroid Build Coastguard Worker itr != subdevices_.end();
71*424fb153SAndroid Build Coastguard Worker ++itr) {
72*424fb153SAndroid Build Coastguard Worker DeviceTree *result = itr->second->UnlockedFindInSubTree(name);
73*424fb153SAndroid Build Coastguard Worker if (result != 0)
74*424fb153SAndroid Build Coastguard Worker return result;
75*424fb153SAndroid Build Coastguard Worker }
76*424fb153SAndroid Build Coastguard Worker return 0;
77*424fb153SAndroid Build Coastguard Worker }
78*424fb153SAndroid Build Coastguard Worker }
79*424fb153SAndroid Build Coastguard Worker
80*424fb153SAndroid Build Coastguard Worker // Atomically add error instance to device.
AddErrorInstance(ErrorInstance * error_instance)81*424fb153SAndroid Build Coastguard Worker void DeviceTree::AddErrorInstance(ErrorInstance *error_instance) {
82*424fb153SAndroid Build Coastguard Worker pthread_mutex_lock(&device_tree_mutex_);
83*424fb153SAndroid Build Coastguard Worker errors_.push_back(error_instance);
84*424fb153SAndroid Build Coastguard Worker pthread_mutex_unlock(&device_tree_mutex_);
85*424fb153SAndroid Build Coastguard Worker }
86*424fb153SAndroid Build Coastguard Worker
87*424fb153SAndroid Build Coastguard Worker // Find or add queried device as necessary.
FindOrAddDevice(string name)88*424fb153SAndroid Build Coastguard Worker DeviceTree *DeviceTree::FindOrAddDevice(string name) {
89*424fb153SAndroid Build Coastguard Worker // Assume named device does not exist and try to insert the device anyway.
90*424fb153SAndroid Build Coastguard Worker // No-op if named device already exists.
91*424fb153SAndroid Build Coastguard Worker InsertSubDevice(name);
92*424fb153SAndroid Build Coastguard Worker // Find and return sub device pointer.
93*424fb153SAndroid Build Coastguard Worker return FindInSubTree(name);
94*424fb153SAndroid Build Coastguard Worker }
95*424fb153SAndroid Build Coastguard Worker
96*424fb153SAndroid Build Coastguard Worker // Pretty prints device tree.
PrettyPrint(string spacer)97*424fb153SAndroid Build Coastguard Worker void DeviceTree::PrettyPrint(string spacer) {
98*424fb153SAndroid Build Coastguard Worker for (std::map<string, DeviceTree*>::iterator itr = subdevices_.begin();
99*424fb153SAndroid Build Coastguard Worker itr != subdevices_.end();
100*424fb153SAndroid Build Coastguard Worker ++itr) {
101*424fb153SAndroid Build Coastguard Worker printf("%s%s\n", spacer.c_str(), itr->first.c_str());
102*424fb153SAndroid Build Coastguard Worker itr->second->PrettyPrint(spacer+spacer);
103*424fb153SAndroid Build Coastguard Worker }
104*424fb153SAndroid Build Coastguard Worker }
105*424fb153SAndroid Build Coastguard Worker
106*424fb153SAndroid Build Coastguard Worker // Atomically add sub device.
107*424fb153SAndroid Build Coastguard Worker // No-op if named device already exists.
InsertSubDevice(string name)108*424fb153SAndroid Build Coastguard Worker void DeviceTree::InsertSubDevice(string name) {
109*424fb153SAndroid Build Coastguard Worker pthread_mutex_lock(&device_tree_mutex_);
110*424fb153SAndroid Build Coastguard Worker if (UnlockedFindInSubTree(name) != 0) {
111*424fb153SAndroid Build Coastguard Worker pthread_mutex_unlock(&device_tree_mutex_);
112*424fb153SAndroid Build Coastguard Worker return;
113*424fb153SAndroid Build Coastguard Worker }
114*424fb153SAndroid Build Coastguard Worker subdevices_[name] = new DeviceTree(name);
115*424fb153SAndroid Build Coastguard Worker subdevices_[name]->parent_ = this;
116*424fb153SAndroid Build Coastguard Worker pthread_mutex_unlock(&device_tree_mutex_);
117*424fb153SAndroid Build Coastguard Worker }
118*424fb153SAndroid Build Coastguard Worker
119*424fb153SAndroid Build Coastguard Worker
120*424fb153SAndroid Build Coastguard Worker // Returns true of any error associated with this device is fatal.
KnownBad()121*424fb153SAndroid Build Coastguard Worker bool DeviceTree::KnownBad() {
122*424fb153SAndroid Build Coastguard Worker pthread_mutex_lock(&device_tree_mutex_);
123*424fb153SAndroid Build Coastguard Worker for (std::list<ErrorInstance*>::iterator itr = errors_.begin();
124*424fb153SAndroid Build Coastguard Worker itr != errors_.end();
125*424fb153SAndroid Build Coastguard Worker ++itr) {
126*424fb153SAndroid Build Coastguard Worker if ((*itr)->severity_ == SAT_ERROR_FATAL) {
127*424fb153SAndroid Build Coastguard Worker pthread_mutex_unlock(&device_tree_mutex_);
128*424fb153SAndroid Build Coastguard Worker return true;
129*424fb153SAndroid Build Coastguard Worker }
130*424fb153SAndroid Build Coastguard Worker }
131*424fb153SAndroid Build Coastguard Worker pthread_mutex_unlock(&device_tree_mutex_);
132*424fb153SAndroid Build Coastguard Worker return false;
133*424fb153SAndroid Build Coastguard Worker }
134*424fb153SAndroid Build Coastguard Worker
135*424fb153SAndroid Build Coastguard Worker
136*424fb153SAndroid Build Coastguard Worker // ErrorDiag constructor.
ErrorDiag()137*424fb153SAndroid Build Coastguard Worker ErrorDiag::ErrorDiag() {
138*424fb153SAndroid Build Coastguard Worker os_ = 0;
139*424fb153SAndroid Build Coastguard Worker system_tree_root_ = 0;
140*424fb153SAndroid Build Coastguard Worker }
141*424fb153SAndroid Build Coastguard Worker
142*424fb153SAndroid Build Coastguard Worker // ErrorDiag destructor.
~ErrorDiag()143*424fb153SAndroid Build Coastguard Worker ErrorDiag::~ErrorDiag() {
144*424fb153SAndroid Build Coastguard Worker if (system_tree_root_)
145*424fb153SAndroid Build Coastguard Worker delete system_tree_root_;
146*424fb153SAndroid Build Coastguard Worker }
147*424fb153SAndroid Build Coastguard Worker
148*424fb153SAndroid Build Coastguard Worker // Set platform specific handle and initialize device tree.
149*424fb153SAndroid Build Coastguard Worker // Returns false on error. true otherwise.
set_os(OsLayer * os)150*424fb153SAndroid Build Coastguard Worker bool ErrorDiag::set_os(OsLayer *os) {
151*424fb153SAndroid Build Coastguard Worker os_ = os;
152*424fb153SAndroid Build Coastguard Worker return(InitializeDeviceTree());
153*424fb153SAndroid Build Coastguard Worker }
154*424fb153SAndroid Build Coastguard Worker
155*424fb153SAndroid Build Coastguard Worker // Create and initialize system device tree.
156*424fb153SAndroid Build Coastguard Worker // Returns false on error. true otherwise.
InitializeDeviceTree()157*424fb153SAndroid Build Coastguard Worker bool ErrorDiag::InitializeDeviceTree() {
158*424fb153SAndroid Build Coastguard Worker system_tree_root_ = new DeviceTree("system_root");
159*424fb153SAndroid Build Coastguard Worker if (!system_tree_root_)
160*424fb153SAndroid Build Coastguard Worker return false;
161*424fb153SAndroid Build Coastguard Worker return true;
162*424fb153SAndroid Build Coastguard Worker }
163*424fb153SAndroid Build Coastguard Worker
164*424fb153SAndroid Build Coastguard Worker // Logs info about a CECC.
165*424fb153SAndroid Build Coastguard Worker // Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise.
AddCeccError(string dimm_string)166*424fb153SAndroid Build Coastguard Worker int ErrorDiag::AddCeccError(string dimm_string) {
167*424fb153SAndroid Build Coastguard Worker DeviceTree *dimm_device = system_tree_root_->FindOrAddDevice(dimm_string);
168*424fb153SAndroid Build Coastguard Worker ECCErrorInstance *error = new ECCErrorInstance;
169*424fb153SAndroid Build Coastguard Worker if (!error)
170*424fb153SAndroid Build Coastguard Worker return -1;
171*424fb153SAndroid Build Coastguard Worker error->severity_ = SAT_ERROR_CORRECTABLE;
172*424fb153SAndroid Build Coastguard Worker dimm_device->AddErrorInstance(error);
173*424fb153SAndroid Build Coastguard Worker return 0;
174*424fb153SAndroid Build Coastguard Worker }
175*424fb153SAndroid Build Coastguard Worker
176*424fb153SAndroid Build Coastguard Worker // Logs info about a UECC.
177*424fb153SAndroid Build Coastguard Worker // Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise.
AddUeccError(string dimm_string)178*424fb153SAndroid Build Coastguard Worker int ErrorDiag::AddUeccError(string dimm_string) {
179*424fb153SAndroid Build Coastguard Worker DeviceTree *dimm_device = system_tree_root_->FindOrAddDevice(dimm_string);
180*424fb153SAndroid Build Coastguard Worker ECCErrorInstance *error = new ECCErrorInstance;
181*424fb153SAndroid Build Coastguard Worker if (!error)
182*424fb153SAndroid Build Coastguard Worker return -1;
183*424fb153SAndroid Build Coastguard Worker error->severity_ = SAT_ERROR_FATAL;
184*424fb153SAndroid Build Coastguard Worker dimm_device->AddErrorInstance(error);
185*424fb153SAndroid Build Coastguard Worker return 0;
186*424fb153SAndroid Build Coastguard Worker }
187*424fb153SAndroid Build Coastguard Worker
188*424fb153SAndroid Build Coastguard Worker // Logs info about a miscompare.
189*424fb153SAndroid Build Coastguard Worker // Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise.
AddMiscompareError(string dimm_string,uint64 addr,int count)190*424fb153SAndroid Build Coastguard Worker int ErrorDiag::AddMiscompareError(string dimm_string, uint64 addr, int count) {
191*424fb153SAndroid Build Coastguard Worker DeviceTree *dimm_device = system_tree_root_->FindOrAddDevice(dimm_string);
192*424fb153SAndroid Build Coastguard Worker MiscompareErrorInstance *error = new MiscompareErrorInstance;
193*424fb153SAndroid Build Coastguard Worker if (!error)
194*424fb153SAndroid Build Coastguard Worker return -1;
195*424fb153SAndroid Build Coastguard Worker error->severity_ = SAT_ERROR_FATAL;
196*424fb153SAndroid Build Coastguard Worker error->addr_ = addr;
197*424fb153SAndroid Build Coastguard Worker dimm_device->AddErrorInstance(error);
198*424fb153SAndroid Build Coastguard Worker os_->ErrorReport(dimm_string.c_str(), "miscompare", count);
199*424fb153SAndroid Build Coastguard Worker return 1;
200*424fb153SAndroid Build Coastguard Worker }
201*424fb153SAndroid Build Coastguard Worker
202*424fb153SAndroid Build Coastguard Worker // Utility Function to translate a virtual address to DIMM number.
203*424fb153SAndroid Build Coastguard Worker // Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise.
AddressToDimmString(OsLayer * os,void * addr,int offset)204*424fb153SAndroid Build Coastguard Worker string ErrorDiag::AddressToDimmString(OsLayer *os, void *addr, int offset) {
205*424fb153SAndroid Build Coastguard Worker char dimm_string[256] = "";
206*424fb153SAndroid Build Coastguard Worker char *vbyteaddr = reinterpret_cast<char*>(addr) + offset;
207*424fb153SAndroid Build Coastguard Worker uint64 paddr = os->VirtualToPhysical(vbyteaddr);
208*424fb153SAndroid Build Coastguard Worker os->FindDimm(paddr, dimm_string, sizeof(dimm_string));
209*424fb153SAndroid Build Coastguard Worker return string(dimm_string);
210*424fb153SAndroid Build Coastguard Worker }
211*424fb153SAndroid Build Coastguard Worker
212*424fb153SAndroid Build Coastguard Worker // Info about a miscompare from a drive.
213*424fb153SAndroid Build Coastguard Worker // Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise.
AddHDDMiscompareError(string devicename,int block,int offset,void * src_addr,void * dst_addr)214*424fb153SAndroid Build Coastguard Worker int ErrorDiag::AddHDDMiscompareError(string devicename, int block, int offset,
215*424fb153SAndroid Build Coastguard Worker void *src_addr, void *dst_addr) {
216*424fb153SAndroid Build Coastguard Worker bool mask_hdd_error = false;
217*424fb153SAndroid Build Coastguard Worker
218*424fb153SAndroid Build Coastguard Worker HDDMiscompareErrorInstance *error = new HDDMiscompareErrorInstance;
219*424fb153SAndroid Build Coastguard Worker if (!error)
220*424fb153SAndroid Build Coastguard Worker return -1;
221*424fb153SAndroid Build Coastguard Worker
222*424fb153SAndroid Build Coastguard Worker error->addr_ = reinterpret_cast<uint64>(src_addr);
223*424fb153SAndroid Build Coastguard Worker error->addr2_ = reinterpret_cast<uint64>(dst_addr);
224*424fb153SAndroid Build Coastguard Worker error->offset_ = offset;
225*424fb153SAndroid Build Coastguard Worker error->block_ = block;
226*424fb153SAndroid Build Coastguard Worker
227*424fb153SAndroid Build Coastguard Worker string src_dimm = AddressToDimmString(os_, src_addr, offset);
228*424fb153SAndroid Build Coastguard Worker string dst_dimm = AddressToDimmString(os_, dst_addr, offset);
229*424fb153SAndroid Build Coastguard Worker
230*424fb153SAndroid Build Coastguard Worker // DIMM name look up success
231*424fb153SAndroid Build Coastguard Worker if (src_dimm.compare("DIMM Unknown")) {
232*424fb153SAndroid Build Coastguard Worker // Add src DIMM as possible miscompare cause.
233*424fb153SAndroid Build Coastguard Worker DeviceTree *src_dimm_dev = system_tree_root_->FindOrAddDevice(src_dimm);
234*424fb153SAndroid Build Coastguard Worker error->causes_.insert(src_dimm_dev);
235*424fb153SAndroid Build Coastguard Worker if (src_dimm_dev->KnownBad()) {
236*424fb153SAndroid Build Coastguard Worker mask_hdd_error = true;
237*424fb153SAndroid Build Coastguard Worker logprintf(5, "Log: supressed %s miscompare report: "
238*424fb153SAndroid Build Coastguard Worker "known bad source: %s\n", devicename.c_str(), src_dimm.c_str());
239*424fb153SAndroid Build Coastguard Worker }
240*424fb153SAndroid Build Coastguard Worker }
241*424fb153SAndroid Build Coastguard Worker if (dst_dimm.compare("DIMM Unknown")) {
242*424fb153SAndroid Build Coastguard Worker // Add dst DIMM as possible miscompare cause.
243*424fb153SAndroid Build Coastguard Worker DeviceTree *dst_dimm_dev = system_tree_root_->FindOrAddDevice(dst_dimm);
244*424fb153SAndroid Build Coastguard Worker error->causes_.insert(dst_dimm_dev);
245*424fb153SAndroid Build Coastguard Worker if (dst_dimm_dev->KnownBad()) {
246*424fb153SAndroid Build Coastguard Worker mask_hdd_error = true;
247*424fb153SAndroid Build Coastguard Worker logprintf(5, "Log: supressed %s miscompare report: "
248*424fb153SAndroid Build Coastguard Worker "known bad destination: %s\n", devicename.c_str(),
249*424fb153SAndroid Build Coastguard Worker dst_dimm.c_str());
250*424fb153SAndroid Build Coastguard Worker }
251*424fb153SAndroid Build Coastguard Worker }
252*424fb153SAndroid Build Coastguard Worker
253*424fb153SAndroid Build Coastguard Worker DeviceTree *hdd_dev = system_tree_root_->FindOrAddDevice(devicename);
254*424fb153SAndroid Build Coastguard Worker hdd_dev->AddErrorInstance(error);
255*424fb153SAndroid Build Coastguard Worker
256*424fb153SAndroid Build Coastguard Worker // HDD error was not masked by bad DIMMs: report bad HDD.
257*424fb153SAndroid Build Coastguard Worker if (!mask_hdd_error) {
258*424fb153SAndroid Build Coastguard Worker os_->ErrorReport(devicename.c_str(), "miscompare", 1);
259*424fb153SAndroid Build Coastguard Worker error->severity_ = SAT_ERROR_FATAL;
260*424fb153SAndroid Build Coastguard Worker return 1;
261*424fb153SAndroid Build Coastguard Worker }
262*424fb153SAndroid Build Coastguard Worker return 0;
263*424fb153SAndroid Build Coastguard Worker }
264*424fb153SAndroid Build Coastguard Worker
265*424fb153SAndroid Build Coastguard Worker // Info about a sector tag miscompare from a drive.
266*424fb153SAndroid Build Coastguard Worker // Returns -1 on error, 1 if diagnoser reports error externally; 0 otherwise.
AddHDDSectorTagError(string devicename,int block,int offset,int sector,void * src_addr,void * dst_addr)267*424fb153SAndroid Build Coastguard Worker int ErrorDiag::AddHDDSectorTagError(string devicename, int block, int offset,
268*424fb153SAndroid Build Coastguard Worker int sector, void *src_addr,
269*424fb153SAndroid Build Coastguard Worker void *dst_addr) {
270*424fb153SAndroid Build Coastguard Worker bool mask_hdd_error = false;
271*424fb153SAndroid Build Coastguard Worker
272*424fb153SAndroid Build Coastguard Worker HDDSectorTagErrorInstance *error = new HDDSectorTagErrorInstance;
273*424fb153SAndroid Build Coastguard Worker if (!error)
274*424fb153SAndroid Build Coastguard Worker return -1;
275*424fb153SAndroid Build Coastguard Worker
276*424fb153SAndroid Build Coastguard Worker error->addr_ = reinterpret_cast<uint64>(src_addr);
277*424fb153SAndroid Build Coastguard Worker error->addr2_ = reinterpret_cast<uint64>(dst_addr);
278*424fb153SAndroid Build Coastguard Worker error->sector_ = sector;
279*424fb153SAndroid Build Coastguard Worker error->block_ = block;
280*424fb153SAndroid Build Coastguard Worker
281*424fb153SAndroid Build Coastguard Worker string src_dimm = AddressToDimmString(os_, src_addr, offset);
282*424fb153SAndroid Build Coastguard Worker string dst_dimm = AddressToDimmString(os_, dst_addr, offset);
283*424fb153SAndroid Build Coastguard Worker
284*424fb153SAndroid Build Coastguard Worker // DIMM name look up success
285*424fb153SAndroid Build Coastguard Worker if (src_dimm.compare("DIMM Unknown")) {
286*424fb153SAndroid Build Coastguard Worker // Add src DIMM as possible miscompare cause.
287*424fb153SAndroid Build Coastguard Worker DeviceTree *src_dimm_dev = system_tree_root_->FindOrAddDevice(src_dimm);
288*424fb153SAndroid Build Coastguard Worker error->causes_.insert(src_dimm_dev);
289*424fb153SAndroid Build Coastguard Worker if (src_dimm_dev->KnownBad()) {
290*424fb153SAndroid Build Coastguard Worker mask_hdd_error = true;
291*424fb153SAndroid Build Coastguard Worker logprintf(5, "Log: supressed %s sector tag error report: "
292*424fb153SAndroid Build Coastguard Worker "known bad source: %s\n", devicename.c_str(), src_dimm.c_str());
293*424fb153SAndroid Build Coastguard Worker }
294*424fb153SAndroid Build Coastguard Worker }
295*424fb153SAndroid Build Coastguard Worker if (dst_dimm.compare("DIMM Unknown")) {
296*424fb153SAndroid Build Coastguard Worker // Add dst DIMM as possible miscompare cause.
297*424fb153SAndroid Build Coastguard Worker DeviceTree *dst_dimm_dev = system_tree_root_->FindOrAddDevice(dst_dimm);
298*424fb153SAndroid Build Coastguard Worker error->causes_.insert(dst_dimm_dev);
299*424fb153SAndroid Build Coastguard Worker if (dst_dimm_dev->KnownBad()) {
300*424fb153SAndroid Build Coastguard Worker mask_hdd_error = true;
301*424fb153SAndroid Build Coastguard Worker logprintf(5, "Log: supressed %s sector tag error report: "
302*424fb153SAndroid Build Coastguard Worker "known bad destination: %s\n", devicename.c_str(),
303*424fb153SAndroid Build Coastguard Worker dst_dimm.c_str());
304*424fb153SAndroid Build Coastguard Worker }
305*424fb153SAndroid Build Coastguard Worker }
306*424fb153SAndroid Build Coastguard Worker
307*424fb153SAndroid Build Coastguard Worker DeviceTree *hdd_dev = system_tree_root_->FindOrAddDevice(devicename);
308*424fb153SAndroid Build Coastguard Worker hdd_dev->AddErrorInstance(error);
309*424fb153SAndroid Build Coastguard Worker
310*424fb153SAndroid Build Coastguard Worker // HDD error was not masked by bad DIMMs: report bad HDD.
311*424fb153SAndroid Build Coastguard Worker if (!mask_hdd_error) {
312*424fb153SAndroid Build Coastguard Worker os_->ErrorReport(devicename.c_str(), "sector", 1);
313*424fb153SAndroid Build Coastguard Worker error->severity_ = SAT_ERROR_FATAL;
314*424fb153SAndroid Build Coastguard Worker return 1;
315*424fb153SAndroid Build Coastguard Worker }
316*424fb153SAndroid Build Coastguard Worker return 0;
317*424fb153SAndroid Build Coastguard Worker }
318