static int smic_detect(struct si_sm_data *smic) { if (read_smic_flags(smic) == 0xff) return 1; return 0; }
static int smic_detect(struct si_sm_data *smic) { /* It's impossible for the SMIC fnags register to be all 1's, (assuming a properly functioning, self-initialized BMC) but that's what you get from reading a bogus address, so we test that first. */ if (read_smic_flags(smic) == 0xff) return 1; return 0; }
static enum si_sm_result smic_event(struct si_sm_data *smic, long time) { unsigned char status; unsigned char flags; unsigned char data; if (smic->state == SMIC_HOSED) { init_smic_data(smic, smic->io); return SI_SM_HOSED; } if (smic->state != SMIC_IDLE) { if (smic_debug & SMIC_DEBUG_STATES) printk(KERN_DEBUG "smic_event - smic->smic_timeout = %ld," " time = %ld\n", smic->smic_timeout, time); if (time < SMIC_RETRY_TIMEOUT) { smic->smic_timeout -= time; if (smic->smic_timeout < 0) { start_error_recovery(smic, "smic timed out."); return SI_SM_CALL_WITH_DELAY; } } } flags = read_smic_flags(smic); if (flags & SMIC_FLAG_BSY) return SI_SM_CALL_WITH_DELAY; status = read_smic_status(smic); if (smic_debug & SMIC_DEBUG_STATES) printk(KERN_DEBUG "smic_event - state = %d, flags = 0x%02x," " status = 0x%02x\n", smic->state, flags, status); switch (smic->state) { case SMIC_IDLE: if (flags & SMIC_SMS_DATA_AVAIL) return SI_SM_ATTN; return SI_SM_IDLE; case SMIC_START_OP: write_smic_control(smic, SMIC_CC_SMS_GET_STATUS); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_OP_OK; break; case SMIC_OP_OK: if (status != SMIC_SC_SMS_READY) { start_error_recovery(smic, "state = SMIC_OP_OK," " status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } write_smic_control(smic, SMIC_CC_SMS_WR_START); write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_WRITE_START; break; case SMIC_WRITE_START: if (status != SMIC_SC_SMS_WR_START) { start_error_recovery(smic, "state = SMIC_WRITE_START, " "status != SMIC_SC_SMS_WR_START"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_WRITE_NEXT: if (status != SMIC_SC_SMS_WR_NEXT) { start_error_recovery(smic, "state = SMIC_WRITE_NEXT, " "status != SMIC_SC_SMS_WR_NEXT"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_WRITE_END: if (status != SMIC_SC_SMS_WR_END) { start_error_recovery(smic, "state = SMIC_WRITE_END, " "status != SMIC_SC_SMS_WR_END"); return SI_SM_CALL_WITH_DELAY; } data = read_smic_data(smic); if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) printk(KERN_DEBUG "SMIC_WRITE_END: data = %02x\n", data); start_error_recovery(smic, "state = SMIC_WRITE_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else smic->state = SMIC_WRITE2READ; break; case SMIC_WRITE2READ: if (flags & SMIC_RX_DATA_READY) { write_smic_control(smic, SMIC_CC_SMS_RD_START); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_START; } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_READ_START: if (status != SMIC_SC_SMS_RD_START) { start_error_recovery(smic, "state = SMIC_READ_START, " "status != SMIC_SC_SMS_RD_START"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else return SI_SM_CALL_WITH_DELAY; break; case SMIC_READ_NEXT: switch (status) { case SMIC_SC_SMS_RD_END: read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_END); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_END; break; case SMIC_SC_SMS_RD_NEXT: if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else return SI_SM_CALL_WITH_DELAY; break; default: start_error_recovery( smic, "state = SMIC_READ_NEXT, " "status != SMIC_SC_SMS_RD_(NEXT|END)"); return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_END: if (status != SMIC_SC_SMS_READY) { start_error_recovery(smic, "state = SMIC_READ_END, " "status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } data = read_smic_data(smic); if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) printk(KERN_DEBUG "SMIC_READ_END: data = %02x\n", data); start_error_recovery(smic, "state = SMIC_READ_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else { smic->state = SMIC_IDLE; return SI_SM_TRANSACTION_COMPLETE; } case SMIC_HOSED: init_smic_data(smic, smic->io); return SI_SM_HOSED; default: if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_DEBUG "smic->state = %d\n", smic->state); start_error_recovery(smic, "state = UNKNOWN"); return SI_SM_CALL_WITH_DELAY; } } smic->smic_timeout = SMIC_RETRY_TIMEOUT; return SI_SM_CALL_WITHOUT_DELAY; }
static enum si_sm_result smic_event (struct si_sm_data *smic, long time) { unsigned char status; unsigned char flags; unsigned char data; if (smic->state == SMIC_HOSED) { init_smic_data(smic, smic->io); return SI_SM_HOSED; } if (smic->state != SMIC_IDLE) { if (smic_debug & SMIC_DEBUG_STATES) { printk(KERN_INFO "smic_event - smic->smic_timeout = %ld," " time = %ld\n", smic->smic_timeout, time); } /* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */ if (time < SMIC_RETRY_TIMEOUT) { smic->smic_timeout -= time; if (smic->smic_timeout < 0) { start_error_recovery(smic, "smic timed out."); return SI_SM_CALL_WITH_DELAY; } } } flags = read_smic_flags(smic); if (flags & SMIC_FLAG_BSY) return SI_SM_CALL_WITH_DELAY; status = read_smic_status (smic); if (smic_debug & SMIC_DEBUG_STATES) printk(KERN_INFO "smic_event - state = %d, flags = 0x%02x," " status = 0x%02x\n", smic->state, flags, status); switch (smic->state) { case SMIC_IDLE: /* in IDLE we check for available messages */ if (flags & (SMIC_SMI | SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL)) { return SI_SM_ATTN; } return SI_SM_IDLE; case SMIC_START_OP: /* sanity check whether smic is really idle */ write_smic_control(smic, SMIC_CC_SMS_GET_STATUS); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_OP_OK; break; case SMIC_OP_OK: if (status != SMIC_SC_SMS_READY) { /* this should not happen */ start_error_recovery(smic, "state = SMIC_OP_OK," " status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } /* OK so far; smic is idle let us start ... */ write_smic_control(smic, SMIC_CC_SMS_WR_START); write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_WRITE_START; break; case SMIC_WRITE_START: if (status != SMIC_SC_SMS_WR_START) { start_error_recovery(smic, "state = SMIC_WRITE_START, " "status != SMIC_SC_SMS_WR_START"); return SI_SM_CALL_WITH_DELAY; } /* we must not issue WR_(NEXT|END) unless TX_DATA_READY is set */ if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { /* last byte */ write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_WRITE_NEXT: if (status != SMIC_SC_SMS_WR_NEXT) { start_error_recovery(smic, "state = SMIC_WRITE_NEXT, " "status != SMIC_SC_SMS_WR_NEXT"); return SI_SM_CALL_WITH_DELAY; } /* this is the same code as in SMIC_WRITE_START */ if (flags & SMIC_TX_DATA_READY) { if (smic->write_count == 1) { write_smic_control(smic, SMIC_CC_SMS_WR_END); smic->state = SMIC_WRITE_END; } else { write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); smic->state = SMIC_WRITE_NEXT; } write_next_byte(smic); write_smic_flags(smic, flags | SMIC_FLAG_BSY); } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_WRITE_END: if (status != SMIC_SC_SMS_WR_END) { start_error_recovery (smic, "state = SMIC_WRITE_END, " "status != SMIC_SC_SMS_WR_END"); return SI_SM_CALL_WITH_DELAY; } /* data register holds an error code */ data = read_smic_data(smic); if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_INFO "SMIC_WRITE_END: data = %02x\n", data); } start_error_recovery(smic, "state = SMIC_WRITE_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else { smic->state = SMIC_WRITE2READ; } break; case SMIC_WRITE2READ: /* we must wait for RX_DATA_READY to be set before we can continue */ if (flags & SMIC_RX_DATA_READY) { write_smic_control(smic, SMIC_CC_SMS_RD_START); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_START; } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_START: if (status != SMIC_SC_SMS_RD_START) { start_error_recovery(smic, "state = SMIC_READ_START, " "status != SMIC_SC_SMS_RD_START"); return SI_SM_CALL_WITH_DELAY; } if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else { return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_NEXT: switch (status) { /* smic tells us that this is the last byte to be read --> clean up */ case SMIC_SC_SMS_RD_END: read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_END); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_END; break; case SMIC_SC_SMS_RD_NEXT: if (flags & SMIC_RX_DATA_READY) { read_next_byte(smic); write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); write_smic_flags(smic, flags | SMIC_FLAG_BSY); smic->state = SMIC_READ_NEXT; } else { return SI_SM_CALL_WITH_DELAY; } break; default: start_error_recovery( smic, "state = SMIC_READ_NEXT, " "status != SMIC_SC_SMS_RD_(NEXT|END)"); return SI_SM_CALL_WITH_DELAY; } break; case SMIC_READ_END: if (status != SMIC_SC_SMS_READY) { start_error_recovery(smic, "state = SMIC_READ_END, " "status != SMIC_SC_SMS_READY"); return SI_SM_CALL_WITH_DELAY; } data = read_smic_data(smic); /* data register holds an error code */ if (data != 0) { if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_INFO "SMIC_READ_END: data = %02x\n", data); } start_error_recovery(smic, "state = SMIC_READ_END, " "data != SUCCESS"); return SI_SM_CALL_WITH_DELAY; } else { smic->state = SMIC_IDLE; return SI_SM_TRANSACTION_COMPLETE; } case SMIC_HOSED: init_smic_data(smic, smic->io); return SI_SM_HOSED; default: if (smic_debug & SMIC_DEBUG_ENABLE) { printk(KERN_WARNING "smic->state = %d\n", smic->state); start_error_recovery(smic, "state = UNKNOWN"); return SI_SM_CALL_WITH_DELAY; } } smic->smic_timeout = SMIC_RETRY_TIMEOUT; return SI_SM_CALL_WITHOUT_DELAY; }