blob: c2ced770453bca5b44b16cdfae238cdddcefb806 [file] [log] [blame]
Vernon Mauerya3702c12019-05-22 13:20:59 -07001/*
2// Copyright (c) 2018 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 <errno.h>
18#include <fcntl.h>
Vernon Mauerya3702c12019-05-22 13:20:59 -070019#include <limits.h>
20#include <sys/stat.h>
21#include <sys/types.h>
22#include <unistd.h>
23
24#include <commandutils.hpp>
25#include <cstdint>
26#include <fstream>
jayaprakash Mutyala853d8292019-05-31 18:17:42 +000027#include <ipmid/api.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070028#include <ipmid/utils.hpp>
29#include <phosphor-logging/log.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070030#include <sdbusplus/message/types.hpp>
31#include <smbiosmdrv2handler.hpp>
32#include <string>
33#include <vector>
34#include <xyz/openbmc_project/Common/error.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070035
36std::unique_ptr<MDRV2> mdrv2 = nullptr;
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +000037static constexpr const uint8_t ccOemInvalidChecksum = 0x85;
jayaprakash Mutyala40fec612019-06-19 11:53:03 +000038static constexpr size_t dataInfoSize = 16;
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +000039static constexpr const uint8_t ccStorageLeak = 0xC4;
Vernon Mauerya3702c12019-05-22 13:20:59 -070040
Vernon Mauerya3702c12019-05-22 13:20:59 -070041static void register_netfn_smbiosmdrv2_functions() __attribute__((constructor));
Vernon Mauerya3702c12019-05-22 13:20:59 -070042
43int MDRV2::agentLookup(const uint16_t &agentId)
44{
45 int agentIndex = -1;
46
47 if (lastAgentId == agentId)
48 {
49 return lastAgentIndex;
50 }
51
52 if (agentId == smbiosAgentId)
53 {
54 return firstAgentIndex;
55 }
56
57 return agentIndex;
58}
59
60int MDRV2::sdplusMdrv2GetProperty(const std::string &name,
61 sdbusplus::message::variant<uint8_t> &value,
62 const std::string &service)
63{
Vernon Mauery15419dd2019-05-24 09:40:30 -070064 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
Vernon Mauerya3702c12019-05-22 13:20:59 -070065 sdbusplus::message::message method =
Vernon Mauery15419dd2019-05-24 09:40:30 -070066 bus->new_method_call(service.c_str(), mdrv2Path, dbusProperties, "Get");
Vernon Mauerya3702c12019-05-22 13:20:59 -070067 method.append(mdrv2Interface, name);
68
Vernon Mauery15419dd2019-05-24 09:40:30 -070069 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070070
71 try
72 {
Vernon Mauery15419dd2019-05-24 09:40:30 -070073 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -070074 reply.read(value);
75 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -070076 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -070077 {
78 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -070079 "Error get property, sdbusplus call failed",
80 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -070081 return -1;
82 }
83
84 return 0;
85}
86
87int MDRV2::syncDirCommonData(uint8_t idIndex, uint32_t size,
88 const std::string &service)
89{
90 std::vector<uint32_t> commonData;
Vernon Mauery15419dd2019-05-24 09:40:30 -070091 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
Vernon Mauerya3702c12019-05-22 13:20:59 -070092 sdbusplus::message::message method =
Vernon Mauery15419dd2019-05-24 09:40:30 -070093 bus->new_method_call(service.c_str(), mdrv2Path, mdrv2Interface,
94 "SynchronizeDirectoryCommonData");
Vernon Mauerya3702c12019-05-22 13:20:59 -070095 method.append(idIndex, size);
96
97 try
98 {
Vernon Mauery15419dd2019-05-24 09:40:30 -070099 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700100 reply.read(commonData);
101 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700102 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700103 {
104 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700105 "Error sync dir common data with service",
106 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700107 return -1;
108 }
109
110 if (commonData.size() < syncDirCommonSize)
111 {
112 phosphor::logging::log<phosphor::logging::level::ERR>(
113 "Error sync dir common data - data length invalid");
114 return -1;
115 }
116 smbiosDir.dir[idIndex].common.dataSetSize = commonData.at(0);
117 smbiosDir.dir[idIndex].common.dataVersion = commonData.at(1);
118 smbiosDir.dir[idIndex].common.timestamp = commonData.at(2);
119
120 return 0;
121}
122
123int MDRV2::findDataId(const uint8_t *dataInfo, const size_t &len,
124 const std::string &service)
125{
126 int idIndex = -1;
127
128 if (dataInfo == nullptr)
129 {
130 phosphor::logging::log<phosphor::logging::level::ERR>(
131 "Error dataInfo, input is null point");
132 return -1;
133 }
134
Vernon Mauery15419dd2019-05-24 09:40:30 -0700135 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
136 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700137 service.c_str(), mdrv2Path, mdrv2Interface, "FindIdIndex");
138 std::vector<uint8_t> info;
139 info.resize(len);
140 std::copy(dataInfo, dataInfo + len, info.data());
141 method.append(info);
142
143 try
144 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700145 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700146 reply.read(idIndex);
147 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700148 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700149 {
150 phosphor::logging::log<phosphor::logging::level::ERR>(
151 "Error find id index",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700152 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700153 phosphor::logging::entry("SERVICE=%s", service.c_str()),
154 phosphor::logging::entry("PATH=%s", mdrv2Path));
155 return -1;
156 }
157
158 return idIndex;
159}
160
161uint16_t MDRV2::getSessionHandle(Mdr2DirStruct *dir)
162{
163 if (dir == NULL)
164 {
165 phosphor::logging::log<phosphor::logging::level::ERR>(
166 "Empty dir point");
167 return 0;
168 }
169 dir->sessionHandle++;
170 if (dir->sessionHandle == 0)
171 {
172 dir->sessionHandle = 1;
173 }
174
175 return dir->sessionHandle;
176}
177
178int MDRV2::findLockHandle(const uint16_t &lockHandle)
179{
180 int idIndex = -1;
181
182 for (int index = 0; index < smbiosDir.dirEntries; index++)
183 {
184 if (lockHandle == smbiosDir.dir[index].lockHandle)
185 {
186 return index;
187 }
188 }
189
190 return idIndex;
191}
192
193bool MDRV2::smbiosIsUpdating(uint8_t index)
194{
195 if (index > maxDirEntries)
196 {
197 return false;
198 }
199 if (smbiosDir.dir[index].stage == MDR2SMBIOSStatusEnum::mdr2Updating)
200 {
201 return true;
202 }
203
204 return false;
205}
206
207uint32_t MDRV2::calcChecksum32(uint8_t *buf, uint32_t len)
208{
209 uint32_t sum = 0;
210
211 if (buf == nullptr)
212 {
213 return invalidChecksum;
214 }
215
216 for (uint32_t index = 0; index < len; index++)
217 {
218 sum += buf[index];
219 }
220
221 return sum;
222}
223
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000224/** @brief implements mdr2 agent status command
225 * @param agentId
226 * @param dirVersion
227 *
228 * @returns IPMI completion code plus response data
229 * - mdrVersion
230 * - agentVersion
231 * - dirVersion
232 * - dirEntries
233 * - dataRequest
234 */
235ipmi::RspType<uint8_t, uint8_t, uint8_t, uint8_t, uint8_t>
236 mdr2AgentStatus(uint16_t agentId, uint8_t dirVersion)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700237{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700238 if (mdrv2 == nullptr)
239 {
240 mdrv2 = std::make_unique<MDRV2>();
241 }
242
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000243 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700244 if (agentIndex == -1)
245 {
246 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000247 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
248 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700249 }
250
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000251 constexpr uint8_t mdrVersion = mdr2Version;
252 constexpr uint8_t agentVersion = smbiosAgentVersion;
253 uint8_t dirVersionResp = mdrv2->smbiosDir.dirVersion;
254 uint8_t dirEntries = mdrv2->smbiosDir.dirEntries;
255 uint8_t dataRequest;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700256
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000257 if (mdrv2->smbiosDir.remoteDirVersion != dirVersion)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700258 {
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000259 mdrv2->smbiosDir.remoteDirVersion = dirVersion;
260 dataRequest =
Vernon Mauerya3702c12019-05-22 13:20:59 -0700261 static_cast<uint8_t>(DirDataRequestEnum::dirDataRequested);
262 }
263 else
264 {
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000265 dataRequest =
Vernon Mauerya3702c12019-05-22 13:20:59 -0700266 static_cast<uint8_t>(DirDataRequestEnum::dirDataNotRequested);
267 }
268
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000269 return ipmi::responseSuccess(mdrVersion, agentVersion, dirVersionResp,
270 dirEntries, dataRequest);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700271}
272
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000273/** @brief implements mdr2 get directory command
274 * @param agentId
275 * @param dirIndex
276 * @returns IPMI completion code plus response data
277 * - dataOut
278 */
279ipmi::RspType<std::vector<uint8_t>> mdr2GetDir(uint16_t agentId,
280 uint8_t dirIndex)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700281{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700282 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
283 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700284
285 if (mdrv2 == nullptr)
286 {
287 mdrv2 = std::make_unique<MDRV2>();
288 }
289
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000290 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700291 if (agentIndex == -1)
292 {
293 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000294 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
295 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700296 }
297
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000298 std::variant<uint8_t> value = 0;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700299 if (0 != mdrv2->sdplusMdrv2GetProperty("DirectoryEntries", value, service))
300 {
301 phosphor::logging::log<phosphor::logging::level::ERR>(
302 "Error getting DirEnries");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000303 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700304 }
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000305 if (dirIndex > std::get<uint8_t>(value))
Vernon Mauerya3702c12019-05-22 13:20:59 -0700306 {
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000307 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700308 }
309
Vernon Mauery15419dd2019-05-24 09:40:30 -0700310 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700311 service.c_str(), mdrv2Path, mdrv2Interface, "GetDirectoryInformation");
312
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000313 method.append(dirIndex);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700314
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000315 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700316 try
317 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700318 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000319 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700320 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700321 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700322 {
323 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700324 "Error get dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700325 phosphor::logging::entry("SERVICE=%s", service.c_str()),
326 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000327 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700328 }
329
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000330 constexpr size_t getDirRespSize = 6;
331 if (dataOut.size() < getDirRespSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700332 {
333 phosphor::logging::log<phosphor::logging::level::ERR>(
334 "Error get dir, response length invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000335 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700336 }
337
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000338 if (dataOut.size() > MAX_IPMI_BUFFER) // length + completion code should no
339 // more than MAX_IPMI_BUFFER
Vernon Mauerya3702c12019-05-22 13:20:59 -0700340 {
341 phosphor::logging::log<phosphor::logging::level::ERR>(
342 "Data length send from service is invalid");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000343 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700344 }
345
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +0000346 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700347}
348
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000349ipmi::RspType<bool> mdr2SendDir(uint16_t agentId, uint8_t dirVersion,
350 uint8_t dirIndex, uint8_t returnedEntries,
351 uint8_t remainingEntries,
352 std::array<uint8_t, 16> dataInfo, uint32_t size,
353 uint32_t dataSetSize, uint32_t dataVersion,
354 uint32_t timestamp)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700355{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700356 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
357 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700358
359 if (mdrv2 == nullptr)
360 {
361 mdrv2 = std::make_unique<MDRV2>();
362 }
363
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000364 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700365 if (agentIndex == -1)
366 {
367 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000368 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
369 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700370 }
371
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000372 if ((dirIndex + returnedEntries) > maxDirEntries)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700373 {
374 phosphor::logging::log<phosphor::logging::level::ERR>(
375 "Too many directory entries");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000376 return ipmi::response(ccStorageLeak);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700377 }
378
Vernon Mauery15419dd2019-05-24 09:40:30 -0700379 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700380 service.c_str(), mdrv2Path, mdrv2Interface, "SendDirectoryInformation");
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000381 method.append(dirVersion, dirIndex, returnedEntries, remainingEntries,
382 dataInfo, size, dataSetSize, dataVersion, timestamp);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700383
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000384 bool terminate = false;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700385 try
386 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700387 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000388 reply.read(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700389 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700390 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700391 {
392 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700393 "Error send dir", phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700394 phosphor::logging::entry("SERVICE=%s", service.c_str()),
395 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000396 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700397 }
398
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +0000399 return ipmi::responseSuccess(terminate);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700400}
401
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000402/** @brief implements mdr2 get data info command
403 * @param agentId
404 * @param dataInfo
405 *
406 * @returns IPMI completion code plus response data
407 * - response - mdrVersion, data info, validFlag,
408 * dataLength, dataVersion, timeStamp
409 */
410ipmi::RspType<std::vector<uint8_t>>
411 mdr2GetDataInfo(uint16_t agentId, std::vector<uint8_t> dataInfo)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700412{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000413 constexpr size_t getDataInfoReqSize = 16;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700414
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000415 if (dataInfo.size() < getDataInfoReqSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700416 {
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000417 return ipmi::responseReqDataLenInvalid();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700418 }
419
Vernon Mauery15419dd2019-05-24 09:40:30 -0700420 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
421 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700422
423 if (mdrv2 == nullptr)
424 {
425 mdrv2 = std::make_unique<MDRV2>();
426 }
427
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000428 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700429 if (agentIndex == -1)
430 {
431 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000432 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
433 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700434 }
435
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000436 int idIndex = mdrv2->findDataId(dataInfo.data(), dataInfo.size(), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700437
438 if ((idIndex < 0) || (idIndex >= maxDirEntries))
439 {
440 phosphor::logging::log<phosphor::logging::level::ERR>(
441 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000442 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700443 }
444
Vernon Mauery15419dd2019-05-24 09:40:30 -0700445 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700446 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataInformation");
447
448 method.append(idIndex);
449
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000450 std::vector<uint8_t> res;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700451 try
452 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700453 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700454 reply.read(res);
455 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700456 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700457 {
458 phosphor::logging::log<phosphor::logging::level::ERR>(
459 "Error get data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700460 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700461 phosphor::logging::entry("SERVICE=%s", service.c_str()),
462 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000463 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700464 }
465
466 if (res.size() != sizeof(MDRiiGetDataInfoResponse))
467 {
468 phosphor::logging::log<phosphor::logging::level::ERR>(
469 "Get data info response length not invalid");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000470 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700471 }
Vernon Mauerya3702c12019-05-22 13:20:59 -0700472
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000473 return ipmi::responseSuccess(res);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700474}
475
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000476/** @brief implements mdr2 data info offer command
477 * @param agentId - Offer a agent ID to get the "Data Set ID"
478 *
479 * @returns IPMI completion code plus response data
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000480 * - dataOut - data Set Id
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000481 */
482ipmi::RspType<std::vector<uint8_t>> mdr2DataInfoOffer(uint16_t agentId)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700483{
Vernon Mauery15419dd2019-05-24 09:40:30 -0700484 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
485 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700486
487 if (mdrv2 == nullptr)
488 {
489 mdrv2 = std::make_unique<MDRV2>();
490 }
491
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000492 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700493 if (agentIndex == -1)
494 {
495 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000496 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
497 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700498 }
499
Vernon Mauery15419dd2019-05-24 09:40:30 -0700500 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700501 service.c_str(), mdrv2Path, mdrv2Interface, "GetDataOffer");
502
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000503 std::vector<uint8_t> dataOut;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700504 try
505 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700506 sdbusplus::message::message reply = bus->call(method);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000507 reply.read(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700508 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700509 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700510 {
511 phosphor::logging::log<phosphor::logging::level::ERR>(
512 "Error send data info offer",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700513 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700514 phosphor::logging::entry("SERVICE=%s", service.c_str()),
515 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000516 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700517 }
518
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000519 constexpr size_t respInfoSize = 16;
520 if (dataOut.size() != respInfoSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700521 {
522 phosphor::logging::log<phosphor::logging::level::ERR>(
523 "Error send data info offer, return length invalid");
jayaprakash Mutyala853d8292019-05-31 18:17:42 +0000524 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700525 }
526
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000527 return ipmi::responseSuccess(dataOut);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700528}
529
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000530/** @brief implements mdr2 send data info command
531 * @param agentId
532 * @param dataInfo
533 * @param validFlag
534 * @param dataLength
535 * @param dataVersion
536 * @param timeStamp
537 *
538 * @returns IPMI completion code plus response data
539 * - bool
540 */
541ipmi::RspType<bool> mdr2SendDataInfo(uint16_t agentId,
542 std::array<uint8_t, dataInfoSize> dataInfo,
543 uint8_t validFlag, uint32_t dataLength,
544 uint32_t dataVersion, uint32_t timeStamp)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700545{
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000546 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700547 {
548 phosphor::logging::log<phosphor::logging::level::ERR>(
549 "Requested data length is out of SMBIOS Table storage size.");
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000550 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700551 }
552
Vernon Mauery15419dd2019-05-24 09:40:30 -0700553 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
554 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700555
556 if (mdrv2 == nullptr)
557 {
558 mdrv2 = std::make_unique<MDRV2>();
559 }
560
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000561 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700562 if (agentIndex == -1)
563 {
564 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000565 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
566 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700567 }
568
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000569 int idIndex = mdrv2->findDataId(dataInfo.data(), sizeof(dataInfo), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700570
571 if ((idIndex < 0) || (idIndex >= maxDirEntries))
572 {
573 phosphor::logging::log<phosphor::logging::level::ERR>(
574 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000575 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700576 }
577
Vernon Mauery15419dd2019-05-24 09:40:30 -0700578 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -0700579 service.c_str(), mdrv2Path, mdrv2Interface, "SendDataInformation");
580
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000581 method.append((uint8_t)idIndex, validFlag, dataLength, dataVersion,
582 timeStamp);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700583
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000584 bool entryChanged = true;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700585 try
586 {
Vernon Mauery15419dd2019-05-24 09:40:30 -0700587 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700588 reply.read(entryChanged);
589 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700590 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700591 {
592 phosphor::logging::log<phosphor::logging::level::ERR>(
593 "Error send data info",
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700594 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -0700595 phosphor::logging::entry("SERVICE=%s", service.c_str()),
596 phosphor::logging::entry("PATH=%s", mdrv2Path));
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000597 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700598 }
599
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +0000600 return ipmi::responseSuccess(entryChanged);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700601}
602
603ipmi_ret_t cmd_mdr2_get_data_block(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
604 ipmi_request_t request,
605 ipmi_response_t response,
606 ipmi_data_len_t data_len,
607 ipmi_context_t context)
608{
609 auto requestData =
610 reinterpret_cast<const MDRiiGetDataBlockRequest *>(request);
611 auto responseData = reinterpret_cast<MDRiiGetDataBlockResponse *>(response);
612 std::tuple<uint8_t, uint32_t, uint32_t, std::vector<uint8_t>> res;
613 std::vector<uint8_t> resData;
614 uint8_t status = 1;
615
616 if (*data_len != sizeof(MDRiiGetDataBlockRequest))
617 {
618 *data_len = 0;
619 return IPMI_CC_REQ_DATA_LEN_INVALID;
620 }
621
622 *data_len = 0;
623
Vernon Mauerya3702c12019-05-22 13:20:59 -0700624 if (mdrv2 == nullptr)
625 {
626 mdrv2 = std::make_unique<MDRV2>();
627 }
628
629 int agentIndex = mdrv2->agentLookup(requestData->agentId);
630 if (agentIndex == -1)
631 {
632 phosphor::logging::log<phosphor::logging::level::ERR>(
633 "Unknown agent id",
634 phosphor::logging::entry("ID=%x", requestData->agentId));
635 return IPMI_CC_PARM_OUT_OF_RANGE;
636 }
637
638 int idIndex = mdrv2->findLockHandle(requestData->lockHandle);
639
640 if ((idIndex < 0) || (idIndex >= maxDirEntries))
641 {
642 phosphor::logging::log<phosphor::logging::level::ERR>(
643 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
644 return IPMI_CC_PARM_OUT_OF_RANGE;
645 }
646
647 if (requestData->xferOffset >= mdrv2->smbiosDir.dir[idIndex].common.size)
648 {
649 phosphor::logging::log<phosphor::logging::level::ERR>(
650 "Offset is outside of range.");
651 return IPMI_CC_PARM_OUT_OF_RANGE;
652 }
653
654 size_t outSize =
655 (requestData->xferLength > mdrv2->smbiosDir.dir[idIndex].xferSize)
656 ? mdrv2->smbiosDir.dir[idIndex].xferSize
657 : requestData->xferLength;
658 if (outSize > UINT_MAX - requestData->xferOffset)
659 {
660 phosphor::logging::log<phosphor::logging::level::ERR>(
661 "Out size and offset are out of range");
662 return IPMI_CC_PARM_OUT_OF_RANGE;
663 }
664 if ((requestData->xferOffset + outSize) >
665 mdrv2->smbiosDir.dir[idIndex].common.size)
666 {
667 outSize =
668 mdrv2->smbiosDir.dir[idIndex].common.size - requestData->xferOffset;
669 }
670
671 responseData->xferLength = outSize;
672 if (responseData->xferLength > requestData->xferLength)
673 {
674 phosphor::logging::log<phosphor::logging::level::ERR>(
675 "Get data block unexpected error.");
676 return IPMI_CC_UNSPECIFIED_ERROR;
677 }
678
679 if ((requestData->xferOffset + outSize) >
680 UINT_MAX -
681 reinterpret_cast<size_t>(mdrv2->smbiosDir.dir[idIndex].dataStorage))
682 {
683 phosphor::logging::log<phosphor::logging::level::ERR>(
684 "Input data to calculate checksum is out of range");
685 return IPMI_CC_PARM_OUT_OF_RANGE;
686 }
687
688 uint32_t u32Checksum = mdrv2->calcChecksum32(
689 mdrv2->smbiosDir.dir[idIndex].dataStorage + requestData->xferOffset,
690 outSize);
691 if (u32Checksum == invalidChecksum)
692 {
693 phosphor::logging::log<phosphor::logging::level::ERR>(
694 "Get data block failed - invalid checksum");
695 return IPMI_CC_OEM_INVALID_CHECKSUM;
696 }
697 responseData->checksum = u32Checksum;
698
699 *data_len = sizeof(responseData->xferLength) +
700 sizeof(responseData->checksum) + outSize;
701
702 if (*data_len > MAX_IPMI_BUFFER) // length + completion code should no more
703 // than MAX_IPMI_BUFFER
704 {
705 phosphor::logging::log<phosphor::logging::level::ERR>(
706 "Data length send from service is invalid");
707 *data_len = 0;
708 return IPMI_CC_RESPONSE_ERROR;
709 }
710
711 std::copy(
712 &mdrv2->smbiosDir.dir[idIndex].dataStorage[requestData->xferOffset],
713 &mdrv2->smbiosDir.dir[idIndex]
714 .dataStorage[requestData->xferOffset + outSize],
715 responseData->data);
716
717 return IPMI_CC_OK;
718}
719
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000720/** @brief implements mdr2 send data block command
721 * @param agentId
722 * @param lockHandle
723 * @param xferOffset
724 * @param xferLength
725 * @param checksum
726 *
727 * @returns IPMI completion code
728 */
729ipmi::RspType<> mdr2SendDataBlock(uint16_t agentId, uint16_t lockHandle,
730 uint32_t xferOffset, uint32_t xferLength,
731 uint32_t checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700732{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700733 if (mdrv2 == nullptr)
734 {
735 mdrv2 = std::make_unique<MDRV2>();
736 }
737
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000738 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700739 if (agentIndex == -1)
740 {
741 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000742 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
743 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700744 }
745
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000746 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700747
748 if ((idIndex < 0) || (idIndex >= maxDirEntries))
749 {
750 phosphor::logging::log<phosphor::logging::level::ERR>(
751 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000752 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700753 }
754
755 if (mdrv2->smbiosIsUpdating(idIndex))
756 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000757 if (xferOffset > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700758 {
759 phosphor::logging::log<phosphor::logging::level::ERR>(
760 "Offset and length are out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000761 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700762 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000763 if (((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700764 mdrv2->smbiosDir.dir[idIndex].maxDataSize) ||
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000765 ((xferOffset + xferLength) >
Vernon Mauerya3702c12019-05-22 13:20:59 -0700766 mdrv2->smbiosDir.dir[idIndex].common.dataSetSize))
767 {
768 phosphor::logging::log<phosphor::logging::level::ERR>(
769 "Send data block Invalid offset/length");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000770 return ipmi::responseReqDataLenExceeded();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700771 }
772 if (reinterpret_cast<size_t>(
773 mdrv2->smbiosDir.dir[idIndex].dataStorage) >
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000774 UINT_MAX - xferOffset)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700775 {
776 phosphor::logging::log<phosphor::logging::level::ERR>(
777 "Offset is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000778 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700779 }
780 uint8_t *destAddr =
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000781 mdrv2->smbiosDir.dir[idIndex].dataStorage + xferOffset;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700782 uint8_t *sourceAddr = reinterpret_cast<uint8_t *>(mdrv2->area->vPtr);
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000783 uint32_t calcChecksum = mdrv2->calcChecksum32(sourceAddr, xferLength);
784 if (calcChecksum != checksum)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700785 {
786 phosphor::logging::log<phosphor::logging::level::ERR>(
787 "Send data block Invalid checksum");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000788 return ipmi::response(ccOemInvalidChecksum);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700789 }
790 else
791 {
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000792 if (reinterpret_cast<size_t>(sourceAddr) > UINT_MAX - xferLength)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700793 {
794 phosphor::logging::log<phosphor::logging::level::ERR>(
795 "Length is out of range");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000796 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700797 }
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000798 std::copy(sourceAddr, sourceAddr + xferLength, destAddr);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700799 }
800 }
801 else
802 {
803 phosphor::logging::log<phosphor::logging::level::ERR>(
804 "Send data block failed, other data is updating");
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000805 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700806 }
807
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +0000808 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700809}
810
811bool MDRV2::storeDatatoFlash(MDRSMBIOSHeader *mdrHdr, uint8_t *data)
812{
813 std::ofstream smbiosFile(mdrType2File,
814 std::ios_base::binary | std::ios_base::trunc);
815 if (!smbiosFile.good())
816 {
817 phosphor::logging::log<phosphor::logging::level::ERR>(
818 "Write data from flash error - Open MDRV2 table file failure");
819 return false;
820 }
821
822 try
823 {
824 smbiosFile.write(reinterpret_cast<char *>(mdrHdr),
825 sizeof(MDRSMBIOSHeader));
826 smbiosFile.write(reinterpret_cast<char *>(data), mdrHdr->dataSize);
827 }
828 catch (std::ofstream::failure &e)
829 {
830 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -0700831 "Write data from flash error - write data error",
832 phosphor::logging::entry("ERROR=%s", e.what()));
Vernon Mauerya3702c12019-05-22 13:20:59 -0700833 return false;
834 }
835
836 return true;
837}
838
839void SharedMemoryArea::Initialize(uint32_t addr, uint32_t areaSize)
840{
841 int memDriver = 0;
842
843 // open mem driver for the system memory access
844 memDriver = open("/dev/vgasharedmem", O_RDONLY);
845 if (memDriver < 0)
846 {
847 phosphor::logging::log<phosphor::logging::level::ERR>(
848 "Cannot access mem driver");
849 throw std::system_error(EIO, std::generic_category());
850 }
851
852 // map the system memory
853 vPtr = mmap(NULL, // where to map to: don't mind
854 areaSize, // how many bytes ?
855 PROT_READ, // want to read and write
856 MAP_SHARED, // no copy on write
857 memDriver, // handle to /dev/mem
858 (physicalAddr & pageMask)); // hopefully the Text-buffer :-)
859
860 close(memDriver);
861 if (vPtr == MAP_FAILED)
862 {
863 phosphor::logging::log<phosphor::logging::level::ERR>(
864 "Failed to map share memory");
865 throw std::system_error(EIO, std::generic_category());
866 }
867 size = areaSize;
868 physicalAddr = addr;
869}
870
871bool MDRV2::smbiosUnlock(uint8_t index)
872{
873 bool ret;
874 switch (smbiosDir.dir[index].stage)
875 {
876 case MDR2SMBIOSStatusEnum::mdr2Updating:
877 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updated;
878 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
879
880 timer->stop();
881 smbiosDir.dir[index].lockHandle = 0;
882 ret = true;
883 break;
884
885 case MDR2SMBIOSStatusEnum::mdr2Updated:
886 case MDR2SMBIOSStatusEnum::mdr2Loaded:
887 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
888
889 timer->stop();
890
891 smbiosDir.dir[index].lockHandle = 0;
892 ret = true;
893 break;
894
895 default:
896 break;
897 }
898
899 return ret;
900}
901
902bool MDRV2::smbiosTryLock(uint8_t flag, uint8_t index, uint16_t *session,
903 uint16_t timeout)
904{
905 bool ret = false;
906 uint32_t u32Status = 0;
907
908 if (timeout == 0)
909 {
910 timeout = defaultTimeout;
911 }
912 std::chrono::microseconds usec(timeout * sysClock);
913
914 switch (smbiosDir.dir[index].stage)
915 {
916 case MDR2SMBIOSStatusEnum::mdr2Updating:
917 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
918 {
919 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
920 timer->start(usec);
921 lockIndex = index;
922
923 *session = getSessionHandle(&smbiosDir);
924 smbiosDir.dir[index].lockHandle = *session;
925 ret = true;
926 }
927 break;
928 case MDR2SMBIOSStatusEnum::mdr2Init:
929 if (flag)
930 {
931 smbiosDir.dir[index].stage = MDR2SMBIOSStatusEnum::mdr2Updating;
932 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
933 timer->start(usec);
934 lockIndex = index;
935
936 *session = getSessionHandle(&smbiosDir);
937 smbiosDir.dir[index].lockHandle = *session;
938 ret = true;
939 }
940 break;
941
942 case MDR2SMBIOSStatusEnum::mdr2Updated:
943 case MDR2SMBIOSStatusEnum::mdr2Loaded:
944 if (smbiosDir.dir[index].lock != MDR2DirLockEnum::mdr2DirLock)
945 {
946 if (flag)
947 {
948 smbiosDir.dir[index].stage =
949 MDR2SMBIOSStatusEnum::mdr2Updating;
950 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirUnlock;
951 }
952 else
953 {
954 smbiosDir.dir[index].lock = MDR2DirLockEnum::mdr2DirLock;
955 }
956
957 timer->start(usec);
958 lockIndex = index;
959
960 *session = getSessionHandle(&smbiosDir);
961 smbiosDir.dir[index].lockHandle = *session;
962 ret = true;
963 }
964 break;
965
966 default:
967 break;
968 }
969 return ret;
970}
971
972void MDRV2::timeoutHandler()
973{
974 smbiosUnlock(lockIndex);
975 mdrv2->area.reset(nullptr);
976}
977
jayaprakash Mutyala40fec612019-06-19 11:53:03 +0000978/** @brief implements mdr2 lock data command
979 * @param agentId
980 * @param dataInfo
981 * @param timeout
982 *
983 * @returns IPMI completion code plus response data
984 * - mdr2Version
985 * - session
986 * - dataLength
987 * - xferAddress
988 * - xferLength
989 */
990ipmi::RspType<uint8_t, // mdr2Version
991 uint16_t, // session
992 uint32_t, // dataLength
993 uint32_t, // xferAddress
994 uint32_t // xferLength
995 >
996 mdr2LockData(uint16_t agentId, std::array<uint8_t, dataInfoSize> dataInfo,
997 uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -0700998{
Vernon Mauerya3702c12019-05-22 13:20:59 -0700999 if (mdrv2 == nullptr)
1000 {
1001 mdrv2 = std::make_unique<MDRV2>();
1002 }
1003
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001004 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001005 if (agentIndex == -1)
1006 {
1007 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001008 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1009 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001010 }
1011
Vernon Mauery15419dd2019-05-24 09:40:30 -07001012 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1013 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001014
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001015 int idIndex = mdrv2->findDataId(dataInfo.data(), sizeof(dataInfo), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001016
1017 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1018 {
1019 phosphor::logging::log<phosphor::logging::level::ERR>(
1020 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001021 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001022 }
1023
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001024 uint16_t session = 0;
1025 if (!mdrv2->smbiosTryLock(0, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001026 {
1027 phosphor::logging::log<phosphor::logging::level::ERR>(
1028 "Lock Data failed - cannot lock idIndex");
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001029 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001030 }
1031
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001032 uint32_t dataLength = mdrv2->smbiosDir.dir[idIndex].common.size;
1033 uint32_t xferAddress = mdrv2->smbiosDir.dir[idIndex].xferBuff;
1034 uint32_t xferLength = mdrv2->smbiosDir.dir[idIndex].xferSize;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001035
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001036 return ipmi::responseSuccess(mdr2Version, session, dataLength, xferAddress,
1037 xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001038}
1039
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001040/** @brief implements mdr2 unlock data command
1041 * @param agentId
1042 * @param lockHandle
1043 *
1044 * @returns IPMI completion code
1045 */
1046ipmi::RspType<> mdr2UnlockData(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001047{
1048 phosphor::logging::log<phosphor::logging::level::ERR>("unlock data");
Vernon Mauerya3702c12019-05-22 13:20:59 -07001049
Vernon Mauerya3702c12019-05-22 13:20:59 -07001050 if (mdrv2 == nullptr)
1051 {
1052 mdrv2 = std::make_unique<MDRV2>();
1053 }
1054
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001055 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001056 if (agentIndex == -1)
1057 {
1058 phosphor::logging::log<phosphor::logging::level::ERR>(
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001059 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1060 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001061 }
1062
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001063 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001064
1065 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1066 {
1067 phosphor::logging::log<phosphor::logging::level::ERR>(
1068 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001069 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001070 }
1071
1072 if (!mdrv2->smbiosUnlock(idIndex))
1073 {
1074 phosphor::logging::log<phosphor::logging::level::ERR>(
1075 "Unlock Data failed - cannot unlock idIndex");
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001076 return ipmi::responseCommandNotAvailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001077 }
1078
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001079 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001080}
1081
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001082/**
1083@brief This command is executed after POST BIOS to get the session info.
1084
1085@param - agentId, dataInfo, dataLength, xferAddress, xferLength, timeout.
1086
1087@return xferStartAck and session on success.
1088**/
1089ipmi::RspType<uint8_t, uint16_t>
1090 cmd_mdr2_data_start(uint16_t agentId, std::array<uint8_t, 16> dataInfo,
1091 uint32_t dataLength, uint32_t xferAddress,
1092 uint32_t xferLength, uint16_t timeout)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001093{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001094 uint16_t session = 0;
1095
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001096 if (dataLength > smbiosTableStorageSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001097 {
1098 phosphor::logging::log<phosphor::logging::level::ERR>(
1099 "Requested data length is out of SMBIOS Table storage size.");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001100 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001101 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001102 if ((xferLength + xferAddress) > mdriiSMSize)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001103 {
1104 phosphor::logging::log<phosphor::logging::level::ERR>(
1105 "Invalid data address and size");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001106 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001107 }
1108
Vernon Mauery15419dd2019-05-24 09:40:30 -07001109 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1110 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001111
1112 if (mdrv2 == nullptr)
1113 {
1114 mdrv2 = std::make_unique<MDRV2>();
1115 }
1116
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001117 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001118 if (agentIndex == -1)
1119 {
1120 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001121 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1122 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001123 }
1124
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001125 int idIndex = mdrv2->findDataId(dataInfo.data(), sizeof(dataInfo), service);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001126
1127 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1128 {
1129 phosphor::logging::log<phosphor::logging::level::ERR>(
1130 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001131 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001132 }
1133
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001134 if (mdrv2->smbiosTryLock(1, idIndex, &session, timeout))
Vernon Mauerya3702c12019-05-22 13:20:59 -07001135 {
1136 try
1137 {
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001138 mdrv2->area =
1139 std::make_unique<SharedMemoryArea>(xferAddress, xferLength);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001140 }
1141 catch (const std::system_error &e)
1142 {
1143 mdrv2->smbiosUnlock(idIndex);
1144 phosphor::logging::log<phosphor::logging::level::ERR>(
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001145 "Unable to access share memory",
1146 phosphor::logging::entry("ERROR=%s", e.what()));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001147 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001148 }
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001149 mdrv2->smbiosDir.dir[idIndex].common.size = dataLength;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001150 mdrv2->smbiosDir.dir[idIndex].lockHandle = session;
1151 if (-1 ==
1152 mdrv2->syncDirCommonData(
1153 idIndex, mdrv2->smbiosDir.dir[idIndex].common.size, service))
1154 {
1155 phosphor::logging::log<phosphor::logging::level::ERR>(
1156 "Unable to sync data to service");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001157 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001158 }
1159 }
1160 else
1161 {
1162 phosphor::logging::log<phosphor::logging::level::ERR>(
1163 "Canot lock smbios");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001164 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001165 }
1166
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001167 static constexpr uint8_t xferStartAck = 1;
Vernon Mauerya3702c12019-05-22 13:20:59 -07001168
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001169 return ipmi::responseSuccess(xferStartAck, session);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001170}
1171
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001172/**
1173@brief This command is executed to close the session.
1174
1175@param - agentId, lockHandle.
1176
1177@return completion code on success.
1178**/
1179ipmi::RspType<> cmd_mdr2_data_done(uint16_t agentId, uint16_t lockHandle)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001180{
Vernon Mauerya3702c12019-05-22 13:20:59 -07001181
1182 if (mdrv2 == nullptr)
1183 {
1184 mdrv2 = std::make_unique<MDRV2>();
1185 }
1186
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001187 int agentIndex = mdrv2->agentLookup(agentId);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001188 if (agentIndex == -1)
1189 {
1190 phosphor::logging::log<phosphor::logging::level::ERR>(
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001191 "Unknown agent id", phosphor::logging::entry("ID=%x", agentId));
1192 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001193 }
1194
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001195 int idIndex = mdrv2->findLockHandle(lockHandle);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001196
1197 if ((idIndex < 0) || (idIndex >= maxDirEntries))
1198 {
1199 phosphor::logging::log<phosphor::logging::level::ERR>(
1200 "Invalid Data ID", phosphor::logging::entry("IDINDEX=%x", idIndex));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001201 return ipmi::responseParmOutOfRange();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001202 }
1203
1204 if (!mdrv2->smbiosUnlock(idIndex))
1205 {
1206 phosphor::logging::log<phosphor::logging::level::ERR>(
1207 "Send data done failed - cannot unlock idIndex");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001208 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001209 }
1210
1211 mdrv2->area.reset(nullptr);
1212 MDRSMBIOSHeader mdr2Smbios;
1213 mdr2Smbios.mdrType = mdrTypeII;
1214 mdr2Smbios.dirVer = mdrv2->smbiosDir.dir[0].common.dataVersion;
1215 mdr2Smbios.timestamp = mdrv2->smbiosDir.dir[0].common.timestamp;
1216 mdr2Smbios.dataSize = mdrv2->smbiosDir.dir[0].common.size;
1217
1218 if (access(smbiosPath, 0) == -1)
1219 {
1220 int flag = mkdir(smbiosPath, S_IRWXU);
1221 if (flag != 0)
1222 {
1223 phosphor::logging::log<phosphor::logging::level::ERR>(
1224 "create folder failed for writting smbios file");
1225 }
1226 }
1227 if (!mdrv2->storeDatatoFlash(
1228 &mdr2Smbios, mdrv2->smbiosDir.dir[smbiosDirIndex].dataStorage))
1229 {
1230 phosphor::logging::log<phosphor::logging::level::ERR>(
1231 "MDR2 Store data to flash failed");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001232 return ipmi::responseDestinationUnavailable();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001233 }
Vernon Mauerya3702c12019-05-22 13:20:59 -07001234 bool status = false;
Vernon Mauery15419dd2019-05-24 09:40:30 -07001235 std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
1236 std::string service = ipmi::getService(*bus, mdrv2Interface, mdrv2Path);
1237 sdbusplus::message::message method = bus->new_method_call(
Vernon Mauerya3702c12019-05-22 13:20:59 -07001238 service.c_str(), mdrv2Path, mdrv2Interface, "AgentSynchronizeData");
1239
1240 try
1241 {
Vernon Mauery15419dd2019-05-24 09:40:30 -07001242 sdbusplus::message::message reply = bus->call(method);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001243 reply.read(status);
1244 }
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001245 catch (sdbusplus::exception_t &e)
Vernon Mauerya3702c12019-05-22 13:20:59 -07001246 {
1247 phosphor::logging::log<phosphor::logging::level::ERR>(
1248 "Error Sync data with service",
Vernon Maueryc7d517e2019-06-18 14:27:00 -07001249 phosphor::logging::entry("ERROR=%s", e.what()),
Vernon Mauerya3702c12019-05-22 13:20:59 -07001250 phosphor::logging::entry("SERVICE=%s", service.c_str()),
1251 phosphor::logging::entry("PATH=%s", mdrv2Path));
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001252 return ipmi::responseResponseError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001253 }
1254
1255 if (!status)
1256 {
1257 phosphor::logging::log<phosphor::logging::level::ERR>(
1258 "Sync data with service failure");
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001259 return ipmi::responseUnspecifiedError();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001260 }
1261
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001262 return ipmi::responseSuccess();
Vernon Mauerya3702c12019-05-22 13:20:59 -07001263}
1264
1265static void register_netfn_smbiosmdrv2_functions(void)
1266{
1267 // MDR V2 Command
1268 // <Get MDRII Status Command>
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001269 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1270 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_AGENT_STATUS,
1271 ipmi::Privilege::Operator, mdr2AgentStatus);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001272
1273 // <Get MDRII Directory Command>
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001274 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1275 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DIR,
1276 ipmi::Privilege::Operator, mdr2GetDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001277
1278 // <Send MDRII Directory Command>
jayaprakash Mutyala7cb59cc2019-06-19 19:17:43 +00001279 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1280 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DIR,
1281 ipmi::Privilege::Operator, mdr2SendDir);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001282
1283 // <Get MDRII Data Info Command>
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001284 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1285 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_INFO,
1286 ipmi::Privilege::Operator, mdr2GetDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001287
1288 // <Send MDRII Info Offer>
jayaprakash Mutyala853d8292019-05-31 18:17:42 +00001289 ipmi::registerHandler(
1290 ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1291 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO_OFFER,
1292 ipmi::Privilege::Operator, mdr2DataInfoOffer);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001293
1294 // <Send MDRII Data Info>
jayaprakash Mutyalaf5d49d62019-06-18 12:28:01 +00001295 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1296 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_INFO,
1297 ipmi::Privilege::Operator, mdr2SendDataInfo);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001298
1299 // <Get MDRII Data Block Command>
1300 ipmi_register_callback(NETFUN_INTEL_APP_OEM,
1301 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_GET_DATA_BLOCK,
1302 NULL, cmd_mdr2_get_data_block, PRIVILEGE_OPERATOR);
1303
1304 // <Send MDRII Data Block>
jayaprakash Mutyala3104b3f2019-06-10 19:23:07 +00001305 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1306 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_SEND_DATA_BLOCK,
1307 ipmi::Privilege::Operator, mdr2SendDataBlock);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001308
1309 // <Lock MDRII Data Command>
jayaprakash Mutyala40fec612019-06-19 11:53:03 +00001310 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1311 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_LOCK_DATA,
1312 ipmi::Privilege::Operator, mdr2LockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001313
1314 // <Unlock MDRII Data Command>
jayaprakash Mutyaladad548b2019-06-12 15:29:39 +00001315 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1316 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_UNLOCK_DATA,
1317 ipmi::Privilege::Operator, mdr2UnlockData);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001318
1319 // <Send MDRII Data Start>
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001320 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1321 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_START,
1322 ipmi::Privilege::Operator, cmd_mdr2_data_start);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001323
1324 // <Send MDRII Data Done>
Deepak Kumar Sahu529d4152019-05-31 18:23:14 +00001325 ipmi::registerHandler(ipmi::prioOemBase, NETFUN_INTEL_APP_OEM,
1326 IPMI_NETFN_INTEL_OEM_APP_CMD::MDRII_DATA_DONE,
1327 ipmi::Privilege::Operator, cmd_mdr2_data_done);
Vernon Mauerya3702c12019-05-22 13:20:59 -07001328}