xref: /openbmc/phosphor-debug-collector/host-transport-extensions/pldm/common/pldm_utils.cpp (revision 03414ffa629d290c16d9561d780d140fa1f0ccfa)
13af5c32bSRamesh Iyyar // SPDX-License-Identifier: Apache-2.0
23af5c32bSRamesh Iyyar 
33af5c32bSRamesh Iyyar #include "pldm_utils.hpp"
43af5c32bSRamesh Iyyar 
53af5c32bSRamesh Iyyar #include "dump_utils.hpp"
63af5c32bSRamesh Iyyar #include "xyz/openbmc_project/Common/error.hpp"
73af5c32bSRamesh Iyyar 
811beea45SLakshmi Yadlapati #include <libpldm/transport.h>
9*03414ffaSLakshmi Yadlapati #include <libpldm/transport/mctp-demux.h>
10*03414ffaSLakshmi Yadlapati #include <poll.h>
1111beea45SLakshmi Yadlapati 
123af5c32bSRamesh Iyyar #include <phosphor-logging/elog-errors.hpp>
13d1f670feSDhruvaraj Subhashchandran #include <phosphor-logging/lg2.hpp>
143af5c32bSRamesh Iyyar 
153af5c32bSRamesh Iyyar namespace phosphor
163af5c32bSRamesh Iyyar {
173af5c32bSRamesh Iyyar namespace dump
183af5c32bSRamesh Iyyar {
193af5c32bSRamesh Iyyar namespace pldm
203af5c32bSRamesh Iyyar {
213af5c32bSRamesh Iyyar 
223af5c32bSRamesh Iyyar using namespace phosphor::logging;
233af5c32bSRamesh Iyyar using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
243af5c32bSRamesh Iyyar using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
253af5c32bSRamesh Iyyar 
2611beea45SLakshmi Yadlapati pldm_instance_db* pldmInstanceIdDb = nullptr;
27*03414ffaSLakshmi Yadlapati pldm_transport* pldmTransport = nullptr;
28*03414ffaSLakshmi Yadlapati pldm_transport_mctp_demux* mctpDemux = nullptr;
2911beea45SLakshmi Yadlapati 
PLDMInstanceManager()3011beea45SLakshmi Yadlapati PLDMInstanceManager::PLDMInstanceManager()
3111beea45SLakshmi Yadlapati {
3211beea45SLakshmi Yadlapati     initPLDMInstanceIdDb();
3311beea45SLakshmi Yadlapati }
3411beea45SLakshmi Yadlapati 
~PLDMInstanceManager()3511beea45SLakshmi Yadlapati PLDMInstanceManager::~PLDMInstanceManager()
3611beea45SLakshmi Yadlapati {
3711beea45SLakshmi Yadlapati     destroyPLDMInstanceIdDb();
3811beea45SLakshmi Yadlapati }
3911beea45SLakshmi Yadlapati 
initPLDMInstanceIdDb()4011beea45SLakshmi Yadlapati void PLDMInstanceManager::initPLDMInstanceIdDb()
4111beea45SLakshmi Yadlapati {
4211beea45SLakshmi Yadlapati     auto rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
4311beea45SLakshmi Yadlapati     if (rc)
4411beea45SLakshmi Yadlapati     {
4511beea45SLakshmi Yadlapati         lg2::error("Error calling pldm_instance_db_init_default, rc = {RC}",
4611beea45SLakshmi Yadlapati                    "RC", rc);
4711beea45SLakshmi Yadlapati         elog<NotAllowed>(Reason(
4811beea45SLakshmi Yadlapati             "Required host dump action via pldm is not allowed due "
4911beea45SLakshmi Yadlapati             "to pldm_open failed"));
5011beea45SLakshmi Yadlapati     }
5111beea45SLakshmi Yadlapati }
5211beea45SLakshmi Yadlapati 
destroyPLDMInstanceIdDb()5311beea45SLakshmi Yadlapati void PLDMInstanceManager::destroyPLDMInstanceIdDb()
5411beea45SLakshmi Yadlapati {
5511beea45SLakshmi Yadlapati     auto rc = pldm_instance_db_destroy(pldmInstanceIdDb);
5611beea45SLakshmi Yadlapati     if (rc)
5711beea45SLakshmi Yadlapati     {
5811beea45SLakshmi Yadlapati         lg2::error("pldm_instance_db_destroy failed rc = {RC}", "RC", rc);
5911beea45SLakshmi Yadlapati     }
6011beea45SLakshmi Yadlapati }
6111beea45SLakshmi Yadlapati 
getPLDMInstanceID(uint8_t tid)6211beea45SLakshmi Yadlapati pldm_instance_id_t getPLDMInstanceID(uint8_t tid)
6311beea45SLakshmi Yadlapati {
6411beea45SLakshmi Yadlapati     pldm_instance_id_t instanceID = 0;
6511beea45SLakshmi Yadlapati 
6611beea45SLakshmi Yadlapati     auto rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
6711beea45SLakshmi Yadlapati     if (rc == -EAGAIN)
6811beea45SLakshmi Yadlapati     {
6911beea45SLakshmi Yadlapati         std::this_thread::sleep_for(std::chrono::milliseconds(100));
7011beea45SLakshmi Yadlapati         rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
7111beea45SLakshmi Yadlapati     }
7211beea45SLakshmi Yadlapati 
7311beea45SLakshmi Yadlapati     if (rc)
7411beea45SLakshmi Yadlapati     {
7511beea45SLakshmi Yadlapati         lg2::error("Failed to get instance id, rc = {RC}", "RC", rc);
7611beea45SLakshmi Yadlapati         elog<NotAllowed>(Reason(
7711beea45SLakshmi Yadlapati             "Failure in communicating with libpldm service, "
7811beea45SLakshmi Yadlapati             "service may not be running"));
7911beea45SLakshmi Yadlapati     }
8011beea45SLakshmi Yadlapati     lg2::info("Got instanceId: {INSTANCE_ID} from PLDM eid: {EID}",
8111beea45SLakshmi Yadlapati               "INSTANCE_ID", instanceID, "EID", tid);
8211beea45SLakshmi Yadlapati 
8311beea45SLakshmi Yadlapati     return instanceID;
8411beea45SLakshmi Yadlapati }
8511beea45SLakshmi Yadlapati 
freePLDMInstanceID(pldm_instance_id_t instanceID,uint8_t tid)8611beea45SLakshmi Yadlapati void freePLDMInstanceID(pldm_instance_id_t instanceID, uint8_t tid)
8711beea45SLakshmi Yadlapati {
8811beea45SLakshmi Yadlapati     auto rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceID);
8911beea45SLakshmi Yadlapati     if (rc)
9011beea45SLakshmi Yadlapati     {
9111beea45SLakshmi Yadlapati         lg2::error(
9211beea45SLakshmi Yadlapati             "pldm_instance_id_free failed to free id = {ID} of tid = {TID} rc = {RC}",
9311beea45SLakshmi Yadlapati             "ID", instanceID, "TID", tid, "RC", rc);
9411beea45SLakshmi Yadlapati     }
9511beea45SLakshmi Yadlapati }
9611beea45SLakshmi Yadlapati 
openPLDM(mctp_eid_t eid)97*03414ffaSLakshmi Yadlapati int openPLDM(mctp_eid_t eid)
983af5c32bSRamesh Iyyar {
99*03414ffaSLakshmi Yadlapati     auto fd = -1;
100*03414ffaSLakshmi Yadlapati     if (pldmTransport)
101*03414ffaSLakshmi Yadlapati     {
102*03414ffaSLakshmi Yadlapati         lg2::error("open: pldmTransport already setup!");
103*03414ffaSLakshmi Yadlapati         elog<NotAllowed>(Reason(
104*03414ffaSLakshmi Yadlapati             "Required host dump action via pldm is not allowed due "
105*03414ffaSLakshmi Yadlapati             "to openPLDM failed"));
106*03414ffaSLakshmi Yadlapati         return fd;
107*03414ffaSLakshmi Yadlapati     }
108*03414ffaSLakshmi Yadlapati 
109*03414ffaSLakshmi Yadlapati     fd = openMctpDemuxTransport(eid);
1103af5c32bSRamesh Iyyar     if (fd < 0)
1113af5c32bSRamesh Iyyar     {
1123af5c32bSRamesh Iyyar         auto e = errno;
113*03414ffaSLakshmi Yadlapati         lg2::error("openPLDM failed, errno: {ERRNO}, FD: FD", "ERRNO", e, "FD",
11418c7d92eSPatrick Williams                    fd);
115973b291eSPatrick Williams         elog<NotAllowed>(Reason(
116973b291eSPatrick Williams             "Required host dump action via pldm is not allowed due "
117*03414ffaSLakshmi Yadlapati             "to openPLDM failed"));
1183af5c32bSRamesh Iyyar     }
1193af5c32bSRamesh Iyyar     return fd;
1203af5c32bSRamesh Iyyar }
1213af5c32bSRamesh Iyyar 
openMctpDemuxTransport(mctp_eid_t eid)122*03414ffaSLakshmi Yadlapati int openMctpDemuxTransport(mctp_eid_t eid)
123*03414ffaSLakshmi Yadlapati {
124*03414ffaSLakshmi Yadlapati     int rc = pldm_transport_mctp_demux_init(&mctpDemux);
125*03414ffaSLakshmi Yadlapati     if (rc)
126*03414ffaSLakshmi Yadlapati     {
127*03414ffaSLakshmi Yadlapati         lg2::error(
128*03414ffaSLakshmi Yadlapati             "openMctpDemuxTransport: Failed to init MCTP demux transport. rc = {RC}",
129*03414ffaSLakshmi Yadlapati             "RC", rc);
130*03414ffaSLakshmi Yadlapati         return rc;
131*03414ffaSLakshmi Yadlapati     }
132*03414ffaSLakshmi Yadlapati 
133*03414ffaSLakshmi Yadlapati     rc = pldm_transport_mctp_demux_map_tid(mctpDemux, eid, eid);
134*03414ffaSLakshmi Yadlapati     if (rc)
135*03414ffaSLakshmi Yadlapati     {
136*03414ffaSLakshmi Yadlapati         lg2::error(
137*03414ffaSLakshmi Yadlapati             "openMctpDemuxTransport: Failed to setup tid to eid mapping. rc = {RC}",
138*03414ffaSLakshmi Yadlapati             "RC", rc);
139*03414ffaSLakshmi Yadlapati         pldmClose();
140*03414ffaSLakshmi Yadlapati         return rc;
141*03414ffaSLakshmi Yadlapati     }
142*03414ffaSLakshmi Yadlapati     pldmTransport = pldm_transport_mctp_demux_core(mctpDemux);
143*03414ffaSLakshmi Yadlapati 
144*03414ffaSLakshmi Yadlapati     struct pollfd pollfd;
145*03414ffaSLakshmi Yadlapati     rc = pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd);
146*03414ffaSLakshmi Yadlapati     if (rc)
147*03414ffaSLakshmi Yadlapati     {
148*03414ffaSLakshmi Yadlapati         lg2::error("openMctpDemuxTransport: Failed to get pollfd. rc = {RC}",
149*03414ffaSLakshmi Yadlapati                    "RC", rc);
150*03414ffaSLakshmi Yadlapati         pldmClose();
151*03414ffaSLakshmi Yadlapati         return rc;
152*03414ffaSLakshmi Yadlapati     }
153*03414ffaSLakshmi Yadlapati     return pollfd.fd;
154*03414ffaSLakshmi Yadlapati }
155*03414ffaSLakshmi Yadlapati 
pldmClose()156*03414ffaSLakshmi Yadlapati void pldmClose()
157*03414ffaSLakshmi Yadlapati {
158*03414ffaSLakshmi Yadlapati     pldm_transport_mctp_demux_destroy(mctpDemux);
159*03414ffaSLakshmi Yadlapati     mctpDemux = nullptr;
160*03414ffaSLakshmi Yadlapati     pldmTransport = nullptr;
161*03414ffaSLakshmi Yadlapati }
162*03414ffaSLakshmi Yadlapati 
1633af5c32bSRamesh Iyyar } // namespace pldm
1643af5c32bSRamesh Iyyar } // namespace dump
1653af5c32bSRamesh Iyyar } // namespace phosphor
166