| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 1 | /* | 
 | 2 | // Copyright (c) 2019 Intel Corporation | 
 | 3 | // | 
 | 4 | // Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 | // you may not use this file except in compliance with the License. | 
 | 6 | // You may obtain a copy of the License at | 
 | 7 | // | 
 | 8 | //      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 | // | 
 | 10 | // Unless required by applicable law or agreed to in writing, software | 
 | 11 | // distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 | // See the License for the specific language governing permissions and | 
 | 14 | // limitations under the License. | 
 | 15 | */ | 
 | 16 |  | 
 | 17 | #include "NVMeSensor.hpp" | 
 | 18 |  | 
 | 19 | #include "NVMeDevice.hpp" | 
 | 20 |  | 
 | 21 | #include <crc32c.h> | 
 | 22 | #include <libmctp-smbus.h> | 
 | 23 |  | 
 | 24 | #include <boost/algorithm/string/replace.hpp> | 
 | 25 | #include <boost/asio/ip/tcp.hpp> | 
| James Feist | 38fb598 | 2020-05-28 10:09:54 -0700 | [diff] [blame] | 26 |  | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 27 | #include <iostream> | 
 | 28 |  | 
 | 29 | static constexpr double maxReading = 127; | 
 | 30 | static constexpr double minReading = 0; | 
 | 31 |  | 
 | 32 | static constexpr bool DEBUG = false; | 
 | 33 |  | 
 | 34 | void rxMessage(uint8_t eid, void* data, void* msg, size_t len); | 
 | 35 |  | 
 | 36 | namespace nvmeMCTP | 
 | 37 | { | 
 | 38 | struct mctp_binding_smbus* smbus = mctp_smbus_init(); | 
 | 39 | struct mctp* mctp = mctp_init(); | 
 | 40 |  | 
 | 41 | static boost::container::flat_map<int, int> inFds; | 
 | 42 | static boost::container::flat_map<int, int> outFds; | 
 | 43 |  | 
 | 44 | int getInFd(int rootBus) | 
 | 45 | { | 
 | 46 |     auto findBus = inFds.find(rootBus); | 
 | 47 |     if (findBus != inFds.end()) | 
 | 48 |     { | 
 | 49 |         return findBus->second; | 
 | 50 |     } | 
 | 51 |     int fd = mctp_smbus_open_in_bus(smbus, rootBus); | 
 | 52 |     if (fd < 0) | 
 | 53 |     { | 
 | 54 |         std::cerr << "Error opening IN Bus " << rootBus << "\n"; | 
 | 55 |     } | 
 | 56 |     inFds[rootBus] = fd; | 
 | 57 |     return fd; | 
 | 58 | } | 
 | 59 |  | 
 | 60 | int getOutFd(int bus) | 
 | 61 | { | 
 | 62 |     auto findBus = outFds.find(bus); | 
 | 63 |     if (findBus != outFds.end()) | 
 | 64 |     { | 
 | 65 |         return findBus->second; | 
 | 66 |     } | 
 | 67 |     int fd = mctp_smbus_open_out_bus(smbus, bus); | 
 | 68 |     if (fd < 0) | 
 | 69 |     { | 
 | 70 |         std::cerr << "Error opening Out Bus " << bus << "\n"; | 
 | 71 |     } | 
 | 72 |     outFds[bus] = fd; | 
 | 73 |     return fd; | 
 | 74 | } | 
 | 75 |  | 
 | 76 | // we don't close the outFd as multiple sensors could be sharing the fd, we need | 
 | 77 | // to close the inFd as it can only be used on 1 socket at a time | 
 | 78 | void closeInFd(int rootBus) | 
 | 79 | { | 
 | 80 |     auto findFd = inFds.find(rootBus); | 
 | 81 |     if (findFd == inFds.end()) | 
 | 82 |     { | 
 | 83 |         return; | 
 | 84 |     } | 
 | 85 |     close(findFd->second); | 
 | 86 |     inFds.erase(rootBus); | 
 | 87 | } | 
 | 88 |  | 
 | 89 | int getRootBus(int inFd) | 
 | 90 | { | 
 | 91 |     // we assume that we won't have too many FDs, so looping is OK | 
 | 92 |     for (const auto [root, fd] : inFds) | 
 | 93 |     { | 
 | 94 |         if (fd == inFd) | 
 | 95 |         { | 
 | 96 |             return root; | 
 | 97 |         } | 
 | 98 |     } | 
 | 99 |  | 
 | 100 |     return -1; | 
 | 101 | } | 
 | 102 |  | 
 | 103 | void init() | 
 | 104 | { | 
 | 105 |     if (mctp == nullptr || smbus == nullptr) | 
 | 106 |     { | 
 | 107 |         throw std::runtime_error("Unable to init mctp"); | 
 | 108 |     } | 
 | 109 |     mctp_smbus_register_bus(smbus, nvmeMCTP::mctp, 0); | 
 | 110 |     mctp_set_rx_all(mctp, rxMessage, nullptr); | 
 | 111 | } | 
 | 112 |  | 
 | 113 | } // namespace nvmeMCTP | 
 | 114 |  | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 115 | void readResponse(const std::shared_ptr<NVMeContext>& nvmeDevice) | 
 | 116 | { | 
 | 117 |     nvmeDevice->nvmeSlaveSocket.async_wait( | 
 | 118 |         boost::asio::ip::tcp::socket::wait_error, | 
 | 119 |         [nvmeDevice](const boost::system::error_code errorCode) { | 
 | 120 |             if (errorCode) | 
 | 121 |             { | 
 | 122 |                 return; | 
 | 123 |             } | 
 | 124 |  | 
 | 125 |             mctp_smbus_set_in_fd(nvmeMCTP::smbus, | 
 | 126 |                                  nvmeMCTP::getInFd(nvmeDevice->rootBus)); | 
 | 127 |  | 
 | 128 |             // through libmctp this will invoke rxMessage | 
 | 129 |             mctp_smbus_read(nvmeMCTP::smbus); | 
 | 130 |         }); | 
 | 131 | } | 
 | 132 |  | 
 | 133 | int nvmeMessageTransmit(mctp& mctp, nvme_mi_msg_request& req) | 
 | 134 | { | 
 | 135 |     std::array<uint8_t, NVME_MI_MSG_BUFFER_SIZE> messageBuf = {}; | 
 | 136 |  | 
 | 137 |     req.header.flags |= NVME_MI_HDR_MESSAGE_TYPE_MI_COMMAND | 
 | 138 |                         << NVME_MI_HDR_FLAG_MSG_TYPE_SHIFT; | 
 | 139 |     req.header.message_type = | 
 | 140 |         NVME_MI_MESSAGE_TYPE | NVME_MI_MCTP_INTEGRITY_CHECK; | 
 | 141 |  | 
 | 142 |     uint32_t integrity = 0; | 
 | 143 |     size_t msgSize = NVME_MI_MSG_REQUEST_HEADER_SIZE + req.request_data_len + | 
 | 144 |                      sizeof(integrity); | 
 | 145 |  | 
 | 146 |     if (sizeof(messageBuf) < msgSize) | 
 | 147 |     { | 
 | 148 |         return EXIT_FAILURE; | 
 | 149 |     } | 
 | 150 |  | 
 | 151 |     messageBuf[0] = req.header.message_type; | 
 | 152 |     messageBuf[1] = req.header.flags; | 
 | 153 |     // Reserved bytes 2-3 | 
 | 154 |  | 
 | 155 |     messageBuf[4] = req.header.opcode; | 
 | 156 |     // reserved bytes 5-7 | 
 | 157 |     messageBuf[8] = req.header.dword0 & 0xff; | 
 | 158 |     messageBuf[9] = (req.header.dword0 >> 8) & 0xff; | 
 | 159 |     messageBuf[10] = (req.header.dword0 >> 16) & 0xff; | 
 | 160 |     messageBuf[11] = (req.header.dword0 >> 24) & 0xff; | 
 | 161 |  | 
 | 162 |     messageBuf[12] = req.header.dword1 & 0xff; | 
 | 163 |     messageBuf[13] = (req.header.dword1 >> 8) & 0xff; | 
 | 164 |     messageBuf[14] = (req.header.dword1 >> 16) & 0xff; | 
 | 165 |     messageBuf[15] = (req.header.dword1 >> 24) & 0xff; | 
 | 166 |  | 
 | 167 |     std::copy_n(req.request_data, req.request_data_len, | 
 | 168 |                 messageBuf.data() + | 
 | 169 |                     static_cast<uint8_t>(NVME_MI_MSG_REQUEST_HEADER_SIZE)); | 
 | 170 |  | 
 | 171 |     msgSize = NVME_MI_MSG_REQUEST_HEADER_SIZE + req.request_data_len; | 
 | 172 |     integrity = crc32c(messageBuf.data(), | 
 | 173 |                        NVME_MI_MSG_REQUEST_HEADER_SIZE + req.request_data_len); | 
 | 174 |     messageBuf[msgSize] = integrity & 0xff; | 
 | 175 |     messageBuf[msgSize + 1] = (integrity >> 8) & 0xff; | 
 | 176 |     messageBuf[msgSize + 2] = (integrity >> 16) & 0xff; | 
 | 177 |     messageBuf[msgSize + 3] = (integrity >> 24) & 0xff; | 
 | 178 |     msgSize += sizeof(integrity); | 
 | 179 |  | 
 | 180 |     return mctp_message_tx(&mctp, 0, messageBuf.data(), msgSize); | 
 | 181 | } | 
 | 182 |  | 
 | 183 | int verifyIntegrity(uint8_t* msg, size_t len) | 
 | 184 | { | 
 | 185 |     uint32_t msgIntegrity = {0}; | 
 | 186 |     if (len < NVME_MI_MSG_RESPONSE_HEADER_SIZE + sizeof(msgIntegrity)) | 
 | 187 |     { | 
 | 188 |         std::cerr << "Not enough bytes for nvme header and trailer\n"; | 
 | 189 |         return -1; | 
 | 190 |     } | 
 | 191 |  | 
 | 192 |     msgIntegrity = (msg[len - 4]) + (msg[len - 3] << 8) + (msg[len - 2] << 16) + | 
 | 193 |                    (msg[len - 1] << 24); | 
 | 194 |  | 
 | 195 |     uint32_t calculateIntegrity = crc32c(msg, len - sizeof(msgIntegrity)); | 
 | 196 |     if (msgIntegrity != calculateIntegrity) | 
 | 197 |     { | 
 | 198 |         std::cerr << "CRC mismatch. Got=" << msgIntegrity | 
 | 199 |                   << " Expected=" << calculateIntegrity << "\n"; | 
 | 200 |         return -1; | 
 | 201 |     } | 
 | 202 |     return 0; | 
 | 203 | } | 
 | 204 |  | 
 | 205 | void readAndProcessNVMeSensor(const std::shared_ptr<NVMeContext>& nvmeDevice) | 
 | 206 | { | 
 | 207 |     struct nvme_mi_msg_request requestMsg = {}; | 
 | 208 |     requestMsg.header.opcode = NVME_MI_OPCODE_HEALTH_STATUS_POLL; | 
 | 209 |     requestMsg.header.dword0 = 0; | 
 | 210 |     requestMsg.header.dword1 = 0; | 
 | 211 |  | 
 | 212 |     int mctpResponseTimeout = 1; | 
 | 213 |  | 
 | 214 |     if (nvmeDevice->sensors.empty()) | 
 | 215 |     { | 
 | 216 |         return; | 
 | 217 |     } | 
 | 218 |  | 
 | 219 |     std::shared_ptr<NVMeSensor>& sensor = nvmeDevice->sensors.front(); | 
 | 220 |  | 
 | 221 |     // setup the timeout timer | 
 | 222 |     nvmeDevice->mctpResponseTimer.expires_from_now( | 
 | 223 |         boost::posix_time::seconds(mctpResponseTimeout)); | 
 | 224 |  | 
 | 225 |     nvmeDevice->mctpResponseTimer.async_wait( | 
 | 226 |         [sensor, nvmeDevice](const boost::system::error_code errorCode) { | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 227 |             if (errorCode) | 
 | 228 |             { | 
| James Feist | 961bf09 | 2020-07-01 16:38:12 -0700 | [diff] [blame] | 229 |                 // timer cancelled successfully | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 230 |                 return; | 
 | 231 |             } | 
| James Feist | 961bf09 | 2020-07-01 16:38:12 -0700 | [diff] [blame] | 232 |  | 
 | 233 |             sensor->incrementError(); | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 234 |  | 
 | 235 |             // cycle it back | 
 | 236 |             nvmeDevice->sensors.pop_front(); | 
 | 237 |             nvmeDevice->sensors.emplace_back(sensor); | 
 | 238 |  | 
 | 239 |             nvmeDevice->nvmeSlaveSocket.cancel(); | 
 | 240 |         }); | 
 | 241 |  | 
 | 242 |     readResponse(nvmeDevice); | 
 | 243 |  | 
 | 244 |     if (DEBUG) | 
 | 245 |     { | 
 | 246 |         std::cout << "Sending message to read data from Drive on bus: " | 
 | 247 |                   << sensor->bus << " , rootBus: " << nvmeDevice->rootBus | 
 | 248 |                   << " device: " << sensor->name << "\n"; | 
 | 249 |     } | 
 | 250 |  | 
 | 251 |     mctp_smbus_set_out_fd(nvmeMCTP::smbus, nvmeMCTP::getOutFd(sensor->bus)); | 
 | 252 |     int rc = nvmeMessageTransmit(*nvmeMCTP::mctp, requestMsg); | 
 | 253 |  | 
 | 254 |     if (rc != 0) | 
 | 255 |     { | 
 | 256 |         std::cerr << "Error sending request message to NVMe device\n"; | 
 | 257 |     } | 
 | 258 | } | 
 | 259 |  | 
 | 260 | static double getTemperatureReading(int8_t reading) | 
 | 261 | { | 
 | 262 |  | 
 | 263 |     if (reading == static_cast<int8_t>(0x80) || | 
 | 264 |         reading == static_cast<int8_t>(0x81)) | 
 | 265 |     { | 
 | 266 |         // 0x80 = No temperature data or temperature data is more the 5 s | 
 | 267 |         // old 0x81 = Temperature sensor failure | 
 | 268 |         return maxReading; | 
 | 269 |     } | 
 | 270 |  | 
 | 271 |     return reading; | 
 | 272 | } | 
 | 273 |  | 
 | 274 | void rxMessage(uint8_t eid, void*, void* msg, size_t len) | 
 | 275 | { | 
 | 276 |     struct nvme_mi_msg_response_header header | 
| James Feist | 38fb598 | 2020-05-28 10:09:54 -0700 | [diff] [blame] | 277 |     {}; | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 278 |  | 
 | 279 |     int inFd = mctp_smbus_get_in_fd(nvmeMCTP::smbus); | 
 | 280 |     int rootBus = nvmeMCTP::getRootBus(inFd); | 
 | 281 |  | 
 | 282 |     NVMEMap& nvmeMap = getNVMEMap(); | 
 | 283 |     auto findMap = nvmeMap.find(rootBus); | 
 | 284 |     if (findMap == nvmeMap.end()) | 
 | 285 |     { | 
 | 286 |         std::cerr << "Unable to lookup root bus " << rootBus << "\n"; | 
 | 287 |         return; | 
 | 288 |     } | 
 | 289 |     std::shared_ptr<NVMeContext>& self = findMap->second; | 
 | 290 |  | 
 | 291 |     if (msg == nullptr) | 
 | 292 |     { | 
 | 293 |         std::cerr << "Bad message received\n"; | 
 | 294 |         return; | 
 | 295 |     } | 
 | 296 |  | 
 | 297 |     if (len <= 0) | 
 | 298 |     { | 
 | 299 |         std::cerr << "Received message not long enough\n"; | 
 | 300 |         return; | 
 | 301 |     } | 
 | 302 |  | 
 | 303 |     if (DEBUG) | 
 | 304 |     { | 
 | 305 |         std::cout << "Eid from the received messaged: " << eid << "\n"; | 
 | 306 |     } | 
 | 307 |  | 
 | 308 |     uint8_t* messageData = static_cast<uint8_t*>(msg); | 
 | 309 |  | 
 | 310 |     if ((*messageData & NVME_MI_MESSAGE_TYPE_MASK) != NVME_MI_MESSAGE_TYPE) | 
 | 311 |     { | 
 | 312 |         std::cerr << "Got unknown type message_type=" | 
 | 313 |                   << (*messageData & NVME_MI_MESSAGE_TYPE_MASK) << "\n"; | 
 | 314 |         return; | 
 | 315 |     } | 
 | 316 |  | 
 | 317 |     if (len < NVME_MI_MSG_RESPONSE_HEADER_SIZE + sizeof(uint32_t)) | 
 | 318 |     { | 
 | 319 |         std::cerr << "Not enough bytes for NVMe header and trailer\n"; | 
 | 320 |         return; | 
 | 321 |     } | 
 | 322 |  | 
 | 323 |     if (verifyIntegrity(messageData, len) != 0) | 
 | 324 |     { | 
 | 325 |         std::cerr << "Verification of message integrity failed\n"; | 
 | 326 |         return; | 
 | 327 |     } | 
 | 328 |  | 
 | 329 |     header.message_type = messageData[0]; | 
 | 330 |     header.flags = messageData[1]; | 
 | 331 |     header.status = messageData[4]; | 
 | 332 |  | 
 | 333 |     if (header.status == NVME_MI_HDR_STATUS_MORE_PROCESSING_REQUIRED) | 
 | 334 |     { | 
 | 335 |         return; | 
 | 336 |     } | 
 | 337 |  | 
 | 338 |     if (header.status != NVME_MI_HDR_STATUS_SUCCESS) | 
 | 339 |     { | 
 | 340 |         std::cerr << "Command failed with status= " << header.status << "\n"; | 
 | 341 |         return; | 
 | 342 |     } | 
 | 343 |  | 
 | 344 |     messageData += NVME_MI_MSG_RESPONSE_HEADER_SIZE; | 
 | 345 |     size_t messageLength = | 
 | 346 |         len - NVME_MI_MSG_RESPONSE_HEADER_SIZE - sizeof(uint32_t); | 
 | 347 |     if (((header.flags >> NVME_MI_HDR_FLAG_MSG_TYPE_SHIFT) & | 
 | 348 |          NVME_MI_HDR_FLAG_MSG_TYPE_MASK) != NVME_MI_HDR_MESSAGE_TYPE_MI_COMMAND) | 
 | 349 |     { | 
 | 350 |         std::cerr << "Not MI type comamnd\n"; | 
 | 351 |         return; | 
 | 352 |     } | 
 | 353 |  | 
 | 354 |     if (messageLength < NVME_MI_HEALTH_STATUS_POLL_MSG_MIN) | 
 | 355 |     { | 
 | 356 |         std::cerr << "Got improperly sized health status poll\n"; | 
 | 357 |         return; | 
 | 358 |     } | 
 | 359 |  | 
 | 360 |     std::shared_ptr<NVMeSensor> sensorInfo = self->sensors.front(); | 
 | 361 |     if (DEBUG) | 
 | 362 |     { | 
 | 363 |         std::cout << "Temperature Reading: " | 
 | 364 |                   << getTemperatureReading(messageData[5]) | 
 | 365 |                   << " Celsius for device " << sensorInfo->name << "\n"; | 
 | 366 |     } | 
 | 367 |  | 
 | 368 |     sensorInfo->updateValue(getTemperatureReading(messageData[5])); | 
 | 369 |  | 
 | 370 |     if (DEBUG) | 
 | 371 |     { | 
 | 372 |         std::cout << "Cancelling the timer now\n"; | 
 | 373 |     } | 
 | 374 |  | 
 | 375 |     // move to back of scan queue | 
 | 376 |     self->sensors.pop_front(); | 
 | 377 |     self->sensors.emplace_back(sensorInfo); | 
 | 378 |  | 
 | 379 |     self->mctpResponseTimer.cancel(); | 
 | 380 | } | 
 | 381 |  | 
 | 382 | NVMeContext::NVMeContext(boost::asio::io_service& io, int rootBus) : | 
 | 383 |     rootBus(rootBus), scanTimer(io), nvmeSlaveSocket(io), mctpResponseTimer(io) | 
 | 384 | { | 
 | 385 |     nvmeSlaveSocket.assign(boost::asio::ip::tcp::v4(), | 
 | 386 |                            nvmeMCTP::getInFd(rootBus)); | 
 | 387 | } | 
 | 388 |  | 
 | 389 | void NVMeContext::pollNVMeDevices() | 
 | 390 | { | 
 | 391 |     scanTimer.expires_from_now(boost::posix_time::seconds(1)); | 
 | 392 |     scanTimer.async_wait( | 
 | 393 |         [self{shared_from_this()}](const boost::system::error_code errorCode) { | 
 | 394 |             if (errorCode == boost::asio::error::operation_aborted) | 
 | 395 |             { | 
 | 396 |                 return; // we're being canceled | 
 | 397 |             } | 
 | 398 |             else if (errorCode) | 
 | 399 |             { | 
 | 400 |                 std::cerr << "Error:" << errorCode.message() << "\n"; | 
 | 401 |                 return; | 
 | 402 |             } | 
 | 403 |             else | 
 | 404 |             { | 
 | 405 |                 readAndProcessNVMeSensor(self); | 
 | 406 |             } | 
 | 407 |  | 
 | 408 |             self->pollNVMeDevices(); | 
 | 409 |         }); | 
 | 410 | } | 
 | 411 |  | 
| James Feist | 375ade2 | 2020-07-16 16:32:10 -0700 | [diff] [blame] | 412 | void NVMeContext::close() | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 413 | { | 
 | 414 |     scanTimer.cancel(); | 
 | 415 |     mctpResponseTimer.cancel(); | 
 | 416 |     nvmeSlaveSocket.cancel(); | 
 | 417 |     nvmeMCTP::closeInFd(rootBus); | 
 | 418 | } | 
 | 419 |  | 
| James Feist | 375ade2 | 2020-07-16 16:32:10 -0700 | [diff] [blame] | 420 | NVMeContext::~NVMeContext() | 
 | 421 | { | 
 | 422 |     close(); | 
 | 423 | } | 
 | 424 |  | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 425 | NVMeSensor::NVMeSensor(sdbusplus::asio::object_server& objectServer, | 
| James Feist | 7d7579f | 2020-09-02 14:13:08 -0700 | [diff] [blame] | 426 |                        boost::asio::io_service&, | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 427 |                        std::shared_ptr<sdbusplus::asio::connection>& conn, | 
 | 428 |                        const std::string& sensorName, | 
 | 429 |                        std::vector<thresholds::Threshold>&& _thresholds, | 
 | 430 |                        const std::string& sensorConfiguration, | 
 | 431 |                        const int busNumber) : | 
 | 432 |     Sensor(boost::replace_all_copy(sensorName, " ", "_"), | 
 | 433 |            std::move(_thresholds), sensorConfiguration, | 
| James Feist | 961bf09 | 2020-07-01 16:38:12 -0700 | [diff] [blame] | 434 |            "xyz.openbmc_project.Configuration.NVMe", maxReading, minReading, | 
| James Feist | e333852 | 2020-09-15 15:40:30 -0700 | [diff] [blame] | 435 |            conn, PowerState::on), | 
| James Feist | 961bf09 | 2020-07-01 16:38:12 -0700 | [diff] [blame] | 436 |     objServer(objectServer), bus(busNumber) | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 437 | { | 
 | 438 |     sensorInterface = objectServer.add_interface( | 
 | 439 |         "/xyz/openbmc_project/sensors/temperature/" + name, | 
 | 440 |         "xyz.openbmc_project.Sensor.Value"); | 
 | 441 |  | 
 | 442 |     if (thresholds::hasWarningInterface(thresholds)) | 
 | 443 |     { | 
 | 444 |         thresholdInterfaceWarning = objectServer.add_interface( | 
 | 445 |             "/xyz/openbmc_project/sensors/temperature/" + name, | 
 | 446 |             "xyz.openbmc_project.Sensor.Threshold.Warning"); | 
 | 447 |     } | 
 | 448 |     if (thresholds::hasCriticalInterface(thresholds)) | 
 | 449 |     { | 
 | 450 |         thresholdInterfaceCritical = objectServer.add_interface( | 
 | 451 |             "/xyz/openbmc_project/sensors/temperature/" + name, | 
 | 452 |             "xyz.openbmc_project.Sensor.Threshold.Critical"); | 
 | 453 |     } | 
 | 454 |     association = objectServer.add_interface( | 
 | 455 |         "/xyz/openbmc_project/sensors/temperature/" + name, | 
 | 456 |         association::interface); | 
 | 457 |  | 
 | 458 |     setInitialProperties(conn); | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 459 | } | 
 | 460 |  | 
 | 461 | NVMeSensor::~NVMeSensor() | 
 | 462 | { | 
 | 463 |     // close the input dev to cancel async operations | 
 | 464 |     objServer.remove_interface(thresholdInterfaceWarning); | 
 | 465 |     objServer.remove_interface(thresholdInterfaceCritical); | 
 | 466 |     objServer.remove_interface(sensorInterface); | 
 | 467 |     objServer.remove_interface(association); | 
 | 468 | } | 
 | 469 |  | 
 | 470 | void NVMeSensor::checkThresholds(void) | 
 | 471 | { | 
| Nikhil Potade | b669b6b | 2019-03-13 10:52:21 -0700 | [diff] [blame] | 472 |     thresholds::checkThresholds(this); | 
 | 473 | } |