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