⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipmi_smic_sm.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ipmi_smic_sm.c * * The state-machine driver for an IPMI SMIC driver * * It started as a copy of Corey Minyard's driver for the KSC interface * and the kernel patch "mmcdev-patch-245" by HP * * modified by:	Hannes Schulz <schulz@schwaar.com> *		ipmi@schwaar.com * * * Corey Minyard's driver for the KSC interface has the following * copyright notice: *   Copyright 2002 MontaVista Software Inc. * * the kernel patch "mmcdev-patch-245" by HP has the following * copyright notice: * (c) Copyright 2001 Grant Grundler (c) Copyright * 2001 Hewlett-Packard Company * * *  This program is free software; you can redistribute it and/or modify it *  under the terms of the GNU General Public License as published by the *  Free Software Foundation; either version 2 of the License, or (at your *  option) any later version. * * *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *  You should have received a copy of the GNU General Public License along *  with this program; if not, write to the Free Software Foundation, Inc., *  675 Mass Ave, Cambridge, MA 02139, USA.  */#include <linux/kernel.h> /* For printk. */#include <linux/string.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/ipmi_msgdefs.h>		/* for completion codes */#include "ipmi_si_sm.h"/* smic_debug is a bit-field *	SMIC_DEBUG_ENABLE -	turned on for now *	SMIC_DEBUG_MSG -	commands and their responses *	SMIC_DEBUG_STATES -	state machine*/#define SMIC_DEBUG_STATES	4#define SMIC_DEBUG_MSG		2#define	SMIC_DEBUG_ENABLE	1static int smic_debug = 1;module_param(smic_debug, int, 0644);MODULE_PARM_DESC(smic_debug, "debug bitmask, 1=enable, 2=messages, 4=states");enum smic_states {	SMIC_IDLE,	SMIC_START_OP,	SMIC_OP_OK,	SMIC_WRITE_START,	SMIC_WRITE_NEXT,	SMIC_WRITE_END,	SMIC_WRITE2READ,	SMIC_READ_START,	SMIC_READ_NEXT,	SMIC_READ_END,	SMIC_HOSED};#define MAX_SMIC_READ_SIZE 80#define MAX_SMIC_WRITE_SIZE 80#define SMIC_MAX_ERROR_RETRIES 3/* Timeouts in microseconds. */#define SMIC_RETRY_TIMEOUT 2000000/* SMIC Flags Register Bits */#define SMIC_RX_DATA_READY	0x80#define SMIC_TX_DATA_READY	0x40/* * SMIC_SMI and SMIC_EVM_DATA_AVAIL are only used by * a few systems, and then only by Systems Management * Interrupts, not by the OS.  Always ignore these bits. * */#define SMIC_SMI		0x10#define SMIC_EVM_DATA_AVAIL	0x08#define SMIC_SMS_DATA_AVAIL	0x04#define SMIC_FLAG_BSY		0x01/* SMIC Error Codes */#define	EC_NO_ERROR		0x00#define	EC_ABORTED		0x01#define	EC_ILLEGAL_CONTROL	0x02#define	EC_NO_RESPONSE		0x03#define	EC_ILLEGAL_COMMAND	0x04#define	EC_BUFFER_FULL		0x05struct si_sm_data{	enum smic_states state;	struct si_sm_io *io;        unsigned char	 write_data[MAX_SMIC_WRITE_SIZE];        int		 write_pos;        int		 write_count;        int		 orig_write_count;        unsigned char	 read_data[MAX_SMIC_READ_SIZE];        int		 read_pos;        int		 truncated;        unsigned int	 error_retries;        long		 smic_timeout;};static unsigned int init_smic_data (struct si_sm_data *smic,				    struct si_sm_io *io){	smic->state = SMIC_IDLE;	smic->io = io;	smic->write_pos = 0;	smic->write_count = 0;	smic->orig_write_count = 0;	smic->read_pos = 0;	smic->error_retries = 0;	smic->truncated = 0;	smic->smic_timeout = SMIC_RETRY_TIMEOUT;	/* We use 3 bytes of I/O. */	return 3;}static int start_smic_transaction(struct si_sm_data *smic,				  unsigned char *data, unsigned int size){	unsigned int i;	if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {		return -1;	}	if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {		return -2;	}	if (smic_debug & SMIC_DEBUG_MSG) {		printk(KERN_INFO "start_smic_transaction -");		for (i = 0; i < size; i ++) {			printk (" %02x", (unsigned char) (data [i]));		}		printk ("\n");	}	smic->error_retries = 0;	memcpy(smic->write_data, data, size);	smic->write_count = size;	smic->orig_write_count = size;	smic->write_pos = 0;	smic->read_pos = 0;	smic->state = SMIC_START_OP;	smic->smic_timeout = SMIC_RETRY_TIMEOUT;	return 0;}static int smic_get_result(struct si_sm_data *smic,			   unsigned char *data, unsigned int length){	int i;	if (smic_debug & SMIC_DEBUG_MSG) {		printk (KERN_INFO "smic_get result -");		for (i = 0; i < smic->read_pos; i ++) {			printk (" %02x", (smic->read_data [i]));		}		printk ("\n");	}	if (length < smic->read_pos) {		smic->read_pos = length;		smic->truncated = 1;	}	memcpy(data, smic->read_data, smic->read_pos);	if ((length >= 3) && (smic->read_pos < 3)) {		data[2] = IPMI_ERR_UNSPECIFIED;		smic->read_pos = 3;	}	if (smic->truncated) {		data[2] = IPMI_ERR_MSG_TRUNCATED;		smic->truncated = 0;	}	return smic->read_pos;}static inline unsigned char read_smic_flags(struct si_sm_data *smic){	return smic->io->inputb(smic->io, 2);}static inline unsigned char read_smic_status(struct si_sm_data *smic){	return smic->io->inputb(smic->io, 1);}static inline unsigned char read_smic_data(struct si_sm_data *smic){	return smic->io->inputb(smic->io, 0);}static inline void write_smic_flags(struct si_sm_data *smic,				    unsigned char   flags){	smic->io->outputb(smic->io, 2, flags);}static inline void write_smic_control(struct si_sm_data *smic,				      unsigned char   control){	smic->io->outputb(smic->io, 1, control);}static inline void write_si_sm_data (struct si_sm_data *smic,				   unsigned char   data){	smic->io->outputb(smic->io, 0, data);}static inline void start_error_recovery(struct si_sm_data *smic, char *reason){	(smic->error_retries)++;	if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {		if (smic_debug & SMIC_DEBUG_ENABLE) {			printk(KERN_WARNING			       "ipmi_smic_drv: smic hosed: %s\n", reason);		}		smic->state = SMIC_HOSED;	} else {		smic->write_count = smic->orig_write_count;		smic->write_pos = 0;		smic->read_pos = 0;		smic->state = SMIC_START_OP;		smic->smic_timeout = SMIC_RETRY_TIMEOUT;	}}static inline void write_next_byte(struct si_sm_data *smic){	write_si_sm_data(smic, smic->write_data[smic->write_pos]);	(smic->write_pos)++;	(smic->write_count)--;}static inline void read_next_byte (struct si_sm_data *smic){	if (smic->read_pos >= MAX_SMIC_READ_SIZE) {		read_smic_data (smic);		smic->truncated = 1;	} else {		smic->read_data[smic->read_pos] = read_smic_data(smic);		(smic->read_pos)++;	}}/*  SMIC Control/Status Code Components */#define	SMIC_GET_STATUS		0x00	/* Control form's name */#define	SMIC_READY		0x00	/* Status  form's name */#define	SMIC_WR_START		0x01	/* Unified Control/Status names... */#define	SMIC_WR_NEXT		0x02#define	SMIC_WR_END		0x03#define	SMIC_RD_START		0x04#define	SMIC_RD_NEXT		0x05#define	SMIC_RD_END		0x06#define	SMIC_CODE_MASK		0x0f#define	SMIC_CONTROL		0x00#define	SMIC_STATUS		0x80#define	SMIC_CS_MASK		0x80#define	SMIC_SMS		0x40#define	SMIC_SMM		0x60#define	SMIC_STREAM_MASK	0x60/*  SMIC Control Codes */#define	SMIC_CC_SMS_GET_STATUS	(SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)#define	SMIC_CC_SMS_WR_START	(SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)#define	SMIC_CC_SMS_WR_NEXT	(SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)#define	SMIC_CC_SMS_WR_END	(SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)#define	SMIC_CC_SMS_RD_START	(SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)#define	SMIC_CC_SMS_RD_NEXT	(SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)#define	SMIC_CC_SMS_RD_END	(SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)#define	SMIC_CC_SMM_GET_STATUS	(SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)#define	SMIC_CC_SMM_WR_START	(SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)#define	SMIC_CC_SMM_WR_NEXT	(SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)#define	SMIC_CC_SMM_WR_END	(SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)#define	SMIC_CC_SMM_RD_START	(SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)#define	SMIC_CC_SMM_RD_NEXT	(SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)#define	SMIC_CC_SMM_RD_END	(SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)/*  SMIC Status Codes */#define	SMIC_SC_SMS_READY	(SMIC_STATUS|SMIC_SMS|SMIC_READY)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -