From e023220be42d5f0ef410238f35364e328d1bff8c Mon Sep 17 00:00:00 2001 From: Robin Mueller Date: Fri, 14 Apr 2023 19:42:11 +0200 Subject: [PATCH] better reset handling --- linux/ipcore/PdecHandler.cpp | 39 +++++++++++++++++++++--------------- linux/ipcore/PdecHandler.h | 6 ++++-- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/linux/ipcore/PdecHandler.cpp b/linux/ipcore/PdecHandler.cpp index 575844ca..70eaf3e6 100644 --- a/linux/ipcore/PdecHandler.cpp +++ b/linux/ipcore/PdecHandler.cpp @@ -156,8 +156,8 @@ ReturnValue_t PdecHandler::polledOperation() { // See https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt.html for more information. ReturnValue_t PdecHandler::irqOperation() { ReturnValue_t result = returnvalue::OK; - int fd = -1; - // Used to unmask IRQ + // int fd = -1; + // Used to unmask IRQ uint32_t info = 1; interruptWindowCd.resetTimer(); @@ -176,7 +176,7 @@ ReturnValue_t PdecHandler::irqOperation() { if (result != returnvalue::OK) { break; } - openIrqFile(&fd); + openIrqFile(); if (ptmeResetWithReinitializationPending) { actionHelper.finish(true, commandedBy, pdec::RESET_PDEC_WITH_REINIITALIZATION); ptmeResetWithReinitializationPending = false; @@ -195,7 +195,7 @@ ReturnValue_t PdecHandler::irqOperation() { } case State::RUNNING: { doPeriodicWork(); - checkAndHandleIrqs(fd, info); + checkAndHandleIrqs(info); break; } case State::WAIT_FOR_RECOVERY: @@ -236,9 +236,9 @@ ReturnValue_t PdecHandler::handleInitState() { return returnvalue::OK; } -void PdecHandler::openIrqFile(int* fd) { - *fd = open(uioNames.irq, O_RDWR); - if (*fd < 0) { +void PdecHandler::openIrqFile() { + irqFd = open(uioNames.irq, O_RDWR); + if (irqFd < 0) { sif::error << "PdecHandler::irqOperation: Opening UIO IRQ file" << uioNames.irq << " failed" << std::endl; triggerEvent(OPEN_IRQ_FILE_FAILED); @@ -246,16 +246,16 @@ void PdecHandler::openIrqFile(int* fd) { } } -ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) { - ssize_t nb = write(fd, &info, sizeof(info)); +ReturnValue_t PdecHandler::checkAndHandleIrqs(uint32_t& info) { + ssize_t nb = write(irqFd, &info, sizeof(info)); if (nb != static_cast(sizeof(info))) { sif::error << "PdecHandler::irqOperation: Unmasking IRQ failed" << std::endl; triggerEvent(WRITE_SYSCALL_ERROR_PDEC, errno); - close(fd); + close(irqFd); state = State::INIT; return returnvalue::FAILED; } - struct pollfd fds = {.fd = fd, .events = POLLIN, .revents = 0}; + struct pollfd fds = {.fd = irqFd, .events = POLLIN, .revents = 0}; int ret = poll(&fds, 1, IRQ_TIMEOUT_MS); if (ret == 0) { // No TCs for timeout period @@ -263,7 +263,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) { resetIrqLimiters(); } else if (ret >= 1) { // Interrupt handling. - nb = read(fd, &info, sizeof(info)); + nb = read(irqFd, &info, sizeof(info)); interruptCounter++; if (nb == static_cast(sizeof(info))) { uint32_t pisr = *(registerBaseAddress + PDEC_PISR_OFFSET); @@ -302,7 +302,7 @@ ReturnValue_t PdecHandler::checkAndHandleIrqs(int fd, uint32_t& info) { sif::error << "PdecHandler::irqOperation: Poll error with errno " << errno << ": " << strerror(errno) << std::endl; triggerEvent(POLL_SYSCALL_ERROR_PDEC, errno); - close(fd); + close(irqFd); state = State::INIT; return returnvalue::FAILED; } @@ -347,7 +347,7 @@ ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t c return EXECUTION_FINISHED; } case RESET_PDEC_WITH_REINIITALIZATION: { - state = State::PDEC_RESET; + initializeReset(); ptmeResetWithReinitializationPending = true; this->commandedBy = commandedBy; return returnvalue::OK; @@ -380,7 +380,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi return returnvalue::FAILED; } // PDEC needs reset to apply this parameter change - state = State::PDEC_RESET; + initializeReset(); return returnvalue::OK; } else if ((domainId == 0) and (uniqueIdentifier == ParameterId::NEGATIVE_WINDOW)) { uint8_t newVal = 0; @@ -402,7 +402,7 @@ ReturnValue_t PdecHandler::getParameter(uint8_t domainId, uint8_t uniqueIdentifi return returnvalue::FAILED; } // PDEC needs reset to apply this parameter change - state = State::PDEC_RESET; + initializeReset(); return returnvalue::OK; } return returnvalue::OK; @@ -797,6 +797,13 @@ ReturnValue_t PdecHandler::postResetOperation() { return result; } +void PdecHandler::initializeReset() { + if (irqFd != 0) { + close(irqFd); + } + state = State::PDEC_RESET; +} + std::string PdecHandler::getMonStatusString(uint32_t status) { switch (status) { case TC_CHANNEL_INACTIVE: diff --git a/linux/ipcore/PdecHandler.h b/linux/ipcore/PdecHandler.h index 70b85ecd..fd3c7362 100644 --- a/linux/ipcore/PdecHandler.h +++ b/linux/ipcore/PdecHandler.h @@ -171,6 +171,7 @@ class PdecHandler : public SystemObject, Countdown genericCheckCd = Countdown(IRQ_TIMEOUT_MS); object_id_t tcDestinationId; + int irqFd = 0; AcceptsTelecommandsIF* tcDestination = nullptr; @@ -243,8 +244,8 @@ class PdecHandler : public SystemObject, ReturnValue_t polledOperation(); ReturnValue_t irqOperation(); ReturnValue_t handleInitState(); - void openIrqFile(int* fd); - ReturnValue_t checkAndHandleIrqs(int fd, uint32_t& info); + void openIrqFile(); + ReturnValue_t checkAndHandleIrqs(uint32_t& info); uint32_t readFar(); @@ -366,6 +367,7 @@ class PdecHandler : public SystemObject, void pdecResetNoInit(); ReturnValue_t postResetOperation(); + void initializeReset(); void initFailedHandler(ReturnValue_t reason);