11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ipmi_smic_sm.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The state-machine driver for an IPMI SMIC driver 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * It started as a copy of Corey Minyard's driver for the KSC interface 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and the kernel patch "mmcdev-patch-245" by HP 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modified by: Hannes Schulz <schulz@schwaar.com> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ipmi@schwaar.com 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Corey Minyard's driver for the KSC interface has the following 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * copyright notice: 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright 2002 MontaVista Software Inc. 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the kernel patch "mmcdev-patch-245" by HP has the following 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * copyright notice: 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (c) Copyright 2001 Grant Grundler (c) Copyright 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2001 Hewlett-Packard Company 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify it 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * under the terms of the GNU General Public License as published by the 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Free Software Foundation; either version 2 of the License, or (at your 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * option) any later version. 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * You should have received a copy of the GNU General Public License along 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * with this program; if not, write to the Free Software Foundation, Inc., 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 675 Mass Ave, Cambridge, MA 02139, USA. */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> /* For printk. */ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/string.h> 46c4edff1c19ef23e15aae64ca03f32c6719822d54Corey Minyard#include <linux/module.h> 47c4edff1c19ef23e15aae64ca03f32c6719822d54Corey Minyard#include <linux/moduleparam.h> 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ipmi_msgdefs.h> /* for completion codes */ 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ipmi_si_sm.h" 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* smic_debug is a bit-field 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SMIC_DEBUG_ENABLE - turned on for now 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SMIC_DEBUG_MSG - commands and their responses 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SMIC_DEBUG_STATES - state machine 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_DEBUG_STATES 4 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_DEBUG_MSG 2 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_DEBUG_ENABLE 1 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smic_debug = 1; 61c4edff1c19ef23e15aae64ca03f32c6719822d54Corey Minyardmodule_param(smic_debug, int, 0644); 62c4edff1c19ef23e15aae64ca03f32c6719822d54Corey MinyardMODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum smic_states { 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_IDLE, 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_START_OP, 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_OP_OK, 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_WRITE_START, 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_WRITE_NEXT, 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_WRITE_END, 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_WRITE2READ, 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_READ_START, 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_READ_NEXT, 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_READ_END, 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_HOSED 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_SMIC_READ_SIZE 80 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MAX_SMIC_WRITE_SIZE 80 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_MAX_ERROR_RETRIES 3 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Timeouts in microseconds. */ 83ccb3368cb4b97e2d8a763b894303e6a127f87bc8Xie XiuQi#define SMIC_RETRY_TIMEOUT (2*USEC_PER_SEC) 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* SMIC Flags Register Bits */ 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_RX_DATA_READY 0x80 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_TX_DATA_READY 0x40 88c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard 89d5a2b89a4943b423b5b0a07783fee4e08424b0b2Corey Minyard/* 90d5a2b89a4943b423b5b0a07783fee4e08424b0b2Corey Minyard * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by 91d5a2b89a4943b423b5b0a07783fee4e08424b0b2Corey Minyard * a few systems, and then only by Systems Management 92d5a2b89a4943b423b5b0a07783fee4e08424b0b2Corey Minyard * Interrupts, not by the OS. Always ignore these bits. 93d5a2b89a4943b423b5b0a07783fee4e08424b0b2Corey Minyard * 94d5a2b89a4943b423b5b0a07783fee4e08424b0b2Corey Minyard */ 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SMI 0x10 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_EVM_DATA_AVAIL 0x08 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SMS_DATA_AVAIL 0x04 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_FLAG_BSY 0x01 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* SMIC Error Codes */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EC_NO_ERROR 0x00 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EC_ABORTED 0x01 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EC_ILLEGAL_CONTROL 0x02 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EC_NO_RESPONSE 0x03 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EC_ILLEGAL_COMMAND 0x04 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EC_BUFFER_FULL 0x05 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyardstruct si_sm_data { 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enum smic_states state; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct si_sm_io *io; 111c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard unsigned char write_data[MAX_SMIC_WRITE_SIZE]; 112c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard int write_pos; 113c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard int write_count; 114c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard int orig_write_count; 115c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard unsigned char read_data[MAX_SMIC_READ_SIZE]; 116c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard int read_pos; 117c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard int truncated; 118c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard unsigned int error_retries; 119c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard long smic_timeout; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 122c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyardstatic unsigned int init_smic_data(struct si_sm_data *smic, 123c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard struct si_sm_io *io) 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_IDLE; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->io = io; 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->write_pos = 0; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->write_count = 0; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->orig_write_count = 0; 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->read_pos = 0; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->error_retries = 0; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->truncated = 0; 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->smic_timeout = SMIC_RETRY_TIMEOUT; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We use 3 bytes of I/O. */ 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 3; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int start_smic_transaction(struct si_sm_data *smic, 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *data, unsigned int size) 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1444d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard if (size < 2) 1454d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard return IPMI_REQ_LEN_INVALID_ERR; 1464d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard if (size > MAX_SMIC_WRITE_SIZE) 1474d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard return IPMI_REQ_LEN_EXCEEDED_ERR; 1484d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard 1494d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) 1504d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard return IPMI_NOT_IN_MY_STATE_ERR; 1514d7cbac7c870ca66d8fb27d68188efbb5de2dffaCorey Minyard 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic_debug & SMIC_DEBUG_MSG) { 153c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(KERN_DEBUG "start_smic_transaction -"); 154c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard for (i = 0; i < size; i++) 155c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(" %02x", (unsigned char) data[i]); 156c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk("\n"); 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->error_retries = 0; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(smic->write_data, data, size); 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->write_count = size; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->orig_write_count = size; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->write_pos = 0; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->read_pos = 0; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_START_OP; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->smic_timeout = SMIC_RETRY_TIMEOUT; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smic_get_result(struct si_sm_data *smic, 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *data, unsigned int length) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic_debug & SMIC_DEBUG_MSG) { 175c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(KERN_DEBUG "smic_get result -"); 176c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard for (i = 0; i < smic->read_pos; i++) 177c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(" %02x", smic->read_data[i]); 178c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk("\n"); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (length < smic->read_pos) { 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->read_pos = length; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->truncated = 1; 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(data, smic->read_data, smic->read_pos); 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((length >= 3) && (smic->read_pos < 3)) { 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[2] = IPMI_ERR_UNSPECIFIED; 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->read_pos = 3; 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->truncated) { 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data[2] = IPMI_ERR_MSG_TRUNCATED; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->truncated = 0; 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return smic->read_pos; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned char read_smic_flags(struct si_sm_data *smic) 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return smic->io->inputb(smic->io, 2); 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned char read_smic_status(struct si_sm_data *smic) 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return smic->io->inputb(smic->io, 1); 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned char read_smic_data(struct si_sm_data *smic) 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return smic->io->inputb(smic->io, 0); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void write_smic_flags(struct si_sm_data *smic, 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char flags) 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->io->outputb(smic->io, 2, flags); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void write_smic_control(struct si_sm_data *smic, 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char control) 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->io->outputb(smic->io, 1, control); 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 224c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyardstatic inline void write_si_sm_data(struct si_sm_data *smic, 225c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard unsigned char data) 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->io->outputb(smic->io, 0, data); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void start_error_recovery(struct si_sm_data *smic, char *reason) 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (smic->error_retries)++; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) { 234c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard if (smic_debug & SMIC_DEBUG_ENABLE) 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_WARNING 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "ipmi_smic_drv: smic hosed: %s\n", reason); 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_HOSED; 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->write_count = smic->orig_write_count; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->write_pos = 0; 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->read_pos = 0; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_START_OP; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->smic_timeout = SMIC_RETRY_TIMEOUT; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void write_next_byte(struct si_sm_data *smic) 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_si_sm_data(smic, smic->write_data[smic->write_pos]); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (smic->write_pos)++; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (smic->write_count)--; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 254c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyardstatic inline void read_next_byte(struct si_sm_data *smic) 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->read_pos >= MAX_SMIC_READ_SIZE) { 257c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard read_smic_data(smic); 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->truncated = 1; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->read_data[smic->read_pos] = read_smic_data(smic); 261c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard smic->read_pos++; 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* SMIC Control/Status Code Components */ 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_GET_STATUS 0x00 /* Control form's name */ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_READY 0x00 /* Status form's name */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_WR_START 0x01 /* Unified Control/Status names... */ 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_WR_NEXT 0x02 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_WR_END 0x03 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_RD_START 0x04 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_RD_NEXT 0x05 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_RD_END 0x06 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CODE_MASK 0x0f 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CONTROL 0x00 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_STATUS 0x80 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CS_MASK 0x80 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SMS 0x40 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SMM 0x60 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_STREAM_MASK 0x60 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* SMIC Control Codes */ 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS) 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START) 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT) 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END) 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START) 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT) 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END) 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS) 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START) 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END) 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START) 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT) 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END) 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* SMIC Status Codes */ 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY) 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START) 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT) 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END) 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START) 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT) 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END) 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY) 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START) 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT) 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END) 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START) 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT) 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END) 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* these are the control/status codes we actually use 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_CC_SMS_GET_STATUS 0x40 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_CC_SMS_WR_START 0x41 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_CC_SMS_WR_NEXT 0x42 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_CC_SMS_WR_END 0x43 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_CC_SMS_RD_START 0x44 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_CC_SMS_RD_NEXT 0x45 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_CC_SMS_RD_END 0x46 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_SC_SMS_READY 0xC0 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_SC_SMS_WR_START 0xC1 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_SC_SMS_WR_NEXT 0xC2 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_SC_SMS_WR_END 0xC3 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_SC_SMS_RD_START 0xC4 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_SC_SMS_RD_NEXT 0xC5 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds SMIC_SC_SMS_RD_END 0xC6 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 336c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyardstatic enum si_sm_result smic_event(struct si_sm_data *smic, long time) 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char status; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char flags; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char data; 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->state == SMIC_HOSED) { 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_smic_data(smic, smic->io); 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_HOSED; 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->state != SMIC_IDLE) { 347c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard if (smic_debug & SMIC_DEBUG_STATES) 348c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(KERN_DEBUG 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "smic_event - smic->smic_timeout = %ld," 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " time = %ld\n", 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->smic_timeout, time); 352c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard /* 353c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * FIXME: smic_event is sometimes called with time > 354c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * SMIC_RETRY_TIMEOUT 355c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard */ 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (time < SMIC_RETRY_TIMEOUT) { 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->smic_timeout -= time; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->smic_timeout < 0) { 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, "smic timed out."); 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds flags = read_smic_flags(smic); 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & SMIC_FLAG_BSY) 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 368c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard status = read_smic_status(smic); 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic_debug & SMIC_DEBUG_STATES) 370c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(KERN_DEBUG 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "smic_event - state = %d, flags = 0x%02x," 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " status = 0x%02x\n", 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state, flags, status); 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (smic->state) { 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_IDLE: 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* in IDLE we check for available messages */ 378d5a2b89a4943b423b5b0a07783fee4e08424b0b2Corey Minyard if (flags & SMIC_SMS_DATA_AVAIL) 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_ATTN; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_IDLE; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_START_OP: 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* sanity check whether smic is really idle */ 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_GET_STATUS); 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_OP_OK; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_OP_OK: 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status != SMIC_SC_SMS_READY) { 391c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard /* this should not happen */ 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_OP_OK," 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " status != SMIC_SC_SMS_READY"); 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* OK so far; smic is idle let us start ... */ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_WR_START); 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_next_byte(smic); 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_WRITE_START; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_WRITE_START: 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status != SMIC_SC_SMS_WR_START) { 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_WRITE_START, " 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "status != SMIC_SC_SMS_WR_START"); 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 411c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard /* 412c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * we must not issue WR_(NEXT|END) unless 413c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * TX_DATA_READY is set 414c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * */ 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & SMIC_TX_DATA_READY) { 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->write_count == 1) { 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* last byte */ 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_WR_END); 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_WRITE_END; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_WRITE_NEXT; 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_next_byte(smic); 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 426c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard } else 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_WRITE_NEXT: 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status != SMIC_SC_SMS_WR_NEXT) { 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_WRITE_NEXT, " 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "status != SMIC_SC_SMS_WR_NEXT"); 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this is the same code as in SMIC_WRITE_START */ 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & SMIC_TX_DATA_READY) { 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic->write_count == 1) { 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_WR_END); 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_WRITE_END; 442c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard } else { 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_WR_NEXT); 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_WRITE_NEXT; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_next_byte(smic); 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 448c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard } else 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_WRITE_END: 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status != SMIC_SC_SMS_WR_END) { 454c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard start_error_recovery(smic, 455c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard "state = SMIC_WRITE_END, " 456c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard "status != SMIC_SC_SMS_WR_END"); 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* data register holds an error code */ 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data = read_smic_data(smic); 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (data != 0) { 462c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard if (smic_debug & SMIC_DEBUG_ENABLE) 463c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(KERN_DEBUG 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "SMIC_WRITE_END: data = %02x\n", data); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_WRITE_END, " 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "data != SUCCESS"); 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 469c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard } else 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_WRITE2READ; 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_WRITE2READ: 474c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard /* 475c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * we must wait for RX_DATA_READY to be set before we 476c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * can continue 477c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard */ 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & SMIC_RX_DATA_READY) { 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_RD_START); 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_READ_START; 482c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard } else 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_READ_START: 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status != SMIC_SC_SMS_RD_START) { 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_READ_START, " 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "status != SMIC_SC_SMS_RD_START"); 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & SMIC_RX_DATA_READY) { 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds read_next_byte(smic); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_READ_NEXT; 498c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard } else 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_READ_NEXT: 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (status) { 504c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard /* 505c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * smic tells us that this is the last byte to be read 506c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * --> clean up 507c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard */ 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_SC_SMS_RD_END: 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds read_next_byte(smic); 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_RD_END); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_READ_END; 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_SC_SMS_RD_NEXT: 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (flags & SMIC_RX_DATA_READY) { 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds read_next_byte(smic); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_control(smic, SMIC_CC_SMS_RD_NEXT); 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds write_smic_flags(smic, flags | SMIC_FLAG_BSY); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_READ_NEXT; 520c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard } else 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery( 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic, 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_READ_NEXT, " 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "status != SMIC_SC_SMS_RD_(NEXT|END)"); 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_READ_END: 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status != SMIC_SC_SMS_READY) { 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_READ_END, " 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "status != SMIC_SC_SMS_READY"); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data = read_smic_data(smic); 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* data register holds an error code */ 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (data != 0) { 542c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard if (smic_debug & SMIC_DEBUG_ENABLE) 543c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(KERN_DEBUG 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "SMIC_READ_END: data = %02x\n", data); 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "state = SMIC_READ_END, " 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "data != SUCCESS"); 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->state = SMIC_IDLE; 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_TRANSACTION_COMPLETE; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case SMIC_HOSED: 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds init_smic_data(smic, smic->io); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_HOSED; 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (smic_debug & SMIC_DEBUG_ENABLE) { 560c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard printk(KERN_DEBUG "smic->state = %d\n", smic->state); 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start_error_recovery(smic, "state = UNKNOWN"); 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITH_DELAY; 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds smic->smic_timeout = SMIC_RETRY_TIMEOUT; 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return SI_SM_CALL_WITHOUT_DELAY; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smic_detect(struct si_sm_data *smic) 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 571c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard /* 572c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * It's impossible for the SMIC fnags register to be all 1's, 573c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * (assuming a properly functioning, self-initialized BMC) 574c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * but that's what you get from reading a bogus address, so we 575c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard * test that first. 576c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyard */ 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (read_smic_flags(smic) == 0xff) 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void smic_cleanup(struct si_sm_data *kcs) 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int smic_size(void) 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sizeof(struct si_sm_data); 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 592c305e3d38e5f54a48a4618496cdc1ada970ebf68Corey Minyardstruct si_sm_handlers smic_smi_handlers = { 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init_data = init_smic_data, 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .start_transaction = start_smic_transaction, 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .get_result = smic_get_result, 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .event = smic_event, 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .detect = smic_detect, 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .cleanup = smic_cleanup, 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .size = smic_size, 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 601