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#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
  40static int smic_debug = 1;
  41module_param(smic_debug, int, 0644);
  42MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");
  43
  44enum 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
  88struct 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
 102static 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
 119static 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
 149static 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
 177static inline unsigned char read_smic_flags(struct si_sm_data *smic)
 178{
 179        return smic->io->inputb(smic->io, 2);
 180}
 181
 182static inline unsigned char read_smic_status(struct si_sm_data *smic)
 183{
 184        return smic->io->inputb(smic->io, 1);
 185}
 186
 187static inline unsigned char read_smic_data(struct si_sm_data *smic)
 188{
 189        return smic->io->inputb(smic->io, 0);
 190}
 191
 192static 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
 198static 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
 204static 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
 210static 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
 226static 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
 233static 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
 315static 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
 545static 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
 559static void smic_cleanup(struct si_sm_data *kcs)
 560{
 561}
 562
 563static int smic_size(void)
 564{
 565        return sizeof(struct si_sm_data);
 566}
 567
 568const 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};
 577