xref: /openbmc/linux/drivers/char/ipmi/ipmi_smic_sm.c (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1 /*
2  * ipmi_smic_sm.c
3  *
4  * The state-machine driver for an IPMI SMIC driver
5  *
6  * It started as a copy of Corey Minyard's driver for the KSC interface
7  * and the kernel patch "mmcdev-patch-245" by HP
8  *
9  * modified by:	Hannes Schulz <schulz@schwaar.com>
10  *		ipmi@schwaar.com
11  *
12  *
13  * Corey Minyard's driver for the KSC interface has the following
14  * copyright notice:
15  *   Copyright 2002 MontaVista Software Inc.
16  *
17  * the kernel patch "mmcdev-patch-245" by HP has the following
18  * copyright notice:
19  * (c) Copyright 2001 Grant Grundler (c) Copyright
20  * 2001 Hewlett-Packard Company
21  *
22  *
23  *  This program is free software; you can redistribute it and/or modify it
24  *  under the terms of the GNU General Public License as published by the
25  *  Free Software Foundation; either version 2 of the License, or (at your
26  *  option) any later version.
27  *
28  *
29  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
30  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
33  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
35  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  *
40  *  You should have received a copy of the GNU General Public License along
41  *  with this program; if not, write to the Free Software Foundation, Inc.,
42  *  675 Mass Ave, Cambridge, MA 02139, USA.  */
43 
44 #include <linux/kernel.h> /* For printk. */
45 #include <linux/string.h>
46 #include <linux/ipmi_msgdefs.h>		/* for completion codes */
47 #include "ipmi_si_sm.h"
48 
49 #define IPMI_SMIC_VERSION "v33"
50 
51 /* smic_debug is a bit-field
52  *	SMIC_DEBUG_ENABLE -	turned on for now
53  *	SMIC_DEBUG_MSG -	commands and their responses
54  *	SMIC_DEBUG_STATES -	state machine
55 */
56 #define SMIC_DEBUG_STATES	4
57 #define SMIC_DEBUG_MSG		2
58 #define	SMIC_DEBUG_ENABLE	1
59 
60 static int smic_debug = 1;
61 
62 enum smic_states {
63 	SMIC_IDLE,
64 	SMIC_START_OP,
65 	SMIC_OP_OK,
66 	SMIC_WRITE_START,
67 	SMIC_WRITE_NEXT,
68 	SMIC_WRITE_END,
69 	SMIC_WRITE2READ,
70 	SMIC_READ_START,
71 	SMIC_READ_NEXT,
72 	SMIC_READ_END,
73 	SMIC_HOSED
74 };
75 
76 #define MAX_SMIC_READ_SIZE 80
77 #define MAX_SMIC_WRITE_SIZE 80
78 #define SMIC_MAX_ERROR_RETRIES 3
79 
80 /* Timeouts in microseconds. */
81 #define SMIC_RETRY_TIMEOUT 100000
82 
83 /* SMIC Flags Register Bits */
84 #define SMIC_RX_DATA_READY	0x80
85 #define SMIC_TX_DATA_READY	0x40
86 #define SMIC_SMI		0x10
87 #define SMIC_EVM_DATA_AVAIL	0x08
88 #define SMIC_SMS_DATA_AVAIL	0x04
89 #define SMIC_FLAG_BSY		0x01
90 
91 /* SMIC Error Codes */
92 #define	EC_NO_ERROR		0x00
93 #define	EC_ABORTED		0x01
94 #define	EC_ILLEGAL_CONTROL	0x02
95 #define	EC_NO_RESPONSE		0x03
96 #define	EC_ILLEGAL_COMMAND	0x04
97 #define	EC_BUFFER_FULL		0x05
98 
99 struct si_sm_data
100 {
101 	enum smic_states state;
102 	struct si_sm_io *io;
103         unsigned char	 write_data[MAX_SMIC_WRITE_SIZE];
104         int		 write_pos;
105         int		 write_count;
106         int		 orig_write_count;
107         unsigned char	 read_data[MAX_SMIC_READ_SIZE];
108         int		 read_pos;
109         int		 truncated;
110         unsigned int	 error_retries;
111         long		 smic_timeout;
112 };
113 
114 static unsigned int init_smic_data (struct si_sm_data *smic,
115 				    struct si_sm_io *io)
116 {
117 	smic->state = SMIC_IDLE;
118 	smic->io = io;
119 	smic->write_pos = 0;
120 	smic->write_count = 0;
121 	smic->orig_write_count = 0;
122 	smic->read_pos = 0;
123 	smic->error_retries = 0;
124 	smic->truncated = 0;
125 	smic->smic_timeout = SMIC_RETRY_TIMEOUT;
126 
127 	/* We use 3 bytes of I/O. */
128 	return 3;
129 }
130 
131 static int start_smic_transaction(struct si_sm_data *smic,
132 				  unsigned char *data, unsigned int size)
133 {
134 	unsigned int i;
135 
136 	if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
137 		return -1;
138 	}
139 	if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
140 		return -2;
141 	}
142 	if (smic_debug & SMIC_DEBUG_MSG) {
143 		printk(KERN_INFO "start_smic_transaction -");
144 		for (i = 0; i < size; i ++) {
145 			printk (" %02x", (unsigned char) (data [i]));
146 		}
147 		printk ("\n");
148 	}
149 	smic->error_retries = 0;
150 	memcpy(smic->write_data, data, size);
151 	smic->write_count = size;
152 	smic->orig_write_count = size;
153 	smic->write_pos = 0;
154 	smic->read_pos = 0;
155 	smic->state = SMIC_START_OP;
156 	smic->smic_timeout = SMIC_RETRY_TIMEOUT;
157 	return 0;
158 }
159 
160 static int smic_get_result(struct si_sm_data *smic,
161 			   unsigned char *data, unsigned int length)
162 {
163 	int i;
164 
165 	if (smic_debug & SMIC_DEBUG_MSG) {
166 		printk (KERN_INFO "smic_get result -");
167 		for (i = 0; i < smic->read_pos; i ++) {
168 			printk (" %02x", (smic->read_data [i]));
169 		}
170 		printk ("\n");
171 	}
172 	if (length < smic->read_pos) {
173 		smic->read_pos = length;
174 		smic->truncated = 1;
175 	}
176 	memcpy(data, smic->read_data, smic->read_pos);
177 
178 	if ((length >= 3) && (smic->read_pos < 3)) {
179 		data[2] = IPMI_ERR_UNSPECIFIED;
180 		smic->read_pos = 3;
181 	}
182 	if (smic->truncated) {
183 		data[2] = IPMI_ERR_MSG_TRUNCATED;
184 		smic->truncated = 0;
185 	}
186 	return smic->read_pos;
187 }
188 
189 static inline unsigned char read_smic_flags(struct si_sm_data *smic)
190 {
191 	return smic->io->inputb(smic->io, 2);
192 }
193 
194 static inline unsigned char read_smic_status(struct si_sm_data *smic)
195 {
196 	return smic->io->inputb(smic->io, 1);
197 }
198 
199 static inline unsigned char read_smic_data(struct si_sm_data *smic)
200 {
201 	return smic->io->inputb(smic->io, 0);
202 }
203 
204 static inline void write_smic_flags(struct si_sm_data *smic,
205 				    unsigned char   flags)
206 {
207 	smic->io->outputb(smic->io, 2, flags);
208 }
209 
210 static inline void write_smic_control(struct si_sm_data *smic,
211 				      unsigned char   control)
212 {
213 	smic->io->outputb(smic->io, 1, control);
214 }
215 
216 static inline void write_si_sm_data (struct si_sm_data *smic,
217 				   unsigned char   data)
218 {
219 	smic->io->outputb(smic->io, 0, data);
220 }
221 
222 static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
223 {
224 	(smic->error_retries)++;
225 	if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
226 		if (smic_debug & SMIC_DEBUG_ENABLE) {
227 			printk(KERN_WARNING
228 			       "ipmi_smic_drv: smic hosed: %s\n", reason);
229 		}
230 		smic->state = SMIC_HOSED;
231 	} else {
232 		smic->write_count = smic->orig_write_count;
233 		smic->write_pos = 0;
234 		smic->read_pos = 0;
235 		smic->state = SMIC_START_OP;
236 		smic->smic_timeout = SMIC_RETRY_TIMEOUT;
237 	}
238 }
239 
240 static inline void write_next_byte(struct si_sm_data *smic)
241 {
242 	write_si_sm_data(smic, smic->write_data[smic->write_pos]);
243 	(smic->write_pos)++;
244 	(smic->write_count)--;
245 }
246 
247 static inline void read_next_byte (struct si_sm_data *smic)
248 {
249 	if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
250 		read_smic_data (smic);
251 		smic->truncated = 1;
252 	} else {
253 		smic->read_data[smic->read_pos] = read_smic_data(smic);
254 		(smic->read_pos)++;
255 	}
256 }
257 
258 /*  SMIC Control/Status Code Components */
259 #define	SMIC_GET_STATUS		0x00	/* Control form's name */
260 #define	SMIC_READY		0x00	/* Status  form's name */
261 #define	SMIC_WR_START		0x01	/* Unified Control/Status names... */
262 #define	SMIC_WR_NEXT		0x02
263 #define	SMIC_WR_END		0x03
264 #define	SMIC_RD_START		0x04
265 #define	SMIC_RD_NEXT		0x05
266 #define	SMIC_RD_END		0x06
267 #define	SMIC_CODE_MASK		0x0f
268 
269 #define	SMIC_CONTROL		0x00
270 #define	SMIC_STATUS		0x80
271 #define	SMIC_CS_MASK		0x80
272 
273 #define	SMIC_SMS		0x40
274 #define	SMIC_SMM		0x60
275 #define	SMIC_STREAM_MASK	0x60
276 
277 /*  SMIC Control Codes */
278 #define	SMIC_CC_SMS_GET_STATUS	(SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
279 #define	SMIC_CC_SMS_WR_START	(SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
280 #define	SMIC_CC_SMS_WR_NEXT	(SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
281 #define	SMIC_CC_SMS_WR_END	(SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
282 #define	SMIC_CC_SMS_RD_START	(SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
283 #define	SMIC_CC_SMS_RD_NEXT	(SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
284 #define	SMIC_CC_SMS_RD_END	(SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
285 
286 #define	SMIC_CC_SMM_GET_STATUS	(SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
287 #define	SMIC_CC_SMM_WR_START	(SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
288 #define	SMIC_CC_SMM_WR_NEXT	(SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
289 #define	SMIC_CC_SMM_WR_END	(SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
290 #define	SMIC_CC_SMM_RD_START	(SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
291 #define	SMIC_CC_SMM_RD_NEXT	(SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
292 #define	SMIC_CC_SMM_RD_END	(SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
293 
294 /*  SMIC Status Codes */
295 #define	SMIC_SC_SMS_READY	(SMIC_STATUS|SMIC_SMS|SMIC_READY)
296 #define	SMIC_SC_SMS_WR_START	(SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
297 #define	SMIC_SC_SMS_WR_NEXT	(SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
298 #define	SMIC_SC_SMS_WR_END	(SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
299 #define	SMIC_SC_SMS_RD_START	(SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
300 #define	SMIC_SC_SMS_RD_NEXT	(SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
301 #define	SMIC_SC_SMS_RD_END	(SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
302 
303 #define	SMIC_SC_SMM_READY	(SMIC_STATUS|SMIC_SMM|SMIC_READY)
304 #define	SMIC_SC_SMM_WR_START	(SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
305 #define	SMIC_SC_SMM_WR_NEXT	(SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
306 #define	SMIC_SC_SMM_WR_END	(SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
307 #define	SMIC_SC_SMM_RD_START	(SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
308 #define	SMIC_SC_SMM_RD_NEXT	(SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
309 #define	SMIC_SC_SMM_RD_END	(SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
310 
311 /* these are the control/status codes we actually use
312 	SMIC_CC_SMS_GET_STATUS	0x40
313 	SMIC_CC_SMS_WR_START	0x41
314 	SMIC_CC_SMS_WR_NEXT	0x42
315 	SMIC_CC_SMS_WR_END	0x43
316 	SMIC_CC_SMS_RD_START	0x44
317 	SMIC_CC_SMS_RD_NEXT	0x45
318 	SMIC_CC_SMS_RD_END	0x46
319 
320 	SMIC_SC_SMS_READY	0xC0
321 	SMIC_SC_SMS_WR_START	0xC1
322 	SMIC_SC_SMS_WR_NEXT	0xC2
323 	SMIC_SC_SMS_WR_END	0xC3
324 	SMIC_SC_SMS_RD_START	0xC4
325 	SMIC_SC_SMS_RD_NEXT	0xC5
326 	SMIC_SC_SMS_RD_END	0xC6
327 */
328 
329 static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
330 {
331 	unsigned char status;
332 	unsigned char flags;
333 	unsigned char data;
334 
335 	if (smic->state == SMIC_HOSED) {
336 		init_smic_data(smic, smic->io);
337 		return SI_SM_HOSED;
338 	}
339 	if (smic->state != SMIC_IDLE) {
340 		if (smic_debug & SMIC_DEBUG_STATES) {
341 			printk(KERN_INFO
342 			       "smic_event - smic->smic_timeout = %ld,"
343 			       " time = %ld\n",
344 			       smic->smic_timeout, time);
345 		}
346 /* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */
347 		if (time < SMIC_RETRY_TIMEOUT) {
348 			smic->smic_timeout -= time;
349 			if (smic->smic_timeout < 0) {
350 				start_error_recovery(smic, "smic timed out.");
351 				return SI_SM_CALL_WITH_DELAY;
352 			}
353 		}
354 	}
355 	flags = read_smic_flags(smic);
356 	if (flags & SMIC_FLAG_BSY)
357 		return SI_SM_CALL_WITH_DELAY;
358 
359 	status = read_smic_status (smic);
360 	if (smic_debug & SMIC_DEBUG_STATES)
361 		printk(KERN_INFO
362 		       "smic_event - state = %d, flags = 0x%02x,"
363 		       " status = 0x%02x\n",
364 		       smic->state, flags, status);
365 
366 	switch (smic->state) {
367 	case SMIC_IDLE:
368 		/* in IDLE we check for available messages */
369 		if (flags & (SMIC_SMI |
370 			     SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
371 		{
372 			return SI_SM_ATTN;
373 		}
374 		return SI_SM_IDLE;
375 
376 	case SMIC_START_OP:
377 		/* sanity check whether smic is really idle */
378 		write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
379 		write_smic_flags(smic, flags | SMIC_FLAG_BSY);
380 		smic->state = SMIC_OP_OK;
381 		break;
382 
383 	case SMIC_OP_OK:
384 		if (status != SMIC_SC_SMS_READY) {
385 				/* this should not happen */
386 			start_error_recovery(smic,
387 					     "state = SMIC_OP_OK,"
388 					     " status != SMIC_SC_SMS_READY");
389 			return SI_SM_CALL_WITH_DELAY;
390 		}
391 		/* OK so far; smic is idle let us start ... */
392 		write_smic_control(smic, SMIC_CC_SMS_WR_START);
393 		write_next_byte(smic);
394 		write_smic_flags(smic, flags | SMIC_FLAG_BSY);
395 		smic->state = SMIC_WRITE_START;
396 		break;
397 
398 	case SMIC_WRITE_START:
399 		if (status != SMIC_SC_SMS_WR_START) {
400 			start_error_recovery(smic,
401 					     "state = SMIC_WRITE_START, "
402 					     "status != SMIC_SC_SMS_WR_START");
403 			return SI_SM_CALL_WITH_DELAY;
404 		}
405 		/* we must not issue WR_(NEXT|END) unless
406                    TX_DATA_READY is set */
407 		if (flags & SMIC_TX_DATA_READY) {
408 			if (smic->write_count == 1) {
409 				/* last byte */
410 				write_smic_control(smic, SMIC_CC_SMS_WR_END);
411 				smic->state = SMIC_WRITE_END;
412 			} else {
413 				write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
414 				smic->state = SMIC_WRITE_NEXT;
415 			}
416 			write_next_byte(smic);
417 			write_smic_flags(smic, flags | SMIC_FLAG_BSY);
418 		}
419 		else {
420 			return SI_SM_CALL_WITH_DELAY;
421 		}
422 		break;
423 
424 	case SMIC_WRITE_NEXT:
425 		if (status != SMIC_SC_SMS_WR_NEXT) {
426 			start_error_recovery(smic,
427 					     "state = SMIC_WRITE_NEXT, "
428 					     "status != SMIC_SC_SMS_WR_NEXT");
429 			return SI_SM_CALL_WITH_DELAY;
430 		}
431 		/* this is the same code as in SMIC_WRITE_START */
432 		if (flags & SMIC_TX_DATA_READY) {
433 			if (smic->write_count == 1) {
434 				write_smic_control(smic, SMIC_CC_SMS_WR_END);
435 				smic->state = SMIC_WRITE_END;
436 			}
437 			else {
438 				write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
439 				smic->state = SMIC_WRITE_NEXT;
440 			}
441 			write_next_byte(smic);
442 			write_smic_flags(smic, flags | SMIC_FLAG_BSY);
443 		}
444 		else {
445 			return SI_SM_CALL_WITH_DELAY;
446 		}
447 		break;
448 
449 	case SMIC_WRITE_END:
450 		if (status != SMIC_SC_SMS_WR_END) {
451 			start_error_recovery (smic,
452 					      "state = SMIC_WRITE_END, "
453 					      "status != SMIC_SC_SMS_WR_END");
454 			return SI_SM_CALL_WITH_DELAY;
455 		}
456 		/* data register holds an error code */
457 		data = read_smic_data(smic);
458 		if (data != 0) {
459 			if (smic_debug & SMIC_DEBUG_ENABLE) {
460 				printk(KERN_INFO
461 				       "SMIC_WRITE_END: data = %02x\n", data);
462 			}
463 			start_error_recovery(smic,
464 					     "state = SMIC_WRITE_END, "
465 					     "data != SUCCESS");
466 			return SI_SM_CALL_WITH_DELAY;
467 		} else {
468 			smic->state = SMIC_WRITE2READ;
469 		}
470 		break;
471 
472 	case SMIC_WRITE2READ:
473 		/* we must wait for RX_DATA_READY to be set before we
474                    can continue */
475 		if (flags & SMIC_RX_DATA_READY) {
476 			write_smic_control(smic, SMIC_CC_SMS_RD_START);
477 			write_smic_flags(smic, flags | SMIC_FLAG_BSY);
478 			smic->state = SMIC_READ_START;
479 		} else {
480 			return SI_SM_CALL_WITH_DELAY;
481 		}
482 		break;
483 
484 	case SMIC_READ_START:
485 		if (status != SMIC_SC_SMS_RD_START) {
486 			start_error_recovery(smic,
487 					     "state = SMIC_READ_START, "
488 					     "status != SMIC_SC_SMS_RD_START");
489 			return SI_SM_CALL_WITH_DELAY;
490 		}
491 		if (flags & SMIC_RX_DATA_READY) {
492 			read_next_byte(smic);
493 			write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
494 			write_smic_flags(smic, flags | SMIC_FLAG_BSY);
495 			smic->state = SMIC_READ_NEXT;
496 		} else {
497 			return SI_SM_CALL_WITH_DELAY;
498 		}
499 		break;
500 
501 	case SMIC_READ_NEXT:
502 		switch (status) {
503 		/* smic tells us that this is the last byte to be read
504                    --> clean up */
505 		case SMIC_SC_SMS_RD_END:
506 			read_next_byte(smic);
507 			write_smic_control(smic, SMIC_CC_SMS_RD_END);
508 			write_smic_flags(smic, flags | SMIC_FLAG_BSY);
509 			smic->state = SMIC_READ_END;
510 			break;
511 		case SMIC_SC_SMS_RD_NEXT:
512 			if (flags & SMIC_RX_DATA_READY) {
513 				read_next_byte(smic);
514 				write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
515 				write_smic_flags(smic, flags | SMIC_FLAG_BSY);
516 				smic->state = SMIC_READ_NEXT;
517 			} else {
518 				return SI_SM_CALL_WITH_DELAY;
519 			}
520 			break;
521 		default:
522 			start_error_recovery(
523 				smic,
524 				"state = SMIC_READ_NEXT, "
525 				"status != SMIC_SC_SMS_RD_(NEXT|END)");
526 			return SI_SM_CALL_WITH_DELAY;
527 		}
528 		break;
529 
530 	case SMIC_READ_END:
531 		if (status != SMIC_SC_SMS_READY) {
532 			start_error_recovery(smic,
533 					     "state = SMIC_READ_END, "
534 					     "status != SMIC_SC_SMS_READY");
535 			return SI_SM_CALL_WITH_DELAY;
536 		}
537 		data = read_smic_data(smic);
538 		/* data register holds an error code */
539 		if (data != 0) {
540 			if (smic_debug & SMIC_DEBUG_ENABLE) {
541 				printk(KERN_INFO
542 				       "SMIC_READ_END: data = %02x\n", data);
543 			}
544 			start_error_recovery(smic,
545 					     "state = SMIC_READ_END, "
546 					     "data != SUCCESS");
547 			return SI_SM_CALL_WITH_DELAY;
548 		} else {
549 			smic->state = SMIC_IDLE;
550 			return SI_SM_TRANSACTION_COMPLETE;
551 		}
552 
553 	case SMIC_HOSED:
554 		init_smic_data(smic, smic->io);
555 		return SI_SM_HOSED;
556 
557 	default:
558 		if (smic_debug & SMIC_DEBUG_ENABLE) {
559 			printk(KERN_WARNING "smic->state = %d\n", smic->state);
560 			start_error_recovery(smic, "state = UNKNOWN");
561 			return SI_SM_CALL_WITH_DELAY;
562 		}
563 	}
564 	smic->smic_timeout = SMIC_RETRY_TIMEOUT;
565 	return SI_SM_CALL_WITHOUT_DELAY;
566 }
567 
568 static int smic_detect(struct si_sm_data *smic)
569 {
570 	/* It's impossible for the SMIC fnags register to be all 1's,
571 	   (assuming a properly functioning, self-initialized BMC)
572 	   but that's what you get from reading a bogus address, so we
573 	   test that first. */
574 	if (read_smic_flags(smic) == 0xff)
575 		return 1;
576 
577 	return 0;
578 }
579 
580 static void smic_cleanup(struct si_sm_data *kcs)
581 {
582 }
583 
584 static int smic_size(void)
585 {
586 	return sizeof(struct si_sm_data);
587 }
588 
589 struct si_sm_handlers smic_smi_handlers =
590 {
591 	.version           = IPMI_SMIC_VERSION,
592 	.init_data         = init_smic_data,
593 	.start_transaction = start_smic_transaction,
594 	.get_result        = smic_get_result,
595 	.event             = smic_event,
596 	.detect            = smic_detect,
597 	.cleanup           = smic_cleanup,
598 	.size              = smic_size,
599 };
600