ipmbbridged.cpp (bbfd00abdbc6d2f7c0389eae91cc055a1d4fe0c3) ipmbbridged.cpp (37a7eace7148ae352d9f4f2fb2ae29e2f0d01e09)
1/* Copyright 2018 Intel
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *

--- 75 unchanged lines hidden (view full) ---

84 {
85 data.insert(data.end(), ipmbBuffer->Header.Req.data,
86 &ipmbBuffer->Header.Req.data[dataLength]);
87 }
88}
89
90int IpmbRequest::ipmbToi2cConstruct(std::vector<uint8_t> &buffer)
91{
1/* Copyright 2018 Intel
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *

--- 75 unchanged lines hidden (view full) ---

84 {
85 data.insert(data.end(), ipmbBuffer->Header.Req.data,
86 &ipmbBuffer->Header.Req.data[dataLength]);
87 }
88}
89
90int IpmbRequest::ipmbToi2cConstruct(std::vector<uint8_t> &buffer)
91{
92 size_t bufferLength = data.size() + ipmbRequestDataHeaderLength +
92 /* Add one byte for length byte as per required by driver */
93 size_t bufferLength = 1 + data.size() + ipmbRequestDataHeaderLength +
93 ipmbConnectionHeaderLength + ipmbChecksumSize;
94
95 if (bufferLength > ipmbMaxFrameLength)
96 {
97 return -1;
98 }
99
100 buffer.resize(bufferLength);
101 static_assert(ipmbMaxFrameLength >= sizeof(IPMB_HEADER));
94 ipmbConnectionHeaderLength + ipmbChecksumSize;
95
96 if (bufferLength > ipmbMaxFrameLength)
97 {
98 return -1;
99 }
100
101 buffer.resize(bufferLength);
102 static_assert(ipmbMaxFrameLength >= sizeof(IPMB_HEADER));
102 auto ipmbBuffer = reinterpret_cast<IPMB_HEADER *>(buffer.data());
103 IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer.data());
104 ipmbPkt->len = bufferLength - 1;
105 IPMB_HEADER *ipmbBuffer = &(ipmbPkt->hdr);
103
104 // constructing buffer from ipmb request
105 ipmbBuffer->Header.Req.address = address;
106 ipmbBuffer->Header.Req.rsNetFnLUN = ipmbNetFnLunSet(netFn, rsLun);
107 ipmbBuffer->Header.Req.rqSA = rqSA;
108 ipmbBuffer->Header.Req.rqSeqLUN = ipmbSeqLunSet(seq, rqLun);
109 ipmbBuffer->Header.Req.cmd = cmd;
110
111 ipmbBuffer->Header.Req.checksum1 = ipmbChecksumCompute(
106
107 // constructing buffer from ipmb request
108 ipmbBuffer->Header.Req.address = address;
109 ipmbBuffer->Header.Req.rsNetFnLUN = ipmbNetFnLunSet(netFn, rsLun);
110 ipmbBuffer->Header.Req.rqSA = rqSA;
111 ipmbBuffer->Header.Req.rqSeqLUN = ipmbSeqLunSet(seq, rqLun);
112 ipmbBuffer->Header.Req.cmd = cmd;
113
114 ipmbBuffer->Header.Req.checksum1 = ipmbChecksumCompute(
112 buffer.data(), ipmbConnectionHeaderLength - ipmbChecksumSize);
115 (uint8_t *)ipmbBuffer, ipmbConnectionHeaderLength - ipmbChecksumSize);
113
114 if (data.size() > 0)
115 {
116 std::copy(data.begin(), data.end(), ipmbBuffer->Header.Req.data);
117 }
118
119 buffer[bufferLength - ipmbChecksumSize] =
116
117 if (data.size() > 0)
118 {
119 std::copy(data.begin(), data.end(), ipmbBuffer->Header.Req.data);
120 }
121
122 buffer[bufferLength - ipmbChecksumSize] =
120 ipmbChecksumCompute(buffer.data() + ipmbChecksum2StartOffset,
123 ipmbChecksumCompute((uint8_t *)ipmbBuffer + ipmbChecksum2StartOffset,
121 (ipmbRequestDataHeaderLength + data.size()));
122
123 return 0;
124}
125
126std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
127 IpmbRequest::returnMatchedResponse()
128{

--- 54 unchanged lines hidden (view full) ---

183 {
184 data.insert(data.end(), ipmbBuffer->Header.Resp.data,
185 &ipmbBuffer->Header.Resp.data[dataLength]);
186 }
187}
188
189std::shared_ptr<std::vector<uint8_t>> IpmbResponse::ipmbToi2cConstruct()
190{
124 (ipmbRequestDataHeaderLength + data.size()));
125
126 return 0;
127}
128
129std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
130 IpmbRequest::returnMatchedResponse()
131{

--- 54 unchanged lines hidden (view full) ---

186 {
187 data.insert(data.end(), ipmbBuffer->Header.Resp.data,
188 &ipmbBuffer->Header.Resp.data[dataLength]);
189 }
190}
191
192std::shared_ptr<std::vector<uint8_t>> IpmbResponse::ipmbToi2cConstruct()
193{
191 size_t bufferLength = data.size() + ipmbResponseDataHeaderLength +
194 /* Add one byte for length byte as per required by driver */
195 size_t bufferLength = 1 + data.size() + ipmbResponseDataHeaderLength +
192 ipmbConnectionHeaderLength + ipmbChecksumSize;
193
194 if (bufferLength > ipmbMaxFrameLength)
195 {
196 return nullptr;
197 }
198
199 std::shared_ptr<std::vector<uint8_t>> buffer =
200 std::make_shared<std::vector<uint8_t>>(bufferLength);
201
196 ipmbConnectionHeaderLength + ipmbChecksumSize;
197
198 if (bufferLength > ipmbMaxFrameLength)
199 {
200 return nullptr;
201 }
202
203 std::shared_ptr<std::vector<uint8_t>> buffer =
204 std::make_shared<std::vector<uint8_t>>(bufferLength);
205
202 auto ipmbBuffer = reinterpret_cast<IPMB_HEADER *>(buffer->data());
206 IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer->data());
207 ipmbPkt->len = bufferLength - 1;
208 IPMB_HEADER *ipmbBuffer = &(ipmbPkt->hdr);
203
204 ipmbBuffer->Header.Resp.address = address;
205 ipmbBuffer->Header.Resp.rqNetFnLUN = ipmbNetFnLunSet(netFn, rqLun);
206 ipmbBuffer->Header.Resp.rsSA = rsSA;
207 ipmbBuffer->Header.Resp.rsSeqLUN = ipmbSeqLunSet(seq, rsLun);
208 ipmbBuffer->Header.Resp.cmd = cmd;
209 ipmbBuffer->Header.Resp.completionCode = completionCode;
210
211 ipmbBuffer->Header.Resp.checksum1 = ipmbChecksumCompute(
209
210 ipmbBuffer->Header.Resp.address = address;
211 ipmbBuffer->Header.Resp.rqNetFnLUN = ipmbNetFnLunSet(netFn, rqLun);
212 ipmbBuffer->Header.Resp.rsSA = rsSA;
213 ipmbBuffer->Header.Resp.rsSeqLUN = ipmbSeqLunSet(seq, rsLun);
214 ipmbBuffer->Header.Resp.cmd = cmd;
215 ipmbBuffer->Header.Resp.completionCode = completionCode;
216
217 ipmbBuffer->Header.Resp.checksum1 = ipmbChecksumCompute(
212 buffer->data(), ipmbConnectionHeaderLength - ipmbChecksumSize);
218 (uint8_t *)ipmbBuffer, ipmbConnectionHeaderLength - ipmbChecksumSize);
213
214 if (data.size() > 0)
215 {
216 std::copy(data.begin(), data.end(), ipmbBuffer->Header.Resp.data);
217 }
218
219 (*buffer)[bufferLength - ipmbChecksumSize] =
219
220 if (data.size() > 0)
221 {
222 std::copy(data.begin(), data.end(), ipmbBuffer->Header.Resp.data);
223 }
224
225 (*buffer)[bufferLength - ipmbChecksumSize] =
220 ipmbChecksumCompute(buffer->data() + ipmbChecksum2StartOffset,
226 ipmbChecksumCompute((uint8_t *)ipmbBuffer + ipmbChecksum2StartOffset,
221 (ipmbResponseDataHeaderLength + data.size()));
222
223 return buffer;
224}
225
226bool IpmbCommandFilter::isBlocked(const uint8_t reqNetFn, const uint8_t cmd)
227{
228 auto blockedCmd = unhandledCommands.find({reqNetFn, cmd});

--- 18 unchanged lines hidden (view full) ---

247}
248
249/**
250 * @brief Ipmb channel
251 */
252void IpmbChannel::ipmbSendI2cFrame(std::shared_ptr<std::vector<uint8_t>> buffer,
253 size_t retriesAttempted = 0)
254{
227 (ipmbResponseDataHeaderLength + data.size()));
228
229 return buffer;
230}
231
232bool IpmbCommandFilter::isBlocked(const uint8_t reqNetFn, const uint8_t cmd)
233{
234 auto blockedCmd = unhandledCommands.find({reqNetFn, cmd});

--- 18 unchanged lines hidden (view full) ---

253}
254
255/**
256 * @brief Ipmb channel
257 */
258void IpmbChannel::ipmbSendI2cFrame(std::shared_ptr<std::vector<uint8_t>> buffer,
259 size_t retriesAttempted = 0)
260{
255 // construct i2c frame and call ioctl to send it
256 auto ipmbFrame = reinterpret_cast<IPMB_HEADER *>(buffer->data());
257 uint8_t targetAddr = ipmbIsResponse(ipmbFrame)
258 ? ipmbFrame->Header.Resp.address
259 : ipmbFrame->Header.Req.address;
260 io.post([this, buffer, retriesAttempted, targetAddr]() {
261 ioWrite ioData(*buffer);
262 boost::system::error_code ec;
263 i2cMasterSocket.io_control(ioData, ec);
264 if (ec)
265 {
266 size_t currentRetryCnt = retriesAttempted;
267 if (currentRetryCnt > ipmbI2cNumberOfRetries)
261 IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer->data());
262 uint8_t targetAddr = ipmbIsResponse(&(ipmbPkt->hdr))
263 ? ipmbPkt->hdr.Header.Resp.address
264 : ipmbPkt->hdr.Header.Req.address;
265 boost::asio::async_write(
266 i2cSlaveDescriptor, boost::asio::buffer(*buffer),
267 [this, buffer, retriesAttempted,
268 targetAddr](const boost::system::error_code &ec, size_t bytesSent) {
269 if (ec)
268 {
270 {
269 std::string msgToLog =
270 "ipmbSendI2cFrame: sent to I2C failed after retries."
271 " busId=" +
272 std::to_string(ipmbBusId) +
273 ", targetAddr=" + std::to_string(targetAddr) +
274 ", error=" + ec.message();
275 phosphor::logging::log<phosphor::logging::level::ERR>(
276 msgToLog.c_str());
277 return;
271 size_t currentRetryCnt = retriesAttempted;
272
273 if (currentRetryCnt > ipmbI2cNumberOfRetries)
274 {
275 std::string msgToLog =
276 "ipmbSendI2cFrame: send to I2C failed after retries."
277 " busId=" +
278 std::to_string(ipmbBusId) +
279 ", targetAddr=" + std::to_string(targetAddr) +
280 ", error=" + ec.message();
281 phosphor::logging::log<phosphor::logging::level::ERR>(
282 msgToLog.c_str());
283 return;
284 }
285 currentRetryCnt++;
286 ipmbSendI2cFrame(buffer, currentRetryCnt);
278 }
287 }
279 currentRetryCnt++;
280 ipmbSendI2cFrame(buffer, currentRetryCnt);
281 }
282 });
288 });
283}
284
285/**
286 * @brief Ipmb Outstanding Requests
287 */
288void IpmbChannel::makeRequestInvalid(IpmbRequest &request)
289{
290 // change request state to invalid and remove it from outstanding requests

--- 48 unchanged lines hidden (view full) ---

339 request->matchedResponse = std::move(response);
340 }
341 }
342}
343
344void IpmbChannel::processI2cEvent()
345{
346 std::array<uint8_t, ipmbMaxFrameLength> buffer{};
289}
290
291/**
292 * @brief Ipmb Outstanding Requests
293 */
294void IpmbChannel::makeRequestInvalid(IpmbRequest &request)
295{
296 // change request state to invalid and remove it from outstanding requests

--- 48 unchanged lines hidden (view full) ---

345 request->matchedResponse = std::move(response);
346 }
347 }
348}
349
350void IpmbChannel::processI2cEvent()
351{
352 std::array<uint8_t, ipmbMaxFrameLength> buffer{};
347 auto ipmbFrame = reinterpret_cast<IPMB_HEADER *>(buffer.data());
353 IPMB_PKT *ipmbPkt = reinterpret_cast<IPMB_PKT *>(buffer.data());
354 IPMB_HEADER *ipmbFrame = &(ipmbPkt->hdr);
348
349 lseek(ipmbi2cSlaveFd, 0, SEEK_SET);
350 int r = read(ipmbi2cSlaveFd, buffer.data(), ipmbMaxFrameLength);
355
356 lseek(ipmbi2cSlaveFd, 0, SEEK_SET);
357 int r = read(ipmbi2cSlaveFd, buffer.data(), ipmbMaxFrameLength);
358
359 /* Substract first byte len size from total frame length */
360 r--;
361
351 if ((r < ipmbMinFrameLength) || (r > ipmbMaxFrameLength))
352 {
353 goto end;
354 }
355
356 // valiate the frame
357 if (!isFrameValid(ipmbFrame, r))
358 {

--- 127 unchanged lines hidden (view full) ---

486 },
487 "xyz.openbmc_project.Ipmi.Host", "/xyz/openbmc_project/Ipmi",
488 "xyz.openbmc_project.Ipmi.Server", "execute",
489 ipmbMessageReceived.netFn, ipmbMessageReceived.rsLun,
490 ipmbMessageReceived.cmd, ipmbMessageReceived.data, options);
491 }
492
493end:
362 if ((r < ipmbMinFrameLength) || (r > ipmbMaxFrameLength))
363 {
364 goto end;
365 }
366
367 // valiate the frame
368 if (!isFrameValid(ipmbFrame, r))
369 {

--- 127 unchanged lines hidden (view full) ---

497 },
498 "xyz.openbmc_project.Ipmi.Host", "/xyz/openbmc_project/Ipmi",
499 "xyz.openbmc_project.Ipmi.Server", "execute",
500 ipmbMessageReceived.netFn, ipmbMessageReceived.rsLun,
501 ipmbMessageReceived.cmd, ipmbMessageReceived.data, options);
502 }
503
504end:
494 i2cSlaveSocket.async_wait(
495 boost::asio::ip::tcp::socket::wait_error,
505 i2cSlaveDescriptor.async_wait(
506 boost::asio::posix::descriptor_base::wait_read,
496 [this](const boost::system::error_code &ec) {
497 if (ec)
498 {
499 phosphor::logging::log<phosphor::logging::level::ERR>(
500 "Error: processI2cEvent()");
501 return;
502 }
503
504 processI2cEvent();
505 });
506}
507
508IpmbChannel::IpmbChannel(boost::asio::io_service &io,
509 uint8_t ipmbBmcSlaveAddress,
510 uint8_t ipmbRqSlaveAddress, ipmbChannelType type,
511 std::shared_ptr<IpmbCommandFilter> commandFilter) :
507 [this](const boost::system::error_code &ec) {
508 if (ec)
509 {
510 phosphor::logging::log<phosphor::logging::level::ERR>(
511 "Error: processI2cEvent()");
512 return;
513 }
514
515 processI2cEvent();
516 });
517}
518
519IpmbChannel::IpmbChannel(boost::asio::io_service &io,
520 uint8_t ipmbBmcSlaveAddress,
521 uint8_t ipmbRqSlaveAddress, ipmbChannelType type,
522 std::shared_ptr<IpmbCommandFilter> commandFilter) :
512 i2cSlaveSocket(io),
513 i2cMasterSocket(io), ipmbBmcSlaveAddress(ipmbBmcSlaveAddress),
523 i2cSlaveDescriptor(io),
524 ipmbBmcSlaveAddress(ipmbBmcSlaveAddress),
514 ipmbRqSlaveAddress(ipmbRqSlaveAddress), type(type),
515 commandFilter(commandFilter)
516{
517}
518
525 ipmbRqSlaveAddress(ipmbRqSlaveAddress), type(type),
526 commandFilter(commandFilter)
527{
528}
529
519int IpmbChannel::ipmbChannelInit(const char *ipmbI2cSlave,
520 const char *ipmbI2cMaster)
530int IpmbChannel::ipmbChannelInit(const char *ipmbI2cSlave)
521{
531{
522 // extract bus id from master path and save
523 std::string ipmbI2cMasterStr(ipmbI2cMaster);
524 auto findHyphen = ipmbI2cMasterStr.find("-");
525 std::string busStr = ipmbI2cMasterStr.substr(findHyphen + 1);
532 // extract bus id from slave path and save
533 std::string ipmbI2cSlaveStr(ipmbI2cSlave);
534 auto findHyphen = ipmbI2cSlaveStr.find("-");
535 std::string busStr = ipmbI2cSlaveStr.substr(findHyphen + 1);
526 try
527 {
528 ipmbBusId = std::stoi(busStr);
529 }
530 catch (std::invalid_argument)
531 {
532 phosphor::logging::log<phosphor::logging::level::ERR>(
536 try
537 {
538 ipmbBusId = std::stoi(busStr);
539 }
540 catch (std::invalid_argument)
541 {
542 phosphor::logging::log<phosphor::logging::level::ERR>(
533 "ipmbChannelInit: invalid bus id in master-path config");
543 "ipmbChannelInit: invalid bus id in slave-path config");
534 return -1;
535 }
536
537 // Check if sysfs has device. If not, enable I2C slave driver by command
544 return -1;
545 }
546
547 // Check if sysfs has device. If not, enable I2C slave driver by command
538 // echo "slave-mqueue 0x1010" > /sys/bus/i2c/devices/i2c-0/new_device
548 // echo "ipmb-dev 0x1010" > /sys/bus/i2c/devices/i2c-0/new_device
539 bool hasSysfs = std::filesystem::exists(ipmbI2cSlave);
540 if (!hasSysfs)
541 {
542 std::string deviceFileName =
543 "/sys/bus/i2c/devices/i2c-" + busStr + "/new_device";
549 bool hasSysfs = std::filesystem::exists(ipmbI2cSlave);
550 if (!hasSysfs)
551 {
552 std::string deviceFileName =
553 "/sys/bus/i2c/devices/i2c-" + busStr + "/new_device";
544 std::string para = "slave-mqueue 0x1010"; // init with BMC addr 0x20
554 std::string para = "ipmb-dev 0x1010"; // init with BMC addr 0x20
545 std::fstream deviceFile;
546 deviceFile.open(deviceFileName, std::ios::out);
547 if (!deviceFile.good())
548 {
549 phosphor::logging::log<phosphor::logging::level::ERR>(
550 "ipmbChannelInit: error opening deviceFile");
551 return -1;
552 }
553 deviceFile << para;
554 deviceFile.close();
555 }
556
555 std::fstream deviceFile;
556 deviceFile.open(deviceFileName, std::ios::out);
557 if (!deviceFile.good())
558 {
559 phosphor::logging::log<phosphor::logging::level::ERR>(
560 "ipmbChannelInit: error opening deviceFile");
561 return -1;
562 }
563 deviceFile << para;
564 deviceFile.close();
565 }
566
557 // open fd to i2c slave device
558 ipmbi2cSlaveFd = open(ipmbI2cSlave, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
567 // open fd to i2c slave device for read write
568 ipmbi2cSlaveFd = open(ipmbI2cSlave, O_RDWR | O_NONBLOCK | O_CLOEXEC);
559 if (ipmbi2cSlaveFd < 0)
560 {
561 phosphor::logging::log<phosphor::logging::level::ERR>(
562 "ipmbChannelInit: error opening ipmbI2cSlave");
563 return -1;
564 }
565
569 if (ipmbi2cSlaveFd < 0)
570 {
571 phosphor::logging::log<phosphor::logging::level::ERR>(
572 "ipmbChannelInit: error opening ipmbI2cSlave");
573 return -1;
574 }
575
566 // open fd to i2c master device
567 ipmbi2cMasterFd = open(ipmbI2cMaster, O_RDWR | O_NONBLOCK);
568 if (ipmbi2cMasterFd < 0)
569 {
570 phosphor::logging::log<phosphor::logging::level::ERR>(
571 "ipmbChannelInit: error opening ipmbI2cMaster");
572 close(ipmbi2cSlaveFd);
573 ipmbi2cSlaveFd = 0;
574 return -1;
575 }
576 i2cSlaveDescriptor.assign(ipmbi2cSlaveFd);
576
577
577 // set slave address of recipient
578 if (ioctl(ipmbi2cMasterFd, I2C_SLAVE,
579 ipmbAddressTo7BitSet(ipmbRqSlaveAddress)) < 0)
580 {
581 phosphor::logging::log<phosphor::logging::level::ERR>(
582 "ipmbChannelInit: error setting ipmbi2cMasterFd slave address");
583 close(ipmbi2cSlaveFd);
584 close(ipmbi2cMasterFd);
585 ipmbi2cSlaveFd = 0;
586 ipmbi2cMasterFd = 0;
587 return -1;
588 }
589
590 i2cMasterSocket.assign(ipmbi2cMasterFd);
591 i2cSlaveSocket.assign(boost::asio::ip::tcp::v4(), ipmbi2cSlaveFd);
592 i2cSlaveSocket.async_wait(
593 boost::asio::ip::tcp::socket::wait_error,
578 i2cSlaveDescriptor.async_wait(
579 boost::asio::posix::descriptor_base::wait_read,
594 [this](const boost::system::error_code &ec) {
595 if (ec)
596 {
597 phosphor::logging::log<phosphor::logging::level::ERR>(
598 "Error: processI2cEvent()");
599 return;
600 }
601
602 processI2cEvent();
603 });
604
605 return 0;
606}
607
608int IpmbChannel::ipmbChannelUpdateSlaveAddress(const uint8_t newBmcSlaveAddr)
609{
610 if (ipmbi2cSlaveFd > 0)
611 {
580 [this](const boost::system::error_code &ec) {
581 if (ec)
582 {
583 phosphor::logging::log<phosphor::logging::level::ERR>(
584 "Error: processI2cEvent()");
585 return;
586 }
587
588 processI2cEvent();
589 });
590
591 return 0;
592}
593
594int IpmbChannel::ipmbChannelUpdateSlaveAddress(const uint8_t newBmcSlaveAddr)
595{
596 if (ipmbi2cSlaveFd > 0)
597 {
612 i2cSlaveSocket.close();
598 i2cSlaveDescriptor.close();
613 close(ipmbi2cSlaveFd);
614 ipmbi2cSlaveFd = 0;
615 }
616
617 // disable old I2C slave driver by command:
618 // echo "0x1010" > /sys/bus/i2c/devices/i2c-0/delete_device
619 std::string deviceFileName;
620 std::string para;

--- 8 unchanged lines hidden (view full) ---

629 "ipmbChannelUpdateSlaveAddress: error opening deviceFile to delete "
630 "sysfs");
631 return -1;
632 }
633 deviceFile << para;
634 deviceFile.close();
635
636 // enable new I2C slave driver by command:
599 close(ipmbi2cSlaveFd);
600 ipmbi2cSlaveFd = 0;
601 }
602
603 // disable old I2C slave driver by command:
604 // echo "0x1010" > /sys/bus/i2c/devices/i2c-0/delete_device
605 std::string deviceFileName;
606 std::string para;

--- 8 unchanged lines hidden (view full) ---

615 "ipmbChannelUpdateSlaveAddress: error opening deviceFile to delete "
616 "sysfs");
617 return -1;
618 }
619 deviceFile << para;
620 deviceFile.close();
621
622 // enable new I2C slave driver by command:
637 // echo "slave-mqueue 0x1012" > /sys/bus/i2c/devices/i2c-0/new_device
623 // echo "ipmb-dev 0x1012" > /sys/bus/i2c/devices/i2c-0/new_device
638 deviceFileName =
639 "/sys/bus/i2c/devices/i2c-" + std::to_string(ipmbBusId) + "/new_device";
640 std::ostringstream hex;
641 uint16_t addr = 0x1000 + (newBmcSlaveAddr >> 1);
642 hex << std::hex << static_cast<uint16_t>(addr);
643 const std::string &addressHexStr = hex.str();
624 deviceFileName =
625 "/sys/bus/i2c/devices/i2c-" + std::to_string(ipmbBusId) + "/new_device";
626 std::ostringstream hex;
627 uint16_t addr = 0x1000 + (newBmcSlaveAddr >> 1);
628 hex << std::hex << static_cast<uint16_t>(addr);
629 const std::string &addressHexStr = hex.str();
644 para = "slave-mqueue 0x" + addressHexStr;
630 para = "ipmb-dev 0x" + addressHexStr;
645 deviceFile.open(deviceFileName, std::ios::out);
646 if (!deviceFile.good())
647 {
648 phosphor::logging::log<phosphor::logging::level::ERR>(
649 "ipmbChannelUpdateSlaveAddress: error opening deviceFile to create "
650 "sysfs");
651 return -1;
652 }
653 deviceFile << para;
654 deviceFile.close();
655
656 // open fd to i2c slave device
631 deviceFile.open(deviceFileName, std::ios::out);
632 if (!deviceFile.good())
633 {
634 phosphor::logging::log<phosphor::logging::level::ERR>(
635 "ipmbChannelUpdateSlaveAddress: error opening deviceFile to create "
636 "sysfs");
637 return -1;
638 }
639 deviceFile << para;
640 deviceFile.close();
641
642 // open fd to i2c slave device
657 std::string ipmbI2cSlaveStr = "/sys/bus/i2c/devices/" +
658 std::to_string(ipmbBusId) + "-" +
659 addressHexStr + "/slave-mqueue";
660 ipmbi2cSlaveFd =
661 open(ipmbI2cSlaveStr.c_str(), O_RDONLY | O_NONBLOCK | O_CLOEXEC);
643 std::string ipmbI2cSlaveStr = "/dev/ipmb-" + std::to_string(ipmbBusId);
644 ipmbi2cSlaveFd = open(ipmbI2cSlaveStr.c_str(), O_RDWR | O_NONBLOCK);
662 if (ipmbi2cSlaveFd < 0)
663 {
664 phosphor::logging::log<phosphor::logging::level::ERR>(
665 "ipmbChannelInit: error opening ipmbI2cSlave");
666 return -1;
667 }
668
669 // start to receive i2c data as slave
645 if (ipmbi2cSlaveFd < 0)
646 {
647 phosphor::logging::log<phosphor::logging::level::ERR>(
648 "ipmbChannelInit: error opening ipmbI2cSlave");
649 return -1;
650 }
651
652 // start to receive i2c data as slave
670 i2cSlaveSocket.assign(boost::asio::ip::tcp::v4(), ipmbi2cSlaveFd);
671 i2cSlaveSocket.async_wait(
672 boost::asio::ip::tcp::socket::wait_error,
653 i2cSlaveDescriptor.assign(ipmbi2cSlaveFd);
654 i2cSlaveDescriptor.async_wait(
655 boost::asio::posix::descriptor_base::wait_read,
673 [this](const boost::system::error_code &ec) {
674 if (ec)
675 {
676 phosphor::logging::log<phosphor::logging::level::ERR>(
677 "Error: processI2cEvent()");
678 return;
679 }
680

--- 47 unchanged lines hidden (view full) ---

728
729 for (int i = 0; i < ipmbNumberOfTries; i++)
730 {
731 boost::system::error_code ec;
732 int i2cRetryCnt = 0;
733
734 for (; i2cRetryCnt < ipmbI2cNumberOfRetries; i2cRetryCnt++)
735 {
656 [this](const boost::system::error_code &ec) {
657 if (ec)
658 {
659 phosphor::logging::log<phosphor::logging::level::ERR>(
660 "Error: processI2cEvent()");
661 return;
662 }
663

--- 47 unchanged lines hidden (view full) ---

711
712 for (int i = 0; i < ipmbNumberOfTries; i++)
713 {
714 boost::system::error_code ec;
715 int i2cRetryCnt = 0;
716
717 for (; i2cRetryCnt < ipmbI2cNumberOfRetries; i2cRetryCnt++)
718 {
736 boost::asio::async_write(
737 i2cMasterSocket,
738 boost::asio::buffer(buffer.data() + ipmbAddressSize,
739 buffer.size() - ipmbAddressSize),
740 yield[ec]);
719 boost::asio::async_write(i2cSlaveDescriptor,
720 boost::asio::buffer(buffer), yield[ec]);
741
742 if (ec)
743 {
744 continue; // retry
745 }
746 break;
747 }
748

--- 62 unchanged lines hidden (view full) ---

811 return -1;
812 }
813 try
814 {
815 auto data = nlohmann::json::parse(configFile, nullptr);
816 for (const auto &channelConfig : data["channels"])
817 {
818 const std::string &typeConfig = channelConfig["type"];
721
722 if (ec)
723 {
724 continue; // retry
725 }
726 break;
727 }
728

--- 62 unchanged lines hidden (view full) ---

791 return -1;
792 }
793 try
794 {
795 auto data = nlohmann::json::parse(configFile, nullptr);
796 for (const auto &channelConfig : data["channels"])
797 {
798 const std::string &typeConfig = channelConfig["type"];
819 const std::string &masterPath = channelConfig["master-path"];
820 const std::string &slavePath = channelConfig["slave-path"];
821 uint8_t bmcAddr = channelConfig["bmc-addr"];
822 uint8_t reqAddr = channelConfig["remote-addr"];
823 ipmbChannelType type = ipmbChannelTypeMap.at(typeConfig);
824
825 auto channel = ipmbChannels.emplace(ipmbChannels.end(), io, bmcAddr,
826 reqAddr, type, commandFilter);
799 const std::string &slavePath = channelConfig["slave-path"];
800 uint8_t bmcAddr = channelConfig["bmc-addr"];
801 uint8_t reqAddr = channelConfig["remote-addr"];
802 ipmbChannelType type = ipmbChannelTypeMap.at(typeConfig);
803
804 auto channel = ipmbChannels.emplace(ipmbChannels.end(), io, bmcAddr,
805 reqAddr, type, commandFilter);
827 if (channel->ipmbChannelInit(slavePath.c_str(),
828 masterPath.c_str()) < 0)
806 if (channel->ipmbChannelInit(slavePath.c_str()) < 0)
829 {
830 phosphor::logging::log<phosphor::logging::level::ERR>(
831 "initializeChannels: channel initialization failed");
832 return -1;
833 }
834 }
835 }
836 catch (nlohmann::json::exception &e)

--- 175 unchanged lines hidden ---
807 {
808 phosphor::logging::log<phosphor::logging::level::ERR>(
809 "initializeChannels: channel initialization failed");
810 return -1;
811 }
812 }
813 }
814 catch (nlohmann::json::exception &e)

--- 175 unchanged lines hidden ---