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 void HostSelector::setInitialHostSelectorValue() 41 { 42 char buf; 43 for (size_t index = 0; index < gpioLineCount; index++) 44 { 45 auto result = ::lseek(config.gpios[index].fd, 0, SEEK_SET); 46 47 if (result < 0) 48 { 49 lg2::error("{TYPE}: Gpio fd lseek error: {ERROR}", "TYPE", 50 getFormFactorType(), "ERROR", errno); 51 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 52 IOError(); 53 } 54 55 result = ::read(config.gpios[index].fd, &buf, sizeof(buf)); 56 if (result < 0) 57 { 58 lg2::error("{TYPE}: Gpio fd read error: {ERROR}", "TYPE", 59 getFormFactorType(), "ERROR", errno); 60 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 61 IOError(); 62 } 63 GpioState gpioState = (buf == '0') ? (GpioState::deassert) 64 : (GpioState::assert); 65 setHostSelectorValue(config.gpios[index].fd, gpioState); 66 size_t hsPosMapped = getMappedHSConfig(hostSelectorPosition); 67 if (hsPosMapped != INVALID_INDEX) 68 { 69 position(hsPosMapped, true); 70 } 71 } 72 } 73 74 void HostSelector::setHostSelectorValue(int fd, GpioState state) 75 { 76 size_t pos = getGpioIndex(fd); 77 78 if (pos == INVALID_INDEX) 79 { 80 return; 81 } 82 auto set_bit = [](size_t& val, size_t n) { val |= 0xff & (1 << n); }; 83 84 auto clr_bit = [](size_t& val, size_t n) { val &= ~(0xff & (1 << n)); }; 85 86 auto bit_op = (state == GpioState::deassert) ? set_bit : clr_bit; 87 88 bit_op(hostSelectorPosition, pos); 89 return; 90 } 91 /** 92 * @brief This method is called from sd-event provided callback function 93 * callbackHandler if platform specific event handling is needed then a 94 * derived class instance with its specific event handling logic along with 95 * init() function can be created to override the default event handling 96 */ 97 98 void HostSelector::handleEvent(sd_event_source* /* es */, int fd, 99 uint32_t /* revents */) 100 { 101 int n = -1; 102 char buf = '0'; 103 104 n = ::lseek(fd, 0, SEEK_SET); 105 106 if (n < 0) 107 { 108 lg2::error("{TYPE}: Gpio fd lseek error: {ERROR}", "TYPE", 109 getFormFactorType(), "ERROR", errno); 110 return; 111 } 112 113 n = ::read(fd, &buf, sizeof(buf)); 114 if (n < 0) 115 { 116 lg2::error("{TYPE}: Gpio fd read error: {ERROR}", "TYPE", 117 getFormFactorType(), "ERROR", errno); 118 throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error:: 119 IOError(); 120 } 121 122 // read the gpio state for the io event received 123 GpioState gpioState = (buf == '0') ? (GpioState::deassert) 124 : (GpioState::assert); 125 126 setHostSelectorValue(fd, gpioState); 127 128 size_t hsPosMapped = getMappedHSConfig(hostSelectorPosition); 129 130 if (hsPosMapped != INVALID_INDEX) 131 { 132 position(hsPosMapped); 133 } 134 } 135