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