summaryrefslogtreecommitdiff
path: root/common/mkbp_fifo.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/mkbp_fifo.c')
-rw-r--r--common/mkbp_fifo.c241
1 files changed, 0 insertions, 241 deletions
diff --git a/common/mkbp_fifo.c b/common/mkbp_fifo.c
deleted file mode 100644
index 428d6412fc..0000000000
--- a/common/mkbp_fifo.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Copyright 2021 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- *
- * Matrix KeyBoard Protocol FIFO buffer implementation
- */
-
-#include "atomic.h"
-#include "common.h"
-#include "keyboard_config.h"
-#include "mkbp_event.h"
-#include "mkbp_fifo.h"
-#include "system.h"
-#include "task.h"
-#include "util.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_KEYBOARD, format, ## args)
-
-/*
- * Common FIFO depth. This needs to be big enough not to overflow if a
- * series of keys is pressed in rapid succession and the kernel is too busy
- * to read them out right away.
- *
- * RAM usage is (depth * #cols); A 16-entry FIFO will consume 16x13=208 bytes,
- * which is non-trivial but not horrible.
- */
-
-static uint32_t fifo_start; /* first entry */
-static uint32_t fifo_end; /* last entry */
-static uint32_t fifo_entries; /* number of existing entries */
-static uint8_t fifo_max_depth = FIFO_DEPTH;
-static struct ec_response_get_next_event fifo[FIFO_DEPTH];
-
-/*
- * Mutex for critical sections of mkbp_fifo_add(), which is called
- * from various tasks.
- */
-K_MUTEX_DEFINE(fifo_add_mutex);
-/*
- * Mutex for critical sections of fifo_remove(), which is called from the
- * hostcmd task and from keyboard_clear_buffer().
- */
-K_MUTEX_DEFINE(fifo_remove_mutex);
-
-static int get_data_size(enum ec_mkbp_event e)
-{
- switch (e) {
- case EC_MKBP_EVENT_KEY_MATRIX:
- return KEYBOARD_COLS_MAX;
-
-#ifdef CONFIG_HOST_EVENT64
- case EC_MKBP_EVENT_HOST_EVENT64:
- return sizeof(uint64_t);
-#endif
-
- case EC_MKBP_EVENT_HOST_EVENT:
- case EC_MKBP_EVENT_BUTTON:
- case EC_MKBP_EVENT_SWITCH:
- case EC_MKBP_EVENT_SYSRQ:
- return sizeof(uint32_t);
- default:
- /* For unknown types, say it's 0. */
- return 0;
- }
-}
-
-/**
- * Pop MKBP event data from FIFO
- *
- * @return EC_SUCCESS if entry popped, EC_ERROR_UNKNOWN if FIFO is empty
- */
-static int fifo_remove(uint8_t *buffp)
-{
- int size;
-
- mutex_lock(&fifo_remove_mutex);
- if (!fifo_entries) {
- /* no entry remaining in FIFO : return last known state */
- int last = (fifo_start + FIFO_DEPTH - 1) % FIFO_DEPTH;
-
- size = get_data_size(fifo[last].event_type);
-
- memcpy(buffp, &fifo[last].data, size);
- mutex_unlock(&fifo_remove_mutex);
-
- /*
- * Bail out without changing any FIFO indices and let the
- * caller know something strange happened. The buffer will
- * will contain the last known state of the keyboard.
- */
- return EC_ERROR_UNKNOWN;
- }
-
- /* Return just the event data. */
- if (buffp) {
- size = get_data_size(fifo[fifo_start].event_type);
- /* skip over event_type. */
- memcpy(buffp, &fifo[fifo_start].data, size);
- }
-
- fifo_start = (fifo_start + 1) % FIFO_DEPTH;
- atomic_sub(&fifo_entries, 1);
- mutex_unlock(&fifo_remove_mutex);
-
- return EC_SUCCESS;
-}
-
-/*****************************************************************************/
-/* Interface */
-
-void mkbp_fifo_depth_update(uint8_t new_max_depth)
-{
- fifo_max_depth = new_max_depth;
-}
-
-
-void mkbp_fifo_clear_keyboard(void)
-{
- int i, new_fifo_entries = 0;
-
- CPRINTS("clear keyboard MKBP fifo");
-
- /*
- * Order of these locks is important to prevent deadlock since
- * mkbp_fifo_add() may call fifo_remove().
- */
- mutex_lock(&fifo_add_mutex);
- mutex_lock(&fifo_remove_mutex);
-
- /* Reset the end position */
- fifo_end = fifo_start;
-
- for (i = 0; i < fifo_entries; i++) {
- int cur = (fifo_start + i) % FIFO_DEPTH;
-
- /* Drop keyboard events */
- if (fifo[cur].event_type == EC_MKBP_EVENT_KEY_MATRIX)
- continue;
-
- /* And move other events to the front */
- memmove(&fifo[fifo_end], &fifo[cur], sizeof(fifo[cur]));
- fifo_end = (fifo_end + 1) % FIFO_DEPTH;
- ++new_fifo_entries;
- }
- fifo_entries = new_fifo_entries;
-
- mutex_unlock(&fifo_remove_mutex);
- mutex_unlock(&fifo_add_mutex);
-}
-
-void mkbp_clear_fifo(void)
-{
- int i;
-
- CPRINTS("clear MKBP fifo");
-
- /*
- * Order of these locks is important to prevent deadlock since
- * mkbp_fifo_add() may call fifo_remove().
- */
- mutex_lock(&fifo_add_mutex);
- mutex_lock(&fifo_remove_mutex);
-
- fifo_start = 0;
- fifo_end = 0;
- /* This assignment is safe since both mutexes are held. */
- fifo_entries = 0;
- for (i = 0; i < FIFO_DEPTH; i++)
- memset(&fifo[i], 0, sizeof(struct ec_response_get_next_event));
-
- mutex_unlock(&fifo_remove_mutex);
- mutex_unlock(&fifo_add_mutex);
-}
-
-test_mockable int mkbp_fifo_add(uint8_t event_type, const uint8_t *buffp)
-{
- uint8_t size;
-
- mutex_lock(&fifo_add_mutex);
- if (fifo_entries >= fifo_max_depth) {
- mutex_unlock(&fifo_add_mutex);
- CPRINTS("MKBP common FIFO depth %d reached",
- fifo_max_depth);
-
- return EC_ERROR_OVERFLOW;
- }
-
- size = get_data_size(event_type);
- fifo[fifo_end].event_type = event_type;
- memcpy(&fifo[fifo_end].data, buffp, size);
- fifo_end = (fifo_end + 1) % FIFO_DEPTH;
- atomic_add(&fifo_entries, 1);
-
- /*
- * If our event didn't generate an interrupt then the host is still
- * asleep. In this case, we don't want to queue our event, except if
- * another event just woke the host (and wake is already in progress).
- */
- if (!mkbp_send_event(event_type) && fifo_entries == 1)
- fifo_remove(NULL);
-
- mutex_unlock(&fifo_add_mutex);
- return EC_SUCCESS;
-}
-
-int mkbp_fifo_get_next_event(uint8_t *out, enum ec_mkbp_event evt)
-{
- uint8_t t = fifo[fifo_start].event_type;
- uint8_t size;
-
- if (!fifo_entries)
- return -1;
-
- /*
- * We need to peek at the next event to check that we were called with
- * the correct event.
- */
- if (t != (uint8_t)evt) {
- /*
- * We were called with the wrong event. The next element in the
- * FIFO's event type doesn't match with what we were called
- * with. Return an error that we're busy. The caller will need
- * to call us with the correct event first.
- */
- return -EC_ERROR_BUSY;
- }
-
- fifo_remove(out);
-
- /* Keep sending events if FIFO is not empty */
- if (fifo_entries)
- mkbp_send_event(fifo[fifo_start].event_type);
-
- /* Return the correct size of the data. */
- size = get_data_size(t);
- if (size)
- return size;
- else
- return -EC_ERROR_UNKNOWN;
-}