The Pedigree Project  0.1
DeviceHashTree.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/machine/DeviceHashTree.h"
21 #include "pedigree/kernel/Log.h"
22 #include "pedigree/kernel/machine/Device.h"
23 #include "pedigree/kernel/utilities/StaticString.h"
24 #include "pedigree/kernel/utilities/sha1/sha1.h"
25 #include "pedigree/kernel/utilities/utility.h"
26 
27 DeviceHashTree DeviceHashTree::m_Instance;
28 
29 DeviceHashTree::DeviceHashTree() : m_bInitialised(false), m_DeviceTree()
30 {
31 }
32 
33 DeviceHashTree::~DeviceHashTree()
34 {
35 }
36 
37 static Device *testDevice(Device *p)
38 {
39  if (p->getType() != Device::Root)
40  DeviceHashTree::instance().add(p);
41 
42  return p;
43 }
44 
46 {
47  Device::foreach (testDevice, root);
48 
49  m_bInitialised = true;
50 }
51 
53 {
54  size_t hash = getHash(p);
55  if (m_DeviceTree.lookup(hash))
56  return;
57 
58  String dump;
59  p->dump(dump);
60 
61  NOTICE("Device hash for `" << dump << "' is: " << hash << ".");
62  m_DeviceTree.insert(hash, p);
63 }
64 
66 {
67  if (!m_bInitialised)
68  return 0;
69  else
70  return m_DeviceTree.lookup(hash);
71 }
72 
74 {
75  if (!m_bInitialised)
76  return 0;
77  else
78  {
79  uint32_t inthash =
80  StringToUnsignedLong(static_cast<const char *>(hash), 0, 16);
81  return m_DeviceTree.lookup(inthash);
82  }
83 }
84 
86 {
87  static SHA1 mySha1;
88 
89  // Grab the device information
90  String name, dump;
91  pChild->getName(name);
92  pChild->dump(dump);
93  uint32_t bus = pChild->getPciBusPosition();
94  uint32_t dev = pChild->getPciDevicePosition();
95  uint32_t func = pChild->getPciFunctionNumber();
96 
97  // Build the string to be hashed
98  NormalStaticString theString;
99  theString.clear();
100  theString += name;
101  theString += "-";
102  theString += dump;
103  theString += "-";
104  theString.append(bus);
105  theString += ".";
106  theString.append(dev);
107  theString += ".";
108  theString.append(func);
109 
110  // Hash the string
111  mySha1.Reset();
112  mySha1.Input(static_cast<const char *>(theString), theString.length());
113  unsigned int digest[5];
114  mySha1.Result(digest);
115 
116  // Only use 4 bytes of the hash
117  return digest[0];
118 }
The device is the root of the device tree.
Definition: Device.h:53
virtual void dump(String &str)
Definition: Device.h:250
uint32_t getPciDevicePosition()
Definition: Device.h:239
virtual void getName(String &str)
Definition: Device.cc:121
size_t getHash(Device *p)
Definition: String.h:49
uint32_t getPciBusPosition()
Definition: Device.h:234
Definition: Device.h:43
uint32_t getPciFunctionNumber()
Definition: Device.h:244
#define NOTICE(text)
Definition: Log.h:74
Device * getDevice(uint32_t hash)
static void foreach(Callback callback, Device *root=0)
Definition: Device.cc:94
void add(Device *p)
virtual Type getType()
Definition: Device.h:163
void fill(Device *root=0)