SaErrorT ohoi_get_power_state (void *hnd, SaHpiResourceIdT id, SaHpiPowerStateT *state) { struct oh_handler_state *handler = (struct oh_handler_state *)hnd; struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_resource_info *ohoi_res_info; struct ohoi_power_info power_state; int rv; power_state.done = 0; power_state.err = 0; power_state.state = state; ohoi_res_info = oh_get_resource_data(handler->rptcache, id); if (ohoi_res_info->type != OHOI_RESOURCE_ENTITY) { dbg("MC does not support power!"); return SA_ERR_HPI_CAPABILITY; } rv = ipmi_control_pointer_cb(ohoi_res_info->power_ctrl, get_power_state, &power_state); if (rv) { dbg("get_power_state failed"); return SA_ERR_HPI_INTERNAL_ERROR; } dbg("waiting for OIPMI to return"); ohoi_loop(&power_state.done, ipmi_handler); return power_state.err; }
SaErrorT ohoi_get_reset_state(void *hnd, SaHpiResourceIdT id, SaHpiResetActionT *act) { struct oh_handler_state *handler = (struct oh_handler_state *)hnd; struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_resource_info *ohoi_res_info; struct ohoi_reset_info reset_state; int rv; reset_state.done = 0; reset_state.err = 0; reset_state.state = act; ohoi_res_info = oh_get_resource_data(handler->rptcache, id); if (ohoi_res_info->type != OHOI_RESOURCE_ENTITY) { dbg("Not support power in MC"); return SA_ERR_HPI_CAPABILITY; } rv = ipmi_control_pointer_cb(ohoi_res_info->reset_ctrl, get_reset_state, &reset_state); if(rv) { dbg("[reset_state] controm pointer callback failed"); return SA_ERR_HPI_INTERNAL_ERROR; } ohoi_loop(&reset_state.done, ipmi_handler); return reset_state.err; }
SaErrorT ohoi_get_control_state(void *hnd, SaHpiResourceIdT id, SaHpiCtrlNumT num, SaHpiCtrlModeT *mode, SaHpiCtrlStateT *state) { struct oh_handler_state *handler = (struct oh_handler_state *)hnd; struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_control_info info; SaErrorT rv; ipmi_control_id_t *ctrl; SaHpiRdrT * rdr; SaHpiUint8T val, mask, idx, i; SaHpiCtrlStateT localstate; SaHpiCtrlModeT localmode; rdr = oh_get_rdr_by_type(handler->rptcache, id, SAHPI_CTRL_RDR, num); if (!rdr) return SA_ERR_HPI_INVALID_RESOURCE; rv = ohoi_get_rdr_data(hnd, id, SAHPI_CTRL_RDR, num, (void *)&ctrl); if (rv!=SA_OK) return rv; if (state == NULL) { state = &localstate; } if (mode == NULL) { mode = &localmode; } memset(state, 0, sizeof(*state)); memset(mode, 0, sizeof(*mode)); info.done = 0; info.state = state; info.state->Type = SAHPI_CTRL_TYPE_OEM; rv = ipmi_control_pointer_cb(*ctrl, _get_control_state, &info); if (rv) { dbg("Unable to retrieve control state"); return SA_ERR_HPI_ERROR; } rv = ohoi_loop(&info.done, ipmi_handler); val = info.state->StateUnion.Oem.Body[0]; if ((rdr->RdrTypeUnion.CtrlRec.Type == SAHPI_CTRL_TYPE_DIGITAL) && (rdr->RdrTypeUnion.CtrlRec.OutputType == SAHPI_CTRL_LED) && (rdr->RdrTypeUnion.CtrlRec.Oem >= OEM_ALARM_BASE)) { oem_alarm_state = val; /* This is a front panel alarm LED. */ state->Type = SAHPI_CTRL_TYPE_DIGITAL; mask = 0x01; idx = rdr->RdrTypeUnion.CtrlRec.Oem - OEM_ALARM_BASE; /* bits 0 - 3 = Pwr, Crit, Maj, Min */ for (i = 0; i < idx; i++) mask = mask << 1; if ((val & mask) == 0) state->StateUnion.Digital = SAHPI_CTRL_STATE_ON; else state->StateUnion.Digital = SAHPI_CTRL_STATE_OFF; } return(rv); }
SaErrorT ohoi_set_control_state(void *hnd, SaHpiResourceIdT id, SaHpiCtrlNumT num, SaHpiCtrlModeT mode, SaHpiCtrlStateT *state) { struct oh_handler_state *handler = (struct oh_handler_state *)hnd; struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_control_info info; SaErrorT rv; ipmi_control_id_t *ctrl; SaHpiRdrT * rdr; SaHpiUint8T val, mask, idx, i; rdr = oh_get_rdr_by_type(handler->rptcache, id, SAHPI_CTRL_RDR, num); if (!rdr) return SA_ERR_HPI_INVALID_RESOURCE; rv = ohoi_get_rdr_data(hnd, id, SAHPI_CTRL_RDR, num, (void *)&ctrl); if (rv!=SA_OK) return rv; if ((rdr->RdrTypeUnion.CtrlRec.Type == SAHPI_CTRL_TYPE_DIGITAL) && (rdr->RdrTypeUnion.CtrlRec.OutputType == SAHPI_CTRL_LED) && (rdr->RdrTypeUnion.CtrlRec.Oem >= OEM_ALARM_BASE)) { /* This is a front panel alarm LED. */ val = oem_alarm_state; val |= 0xf0; /* h.o. nibble always write 1 */ mask = 0x01; idx = rdr->RdrTypeUnion.CtrlRec.Oem - OEM_ALARM_BASE; /* bits 0 - 3 = Pwr, Crit, Maj, Min */ for (i = 0; i < idx; i++) mask = mask << 1; if (state->StateUnion.Digital == SAHPI_CTRL_STATE_ON) val &= (0xff - mask); /*turn it on */ else /* turn it off */ val |= mask; state->Type = SAHPI_CTRL_TYPE_OEM; state->StateUnion.Oem.BodyLength = 1; state->StateUnion.Oem.Body[0] = val; } info.done = 0; info.state = state; if (info.state->Type != SAHPI_CTRL_TYPE_OEM) { dbg("IPMI only support OEM control"); return SA_ERR_HPI_INVALID_CMD; } rv = ipmi_control_pointer_cb(*ctrl, _set_control_state, &info); if (rv) { dbg("Unable to retrieve control state"); return SA_ERR_HPI_ERROR; } ohoi_loop(&info.done, ipmi_handler); return SA_OK; }
SaErrorT ohoi_set_reset_state(void *hnd, SaHpiResourceIdT id, SaHpiResetActionT act) { struct oh_handler_state *handler = (struct oh_handler_state *)hnd; struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_reset_info info; struct ohoi_resource_info *ohoi_res_info; int rv; info.done = 0; info.err = 0; if ((act == SAHPI_COLD_RESET) || (act == SAHPI_WARM_RESET)) { dbg("ResetAction requested: %d", act); info.state = &act; } else { dbg("Currently we only support cold and warm reset"); return SA_ERR_HPI_INVALID_CMD; } ohoi_res_info = oh_get_resource_data(handler->rptcache, id); if (ohoi_res_info->type == OHOI_RESOURCE_ENTITY) { rv = ipmi_control_pointer_cb(ohoi_res_info->reset_ctrl, set_resource_reset_state, &info); } else { rv = ipmi_mc_pointer_cb(ohoi_res_info->u.mc_id, set_mc_reset_state, &info); } if (rv) { dbg("Not support reset in the entity or mc"); return SA_ERR_HPI_CAPABILITY; } /* wait until reset_done is called to exit this function */ rv = ohoi_loop(&info.done, ipmi_handler); if ((rv == SA_OK) && (info.err == 0)) { return SA_OK; } else if (info.err) { return info.err; } else { return rv; } }
SaErrorT ohoi_set_power_state(void *hnd, SaHpiResourceIdT id, SaHpiPowerStateT state) { struct ohoi_resource_info *ohoi_res_info; struct oh_handler_state *handler = (struct oh_handler_state *)hnd; struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_power_info power_info; int rv; power_info.done = 0; power_info.state = &state; ohoi_res_info = oh_get_resource_data(handler->rptcache, id); if (ohoi_res_info->type != OHOI_RESOURCE_ENTITY) { dbg("Not support power in MC"); return SA_ERR_HPI_INVALID_CMD; } switch (state) { case SAHPI_POWER_ON: rv = ipmi_control_pointer_cb(ohoi_res_info->power_ctrl, set_power_state_on, &power_info); if (rv) { dbg("set_power_state_on failed"); return SA_ERR_HPI_INTERNAL_ERROR; } break; case SAHPI_POWER_OFF: rv = ipmi_control_pointer_cb(ohoi_res_info->power_ctrl, set_power_state_off, &power_info); if (rv) { dbg("set_power_state_off failed"); return SA_ERR_HPI_INTERNAL_ERROR; } break; case SAHPI_POWER_CYCLE: dbg("CYCLE power"); SaHpiPowerStateT cy_state = 0; cy_state = SAHPI_POWER_OFF; power_info.state = &cy_state; rv = ipmi_control_pointer_cb(ohoi_res_info->power_ctrl, set_power_state_off, &power_info); if (rv) { dbg("set_power_state_off failed"); return SA_ERR_HPI_INTERNAL_ERROR; } ohoi_loop(&power_info.done, ipmi_handler); dbg("CYCLE Stage 1: OK"); if ((power_info.done) && (power_info.err == SA_OK)) { dbg("CYCLE: done = %d , err = %d", power_info.done, power_info.err); cy_state = SAHPI_POWER_ON; power_info.state = &cy_state; power_info.done = 0; rv = ipmi_control_pointer_cb(ohoi_res_info->power_ctrl, set_power_state_on, &power_info); if (rv) { dbg("set_power_state_on failed"); return SA_ERR_HPI_INTERNAL_ERROR; } } break; default: dbg("Invalid power state requested"); return SA_ERR_HPI_INVALID_PARAMS; } ohoi_loop(&power_info.done, ipmi_handler); return power_info.err; }
static int test_event_handler_0(ipmi_mc_t *mc, ipmi_event_t *event, void *cb_data) { unsigned char data[13]; ipmi_domain_t *domain = ipmi_mc_get_domain(mc); ipmi_mc_t *src_mc; ipmi_ipmb_addr_t addr; if (ipmi_event_get_type(event) == 0xc0) { ipmi_control_id_t id; event_info_t info; int rv; ipmi_time_t timestamp; if (ipmi_event_get_data(event, data, 0, 13) != 13) return 0; timestamp = ipmi_get_uint32(&data[0]); if (timestamp < ipmi_mc_get_startup_SEL_time(mc)) /* It's an old event, ignore it. */ return 0; if (data[6] != 1) /* Wrong version */ return 0; addr.addr_type = IPMI_IPMB_ADDR_TYPE; addr.channel = 0; addr.lun = 0; addr.slave_addr = data[4]; /* Find the MC. */ src_mc = _ipmi_find_mc_by_addr(domain, (ipmi_addr_t *) &addr, sizeof(addr)); if (!src_mc) return 0; id.mcid = ipmi_mc_convert_to_id(src_mc); id.lun = 4; id.control_num = POWER_CONTROL(data[8]); info.err = 0; info.event = event; info.valid_vals[0] = 1; info.vals[0] = data[10]; info.handled = IPMI_EVENT_NOT_HANDLED; rv = ipmi_control_pointer_cb(id, event_control_cb, &info); if (!rv) rv = info.err; _ipmi_mc_put(src_mc); if (!rv) return 1; } return 0; }
SaErrorT orig_set_control_state(struct oh_handler_state *handler, struct ohoi_control_info *c, SaHpiRdrT * rdr, SaHpiCtrlModeT mode, SaHpiCtrlStateT *state) { struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_ctrl_info info; SaErrorT rv; ipmi_control_id_t ctrl; ctrl = c->info.orig_ctrl_info.ctrl_id; if ((rdr->RdrTypeUnion.CtrlRec.Type == SAHPI_CTRL_TYPE_OEM) && (rdr->RdrTypeUnion.CtrlRec.OutputType == SAHPI_CTRL_LED) && (rdr->RdrTypeUnion.CtrlRec.TypeUnion.Oem.MId == ATCAHPI_PICMG_MID)) { /* This is ATCA led */ if (state != NULL) { if (state->StateUnion.Oem.MId != ATCAHPI_PICMG_MID) { dbg("state->StateUnion.Mid isn't ATCAHPI_PICMG_MID"); return SA_ERR_HPI_INVALID_DATA; } if (state->StateUnion.Oem.BodyLength != 7) { dbg("state->StateUnion.Oem.BodyLength(%d) != 7", state->StateUnion.Oem.BodyLength); return SA_ERR_HPI_INVALID_DATA; } SaHpiUint8T *body = &state->StateUnion.Oem.Body[0]; if ((body[2] == 0) || ((body[2] & (body[2] - 1)) != 0)) { /* exactly one color must be set */ return SA_ERR_HPI_INVALID_DATA; } if (!(body[2] & rdr->RdrTypeUnion.CtrlRec.TypeUnion.Oem.ConfigData[0])) { /* LED doesn't support this color */ return SA_ERR_HPI_INVALID_DATA; } } info.done = 0; info.err = 0; info.rdr = rdr; info.handler = handler; info.mode = mode; info.state = state; rv = ipmi_control_pointer_cb(ctrl, _set_atca_led, &info); if (rv) { dbg("ipmi_control_pointer_cb. rv = %d", rv); return SA_ERR_HPI_INVALID_DATA; } rv = ohoi_loop(&info.done, handler->data); if (rv != SA_OK) { dbg("ohoi_loop. rv = %d", rv); return rv; } if (info.err != SA_OK) { dbg("info.err = %d", info.err); return info.err; } c->mode = mode; return SA_OK; } if (mode == SAHPI_CTRL_MODE_AUTO) { c->mode = mode; return SA_OK; } if ((rdr->RdrTypeUnion.CtrlRec.Type == SAHPI_CTRL_TYPE_DIGITAL) && (rdr->RdrTypeUnion.CtrlRec.OutputType == SAHPI_CTRL_LED) && (rdr->RdrTypeUnion.CtrlRec.Oem >= OEM_ALARM_BASE)) { /* This is a front panel alarm LED. */ rv = set_front_panrl_alarm_led(handler, c, rdr, ctrl, rdr->RdrTypeUnion.CtrlRec.Oem - OEM_ALARM_BASE, mode, state); if (rv == SA_OK) { c->mode = mode; } return rv; } info.done = 0; info.state = state; info.err = SA_OK; if (info.state->Type != SAHPI_CTRL_TYPE_OEM) { dbg("IPMI only support OEM control"); return SA_ERR_HPI_INVALID_CMD; } rv = ipmi_control_pointer_cb(ctrl, _set_control_state, &info); if (rv) { dbg("Unable to set control state"); return SA_ERR_HPI_ERROR; } rv = ohoi_loop(&info.done, ipmi_handler); if (rv != SA_OK) { return rv; } if (info.err != SA_OK) { return info.err; } c->mode = mode; return SA_OK; }
static SaErrorT set_front_panrl_alarm_led(void *hnd, struct ohoi_control_info *c, SaHpiRdrT * rdr, ipmi_control_id_t ctrl, SaHpiUint8T idx, SaHpiCtrlModeT mode, SaHpiCtrlStateT *state) { struct oh_handler_state *handler = (struct oh_handler_state *)hnd; struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_ctrl_info info; SaErrorT rv; SaHpiUint8T val, mask; SaHpiCtrlStateT my_state; /* just get the current control states */ rv = orig_get_control_state(hnd, c, rdr, NULL, &my_state); if (rv != SA_OK) { return SA_ERR_HPI_NOT_PRESENT; } if (my_state.Type != state->Type) { return SA_ERR_HPI_INVALID_DATA; } val = oem_alarm_state; val |= 0xf0; /* h.o. nibble always write 1 */ state->Type = SAHPI_CTRL_TYPE_OEM; state->StateUnion.Oem.BodyLength = 1; state->StateUnion.Oem.Body[0] = val; mask = 0x01; /* bits 0 - 3 = Pwr, Crit, Maj, Min */ mask = 1 << idx; // for (i = 0; i < idx; i++) mask = mask << 1; info.done = 0; info.state = state; info.err = SA_OK; switch (state->StateUnion.Digital) { case SAHPI_CTRL_STATE_ON : if (!(val & mask)) { /* already turned on */ return SA_OK; } state->StateUnion.Oem.Body[0] = val & ~mask; break; case SAHPI_CTRL_STATE_OFF : if (val & mask) { /* already turned off */ return SA_OK; } state->StateUnion.Oem.Body[0] = val |mask; break; case SAHPI_CTRL_STATE_PULSE_ON : if (!(val & mask)) { /* already turned on */ return SA_ERR_HPI_INVALID_REQUEST; } /* turn it on */ state->StateUnion.Oem.Body[0] = val & ~mask; rv = ipmi_control_pointer_cb(ctrl, _set_control_state, &info); if (rv) { dbg("Unable to set control state"); return SA_ERR_HPI_ERROR; } rv = ohoi_loop(&info.done, ipmi_handler); if (info.err != SA_OK) { dbg("Unable to set control state"); return info.err; } if (rv != SA_OK) { dbg("Unable to set control state"); return rv; } /* then turn it off. IPMI is slow, it provides us delay */ state->StateUnion.Oem.Body[0] = val | mask; break; case SAHPI_CTRL_STATE_PULSE_OFF : if (val & mask) { /* already turned off */ return SA_ERR_HPI_INVALID_REQUEST; } /* turn it off */ state->StateUnion.Oem.Body[0] = val | mask; rv = ipmi_control_pointer_cb(ctrl, _set_control_state, &info); if (rv) { dbg("Unable to set control state"); return SA_ERR_HPI_ERROR; } rv = ohoi_loop(&info.done, ipmi_handler); if (info.err != SA_OK) { dbg("Unable to set control state"); return info.err; } if (rv != SA_OK) { dbg("Unable to set control state"); return rv; } /* then turn it on. IPMI is slow, it provides us delay */ state->StateUnion.Oem.Body[0] = val | mask; break; default : return SA_ERR_HPI_INVALID_PARAMS; } rv = ipmi_control_pointer_cb(ctrl, _set_control_state, &info); if (rv) { dbg("Unable to set control state"); return SA_ERR_HPI_ERROR; } rv = ohoi_loop(&info.done, ipmi_handler); if (info.err != SA_OK) { dbg("Unable to set control state"); return info.err; } if (rv != SA_OK) { dbg("Unable to set control state"); return rv; } return SA_OK; }
SaErrorT orig_get_control_state(struct oh_handler_state *handler, struct ohoi_control_info *c, SaHpiRdrT * rdr, SaHpiCtrlModeT *mode, SaHpiCtrlStateT *state) { struct ohoi_handler *ipmi_handler = (struct ohoi_handler *)handler->data; struct ohoi_ctrl_info info; SaErrorT rv; ipmi_control_id_t ctrl; SaHpiUint8T val, mask, idx, i; SaHpiCtrlStateT localstate; SaHpiCtrlModeT localmode; ctrl = c->info.orig_ctrl_info.ctrl_id; if (state == NULL) { state = &localstate; } if (mode == NULL) { mode = &localmode; } if ((rdr->RdrTypeUnion.CtrlRec.Type == SAHPI_CTRL_TYPE_OEM) && (rdr->RdrTypeUnion.CtrlRec.OutputType == SAHPI_CTRL_LED) && (rdr->RdrTypeUnion.CtrlRec.TypeUnion.Oem.MId == ATCAHPI_PICMG_MID)) { /* This is ATCA led */ info.done = 0; info.err = SA_OK; info.rdr = rdr; info.handler = handler; info.mode = 0; info.state = state; rv = ipmi_control_pointer_cb(ctrl, _get_atca_led, &info); if (rv) { dbg("ipmi_control_pointer_cb. rv = %d", rv); return SA_ERR_HPI_INVALID_DATA; } rv = ohoi_loop(&info.done, handler->data); if (rv != SA_OK) { dbg("ohoi_loop. rv = %d", rv); return rv; } if (info.err != SA_OK) { dbg("info.err = %d", info.err); return info.err; } *mode = info.mode; c->mode = info.mode; return SA_OK; } *mode = c->mode; memset(state, 0, sizeof(*state)); info.done = 0; info.state = state; info.err = SA_OK; info.state->Type = SAHPI_CTRL_TYPE_OEM; rv = ipmi_control_pointer_cb(ctrl, _get_control_state, &info); if (rv) { dbg("Unable to retrieve control state"); return SA_ERR_HPI_ERROR; } rv = ohoi_loop(&info.done, ipmi_handler); if (rv != SA_OK) { return rv; } if (info.err != SA_OK) { return info.err; } val = info.state->StateUnion.Oem.Body[0]; if ((rdr->RdrTypeUnion.CtrlRec.Type == SAHPI_CTRL_TYPE_DIGITAL) && (rdr->RdrTypeUnion.CtrlRec.OutputType == SAHPI_CTRL_LED) && (rdr->RdrTypeUnion.CtrlRec.Oem >= OEM_ALARM_BASE)) { oem_alarm_state = val; /* This is a front panel alarm LED. */ state->Type = SAHPI_CTRL_TYPE_DIGITAL; mask = 0x01; idx = rdr->RdrTypeUnion.CtrlRec.Oem - OEM_ALARM_BASE; /* bits 0 - 3 = Pwr, Crit, Maj, Min */ for (i = 0; i < idx; i++) mask = mask << 1; if ((val & mask) == 0) state->StateUnion.Digital = SAHPI_CTRL_STATE_ON; else state->StateUnion.Digital = SAHPI_CTRL_STATE_OFF; } return SA_OK; }