brintos

brintos / linux-shallow public Read only

0
0
Text · 12.6 KiB · ecfcb50 Raw
543 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * ipmi_kcs_sm.c4 *5 * State machine for handling IPMI KCS interfaces.6 *7 * Author: MontaVista Software, Inc.8 *         Corey Minyard <minyard@mvista.com>9 *         source@mvista.com10 *11 * Copyright 2002 MontaVista Software Inc.12 */13 14/*15 * This state machine is taken from the state machine in the IPMI spec,16 * pretty much verbatim.  If you have questions about the states, see17 * that document.18 */19 20#define DEBUG /* So dev_dbg() is always available. */21 22#include <linux/kernel.h> /* For printk. */23#include <linux/module.h>24#include <linux/moduleparam.h>25#include <linux/string.h>26#include <linux/jiffies.h>27#include <linux/ipmi_msgdefs.h>		/* for completion codes */28#include "ipmi_si_sm.h"29 30/* kcs_debug is a bit-field31 *	KCS_DEBUG_ENABLE -	turned on for now32 *	KCS_DEBUG_MSG    -	commands and their responses33 *	KCS_DEBUG_STATES -	state machine34 */35#define KCS_DEBUG_STATES	436#define KCS_DEBUG_MSG		237#define	KCS_DEBUG_ENABLE	138 39static int kcs_debug;40module_param(kcs_debug, int, 0644);41MODULE_PARM_DESC(kcs_debug, "debug bitmask, 1=enable, 2=messages, 4=states");42 43/* The states the KCS driver may be in. */44enum kcs_states {45	/* The KCS interface is currently doing nothing. */46	KCS_IDLE,47 48	/*49	 * We are starting an operation.  The data is in the output50	 * buffer, but nothing has been done to the interface yet.  This51	 * was added to the state machine in the spec to wait for the52	 * initial IBF.53	 */54	KCS_START_OP,55 56	/* We have written a write cmd to the interface. */57	KCS_WAIT_WRITE_START,58 59	/* We are writing bytes to the interface. */60	KCS_WAIT_WRITE,61 62	/*63	 * We have written the write end cmd to the interface, and64	 * still need to write the last byte.65	 */66	KCS_WAIT_WRITE_END,67 68	/* We are waiting to read data from the interface. */69	KCS_WAIT_READ,70 71	/*72	 * State to transition to the error handler, this was added to73	 * the state machine in the spec to be sure IBF was there.74	 */75	KCS_ERROR0,76 77	/*78	 * First stage error handler, wait for the interface to79	 * respond.80	 */81	KCS_ERROR1,82 83	/*84	 * The abort cmd has been written, wait for the interface to85	 * respond.86	 */87	KCS_ERROR2,88 89	/*90	 * We wrote some data to the interface, wait for it to switch91	 * to read mode.92	 */93	KCS_ERROR3,94 95	/* The hardware failed to follow the state machine. */96	KCS_HOSED97};98 99#define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH100#define MAX_KCS_WRITE_SIZE IPMI_MAX_MSG_LENGTH101 102/* Timeouts in microseconds. */103#define IBF_RETRY_TIMEOUT (5*USEC_PER_SEC)104#define OBF_RETRY_TIMEOUT (5*USEC_PER_SEC)105#define MAX_ERROR_RETRIES 10106#define ERROR0_OBF_WAIT_JIFFIES (2*HZ)107 108struct si_sm_data {109	enum kcs_states  state;110	struct si_sm_io *io;111	unsigned char    write_data[MAX_KCS_WRITE_SIZE];112	int              write_pos;113	int              write_count;114	int              orig_write_count;115	unsigned char    read_data[MAX_KCS_READ_SIZE];116	int              read_pos;117	int	         truncated;118 119	unsigned int  error_retries;120	long          ibf_timeout;121	long          obf_timeout;122	unsigned long  error0_timeout;123};124 125static unsigned int init_kcs_data_with_state(struct si_sm_data *kcs,126				  struct si_sm_io *io, enum kcs_states state)127{128	kcs->state = state;129	kcs->io = io;130	kcs->write_pos = 0;131	kcs->write_count = 0;132	kcs->orig_write_count = 0;133	kcs->read_pos = 0;134	kcs->error_retries = 0;135	kcs->truncated = 0;136	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;137	kcs->obf_timeout = OBF_RETRY_TIMEOUT;138 139	/* Reserve 2 I/O bytes. */140	return 2;141}142 143static unsigned int init_kcs_data(struct si_sm_data *kcs,144				  struct si_sm_io *io)145{146	return init_kcs_data_with_state(kcs, io, KCS_IDLE);147}148 149static inline unsigned char read_status(struct si_sm_data *kcs)150{151	return kcs->io->inputb(kcs->io, 1);152}153 154static inline unsigned char read_data(struct si_sm_data *kcs)155{156	return kcs->io->inputb(kcs->io, 0);157}158 159static inline void write_cmd(struct si_sm_data *kcs, unsigned char data)160{161	kcs->io->outputb(kcs->io, 1, data);162}163 164static inline void write_data(struct si_sm_data *kcs, unsigned char data)165{166	kcs->io->outputb(kcs->io, 0, data);167}168 169/* Control codes. */170#define KCS_GET_STATUS_ABORT	0x60171#define KCS_WRITE_START		0x61172#define KCS_WRITE_END		0x62173#define KCS_READ_BYTE		0x68174 175/* Status bits. */176#define GET_STATUS_STATE(status) (((status) >> 6) & 0x03)177#define KCS_IDLE_STATE	0178#define KCS_READ_STATE	1179#define KCS_WRITE_STATE	2180#define KCS_ERROR_STATE	3181#define GET_STATUS_ATN(status) ((status) & 0x04)182#define GET_STATUS_IBF(status) ((status) & 0x02)183#define GET_STATUS_OBF(status) ((status) & 0x01)184 185 186static inline void write_next_byte(struct si_sm_data *kcs)187{188	write_data(kcs, kcs->write_data[kcs->write_pos]);189	(kcs->write_pos)++;190	(kcs->write_count)--;191}192 193static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)194{195	(kcs->error_retries)++;196	if (kcs->error_retries > MAX_ERROR_RETRIES) {197		if (kcs_debug & KCS_DEBUG_ENABLE)198			dev_dbg(kcs->io->dev, "ipmi_kcs_sm: kcs hosed: %s\n",199				reason);200		kcs->state = KCS_HOSED;201	} else {202		kcs->error0_timeout = jiffies + ERROR0_OBF_WAIT_JIFFIES;203		kcs->state = KCS_ERROR0;204	}205}206 207static inline void read_next_byte(struct si_sm_data *kcs)208{209	if (kcs->read_pos >= MAX_KCS_READ_SIZE) {210		/* Throw the data away and mark it truncated. */211		read_data(kcs);212		kcs->truncated = 1;213	} else {214		kcs->read_data[kcs->read_pos] = read_data(kcs);215		(kcs->read_pos)++;216	}217	write_data(kcs, KCS_READ_BYTE);218}219 220static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,221			    long time)222{223	if (GET_STATUS_IBF(status)) {224		kcs->ibf_timeout -= time;225		if (kcs->ibf_timeout < 0) {226			start_error_recovery(kcs, "IBF not ready in time");227			kcs->ibf_timeout = IBF_RETRY_TIMEOUT;228			return 1;229		}230		return 0;231	}232	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;233	return 1;234}235 236static inline int check_obf(struct si_sm_data *kcs, unsigned char status,237			    long time)238{239	if (!GET_STATUS_OBF(status)) {240		kcs->obf_timeout -= time;241		if (kcs->obf_timeout < 0) {242			kcs->obf_timeout = OBF_RETRY_TIMEOUT;243			start_error_recovery(kcs, "OBF not ready in time");244			return 1;245		}246		return 0;247	}248	kcs->obf_timeout = OBF_RETRY_TIMEOUT;249	return 1;250}251 252static void clear_obf(struct si_sm_data *kcs, unsigned char status)253{254	if (GET_STATUS_OBF(status))255		read_data(kcs);256}257 258static void restart_kcs_transaction(struct si_sm_data *kcs)259{260	kcs->write_count = kcs->orig_write_count;261	kcs->write_pos = 0;262	kcs->read_pos = 0;263	kcs->state = KCS_WAIT_WRITE_START;264	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;265	kcs->obf_timeout = OBF_RETRY_TIMEOUT;266	write_cmd(kcs, KCS_WRITE_START);267}268 269static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,270				 unsigned int size)271{272	unsigned int i;273 274	if (size < 2)275		return IPMI_REQ_LEN_INVALID_ERR;276	if (size > MAX_KCS_WRITE_SIZE)277		return IPMI_REQ_LEN_EXCEEDED_ERR;278 279	if (kcs->state != KCS_IDLE) {280		dev_warn(kcs->io->dev, "KCS in invalid state %d\n", kcs->state);281		return IPMI_NOT_IN_MY_STATE_ERR;282	}283 284	if (kcs_debug & KCS_DEBUG_MSG) {285		dev_dbg(kcs->io->dev, "%s -", __func__);286		for (i = 0; i < size; i++)287			pr_cont(" %02x", data[i]);288		pr_cont("\n");289	}290	kcs->error_retries = 0;291	memcpy(kcs->write_data, data, size);292	kcs->write_count = size;293	kcs->orig_write_count = size;294	kcs->write_pos = 0;295	kcs->read_pos = 0;296	kcs->state = KCS_START_OP;297	kcs->ibf_timeout = IBF_RETRY_TIMEOUT;298	kcs->obf_timeout = OBF_RETRY_TIMEOUT;299	return 0;300}301 302static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data,303			  unsigned int length)304{305	if (length < kcs->read_pos) {306		kcs->read_pos = length;307		kcs->truncated = 1;308	}309 310	memcpy(data, kcs->read_data, kcs->read_pos);311 312	if ((length >= 3) && (kcs->read_pos < 3)) {313		/* Guarantee that we return at least 3 bytes, with an314		   error in the third byte if it is too short. */315		data[2] = IPMI_ERR_UNSPECIFIED;316		kcs->read_pos = 3;317	}318	if (kcs->truncated) {319		/*320		 * Report a truncated error.  We might overwrite321		 * another error, but that's too bad, the user needs322		 * to know it was truncated.323		 */324		data[2] = IPMI_ERR_MSG_TRUNCATED;325		kcs->truncated = 0;326	}327 328	return kcs->read_pos;329}330 331/*332 * This implements the state machine defined in the IPMI manual, see333 * that for details on how this works.  Divide that flowchart into334 * sections delimited by "Wait for IBF" and this will become clear.335 */336static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)337{338	unsigned char status;339	unsigned char state;340 341	status = read_status(kcs);342 343	if (kcs_debug & KCS_DEBUG_STATES)344		dev_dbg(kcs->io->dev,345			"KCS: State = %d, %x\n", kcs->state, status);346 347	/* All states wait for ibf, so just do it here. */348	if (!check_ibf(kcs, status, time))349		return SI_SM_CALL_WITH_DELAY;350 351	/* Just about everything looks at the KCS state, so grab that, too. */352	state = GET_STATUS_STATE(status);353 354	switch (kcs->state) {355	case KCS_IDLE:356		/* If there's and interrupt source, turn it off. */357		clear_obf(kcs, status);358 359		if (GET_STATUS_ATN(status))360			return SI_SM_ATTN;361		else362			return SI_SM_IDLE;363 364	case KCS_START_OP:365		if (state != KCS_IDLE_STATE) {366			start_error_recovery(kcs,367					     "State machine not idle at start");368			break;369		}370 371		clear_obf(kcs, status);372		write_cmd(kcs, KCS_WRITE_START);373		kcs->state = KCS_WAIT_WRITE_START;374		break;375 376	case KCS_WAIT_WRITE_START:377		if (state != KCS_WRITE_STATE) {378			start_error_recovery(379				kcs,380				"Not in write state at write start");381			break;382		}383		read_data(kcs);384		if (kcs->write_count == 1) {385			write_cmd(kcs, KCS_WRITE_END);386			kcs->state = KCS_WAIT_WRITE_END;387		} else {388			write_next_byte(kcs);389			kcs->state = KCS_WAIT_WRITE;390		}391		break;392 393	case KCS_WAIT_WRITE:394		if (state != KCS_WRITE_STATE) {395			start_error_recovery(kcs,396					     "Not in write state for write");397			break;398		}399		clear_obf(kcs, status);400		if (kcs->write_count == 1) {401			write_cmd(kcs, KCS_WRITE_END);402			kcs->state = KCS_WAIT_WRITE_END;403		} else {404			write_next_byte(kcs);405		}406		break;407 408	case KCS_WAIT_WRITE_END:409		if (state != KCS_WRITE_STATE) {410			start_error_recovery(kcs,411					     "Not in write state"412					     " for write end");413			break;414		}415		clear_obf(kcs, status);416		write_next_byte(kcs);417		kcs->state = KCS_WAIT_READ;418		break;419 420	case KCS_WAIT_READ:421		if ((state != KCS_READ_STATE) && (state != KCS_IDLE_STATE)) {422			start_error_recovery(423				kcs,424				"Not in read or idle in read state");425			break;426		}427 428		if (state == KCS_READ_STATE) {429			if (!check_obf(kcs, status, time))430				return SI_SM_CALL_WITH_DELAY;431			read_next_byte(kcs);432		} else {433			/*434			 * We don't implement this exactly like the state435			 * machine in the spec.  Some broken hardware436			 * does not write the final dummy byte to the437			 * read register.  Thus obf will never go high438			 * here.  We just go straight to idle, and we439			 * handle clearing out obf in idle state if it440			 * happens to come in.441			 */442			clear_obf(kcs, status);443			kcs->orig_write_count = 0;444			kcs->state = KCS_IDLE;445			return SI_SM_TRANSACTION_COMPLETE;446		}447		break;448 449	case KCS_ERROR0:450		clear_obf(kcs, status);451		status = read_status(kcs);452		if (GET_STATUS_OBF(status))453			/* controller isn't responding */454			if (time_before(jiffies, kcs->error0_timeout))455				return SI_SM_CALL_WITH_TICK_DELAY;456		write_cmd(kcs, KCS_GET_STATUS_ABORT);457		kcs->state = KCS_ERROR1;458		break;459 460	case KCS_ERROR1:461		clear_obf(kcs, status);462		write_data(kcs, 0);463		kcs->state = KCS_ERROR2;464		break;465 466	case KCS_ERROR2:467		if (state != KCS_READ_STATE) {468			start_error_recovery(kcs,469					     "Not in read state for error2");470			break;471		}472		if (!check_obf(kcs, status, time))473			return SI_SM_CALL_WITH_DELAY;474 475		clear_obf(kcs, status);476		write_data(kcs, KCS_READ_BYTE);477		kcs->state = KCS_ERROR3;478		break;479 480	case KCS_ERROR3:481		if (state != KCS_IDLE_STATE) {482			start_error_recovery(kcs,483					     "Not in idle state for error3");484			break;485		}486 487		if (!check_obf(kcs, status, time))488			return SI_SM_CALL_WITH_DELAY;489 490		clear_obf(kcs, status);491		if (kcs->orig_write_count) {492			restart_kcs_transaction(kcs);493		} else {494			kcs->state = KCS_IDLE;495			return SI_SM_TRANSACTION_COMPLETE;496		}497		break;498 499	case KCS_HOSED:500		break;501	}502 503	if (kcs->state == KCS_HOSED) {504		init_kcs_data_with_state(kcs, kcs->io, KCS_ERROR0);505		return SI_SM_HOSED;506	}507 508	return SI_SM_CALL_WITHOUT_DELAY;509}510 511static int kcs_size(void)512{513	return sizeof(struct si_sm_data);514}515 516static int kcs_detect(struct si_sm_data *kcs)517{518	/*519	 * It's impossible for the KCS status register to be all 1's,520	 * (assuming a properly functioning, self-initialized BMC)521	 * but that's what you get from reading a bogus address, so we522	 * test that first.523	 */524	if (read_status(kcs) == 0xff)525		return 1;526 527	return 0;528}529 530static void kcs_cleanup(struct si_sm_data *kcs)531{532}533 534const struct si_sm_handlers kcs_smi_handlers = {535	.init_data         = init_kcs_data,536	.start_transaction = start_kcs_transaction,537	.get_result        = get_kcs_result,538	.event             = kcs_event,539	.detect            = kcs_detect,540	.cleanup           = kcs_cleanup,541	.size              = kcs_size,542};543