summaryrefslogtreecommitdiff
path: root/drivers/char/ipmi/ipmi_kcs_sm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_kcs_sm.c')
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c153
1 files changed, 91 insertions, 62 deletions
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index c1b8228cb7b6..80704875794c 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -60,37 +60,58 @@ MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
/* The states the KCS driver may be in. */
enum kcs_states {
- KCS_IDLE, /* The KCS interface is currently
- doing nothing. */
- KCS_START_OP, /* We are starting an operation. The
- data is in the output buffer, but
- nothing has been done to the
- interface yet. This was added to
- the state machine in the spec to
- wait for the initial IBF. */
- KCS_WAIT_WRITE_START, /* We have written a write cmd to the
- interface. */
- KCS_WAIT_WRITE, /* We are writing bytes to the
- interface. */
- KCS_WAIT_WRITE_END, /* We have written the write end cmd
- to the interface, and still need to
- write the last byte. */
- KCS_WAIT_READ, /* We are waiting to read data from
- the interface. */
- KCS_ERROR0, /* State to transition to the error
- handler, this was added to the
- state machine in the spec to be
- sure IBF was there. */
- KCS_ERROR1, /* First stage error handler, wait for
- the interface to respond. */
- KCS_ERROR2, /* The abort cmd has been written,
- wait for the interface to
- respond. */
- KCS_ERROR3, /* We wrote some data to the
- interface, wait for it to switch to
- read mode. */
- KCS_HOSED /* The hardware failed to follow the
- state machine. */
+ /* The KCS interface is currently doing nothing. */
+ KCS_IDLE,
+
+ /*
+ * We are starting an operation. The data is in the output
+ * buffer, but nothing has been done to the interface yet. This
+ * was added to the state machine in the spec to wait for the
+ * initial IBF.
+ */
+ KCS_START_OP,
+
+ /* We have written a write cmd to the interface. */
+ KCS_WAIT_WRITE_START,
+
+ /* We are writing bytes to the interface. */
+ KCS_WAIT_WRITE,
+
+ /*
+ * We have written the write end cmd to the interface, and
+ * still need to write the last byte.
+ */
+ KCS_WAIT_WRITE_END,
+
+ /* We are waiting to read data from the interface. */
+ KCS_WAIT_READ,
+
+ /*
+ * State to transition to the error handler, this was added to
+ * the state machine in the spec to be sure IBF was there.
+ */
+ KCS_ERROR0,
+
+ /*
+ * First stage error handler, wait for the interface to
+ * respond.
+ */
+ KCS_ERROR1,
+
+ /*
+ * The abort cmd has been written, wait for the interface to
+ * respond.
+ */
+ KCS_ERROR2,
+
+ /*
+ * We wrote some data to the interface, wait for it to switch
+ * to read mode.
+ */
+ KCS_ERROR3,
+
+ /* The hardware failed to follow the state machine. */
+ KCS_HOSED
};
#define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH
@@ -102,8 +123,7 @@ enum kcs_states {
#define MAX_ERROR_RETRIES 10
#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)
-struct si_sm_data
-{
+struct si_sm_data {
enum kcs_states state;
struct si_sm_io *io;
unsigned char write_data[MAX_KCS_WRITE_SIZE];
@@ -187,7 +207,8 @@ static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
(kcs->error_retries)++;
if (kcs->error_retries > MAX_ERROR_RETRIES) {
if (kcs_debug & KCS_DEBUG_ENABLE)
- printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n", reason);
+ printk(KERN_DEBUG "ipmi_kcs_sm: kcs hosed: %s\n",
+ reason);
kcs->state = KCS_HOSED;
} else {
kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;
@@ -271,10 +292,9 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
if (kcs_debug & KCS_DEBUG_MSG) {
printk(KERN_DEBUG "start_kcs_transaction -");
- for (i = 0; i < size; i ++) {
+ for (i = 0; i < size; i++)
printk(" %02x", (unsigned char) (data [i]));
- }
- printk ("\n");
+ printk("\n");
}
kcs->error_retries = 0;
memcpy(kcs->write_data, data, size);
@@ -305,9 +325,11 @@ static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data,
kcs->read_pos = 3;
}
if (kcs->truncated) {
- /* Report a truncated error. We might overwrite
- another error, but that's too bad, the user needs
- to know it was truncated. */
+ /*
+ * Report a truncated error. We might overwrite
+ * another error, but that's too bad, the user needs
+ * to know it was truncated.
+ */
data[2] = IPMI_ERR_MSG_TRUNCATED;
kcs->truncated = 0;
}
@@ -315,9 +337,11 @@ static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data,
return kcs->read_pos;
}
-/* This implements the state machine defined in the IPMI manual, see
- that for details on how this works. Divide that flowchart into
- sections delimited by "Wait for IBF" and this will become clear. */
+/*
+ * This implements the state machine defined in the IPMI manual, see
+ * that for details on how this works. Divide that flowchart into
+ * sections delimited by "Wait for IBF" and this will become clear.
+ */
static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
{
unsigned char status;
@@ -388,11 +412,12 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
write_next_byte(kcs);
}
break;
-
+
case KCS_WAIT_WRITE_END:
if (state != KCS_WRITE_STATE) {
start_error_recovery(kcs,
- "Not in write state for write end");
+ "Not in write state"
+ " for write end");
break;
}
clear_obf(kcs, status);
@@ -413,13 +438,15 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
return SI_SM_CALL_WITH_DELAY;
read_next_byte(kcs);
} else {
- /* We don't implement this exactly like the state
- machine in the spec. Some broken hardware
- does not write the final dummy byte to the
- read register. Thus obf will never go high
- here. We just go straight to idle, and we
- handle clearing out obf in idle state if it
- happens to come in. */
+ /*
+ * We don't implement this exactly like the state
+ * machine in the spec. Some broken hardware
+ * does not write the final dummy byte to the
+ * read register. Thus obf will never go high
+ * here. We just go straight to idle, and we
+ * handle clearing out obf in idle state if it
+ * happens to come in.
+ */
clear_obf(kcs, status);
kcs->orig_write_count = 0;
kcs->state = KCS_IDLE;
@@ -430,7 +457,8 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
case KCS_ERROR0:
clear_obf(kcs, status);
status = read_status(kcs);
- if (GET_STATUS_OBF(status)) /* controller isn't responding */
+ if (GET_STATUS_OBF(status))
+ /* controller isn't responding */
if (time_before(jiffies, kcs->error0_timeout))
return SI_SM_CALL_WITH_TICK_DELAY;
write_cmd(kcs, KCS_GET_STATUS_ABORT);
@@ -442,7 +470,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
write_data(kcs, 0);
kcs->state = KCS_ERROR2;
break;
-
+
case KCS_ERROR2:
if (state != KCS_READ_STATE) {
start_error_recovery(kcs,
@@ -456,7 +484,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
write_data(kcs, KCS_READ_BYTE);
kcs->state = KCS_ERROR3;
break;
-
+
case KCS_ERROR3:
if (state != KCS_IDLE_STATE) {
start_error_recovery(kcs,
@@ -475,7 +503,7 @@ static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
return SI_SM_TRANSACTION_COMPLETE;
}
break;
-
+
case KCS_HOSED:
break;
}
@@ -495,10 +523,12 @@ static int kcs_size(void)
static int kcs_detect(struct si_sm_data *kcs)
{
- /* It's impossible for the KCS status 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. */
+ /*
+ * It's impossible for the KCS status 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_status(kcs) == 0xff)
return 1;
@@ -509,8 +539,7 @@ static void kcs_cleanup(struct si_sm_data *kcs)
{
}
-struct si_sm_handlers kcs_smi_handlers =
-{
+struct si_sm_handlers kcs_smi_handlers = {
.init_data = init_kcs_data,
.start_transaction = start_kcs_transaction,
.get_result = get_kcs_result,