source: mainline/kernel/generic/src/console/chardev.c@ 1eaead4

ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1eaead4 was 7c5320c, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 2 years ago

Use the semaphore interface instead of waitq in some places

Since we already have an underused semaphore API in the kernel,
it would be worthwhile to use it in places where the baseline
semaphore semantics are needed. It makes the function of the
calls obvious even to people unfamiliar with the details of
waitq API.

  • Property mode set to 100644
File size: 4.4 KB
RevLine 
[2677758]1/*
[df4ed85]2 * Copyright (c) 2005 Jakub Jermar
[2677758]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[174156fd]29/** @addtogroup kernel_generic_console
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[63e27ef]35#include <assert.h>
[b9c7425]36#include <adt/list.h>
[2677758]37#include <console/chardev.h>
38#include <synch/waitq.h>
39#include <synch/spinlock.h>
[bab75df6]40#include <stdio.h>
[b2e121a]41#include <halt.h>
[1066041]42#include <cpu.h>
[2677758]43
[a7efdec]44/** Initialize input character device.
45 *
46 * @param indev Input character device.
47 * @param op Implementation of input character device operations.
[607c5f9]48 *
49 */
[a000878c]50void indev_initialize(const char *name, indev_t *indev,
[a7efdec]51 indev_operations_t *op)
[2677758]52{
[a7efdec]53 indev->name = name;
[7c5320c]54 semaphore_initialize(&indev->wq, 0);
[da1bafb]55 irq_spinlock_initialize(&indev->lock, "chardev.indev.lock");
[a7efdec]56 indev->counter = 0;
57 indev->index = 0;
58 indev->op = op;
[607c5f9]59}
60
61/** Push character read from input character device.
62 *
[a7efdec]63 * @param indev Input character device.
64 * @param ch Character being pushed.
65 *
[607c5f9]66 */
[28a5ebd]67void indev_push_character(indev_t *indev, char32_t ch)
[607c5f9]68{
[63e27ef]69 assert(indev);
[a35b458]70
[da1bafb]71 irq_spinlock_lock(&indev->lock, true);
[a7efdec]72 if (indev->counter == INDEV_BUFLEN - 1) {
73 /* Buffer full */
[da1bafb]74 irq_spinlock_unlock(&indev->lock, true);
[a7efdec]75 return;
[607c5f9]76 }
[a35b458]77
[a7efdec]78 indev->counter++;
79 indev->buffer[indev->index++] = ch;
[a35b458]80
[a7efdec]81 /* Index modulo size of buffer */
82 indev->index = indev->index % INDEV_BUFLEN;
[7c5320c]83 semaphore_up(&indev->wq);
[da1bafb]84 irq_spinlock_unlock(&indev->lock, true);
[a7efdec]85}
86
[44b7783]87/** Pop character from input character device.
88 *
89 * @param indev Input character device.
90 *
91 * @return Character read.
92 *
93 */
[28a5ebd]94char32_t indev_pop_character(indev_t *indev)
[44b7783]95{
[036e97c]96 if (atomic_load(&haltstate)) {
[7ddc2c7]97 /*
98 * If we are here, we are hopefully on the processor that
[44b7783]99 * issued the 'halt' command, so proceed to read the character
100 * directly from input
101 */
102 if (check_poll(indev))
103 return indev->op->poll(indev);
[a35b458]104
[44b7783]105 /* No other way of interacting with user */
106 interrupts_disable();
[a35b458]107
[44b7783]108 if (CPU)
109 printf("cpu%u: ", CPU->id);
110 else
111 printf("cpu: ");
[a35b458]112
[44b7783]113 printf("halted (no polling input)\n");
114 cpu_halt();
115 }
[a35b458]116
[7c5320c]117 semaphore_down(&indev->wq);
[da1bafb]118 irq_spinlock_lock(&indev->lock, true);
[28a5ebd]119 char32_t ch = indev->buffer[(indev->index - indev->counter) %
[7ddc2c7]120 INDEV_BUFLEN];
[44b7783]121 indev->counter--;
[da1bafb]122 irq_spinlock_unlock(&indev->lock, true);
[a35b458]123
[44b7783]124 return ch;
125}
126
[7ddc2c7]127/** Signal out-of-band condition
128 *
129 * @param indev Input character device.
130 * @param signal Out-of-band condition to signal.
131 *
132 */
133void indev_signal(indev_t *indev, indev_signal_t signal)
134{
135 if ((indev != NULL) && (indev->op != NULL) &&
136 (indev->op->signal != NULL))
137 indev->op->signal(indev, signal);
138}
139
[a7efdec]140/** Initialize output character device.
141 *
142 * @param outdev Output character device.
143 * @param op Implementation of output character device operations.
144 *
145 */
[a000878c]146void outdev_initialize(const char *name, outdev_t *outdev,
[a7efdec]147 outdev_operations_t *op)
148{
149 outdev->name = name;
[da1bafb]150 spinlock_initialize(&outdev->lock, "chardev.outdev.lock");
[b9c7425]151 link_initialize(&outdev->link);
152 list_initialize(&outdev->list);
[a7efdec]153 outdev->op = op;
[2677758]154}
[b45c443]155
[44b7783]156bool check_poll(indev_t *indev)
157{
158 if (indev == NULL)
159 return false;
[a35b458]160
[44b7783]161 if (indev->op == NULL)
162 return false;
[a35b458]163
[44b7783]164 return (indev->op->poll != NULL);
165}
166
[06e1e95]167/** @}
[b45c443]168 */
Note: See TracBrowser for help on using the repository browser.