1 /*
2 * ipmi_kcs_sm.c
3 *
4 * State machine for handling IPMI KCS interfaces.
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2002 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU General Public License along
30 * with this program; if not, write to the Free Software Foundation, Inc.,
31 * 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33
34 /*
35 * This state machine is taken from the state machine in the IPMI spec,
36 * pretty much verbatim. If you have questions about the states, see
37 * that document.
38 */
39
40 #include <asm/io.h>
41 #include <asm/string.h> /* Gets rid of memcpy warning */
42
43 #include "ipmi_kcs_sm.h"
44
45 /* Set this if you want a printout of why the state machine was hosed
46 when it gets hosed. */
47 #define DEBUG_HOSED_REASON
48
49 /* Print the state machine state on entry every time. */
50 #undef DEBUG_STATE
51
52 /* The states the KCS driver may be in. */
53 enum kcs_states {
54 KCS_IDLE, /* The KCS interface is currently
55 doing nothing. */
56 KCS_START_OP, /* We are starting an operation. The
57 data is in the output buffer, but
58 nothing has been done to the
59 interface yet. This was added to
60 the state machine in the spec to
61 wait for the initial IBF. */
62 KCS_WAIT_WRITE_START, /* We have written a write cmd to the
63 interface. */
64 KCS_WAIT_WRITE, /* We are writing bytes to the
65 interface. */
66 KCS_WAIT_WRITE_END, /* We have written the write end cmd
67 to the interface, and still need to
68 write the last byte. */
69 KCS_WAIT_READ, /* We are waiting to read data from
70 the interface. */
71 KCS_ERROR0, /* State to transition to the error
72 handler, this was added to the
73 state machine in the spec to be
74 sure IBF was there. */
75 KCS_ERROR1, /* First stage error handler, wait for
76 the interface to respond. */
77 KCS_ERROR2, /* The abort cmd has been written,
78 wait for the interface to
79 respond. */
80 KCS_ERROR3, /* We wrote some data to the
81 interface, wait for it to switch to
82 read mode. */
83 KCS_HOSED /* The hardware failed to follow the
84 state machine. */
85 };
86
87 #define MAX_KCS_READ_SIZE 80
88 #define MAX_KCS_WRITE_SIZE 80
89
90 /* Timeouts in microseconds. */
91 #define IBF_RETRY_TIMEOUT 1000000
92 #define OBF_RETRY_TIMEOUT 1000000
93 #define MAX_ERROR_RETRIES 10
94
95 #define IPMI_ERR_MSG_TRUNCATED 0xc6
96 #define IPMI_ERR_UNSPECIFIED 0xff
97
98 struct kcs_data
99 {
100 enum kcs_states state;
101 unsigned int port;
102 unsigned char *addr;
103 unsigned char write_data[MAX_KCS_WRITE_SIZE];
104 int write_pos;
105 int write_count;
106 int orig_write_count;
107 unsigned char read_data[MAX_KCS_READ_SIZE];
108 int read_pos;
109 int truncated;
110
111 unsigned int error_retries;
112 long ibf_timeout;
113 long obf_timeout;
114 };
115
init_kcs_data(struct kcs_data * kcs,unsigned int port,unsigned char * addr)116 void init_kcs_data(struct kcs_data *kcs, unsigned int port, unsigned char *addr)
117 {
118 kcs->state = KCS_IDLE;
119 kcs->port = port;
120 kcs->addr = addr;
121 kcs->write_pos = 0;
122 kcs->write_count = 0;
123 kcs->orig_write_count = 0;
124 kcs->read_pos = 0;
125 kcs->error_retries = 0;
126 kcs->truncated = 0;
127 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
128 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
129 }
130
131 /* Remember, init_one_kcs() insured port and addr can't both be set */
132
read_status(struct kcs_data * kcs)133 static inline unsigned char read_status(struct kcs_data *kcs)
134 {
135 if (kcs->port)
136 return inb(kcs->port + 1);
137 else
138 return readb(kcs->addr + 1);
139 }
140
read_data(struct kcs_data * kcs)141 static inline unsigned char read_data(struct kcs_data *kcs)
142 {
143 if (kcs->port)
144 return inb(kcs->port + 0);
145 else
146 return readb(kcs->addr + 0);
147 }
148
write_cmd(struct kcs_data * kcs,unsigned char data)149 static inline void write_cmd(struct kcs_data *kcs, unsigned char data)
150 {
151 if (kcs->port)
152 outb(data, kcs->port + 1);
153 else
154 writeb(data, kcs->addr + 1);
155 }
156
write_data(struct kcs_data * kcs,unsigned char data)157 static inline void write_data(struct kcs_data *kcs, unsigned char data)
158 {
159 if (kcs->port)
160 outb(data, kcs->port + 0);
161 else
162 writeb(data, kcs->addr + 0);
163 }
164
165 /* Control codes. */
166 #define KCS_GET_STATUS_ABORT 0x60
167 #define KCS_WRITE_START 0x61
168 #define KCS_WRITE_END 0x62
169 #define KCS_READ_BYTE 0x68
170
171 /* Status bits. */
172 #define GET_STATUS_STATE(status) (((status) >> 6) & 0x03)
173 #define KCS_IDLE_STATE 0
174 #define KCS_READ_STATE 1
175 #define KCS_WRITE_STATE 2
176 #define KCS_ERROR_STATE 3
177 #define GET_STATUS_ATN(status) ((status) & 0x04)
178 #define GET_STATUS_IBF(status) ((status) & 0x02)
179 #define GET_STATUS_OBF(status) ((status) & 0x01)
180
181
write_next_byte(struct kcs_data * kcs)182 static inline void write_next_byte(struct kcs_data *kcs)
183 {
184 write_data(kcs, kcs->write_data[kcs->write_pos]);
185 (kcs->write_pos)++;
186 (kcs->write_count)--;
187 }
188
start_error_recovery(struct kcs_data * kcs,char * reason)189 static inline void start_error_recovery(struct kcs_data *kcs, char *reason)
190 {
191 (kcs->error_retries)++;
192 if (kcs->error_retries > MAX_ERROR_RETRIES) {
193 #ifdef DEBUG_HOSED_REASON
194 printk("ipmi_kcs_sm: kcs hosed: %s\n", reason);
195 #endif
196 kcs->state = KCS_HOSED;
197 } else {
198 kcs->state = KCS_ERROR0;
199 }
200 }
201
read_next_byte(struct kcs_data * kcs)202 static inline void read_next_byte(struct kcs_data *kcs)
203 {
204 if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
205 /* Throw the data away and mark it truncated. */
206 read_data(kcs);
207 kcs->truncated = 1;
208 } else {
209 kcs->read_data[kcs->read_pos] = read_data(kcs);
210 (kcs->read_pos)++;
211 }
212 write_data(kcs, KCS_READ_BYTE);
213 }
214
check_ibf(struct kcs_data * kcs,unsigned char status,long time)215 static inline int check_ibf(struct kcs_data *kcs,
216 unsigned char status,
217 long time)
218 {
219 if (GET_STATUS_IBF(status)) {
220 kcs->ibf_timeout -= time;
221 if (kcs->ibf_timeout < 0) {
222 start_error_recovery(kcs, "IBF not ready in time");
223 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
224 return 1;
225 }
226 return 0;
227 }
228 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
229 return 1;
230 }
231
check_obf(struct kcs_data * kcs,unsigned char status,long time)232 static inline int check_obf(struct kcs_data *kcs,
233 unsigned char status,
234 long time)
235 {
236 if (! GET_STATUS_OBF(status)) {
237 kcs->obf_timeout -= time;
238 if (kcs->obf_timeout < 0) {
239 start_error_recovery(kcs, "OBF not ready in time");
240 return 1;
241 }
242 return 0;
243 }
244 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
245 return 1;
246 }
247
clear_obf(struct kcs_data * kcs,unsigned char status)248 static void clear_obf(struct kcs_data *kcs, unsigned char status)
249 {
250 if (GET_STATUS_OBF(status))
251 read_data(kcs);
252 }
253
restart_kcs_transaction(struct kcs_data * kcs)254 static void restart_kcs_transaction(struct kcs_data *kcs)
255 {
256 kcs->write_count = kcs->orig_write_count;
257 kcs->write_pos = 0;
258 kcs->read_pos = 0;
259 kcs->state = KCS_WAIT_WRITE_START;
260 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
261 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
262 write_cmd(kcs, KCS_WRITE_START);
263 }
264
start_kcs_transaction(struct kcs_data * kcs,char * data,unsigned int size)265 int start_kcs_transaction(struct kcs_data *kcs, char *data, unsigned int size)
266 {
267 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
268 return -1;
269 }
270
271 if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) {
272 return -2;
273 }
274
275 kcs->error_retries = 0;
276 memcpy(kcs->write_data, data, size);
277 kcs->write_count = size;
278 kcs->orig_write_count = size;
279 kcs->write_pos = 0;
280 kcs->read_pos = 0;
281 kcs->state = KCS_START_OP;
282 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
283 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
284 return 0;
285 }
286
kcs_get_result(struct kcs_data * kcs,unsigned char * data,int length)287 int kcs_get_result(struct kcs_data *kcs, unsigned char *data, int length)
288 {
289 if (length < kcs->read_pos) {
290 kcs->read_pos = length;
291 kcs->truncated = 1;
292 }
293
294 memcpy(data, kcs->read_data, kcs->read_pos);
295
296 if ((length >= 3) && (kcs->read_pos < 3)) {
297 /* Guarantee that we return at least 3 bytes, with an
298 error in the third byte if it is too short. */
299 data[2] = IPMI_ERR_UNSPECIFIED;
300 kcs->read_pos = 3;
301 }
302 if (kcs->truncated) {
303 /* Report a truncated error. We might overwrite
304 another error, but that's too bad, the user needs
305 to know it was truncated. */
306 data[2] = IPMI_ERR_MSG_TRUNCATED;
307 kcs->truncated = 0;
308 }
309
310 return kcs->read_pos;
311 }
312
313 /* This implements the state machine defined in the IPMI manual, see
314 that for details on how this works. Divide that flowchart into
315 sections delimited by "Wait for IBF" and this will become clear. */
kcs_event(struct kcs_data * kcs,long time)316 enum kcs_result kcs_event(struct kcs_data *kcs, long time)
317 {
318 unsigned char status;
319 unsigned char state;
320
321 status = read_status(kcs);
322
323 #ifdef DEBUG_STATE
324 printk(" State = %d, %x\n", kcs->state, status);
325 #endif
326 /* All states wait for ibf, so just do it here. */
327 if (!check_ibf(kcs, status, time))
328 return KCS_CALL_WITH_DELAY;
329
330 /* Just about everything looks at the KCS state, so grab that, too. */
331 state = GET_STATUS_STATE(status);
332
333 switch (kcs->state) {
334 case KCS_IDLE:
335 /* If there's and interrupt source, turn it off. */
336 clear_obf(kcs, status);
337
338 if (GET_STATUS_ATN(status))
339 return KCS_ATTN;
340 else
341 return KCS_SM_IDLE;
342
343 case KCS_START_OP:
344 if (state != KCS_IDLE) {
345 start_error_recovery(kcs,
346 "State machine not idle at start");
347 break;
348 }
349
350 clear_obf(kcs, status);
351 write_cmd(kcs, KCS_WRITE_START);
352 kcs->state = KCS_WAIT_WRITE_START;
353 break;
354
355 case KCS_WAIT_WRITE_START:
356 if (state != KCS_WRITE_STATE) {
357 start_error_recovery(
358 kcs,
359 "Not in write state at write start");
360 break;
361 }
362 read_data(kcs);
363 if (kcs->write_count == 1) {
364 write_cmd(kcs, KCS_WRITE_END);
365 kcs->state = KCS_WAIT_WRITE_END;
366 } else {
367 write_next_byte(kcs);
368 kcs->state = KCS_WAIT_WRITE;
369 }
370 break;
371
372 case KCS_WAIT_WRITE:
373 if (state != KCS_WRITE_STATE) {
374 start_error_recovery(kcs,
375 "Not in write state for write");
376 break;
377 }
378 clear_obf(kcs, status);
379 if (kcs->write_count == 1) {
380 write_cmd(kcs, KCS_WRITE_END);
381 kcs->state = KCS_WAIT_WRITE_END;
382 } else {
383 write_next_byte(kcs);
384 }
385 break;
386
387 case KCS_WAIT_WRITE_END:
388 if (state != KCS_WRITE_STATE) {
389 start_error_recovery(kcs,
390 "Not in write state for write end");
391 break;
392 }
393 clear_obf(kcs, status);
394 write_next_byte(kcs);
395 kcs->state = KCS_WAIT_READ;
396 break;
397
398 case KCS_WAIT_READ:
399 if ((state != KCS_READ_STATE) && (state != KCS_IDLE_STATE)) {
400 start_error_recovery(
401 kcs,
402 "Not in read or idle in read state");
403 break;
404 }
405
406 if (state == KCS_READ_STATE) {
407 if (! check_obf(kcs, status, time))
408 return KCS_CALL_WITH_DELAY;
409 read_next_byte(kcs);
410 } else {
411 /* We don't implement this exactly like the state
412 machine in the spec. Some broken hardware
413 does not write the final dummy byte to the
414 read register. Thus obf will never go high
415 here. We just go straight to idle, and we
416 handle clearing out obf in idle state if it
417 happens to come in. */
418 clear_obf(kcs, status);
419 kcs->orig_write_count = 0;
420 kcs->state = KCS_IDLE;
421 return KCS_TRANSACTION_COMPLETE;
422 }
423 break;
424
425 case KCS_ERROR0:
426 clear_obf(kcs, status);
427 write_cmd(kcs, KCS_GET_STATUS_ABORT);
428 kcs->state = KCS_ERROR1;
429 break;
430
431 case KCS_ERROR1:
432 clear_obf(kcs, status);
433 write_data(kcs, 0);
434 kcs->state = KCS_ERROR2;
435 break;
436
437 case KCS_ERROR2:
438 if (state != KCS_READ_STATE) {
439 start_error_recovery(kcs,
440 "Not in read state for error2");
441 break;
442 }
443 if (! check_obf(kcs, status, time))
444 return KCS_CALL_WITH_DELAY;
445
446 clear_obf(kcs, status);
447 write_data(kcs, KCS_READ_BYTE);
448 kcs->state = KCS_ERROR3;
449 break;
450
451 case KCS_ERROR3:
452 if (state != KCS_IDLE_STATE) {
453 start_error_recovery(kcs,
454 "Not in idle state for error3");
455 break;
456 }
457
458 if (! check_obf(kcs, status, time))
459 return KCS_CALL_WITH_DELAY;
460
461 clear_obf(kcs, status);
462 if (kcs->orig_write_count) {
463 restart_kcs_transaction(kcs);
464 } else {
465 kcs->state = KCS_IDLE;
466 return KCS_TRANSACTION_COMPLETE;
467 }
468 break;
469
470 case KCS_HOSED:
471 break;
472 }
473
474 if (kcs->state == KCS_HOSED) {
475 init_kcs_data(kcs, kcs->port, kcs->addr);
476 return KCS_SM_HOSED;
477 }
478
479 return KCS_CALL_WITHOUT_DELAY;
480 }
481
kcs_size(void)482 int kcs_size(void)
483 {
484 return sizeof(struct kcs_data);
485 }
486