root/drivers/char/ipmi/ipmi_smic_sm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. init_smic_data
  2. start_smic_transaction
  3. smic_get_result
  4. read_smic_flags
  5. read_smic_status
  6. read_smic_data
  7. write_smic_flags
  8. write_smic_control
  9. write_si_sm_data
  10. start_error_recovery
  11. write_next_byte
  12. read_next_byte
  13. smic_event
  14. smic_detect
  15. smic_cleanup
  16. smic_size

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

/* [<][>][^][v][top][bottom][index][help] */