diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2012-06-01 16:33:58 +0800 |
---|---|---|
committer | Gerrit <chrome-bot@google.com> | 2012-06-07 20:48:51 -0700 |
commit | 210ddfefcfe90944c70105463beb6f795513c5e6 (patch) | |
tree | d979799b7cdf940bfadaaeb5e258e24b0841c299 /common/queue.c | |
parent | c4ac74a11dfa66d6ad725833e2aac6579b0c76ed (diff) | |
download | chrome-ec-210ddfefcfe90944c70105463beb6f795513c5e6.tar.gz |
Refactor the i8042 module to be thread-safe.
Any command/data coming from host will be placed in from_host queue, and
the interrupt handler returns immediately. The i8042_command_task() will
handle them later.
Data reply to the host will be protected by the mutex.
BUG=chrome-os-partner:10090
TEST=randomly play around on the link board.
Change-Id: Ic19d5abd1abf8dc261ddaad4224cd9305c2f36a4
Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/24299
Commit-Ready: Yung-Chieh Lo <yjlou%chromium.org@gtempaccount.com>
Reviewed-by: Yung-Chieh Lo <yjlou%chromium.org@gtempaccount.com>
Tested-by: Yung-Chieh Lo <yjlou%chromium.org@gtempaccount.com>
Diffstat (limited to 'common/queue.c')
-rw-r--r-- | common/queue.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/common/queue.c b/common/queue.c new file mode 100644 index 0000000000..8018e4c0b0 --- /dev/null +++ b/common/queue.c @@ -0,0 +1,53 @@ +/* Copyright (c) 2012 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. + * + * Queue data structure implementation. + */ +#include "queue.h" +#include "util.h" + +void queue_reset(struct queue *queue) +{ + queue->head = queue->tail = 0; +} + +int queue_is_empty(const struct queue *q) +{ + return q->head == q->tail; +} + +int queue_has_space(const struct queue *q, int unit_count) +{ + return (q->tail + unit_count * q->unit_bytes) <= + (q->head + q->buf_bytes - q->unit_bytes); +} + +void queue_add_units(struct queue *q, const void *src, int unit_count) +{ + const uint8_t *s = (const uint8_t *)src; + + if (!queue_has_space(q, unit_count)) + return; + + for (unit_count *= q->unit_bytes; unit_count; unit_count--) { + q->buf[q->tail++] = *(s++); + q->tail %= q->buf_bytes; + } +} + +int queue_remove_unit(struct queue *q, void *dest) +{ + int count; + uint8_t *d = (uint8_t *)dest; + + if (queue_is_empty(q)) + return 0; + + for (count = q->unit_bytes; count; count--) { + *(d++) = q->buf[q->head++]; + q->head %= q->buf_bytes; + } + + return 1; +} |