cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

cros_ec_proto.c (26684B)


      1// SPDX-License-Identifier: GPL-2.0
      2// ChromeOS EC communication protocol helper functions
      3//
      4// Copyright (C) 2015 Google, Inc
      5
      6#include <linux/delay.h>
      7#include <linux/device.h>
      8#include <linux/module.h>
      9#include <linux/platform_data/cros_ec_commands.h>
     10#include <linux/platform_data/cros_ec_proto.h>
     11#include <linux/slab.h>
     12#include <asm/unaligned.h>
     13
     14#include "cros_ec_trace.h"
     15
     16#define EC_COMMAND_RETRIES	50
     17
     18static const int cros_ec_error_map[] = {
     19	[EC_RES_INVALID_COMMAND] = -EOPNOTSUPP,
     20	[EC_RES_ERROR] = -EIO,
     21	[EC_RES_INVALID_PARAM] = -EINVAL,
     22	[EC_RES_ACCESS_DENIED] = -EACCES,
     23	[EC_RES_INVALID_RESPONSE] = -EPROTO,
     24	[EC_RES_INVALID_VERSION] = -ENOPROTOOPT,
     25	[EC_RES_INVALID_CHECKSUM] = -EBADMSG,
     26	[EC_RES_IN_PROGRESS] = -EINPROGRESS,
     27	[EC_RES_UNAVAILABLE] = -ENODATA,
     28	[EC_RES_TIMEOUT] = -ETIMEDOUT,
     29	[EC_RES_OVERFLOW] = -EOVERFLOW,
     30	[EC_RES_INVALID_HEADER] = -EBADR,
     31	[EC_RES_REQUEST_TRUNCATED] = -EBADR,
     32	[EC_RES_RESPONSE_TOO_BIG] = -EFBIG,
     33	[EC_RES_BUS_ERROR] = -EFAULT,
     34	[EC_RES_BUSY] = -EBUSY,
     35	[EC_RES_INVALID_HEADER_VERSION] = -EBADMSG,
     36	[EC_RES_INVALID_HEADER_CRC] = -EBADMSG,
     37	[EC_RES_INVALID_DATA_CRC] = -EBADMSG,
     38	[EC_RES_DUP_UNAVAILABLE] = -ENODATA,
     39};
     40
     41static int cros_ec_map_error(uint32_t result)
     42{
     43	int ret = 0;
     44
     45	if (result != EC_RES_SUCCESS) {
     46		if (result < ARRAY_SIZE(cros_ec_error_map) && cros_ec_error_map[result])
     47			ret = cros_ec_error_map[result];
     48		else
     49			ret = -EPROTO;
     50	}
     51
     52	return ret;
     53}
     54
     55static int prepare_packet(struct cros_ec_device *ec_dev,
     56			  struct cros_ec_command *msg)
     57{
     58	struct ec_host_request *request;
     59	u8 *out;
     60	int i;
     61	u8 csum = 0;
     62
     63	if (msg->outsize + sizeof(*request) > ec_dev->dout_size)
     64		return -EINVAL;
     65
     66	out = ec_dev->dout;
     67	request = (struct ec_host_request *)out;
     68	request->struct_version = EC_HOST_REQUEST_VERSION;
     69	request->checksum = 0;
     70	request->command = msg->command;
     71	request->command_version = msg->version;
     72	request->reserved = 0;
     73	request->data_len = msg->outsize;
     74
     75	for (i = 0; i < sizeof(*request); i++)
     76		csum += out[i];
     77
     78	/* Copy data and update checksum */
     79	memcpy(out + sizeof(*request), msg->data, msg->outsize);
     80	for (i = 0; i < msg->outsize; i++)
     81		csum += msg->data[i];
     82
     83	request->checksum = -csum;
     84
     85	return sizeof(*request) + msg->outsize;
     86}
     87
     88static int send_command(struct cros_ec_device *ec_dev,
     89			struct cros_ec_command *msg)
     90{
     91	int ret;
     92	int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
     93
     94	if (ec_dev->proto_version > 2)
     95		xfer_fxn = ec_dev->pkt_xfer;
     96	else
     97		xfer_fxn = ec_dev->cmd_xfer;
     98
     99	if (!xfer_fxn) {
    100		/*
    101		 * This error can happen if a communication error happened and
    102		 * the EC is trying to use protocol v2, on an underlying
    103		 * communication mechanism that does not support v2.
    104		 */
    105		dev_err_once(ec_dev->dev,
    106			     "missing EC transfer API, cannot send command\n");
    107		return -EIO;
    108	}
    109
    110	trace_cros_ec_request_start(msg);
    111	ret = (*xfer_fxn)(ec_dev, msg);
    112	trace_cros_ec_request_done(msg, ret);
    113	if (msg->result == EC_RES_IN_PROGRESS) {
    114		int i;
    115		struct cros_ec_command *status_msg;
    116		struct ec_response_get_comms_status *status;
    117
    118		status_msg = kmalloc(sizeof(*status_msg) + sizeof(*status),
    119				     GFP_KERNEL);
    120		if (!status_msg)
    121			return -ENOMEM;
    122
    123		status_msg->version = 0;
    124		status_msg->command = EC_CMD_GET_COMMS_STATUS;
    125		status_msg->insize = sizeof(*status);
    126		status_msg->outsize = 0;
    127
    128		/*
    129		 * Query the EC's status until it's no longer busy or
    130		 * we encounter an error.
    131		 */
    132		for (i = 0; i < EC_COMMAND_RETRIES; i++) {
    133			usleep_range(10000, 11000);
    134
    135			trace_cros_ec_request_start(status_msg);
    136			ret = (*xfer_fxn)(ec_dev, status_msg);
    137			trace_cros_ec_request_done(status_msg, ret);
    138			if (ret == -EAGAIN)
    139				continue;
    140			if (ret < 0)
    141				break;
    142
    143			msg->result = status_msg->result;
    144			if (status_msg->result != EC_RES_SUCCESS)
    145				break;
    146
    147			status = (struct ec_response_get_comms_status *)
    148				 status_msg->data;
    149			if (!(status->flags & EC_COMMS_STATUS_PROCESSING))
    150				break;
    151		}
    152
    153		kfree(status_msg);
    154	}
    155
    156	return ret;
    157}
    158
    159/**
    160 * cros_ec_prepare_tx() - Prepare an outgoing message in the output buffer.
    161 * @ec_dev: Device to register.
    162 * @msg: Message to write.
    163 *
    164 * This is intended to be used by all ChromeOS EC drivers, but at present
    165 * only SPI uses it. Once LPC uses the same protocol it can start using it.
    166 * I2C could use it now, with a refactor of the existing code.
    167 *
    168 * Return: number of prepared bytes on success or negative error code.
    169 */
    170int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
    171		       struct cros_ec_command *msg)
    172{
    173	u8 *out;
    174	u8 csum;
    175	int i;
    176
    177	if (ec_dev->proto_version > 2)
    178		return prepare_packet(ec_dev, msg);
    179
    180	if (msg->outsize > EC_PROTO2_MAX_PARAM_SIZE)
    181		return -EINVAL;
    182
    183	out = ec_dev->dout;
    184	out[0] = EC_CMD_VERSION0 + msg->version;
    185	out[1] = msg->command;
    186	out[2] = msg->outsize;
    187	csum = out[0] + out[1] + out[2];
    188	for (i = 0; i < msg->outsize; i++)
    189		csum += out[EC_MSG_TX_HEADER_BYTES + i] = msg->data[i];
    190	out[EC_MSG_TX_HEADER_BYTES + msg->outsize] = csum;
    191
    192	return EC_MSG_TX_PROTO_BYTES + msg->outsize;
    193}
    194EXPORT_SYMBOL(cros_ec_prepare_tx);
    195
    196/**
    197 * cros_ec_check_result() - Check ec_msg->result.
    198 * @ec_dev: EC device.
    199 * @msg: Message to check.
    200 *
    201 * This is used by ChromeOS EC drivers to check the ec_msg->result for
    202 * errors and to warn about them.
    203 *
    204 * Return: 0 on success or negative error code.
    205 */
    206int cros_ec_check_result(struct cros_ec_device *ec_dev,
    207			 struct cros_ec_command *msg)
    208{
    209	switch (msg->result) {
    210	case EC_RES_SUCCESS:
    211		return 0;
    212	case EC_RES_IN_PROGRESS:
    213		dev_dbg(ec_dev->dev, "command 0x%02x in progress\n",
    214			msg->command);
    215		return -EAGAIN;
    216	default:
    217		dev_dbg(ec_dev->dev, "command 0x%02x returned %d\n",
    218			msg->command, msg->result);
    219		return 0;
    220	}
    221}
    222EXPORT_SYMBOL(cros_ec_check_result);
    223
    224/*
    225 * cros_ec_get_host_event_wake_mask
    226 *
    227 * Get the mask of host events that cause wake from suspend.
    228 *
    229 * @ec_dev: EC device to call
    230 * @msg: message structure to use
    231 * @mask: result when function returns >=0.
    232 *
    233 * LOCKING:
    234 * the caller has ec_dev->lock mutex, or the caller knows there is
    235 * no other command in progress.
    236 */
    237static int cros_ec_get_host_event_wake_mask(struct cros_ec_device *ec_dev,
    238					    struct cros_ec_command *msg,
    239					    uint32_t *mask)
    240{
    241	struct ec_response_host_event_mask *r;
    242	int ret;
    243
    244	msg->command = EC_CMD_HOST_EVENT_GET_WAKE_MASK;
    245	msg->version = 0;
    246	msg->outsize = 0;
    247	msg->insize = sizeof(*r);
    248
    249	ret = send_command(ec_dev, msg);
    250	if (ret >= 0) {
    251		if (msg->result == EC_RES_INVALID_COMMAND)
    252			return -EOPNOTSUPP;
    253		if (msg->result != EC_RES_SUCCESS)
    254			return -EPROTO;
    255	}
    256	if (ret > 0) {
    257		r = (struct ec_response_host_event_mask *)msg->data;
    258		*mask = r->mask;
    259	}
    260
    261	return ret;
    262}
    263
    264static int cros_ec_host_command_proto_query(struct cros_ec_device *ec_dev,
    265					    int devidx,
    266					    struct cros_ec_command *msg)
    267{
    268	/*
    269	 * Try using v3+ to query for supported protocols. If this
    270	 * command fails, fall back to v2. Returns the highest protocol
    271	 * supported by the EC.
    272	 * Also sets the max request/response/passthru size.
    273	 */
    274	int ret;
    275
    276	if (!ec_dev->pkt_xfer)
    277		return -EPROTONOSUPPORT;
    278
    279	memset(msg, 0, sizeof(*msg));
    280	msg->command = EC_CMD_PASSTHRU_OFFSET(devidx) | EC_CMD_GET_PROTOCOL_INFO;
    281	msg->insize = sizeof(struct ec_response_get_protocol_info);
    282
    283	ret = send_command(ec_dev, msg);
    284	/*
    285	 * Send command once again when timeout occurred.
    286	 * Fingerprint MCU (FPMCU) is restarted during system boot which
    287	 * introduces small window in which FPMCU won't respond for any
    288	 * messages sent by kernel. There is no need to wait before next
    289	 * attempt because we waited at least EC_MSG_DEADLINE_MS.
    290	 */
    291	if (ret == -ETIMEDOUT)
    292		ret = send_command(ec_dev, msg);
    293
    294	if (ret < 0) {
    295		dev_dbg(ec_dev->dev,
    296			"failed to check for EC[%d] protocol version: %d\n",
    297			devidx, ret);
    298		return ret;
    299	}
    300
    301	if (devidx > 0 && msg->result == EC_RES_INVALID_COMMAND)
    302		return -ENODEV;
    303	else if (msg->result != EC_RES_SUCCESS)
    304		return msg->result;
    305
    306	return 0;
    307}
    308
    309static int cros_ec_host_command_proto_query_v2(struct cros_ec_device *ec_dev)
    310{
    311	struct cros_ec_command *msg;
    312	struct ec_params_hello *hello_params;
    313	struct ec_response_hello *hello_response;
    314	int ret;
    315	int len = max(sizeof(*hello_params), sizeof(*hello_response));
    316
    317	msg = kmalloc(sizeof(*msg) + len, GFP_KERNEL);
    318	if (!msg)
    319		return -ENOMEM;
    320
    321	msg->version = 0;
    322	msg->command = EC_CMD_HELLO;
    323	hello_params = (struct ec_params_hello *)msg->data;
    324	msg->outsize = sizeof(*hello_params);
    325	hello_response = (struct ec_response_hello *)msg->data;
    326	msg->insize = sizeof(*hello_response);
    327
    328	hello_params->in_data = 0xa0b0c0d0;
    329
    330	ret = send_command(ec_dev, msg);
    331
    332	if (ret < 0) {
    333		dev_dbg(ec_dev->dev,
    334			"EC failed to respond to v2 hello: %d\n",
    335			ret);
    336		goto exit;
    337	} else if (msg->result != EC_RES_SUCCESS) {
    338		dev_err(ec_dev->dev,
    339			"EC responded to v2 hello with error: %d\n",
    340			msg->result);
    341		ret = msg->result;
    342		goto exit;
    343	} else if (hello_response->out_data != 0xa1b2c3d4) {
    344		dev_err(ec_dev->dev,
    345			"EC responded to v2 hello with bad result: %u\n",
    346			hello_response->out_data);
    347		ret = -EBADMSG;
    348		goto exit;
    349	}
    350
    351	ret = 0;
    352
    353 exit:
    354	kfree(msg);
    355	return ret;
    356}
    357
    358/*
    359 * cros_ec_get_host_command_version_mask
    360 *
    361 * Get the version mask of a given command.
    362 *
    363 * @ec_dev: EC device to call
    364 * @msg: message structure to use
    365 * @cmd: command to get the version of.
    366 * @mask: result when function returns 0.
    367 *
    368 * @return 0 on success, error code otherwise
    369 *
    370 * LOCKING:
    371 * the caller has ec_dev->lock mutex or the caller knows there is
    372 * no other command in progress.
    373 */
    374static int cros_ec_get_host_command_version_mask(struct cros_ec_device *ec_dev,
    375	u16 cmd, u32 *mask)
    376{
    377	struct ec_params_get_cmd_versions *pver;
    378	struct ec_response_get_cmd_versions *rver;
    379	struct cros_ec_command *msg;
    380	int ret;
    381
    382	msg = kmalloc(sizeof(*msg) + max(sizeof(*rver), sizeof(*pver)),
    383		      GFP_KERNEL);
    384	if (!msg)
    385		return -ENOMEM;
    386
    387	msg->version = 0;
    388	msg->command = EC_CMD_GET_CMD_VERSIONS;
    389	msg->insize = sizeof(*rver);
    390	msg->outsize = sizeof(*pver);
    391
    392	pver = (struct ec_params_get_cmd_versions *)msg->data;
    393	pver->cmd = cmd;
    394
    395	ret = send_command(ec_dev, msg);
    396	if (ret > 0) {
    397		rver = (struct ec_response_get_cmd_versions *)msg->data;
    398		*mask = rver->version_mask;
    399	}
    400
    401	kfree(msg);
    402
    403	return ret;
    404}
    405
    406/**
    407 * cros_ec_query_all() -  Query the protocol version supported by the
    408 *         ChromeOS EC.
    409 * @ec_dev: Device to register.
    410 *
    411 * Return: 0 on success or negative error code.
    412 */
    413int cros_ec_query_all(struct cros_ec_device *ec_dev)
    414{
    415	struct device *dev = ec_dev->dev;
    416	struct cros_ec_command *proto_msg;
    417	struct ec_response_get_protocol_info *proto_info;
    418	u32 ver_mask = 0;
    419	int ret;
    420
    421	proto_msg = kzalloc(sizeof(*proto_msg) + sizeof(*proto_info),
    422			    GFP_KERNEL);
    423	if (!proto_msg)
    424		return -ENOMEM;
    425
    426	/* First try sending with proto v3. */
    427	ec_dev->proto_version = 3;
    428	ret = cros_ec_host_command_proto_query(ec_dev, 0, proto_msg);
    429
    430	if (ret == 0) {
    431		proto_info = (struct ec_response_get_protocol_info *)
    432			proto_msg->data;
    433		ec_dev->max_request = proto_info->max_request_packet_size -
    434			sizeof(struct ec_host_request);
    435		ec_dev->max_response = proto_info->max_response_packet_size -
    436			sizeof(struct ec_host_response);
    437		ec_dev->proto_version =
    438			min(EC_HOST_REQUEST_VERSION,
    439					fls(proto_info->protocol_versions) - 1);
    440		dev_dbg(ec_dev->dev,
    441			"using proto v%u\n",
    442			ec_dev->proto_version);
    443
    444		ec_dev->din_size = ec_dev->max_response +
    445			sizeof(struct ec_host_response) +
    446			EC_MAX_RESPONSE_OVERHEAD;
    447		ec_dev->dout_size = ec_dev->max_request +
    448			sizeof(struct ec_host_request) +
    449			EC_MAX_REQUEST_OVERHEAD;
    450
    451		/*
    452		 * Check for PD
    453		 */
    454		ret = cros_ec_host_command_proto_query(ec_dev, 1, proto_msg);
    455
    456		if (ret) {
    457			dev_dbg(ec_dev->dev, "no PD chip found: %d\n", ret);
    458			ec_dev->max_passthru = 0;
    459		} else {
    460			dev_dbg(ec_dev->dev, "found PD chip\n");
    461			ec_dev->max_passthru =
    462				proto_info->max_request_packet_size -
    463				sizeof(struct ec_host_request);
    464		}
    465	} else {
    466		/* Try querying with a v2 hello message. */
    467		ec_dev->proto_version = 2;
    468		ret = cros_ec_host_command_proto_query_v2(ec_dev);
    469
    470		if (ret == 0) {
    471			/* V2 hello succeeded. */
    472			dev_dbg(ec_dev->dev, "falling back to proto v2\n");
    473
    474			ec_dev->max_request = EC_PROTO2_MAX_PARAM_SIZE;
    475			ec_dev->max_response = EC_PROTO2_MAX_PARAM_SIZE;
    476			ec_dev->max_passthru = 0;
    477			ec_dev->pkt_xfer = NULL;
    478			ec_dev->din_size = EC_PROTO2_MSG_BYTES;
    479			ec_dev->dout_size = EC_PROTO2_MSG_BYTES;
    480		} else {
    481			/*
    482			 * It's possible for a test to occur too early when
    483			 * the EC isn't listening. If this happens, we'll
    484			 * test later when the first command is run.
    485			 */
    486			ec_dev->proto_version = EC_PROTO_VERSION_UNKNOWN;
    487			dev_dbg(ec_dev->dev, "EC query failed: %d\n", ret);
    488			goto exit;
    489		}
    490	}
    491
    492	devm_kfree(dev, ec_dev->din);
    493	devm_kfree(dev, ec_dev->dout);
    494
    495	ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL);
    496	if (!ec_dev->din) {
    497		ret = -ENOMEM;
    498		goto exit;
    499	}
    500
    501	ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL);
    502	if (!ec_dev->dout) {
    503		devm_kfree(dev, ec_dev->din);
    504		ret = -ENOMEM;
    505		goto exit;
    506	}
    507
    508	/* Probe if MKBP event is supported */
    509	ret = cros_ec_get_host_command_version_mask(ec_dev,
    510						    EC_CMD_GET_NEXT_EVENT,
    511						    &ver_mask);
    512	if (ret < 0 || ver_mask == 0)
    513		ec_dev->mkbp_event_supported = 0;
    514	else
    515		ec_dev->mkbp_event_supported = fls(ver_mask);
    516
    517	dev_dbg(ec_dev->dev, "MKBP support version %u\n",
    518		ec_dev->mkbp_event_supported - 1);
    519
    520	/* Probe if host sleep v1 is supported for S0ix failure detection. */
    521	ret = cros_ec_get_host_command_version_mask(ec_dev,
    522						    EC_CMD_HOST_SLEEP_EVENT,
    523						    &ver_mask);
    524	ec_dev->host_sleep_v1 = (ret >= 0 && (ver_mask & EC_VER_MASK(1)));
    525
    526	/* Get host event wake mask. */
    527	ret = cros_ec_get_host_event_wake_mask(ec_dev, proto_msg,
    528					       &ec_dev->host_event_wake_mask);
    529	if (ret < 0) {
    530		/*
    531		 * If the EC doesn't support EC_CMD_HOST_EVENT_GET_WAKE_MASK,
    532		 * use a reasonable default. Note that we ignore various
    533		 * battery, AC status, and power-state events, because (a)
    534		 * those can be quite common (e.g., when sitting at full
    535		 * charge, on AC) and (b) these are not actionable wake events;
    536		 * if anything, we'd like to continue suspending (to save
    537		 * power), not wake up.
    538		 */
    539		ec_dev->host_event_wake_mask = U32_MAX &
    540			~(EC_HOST_EVENT_MASK(EC_HOST_EVENT_LID_CLOSED) |
    541			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_AC_DISCONNECTED) |
    542			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_LOW) |
    543			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_CRITICAL) |
    544			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY) |
    545			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_PD_MCU) |
    546			  EC_HOST_EVENT_MASK(EC_HOST_EVENT_BATTERY_STATUS));
    547		/*
    548		 * Old ECs may not support this command. Complain about all
    549		 * other errors.
    550		 */
    551		if (ret != -EOPNOTSUPP)
    552			dev_err(ec_dev->dev,
    553				"failed to retrieve wake mask: %d\n", ret);
    554	}
    555
    556	ret = 0;
    557
    558exit:
    559	kfree(proto_msg);
    560	return ret;
    561}
    562EXPORT_SYMBOL(cros_ec_query_all);
    563
    564/**
    565 * cros_ec_cmd_xfer() - Send a command to the ChromeOS EC.
    566 * @ec_dev: EC device.
    567 * @msg: Message to write.
    568 *
    569 * Call this to send a command to the ChromeOS EC. This should be used instead
    570 * of calling the EC's cmd_xfer() callback directly. This function does not
    571 * convert EC command execution error codes to Linux error codes. Most
    572 * in-kernel users will want to use cros_ec_cmd_xfer_status() instead since
    573 * that function implements the conversion.
    574 *
    575 * Return:
    576 * >0 - EC command was executed successfully. The return value is the number
    577 *      of bytes returned by the EC (excluding the header).
    578 * =0 - EC communication was successful. EC command execution results are
    579 *      reported in msg->result. The result will be EC_RES_SUCCESS if the
    580 *      command was executed successfully or report an EC command execution
    581 *      error.
    582 * <0 - EC communication error. Return value is the Linux error code.
    583 */
    584int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev, struct cros_ec_command *msg)
    585{
    586	int ret;
    587
    588	mutex_lock(&ec_dev->lock);
    589	if (ec_dev->proto_version == EC_PROTO_VERSION_UNKNOWN) {
    590		ret = cros_ec_query_all(ec_dev);
    591		if (ret) {
    592			dev_err(ec_dev->dev,
    593				"EC version unknown and query failed; aborting command\n");
    594			mutex_unlock(&ec_dev->lock);
    595			return ret;
    596		}
    597	}
    598
    599	if (msg->insize > ec_dev->max_response) {
    600		dev_dbg(ec_dev->dev, "clamping message receive buffer\n");
    601		msg->insize = ec_dev->max_response;
    602	}
    603
    604	if (msg->command < EC_CMD_PASSTHRU_OFFSET(1)) {
    605		if (msg->outsize > ec_dev->max_request) {
    606			dev_err(ec_dev->dev,
    607				"request of size %u is too big (max: %u)\n",
    608				msg->outsize,
    609				ec_dev->max_request);
    610			mutex_unlock(&ec_dev->lock);
    611			return -EMSGSIZE;
    612		}
    613	} else {
    614		if (msg->outsize > ec_dev->max_passthru) {
    615			dev_err(ec_dev->dev,
    616				"passthru rq of size %u is too big (max: %u)\n",
    617				msg->outsize,
    618				ec_dev->max_passthru);
    619			mutex_unlock(&ec_dev->lock);
    620			return -EMSGSIZE;
    621		}
    622	}
    623
    624	ret = send_command(ec_dev, msg);
    625	mutex_unlock(&ec_dev->lock);
    626
    627	return ret;
    628}
    629EXPORT_SYMBOL(cros_ec_cmd_xfer);
    630
    631/**
    632 * cros_ec_cmd_xfer_status() - Send a command to the ChromeOS EC.
    633 * @ec_dev: EC device.
    634 * @msg: Message to write.
    635 *
    636 * Call this to send a command to the ChromeOS EC. This should be used instead of calling the EC's
    637 * cmd_xfer() callback directly. It returns success status only if both the command was transmitted
    638 * successfully and the EC replied with success status.
    639 *
    640 * Return:
    641 * >=0 - The number of bytes transferred.
    642 * <0 - Linux error code
    643 */
    644int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
    645			    struct cros_ec_command *msg)
    646{
    647	int ret, mapped;
    648
    649	ret = cros_ec_cmd_xfer(ec_dev, msg);
    650	if (ret < 0)
    651		return ret;
    652
    653	mapped = cros_ec_map_error(msg->result);
    654	if (mapped) {
    655		dev_dbg(ec_dev->dev, "Command result (err: %d [%d])\n",
    656			msg->result, mapped);
    657		ret = mapped;
    658	}
    659
    660	return ret;
    661}
    662EXPORT_SYMBOL(cros_ec_cmd_xfer_status);
    663
    664static int get_next_event_xfer(struct cros_ec_device *ec_dev,
    665			       struct cros_ec_command *msg,
    666			       struct ec_response_get_next_event_v1 *event,
    667			       int version, uint32_t size)
    668{
    669	int ret;
    670
    671	msg->version = version;
    672	msg->command = EC_CMD_GET_NEXT_EVENT;
    673	msg->insize = size;
    674	msg->outsize = 0;
    675
    676	ret = cros_ec_cmd_xfer_status(ec_dev, msg);
    677	if (ret > 0) {
    678		ec_dev->event_size = ret - 1;
    679		ec_dev->event_data = *event;
    680	}
    681
    682	return ret;
    683}
    684
    685static int get_next_event(struct cros_ec_device *ec_dev)
    686{
    687	struct {
    688		struct cros_ec_command msg;
    689		struct ec_response_get_next_event_v1 event;
    690	} __packed buf;
    691	struct cros_ec_command *msg = &buf.msg;
    692	struct ec_response_get_next_event_v1 *event = &buf.event;
    693	const int cmd_version = ec_dev->mkbp_event_supported - 1;
    694
    695	memset(msg, 0, sizeof(*msg));
    696	if (ec_dev->suspended) {
    697		dev_dbg(ec_dev->dev, "Device suspended.\n");
    698		return -EHOSTDOWN;
    699	}
    700
    701	if (cmd_version == 0)
    702		return get_next_event_xfer(ec_dev, msg, event, 0,
    703				  sizeof(struct ec_response_get_next_event));
    704
    705	return get_next_event_xfer(ec_dev, msg, event, cmd_version,
    706				sizeof(struct ec_response_get_next_event_v1));
    707}
    708
    709static int get_keyboard_state_event(struct cros_ec_device *ec_dev)
    710{
    711	u8 buffer[sizeof(struct cros_ec_command) +
    712		  sizeof(ec_dev->event_data.data)];
    713	struct cros_ec_command *msg = (struct cros_ec_command *)&buffer;
    714
    715	msg->version = 0;
    716	msg->command = EC_CMD_MKBP_STATE;
    717	msg->insize = sizeof(ec_dev->event_data.data);
    718	msg->outsize = 0;
    719
    720	ec_dev->event_size = cros_ec_cmd_xfer_status(ec_dev, msg);
    721	ec_dev->event_data.event_type = EC_MKBP_EVENT_KEY_MATRIX;
    722	memcpy(&ec_dev->event_data.data, msg->data,
    723	       sizeof(ec_dev->event_data.data));
    724
    725	return ec_dev->event_size;
    726}
    727
    728/**
    729 * cros_ec_get_next_event() - Fetch next event from the ChromeOS EC.
    730 * @ec_dev: Device to fetch event from.
    731 * @wake_event: Pointer to a bool set to true upon return if the event might be
    732 *              treated as a wake event. Ignored if null.
    733 * @has_more_events: Pointer to bool set to true if more than one event is
    734 *              pending.
    735 *              Some EC will set this flag to indicate cros_ec_get_next_event()
    736 *              can be called multiple times in a row.
    737 *              It is an optimization to prevent issuing a EC command for
    738 *              nothing or wait for another interrupt from the EC to process
    739 *              the next message.
    740 *              Ignored if null.
    741 *
    742 * Return: negative error code on errors; 0 for no data; or else number of
    743 * bytes received (i.e., an event was retrieved successfully). Event types are
    744 * written out to @ec_dev->event_data.event_type on success.
    745 */
    746int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
    747			   bool *wake_event,
    748			   bool *has_more_events)
    749{
    750	u8 event_type;
    751	u32 host_event;
    752	int ret;
    753
    754	/*
    755	 * Default value for wake_event.
    756	 * Wake up on keyboard event, wake up for spurious interrupt or link
    757	 * error to the EC.
    758	 */
    759	if (wake_event)
    760		*wake_event = true;
    761
    762	/*
    763	 * Default value for has_more_events.
    764	 * EC will raise another interrupt if AP does not process all events
    765	 * anyway.
    766	 */
    767	if (has_more_events)
    768		*has_more_events = false;
    769
    770	if (!ec_dev->mkbp_event_supported)
    771		return get_keyboard_state_event(ec_dev);
    772
    773	ret = get_next_event(ec_dev);
    774	if (ret <= 0)
    775		return ret;
    776
    777	if (has_more_events)
    778		*has_more_events = ec_dev->event_data.event_type &
    779			EC_MKBP_HAS_MORE_EVENTS;
    780	ec_dev->event_data.event_type &= EC_MKBP_EVENT_TYPE_MASK;
    781
    782	if (wake_event) {
    783		event_type = ec_dev->event_data.event_type;
    784		host_event = cros_ec_get_host_event(ec_dev);
    785
    786		/*
    787		 * Sensor events need to be parsed by the sensor sub-device.
    788		 * Defer them, and don't report the wakeup here.
    789		 */
    790		if (event_type == EC_MKBP_EVENT_SENSOR_FIFO) {
    791			*wake_event = false;
    792		} else if (host_event) {
    793			/* rtc_update_irq() already handles wakeup events. */
    794			if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC))
    795				*wake_event = false;
    796			/* Masked host-events should not count as wake events. */
    797			if (!(host_event & ec_dev->host_event_wake_mask))
    798				*wake_event = false;
    799		}
    800	}
    801
    802	return ret;
    803}
    804EXPORT_SYMBOL(cros_ec_get_next_event);
    805
    806/**
    807 * cros_ec_get_host_event() - Return a mask of event set by the ChromeOS EC.
    808 * @ec_dev: Device to fetch event from.
    809 *
    810 * When MKBP is supported, when the EC raises an interrupt, we collect the
    811 * events raised and call the functions in the ec notifier. This function
    812 * is a helper to know which events are raised.
    813 *
    814 * Return: 0 on error or non-zero bitmask of one or more EC_HOST_EVENT_*.
    815 */
    816u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev)
    817{
    818	u32 host_event;
    819
    820	if (!ec_dev->mkbp_event_supported)
    821		return 0;
    822
    823	if (ec_dev->event_data.event_type != EC_MKBP_EVENT_HOST_EVENT)
    824		return 0;
    825
    826	if (ec_dev->event_size != sizeof(host_event)) {
    827		dev_warn(ec_dev->dev, "Invalid host event size\n");
    828		return 0;
    829	}
    830
    831	host_event = get_unaligned_le32(&ec_dev->event_data.data.host_event);
    832
    833	return host_event;
    834}
    835EXPORT_SYMBOL(cros_ec_get_host_event);
    836
    837/**
    838 * cros_ec_check_features() - Test for the presence of EC features
    839 *
    840 * @ec: EC device, does not have to be connected directly to the AP,
    841 *      can be daisy chained through another device.
    842 * @feature: One of ec_feature_code bit.
    843 *
    844 * Call this function to test whether the ChromeOS EC supports a feature.
    845 *
    846 * Return: true if supported, false if not (or if an error was encountered).
    847 */
    848bool cros_ec_check_features(struct cros_ec_dev *ec, int feature)
    849{
    850	struct ec_response_get_features *features = &ec->features;
    851	int ret;
    852
    853	if (features->flags[0] == -1U && features->flags[1] == -1U) {
    854		/* features bitmap not read yet */
    855		ret = cros_ec_command(ec->ec_dev, 0, EC_CMD_GET_FEATURES + ec->cmd_offset,
    856				      NULL, 0, features, sizeof(*features));
    857		if (ret < 0) {
    858			dev_warn(ec->dev, "cannot get EC features: %d\n", ret);
    859			memset(features, 0, sizeof(*features));
    860		}
    861
    862		dev_dbg(ec->dev, "EC features %08x %08x\n",
    863			features->flags[0], features->flags[1]);
    864	}
    865
    866	return !!(features->flags[feature / 32] & EC_FEATURE_MASK_0(feature));
    867}
    868EXPORT_SYMBOL_GPL(cros_ec_check_features);
    869
    870/**
    871 * cros_ec_get_sensor_count() - Return the number of MEMS sensors supported.
    872 *
    873 * @ec: EC device, does not have to be connected directly to the AP,
    874 *      can be daisy chained through another device.
    875 * Return: < 0 in case of error.
    876 */
    877int cros_ec_get_sensor_count(struct cros_ec_dev *ec)
    878{
    879	/*
    880	 * Issue a command to get the number of sensor reported.
    881	 * If not supported, check for legacy mode.
    882	 */
    883	int ret, sensor_count;
    884	struct ec_params_motion_sense *params;
    885	struct ec_response_motion_sense *resp;
    886	struct cros_ec_command *msg;
    887	struct cros_ec_device *ec_dev = ec->ec_dev;
    888	u8 status;
    889
    890	msg = kzalloc(sizeof(*msg) + max(sizeof(*params), sizeof(*resp)),
    891		      GFP_KERNEL);
    892	if (!msg)
    893		return -ENOMEM;
    894
    895	msg->version = 1;
    896	msg->command = EC_CMD_MOTION_SENSE_CMD + ec->cmd_offset;
    897	msg->outsize = sizeof(*params);
    898	msg->insize = sizeof(*resp);
    899
    900	params = (struct ec_params_motion_sense *)msg->data;
    901	params->cmd = MOTIONSENSE_CMD_DUMP;
    902
    903	ret = cros_ec_cmd_xfer_status(ec->ec_dev, msg);
    904	if (ret < 0) {
    905		sensor_count = ret;
    906	} else {
    907		resp = (struct ec_response_motion_sense *)msg->data;
    908		sensor_count = resp->dump.sensor_count;
    909	}
    910	kfree(msg);
    911
    912	/*
    913	 * Check legacy mode: Let's find out if sensors are accessible
    914	 * via LPC interface.
    915	 */
    916	if (sensor_count < 0 && ec->cmd_offset == 0 && ec_dev->cmd_readmem) {
    917		ret = ec_dev->cmd_readmem(ec_dev, EC_MEMMAP_ACC_STATUS,
    918				1, &status);
    919		if (ret >= 0 &&
    920		    (status & EC_MEMMAP_ACC_STATUS_PRESENCE_BIT)) {
    921			/*
    922			 * We have 2 sensors, one in the lid, one in the base.
    923			 */
    924			sensor_count = 2;
    925		} else {
    926			/*
    927			 * EC uses LPC interface and no sensors are presented.
    928			 */
    929			sensor_count = 0;
    930		}
    931	}
    932	return sensor_count;
    933}
    934EXPORT_SYMBOL_GPL(cros_ec_get_sensor_count);
    935
    936/**
    937 * cros_ec_command - Send a command to the EC.
    938 *
    939 * @ec_dev: EC device
    940 * @version: EC command version
    941 * @command: EC command
    942 * @outdata: EC command output data
    943 * @outsize: Size of outdata
    944 * @indata: EC command input data
    945 * @insize: Size of indata
    946 *
    947 * Return: >= 0 on success, negative error number on failure.
    948 */
    949int cros_ec_command(struct cros_ec_device *ec_dev,
    950		    unsigned int version,
    951		    int command,
    952		    void *outdata,
    953		    int outsize,
    954		    void *indata,
    955		    int insize)
    956{
    957	struct cros_ec_command *msg;
    958	int ret;
    959
    960	msg = kzalloc(sizeof(*msg) + max(insize, outsize), GFP_KERNEL);
    961	if (!msg)
    962		return -ENOMEM;
    963
    964	msg->version = version;
    965	msg->command = command;
    966	msg->outsize = outsize;
    967	msg->insize = insize;
    968
    969	if (outsize)
    970		memcpy(msg->data, outdata, outsize);
    971
    972	ret = cros_ec_cmd_xfer_status(ec_dev, msg);
    973	if (ret < 0)
    974		goto error;
    975
    976	if (insize)
    977		memcpy(indata, msg->data, insize);
    978error:
    979	kfree(msg);
    980	return ret;
    981}
    982EXPORT_SYMBOL_GPL(cros_ec_command);