/** * Parse a protocol packet. * * @param buf Buffer containing the protocol packet. Must not be NULL. * @param floatval Pointer to a float variable. That variable will be modified * in-place depending on the protocol packet. Must not be NULL. * @param analog Pointer to a struct sr_datafeed_analog. The struct will be * filled with data according to the protocol packet. * Must not be NULL. * @param info Pointer to a struct metex14_info. The struct will be filled * with data according to the protocol packet. Must not be NULL. * * @return SR_OK upon success, SR_ERR upon failure. Upon errors, the * 'analog' variable contents are undefined and should not be used. */ SR_PRIV int sr_metex14_parse(const uint8_t *buf, float *floatval, struct sr_datafeed_analog *analog, void *info) { int ret, exponent = 0; struct metex14_info *info_local; info_local = (struct metex14_info *)info; /* Don't print byte 13. That one contains the carriage return. */ sr_dbg("DMM packet: \"%.13s\"", buf); memset(info_local, 0x00, sizeof(struct metex14_info)); if ((ret = parse_value(buf, info_local, floatval, &exponent)) != SR_OK) { sr_dbg("Error parsing value: %d.", ret); return ret; } parse_flags((const char *)buf, info_local); handle_flags(analog, floatval, &exponent, info_local); analog->encoding->digits = -exponent; analog->spec->spec_digits = -exponent; return SR_OK; }
SR_PRIV int sr_vc870_parse(const uint8_t *buf, float *floatval, struct sr_datafeed_analog_old *analog, void *info) { int ret; struct vc870_info *info_local; info_local = (struct vc870_info *)info; memset(info_local, 0, sizeof(struct vc870_info)); if (!sr_vc870_packet_valid(buf)) return SR_ERR; parse_flags(buf, info_local); if ((ret = parse_value(buf, info_local, floatval)) != SR_OK) { sr_dbg("Error parsing value: %d.", ret); return ret; } if ((ret = parse_range(buf[2], floatval, info_local)) != SR_OK) return ret; handle_flags(analog, floatval, info_local); return SR_OK; }
/** * Parse a protocol packet. * * @param buf Buffer containing the protocol packet. Must not be NULL. * @param floatval Pointer to a float variable. That variable will contain the * result value upon parsing success. Must not be NULL. * @param analog Pointer to a struct sr_datafeed_analog_old. The struct will be * filled with data according to the protocol packet. * Must not be NULL. * @param info Pointer to a struct kern_info. The struct will be filled * with data according to the protocol packet. Must not be NULL. * * @return SR_OK upon success, SR_ERR upon failure. Upon errors, the * 'analog' variable contents are undefined and should not be used. */ SR_PRIV int sr_kern_parse(const uint8_t *buf, float *floatval, struct sr_datafeed_analog_old *analog, void *info) { int ret; struct kern_info *info_local; info_local = (struct kern_info *)info; info_local->buflen = get_buflen(buf); if ((ret = parse_value(buf, floatval, info_local)) != SR_OK) { sr_dbg("Error parsing value: %d.", ret); return ret; } parse_flags(buf, info_local); handle_flags(analog, floatval, info_local); return SR_OK; }
/** * Parse a protocol packet. * * @param buf Buffer containing the protocol packet. Must not be NULL. * @param floatval Pointer to a float variable. That variable will contain the * result value upon parsing success. Must not be NULL. * @param analog Pointer to a struct sr_datafeed_analog. The struct will be * filled with data according to the protocol packet. * Must not be NULL. * @param info Pointer to a struct fs9922_info. The struct will be filled * with data according to the protocol packet. Must not be NULL. * * @return SR_OK upon success, SR_ERR upon failure. Upon errors, the * 'analog' variable contents are undefined and should not be used. */ SR_PRIV int sr_fs9922_parse(const uint8_t *buf, float *floatval, struct sr_datafeed_analog *analog, void *info) { int ret, exponent = 0; struct fs9922_info *info_local; info_local = info; if ((ret = parse_value(buf, floatval, &exponent)) != SR_OK) { sr_dbg("Error parsing value: %d.", ret); return ret; } parse_flags(buf, info_local); handle_flags(analog, floatval, &exponent, info_local); analog->encoding->digits = -exponent; analog->spec->spec_digits = -exponent; return SR_OK; }
static void handle_transaction_done(struct smi_info *smi_info) { struct ipmi_smi_msg *msg; debug_timestamp("Done"); switch (smi_info->si_state) { case SI_NORMAL: if (!smi_info->curr_msg) break; smi_info->curr_msg->rsp_size = smi_info->handlers->get_result( smi_info->si_sm, smi_info->curr_msg->rsp, IPMI_MAX_MSG_LENGTH); /* * Do this here becase deliver_recv_msg() releases the * lock, and a new message can be put in during the * time the lock is released. */ msg = smi_info->curr_msg; smi_info->curr_msg = NULL; deliver_recv_msg(smi_info, msg); break; case SI_GETTING_FLAGS: { unsigned char msg[4]; unsigned int len; /* We got the flags from the SMI, now handle them. */ len = smi_info->handlers->get_result(smi_info->si_sm, msg, 4); if (msg[2] != 0) { /* Error fetching flags, just give up for now. */ smi_info->si_state = SI_NORMAL; } else if (len < 4) { /* * Hmm, no flags. That's technically illegal, but * don't use uninitialized data. */ smi_info->si_state = SI_NORMAL; } else { smi_info->msg_flags = msg[3]; handle_flags(smi_info); } break; } case SI_CLEARING_FLAGS: { unsigned char msg[3]; /* We cleared the flags. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 3); if (msg[2] != 0) { /* Error clearing flags */ dev_warn(smi_info->dev, "Error clearing flags: %2.2x\n", msg[2]); } smi_info->si_state = SI_NORMAL; break; } case SI_GETTING_EVENTS: { smi_info->curr_msg->rsp_size = smi_info->handlers->get_result( smi_info->si_sm, smi_info->curr_msg->rsp, IPMI_MAX_MSG_LENGTH); /* * Do this here becase deliver_recv_msg() releases the * lock, and a new message can be put in during the * time the lock is released. */ msg = smi_info->curr_msg; smi_info->curr_msg = NULL; if (msg->rsp[2] != 0) { /* Error getting event, probably done. */ msg->done(msg); /* Take off the event flag. */ smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; handle_flags(smi_info); } else { smi_inc_stat(smi_info, events); /* * Do this before we deliver the message * because delivering the message releases the * lock and something else can mess with the * state. */ handle_flags(smi_info); deliver_recv_msg(smi_info, msg); } break; } case SI_GETTING_MESSAGES: { smi_info->curr_msg->rsp_size = smi_info->handlers->get_result( smi_info->si_sm, smi_info->curr_msg->rsp, IPMI_MAX_MSG_LENGTH); /* * Do this here becase deliver_recv_msg() releases the * lock, and a new message can be put in during the * time the lock is released. */ msg = smi_info->curr_msg; smi_info->curr_msg = NULL; if (msg->rsp[2] != 0) { /* Error getting event, probably done. */ msg->done(msg); /* Take off the msg flag. */ smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL; handle_flags(smi_info); } else { smi_inc_stat(smi_info, incoming_messages); /* * Do this before we deliver the message * because delivering the message releases the * lock and something else can mess with the * state. */ handle_flags(smi_info); deliver_recv_msg(smi_info, msg); } break; } case SI_CHECKING_ENABLES: { unsigned char msg[4]; u8 enables; bool irq_on; /* We got the flags from the SMI, now handle them. */ smi_info->handlers->get_result(smi_info->si_sm, msg, 4); if (msg[2] != 0) { dev_warn(smi_info->dev, "Couldn't get irq info: %x.\n", msg[2]); dev_warn(smi_info->dev, "Maybe ok, but ipmi might run very slowly.\n"); smi_info->si_state = SI_NORMAL; break; } enables = current_global_enables(smi_info, 0, &irq_on); if (smi_info->si_type == SI_BT) /* BT has its own interrupt enable bit. */ check_bt_irq(smi_info, irq_on); if (enables != (msg[3] & GLOBAL_ENABLES_MASK)) { /* Enables are not correct, fix them. */ msg[0] = (IPMI_NETFN_APP_REQUEST << 2); msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; msg[2] = enables | (msg[3] & ~GLOBAL_ENABLES_MASK); smi_info->handlers->start_transaction( smi_info->si_sm, msg, 3); smi_info->si_state = SI_SETTING_ENABLES; } else if (smi_info->supports_event_msg_buff) { smi_info->curr_msg = ipmi_alloc_smi_msg(); if (!smi_info->curr_msg) { smi_info->si_state = SI_NORMAL; break; } start_getting_msg_queue(smi_info); } else { smi_info->si_state = SI_NORMAL; } break; } case SI_SETTING_ENABLES: { unsigned char msg[4]; smi_info->handlers->get_result(smi_info->si_sm, msg, 4); if (msg[2] != 0) dev_warn(smi_info->dev, "Could not set the global enables: 0x%x.\n", msg[2]); if (smi_info->supports_event_msg_buff) { smi_info->curr_msg = ipmi_alloc_smi_msg(); if (!smi_info->curr_msg) { smi_info->si_state = SI_NORMAL; break; } start_getting_msg_queue(smi_info); } else { smi_info->si_state = SI_NORMAL; } break; } } }
static void handle_transaction_done(struct kcs_info *kcs_info) { struct ipmi_smi_msg *msg; #ifdef DEBUG_TIMING struct timeval t; do_gettimeofday(&t); printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec); #endif switch (kcs_info->kcs_state) { case KCS_NORMAL: if (!kcs_info->curr_msg) break; kcs_info->curr_msg->rsp_size = kcs_get_result(kcs_info->kcs_sm, kcs_info->curr_msg->rsp, IPMI_MAX_MSG_LENGTH); /* Do this here becase deliver_recv_msg() releases the lock, and a new message can be put in during the time the lock is released. */ msg = kcs_info->curr_msg; kcs_info->curr_msg = NULL; deliver_recv_msg(kcs_info, msg); break; case KCS_GETTING_FLAGS: { unsigned char msg[4]; unsigned int len; /* We got the flags from the KCS, now handle them. */ len = kcs_get_result(kcs_info->kcs_sm, msg, 4); if (msg[2] != 0) { /* Error fetching flags, just give up for now. */ kcs_info->kcs_state = KCS_NORMAL; } else if (len < 3) { /* Hmm, no flags. That's technically illegal, but don't use uninitialized data. */ kcs_info->kcs_state = KCS_NORMAL; } else { kcs_info->msg_flags = msg[3]; handle_flags(kcs_info); } break; } case KCS_CLEARING_FLAGS: case KCS_CLEARING_FLAGS_THEN_SET_IRQ: { unsigned char msg[3]; /* We cleared the flags. */ kcs_get_result(kcs_info->kcs_sm, msg, 3); if (msg[2] != 0) { /* Error clearing flags */ printk(KERN_WARNING "ipmi_kcs: Error clearing flags: %2.2x\n", msg[2]); } if (kcs_info->kcs_state == KCS_CLEARING_FLAGS_THEN_SET_IRQ) start_enable_irq(kcs_info); else kcs_info->kcs_state = KCS_NORMAL; break; } case KCS_GETTING_EVENTS: { kcs_info->curr_msg->rsp_size = kcs_get_result(kcs_info->kcs_sm, kcs_info->curr_msg->rsp, IPMI_MAX_MSG_LENGTH); /* Do this here becase deliver_recv_msg() releases the lock, and a new message can be put in during the time the lock is released. */ msg = kcs_info->curr_msg; kcs_info->curr_msg = NULL; if (msg->rsp[2] != 0) { /* Error getting event, probably done. */ msg->done(msg); /* Take off the event flag. */ kcs_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; } else { deliver_recv_msg(kcs_info, msg); } handle_flags(kcs_info); break; } case KCS_GETTING_MESSAGES: { kcs_info->curr_msg->rsp_size = kcs_get_result(kcs_info->kcs_sm, kcs_info->curr_msg->rsp, IPMI_MAX_MSG_LENGTH); /* Do this here becase deliver_recv_msg() releases the lock, and a new message can be put in during the time the lock is released. */ msg = kcs_info->curr_msg; kcs_info->curr_msg = NULL; if (msg->rsp[2] != 0) { /* Error getting event, probably done. */ msg->done(msg); /* Take off the msg flag. */ kcs_info->msg_flags &= ~RECEIVE_MSG_AVAIL; } else { deliver_recv_msg(kcs_info, msg); } handle_flags(kcs_info); break; } case KCS_ENABLE_INTERRUPTS1: { unsigned char msg[4]; /* We got the flags from the KCS, now handle them. */ kcs_get_result(kcs_info->kcs_sm, msg, 4); if (msg[2] != 0) { printk(KERN_WARNING "ipmi_kcs: Could not enable interrupts" ", failed get, using polled mode.\n"); kcs_info->kcs_state = KCS_NORMAL; } else { msg[0] = (IPMI_NETFN_APP_REQUEST << 2); msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; msg[2] = msg[3] | 1; /* enable msg queue int */ start_kcs_transaction(kcs_info->kcs_sm, msg,3); kcs_info->kcs_state = KCS_ENABLE_INTERRUPTS2; } break; } case KCS_ENABLE_INTERRUPTS2: { unsigned char msg[4]; /* We got the flags from the KCS, now handle them. */ kcs_get_result(kcs_info->kcs_sm, msg, 4); if (msg[2] != 0) { printk(KERN_WARNING "ipmi_kcs: Could not enable interrupts" ", failed set, using polled mode.\n"); } kcs_info->kcs_state = KCS_NORMAL; break; } } }