1 2 #include "hostSelector_switch.hpp" 3 4 #include <error.h> 5 6 #include <phosphor-logging/lg2.hpp> 7 8 // add the button iface class to registry 9 static ButtonIFRegister<HostSelector> buttonRegister; 10 11 size_t HostSelector::getMappedHSConfig(size_t hsPosition) 12 { 13 size_t adjustedPosition = INVALID_INDEX; // set bmc as default value 14 std::string hsPosStr; 15 hsPosStr = std::to_string(hsPosition); 16 17 if (hsPosMap.find(hsPosStr) != hsPosMap.end()) 18 { 19 adjustedPosition = hsPosMap[hsPosStr]; 20 } 21 else 22 { 23 lg2::debug("getMappedHSConfig : {TYPE}: no valid value in map.", "TYPE", 24 getFormFactorType()); 25 } 26 return adjustedPosition; 27 } 28 29 size_t HostSelector::getGpioIndex(int fd) 30 { 31 for (size_t index = 0; index < gpioLineCount; index++) 32 { 33 if (config.gpios[index].fd == fd) 34 { 35 return index; 36 } 37 } 38 return INVALID_INDEX; 39 } 40 41 char HostSelector::getValueFromFd(int fd) 42 { 43 char buf; 44 auto result = ::lseek(fd, 0, SEEK_SET); 45 46 if (result < 0) 47 { 48 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 49 IOError(); 50 } 51 52 result = ::read(fd, &buf, sizeof(buf)); 53 if (result < 0) 54 { 55 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 56 IOError(); 57 } 58 return buf; 59 } 60 61 void HostSelector::setInitialHostSelectorValue() 62 { 63 size_t hsPosMapped = 0; 64 65 try 66 { 67 if (config.type == ConfigType::gpio) 68 { 69 for (size_t index = 0; index < gpioLineCount; index++) 70 { 71 GpioState gpioState = 72 (getValueFromFd(config.gpios[index].fd) == '0') 73 ? (GpioState::deassert) 74 : (GpioState::assert); 75 setHostSelectorValue(config.gpios[index].fd, gpioState); 76 } 77 hsPosMapped = getMappedHSConfig(hostSelectorPosition); 78 } 79 else if (config.type == ConfigType::cpld) 80 { 81 hsPosMapped = getValueFromFd(config.cpld.cpldMappedFd) - '0'; 82 } 83 } 84 catch (const std::exception& e) 85 { 86 lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE", 87 getFormFactorType(), "ERROR", e.what()); 88 } 89 90 if (hsPosMapped != INVALID_INDEX) 91 { 92 position(hsPosMapped, true); 93 } 94 } 95 96 void HostSelector::setHostSelectorValue(int fd, GpioState state) 97 { 98 size_t pos = getGpioIndex(fd); 99 100 if (pos == INVALID_INDEX) 101 { 102 return; 103 } 104 auto set_bit = [](size_t& val, size_t n) { val |= 0xff & (1 << n); }; 105 106 auto clr_bit = [](size_t& val, size_t n) { val &= ~(0xff & (1 << n)); }; 107 108 auto bit_op = (state == GpioState::deassert) ? set_bit : clr_bit; 109 110 bit_op(hostSelectorPosition, pos); 111 return; 112 } 113 /** 114 * @brief This method is called from sd-event provided callback function 115 * callbackHandler if platform specific event handling is needed then a 116 * derived class instance with its specific event handling logic along with 117 * init() function can be created to override the default event handling 118 */ 119 120 void HostSelector::handleEvent(sd_event_source* /* es */, int fd, 121 uint32_t /* revents */) 122 { 123 char buf = '0'; 124 try 125 { 126 buf = getValueFromFd(fd); 127 } 128 catch (const std::exception& e) 129 { 130 lg2::error("{TYPE}: exception while reading fd : {ERROR}", "TYPE", 131 getFormFactorType(), "ERROR", e.what()); 132 return; 133 } 134 135 size_t hsPosMapped = 0; 136 if (config.type == ConfigType::gpio) 137 { 138 // read the gpio state for the io event received 139 GpioState gpioState = (buf == '0') ? (GpioState::deassert) 140 : (GpioState::assert); 141 142 setHostSelectorValue(fd, gpioState); 143 hsPosMapped = getMappedHSConfig(hostSelectorPosition); 144 } 145 else if (config.type == ConfigType::cpld) 146 { 147 hsPosMapped = buf - '0'; 148 } 149 150 if (hsPosMapped != INVALID_INDEX) 151 { 152 position(hsPosMapped); 153 } 154 } 155