ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / ipmi / ipmi_smic_sm.c
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 "v31"
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 };