Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / prex-0.9.0 / bsp / drv / dev / base / cons.c @ 03e9c04a

History | View | Annotate | Download (4.64 KB)

1
/*-
2
 * Copyright (c) 2008-2009, Kohsuke Ohtani
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
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 * 3. Neither the name of the author nor the names of any co-contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
 * SUCH DAMAGE.
28
 */
29

    
30
/*
31
 * cons.c - console redirection driver
32
 */
33

    
34
#include <driver.h>
35
#include <cons.h>
36
#include <sys/dbgctl.h>
37

    
38
static int cons_open(device_t, int);
39
static int cons_close(device_t);
40
static int cons_read(device_t, char *, size_t *, int);
41
static int cons_write(device_t, char *, size_t *, int);
42
static int cons_ioctl(device_t, u_long, void *);
43
static int cons_devctl(device_t, u_long, void *);
44
static int cons_init(struct driver *);
45

    
46
static struct devops cons_devops = {
47
        /* open */        cons_open,
48
        /* close */        cons_close,
49
        /* read */        cons_read,
50
        /* write */        cons_write,
51
        /* ioctl */        cons_ioctl,
52
        /* devctl */        cons_devctl,
53
};
54

    
55
struct driver cons_driver = {
56
        /* name */        "cons",
57
        /* devops */        &cons_devops,
58
        /* devsz */        0,
59
        /* flags */        0,
60
        /* probe */        NULL,
61
        /* init */        cons_init,
62
        /* unload */        NULL,
63
};
64

    
65
static struct diag_ops cons_diag_ops = {
66
        /* puts */        cons_puts,
67
};
68

    
69
static struct consdev *consdev;                /* console device info */
70

    
71
static int
72
cons_open(device_t dev, int mode)
73
{
74

    
75
        ASSERT(consdev != NULL);
76
        dev = consdev->dev;
77
        return consdev->devops->open(dev, mode);
78
}
79

    
80
static int
81
cons_close(device_t dev)
82
{
83

    
84
        ASSERT(consdev != NULL);
85
        dev = consdev->dev;
86
        return consdev->devops->close(dev);
87
}
88

    
89
static int
90
cons_read(device_t dev, char *buf, size_t *nbyte, int blkno)
91
{
92

    
93
        ASSERT(consdev != NULL);
94
        dev = consdev->dev;
95
        return consdev->devops->read(dev, buf, nbyte, blkno);
96
}
97

    
98
static int
99
cons_write(device_t dev, char *buf, size_t *nbyte, int blkno)
100
{
101

    
102
        ASSERT(consdev != NULL);
103
        dev = consdev->dev;
104
        return consdev->devops->write(dev, buf, nbyte, blkno);
105
}
106

    
107
static int
108
cons_ioctl(device_t dev, u_long cmd, void *arg)
109
{
110

    
111
        ASSERT(consdev != NULL);
112
        dev = consdev->dev;
113
        return consdev->devops->ioctl(dev, cmd, arg);
114
}
115

    
116
static int
117
cons_devctl(device_t dev, u_long cmd, void *arg)
118
{
119

    
120
        ASSERT(consdev != NULL);
121
        dev = consdev->dev;
122
        return consdev->devops->devctl(dev, cmd, arg);
123
}
124

    
125
/*
126
 * Poll (busy wait) for a input and return the input key.
127
 * cons_pollc() must be called before cons_getc() could be used.
128
 * cons_getc() should be used only for kernel deugger.
129
 */
130
int
131
cons_getc(void)
132
{
133

    
134
        ASSERT(consdev != NULL);
135
        return consdev->cngetc(consdev->dev);
136
}
137

    
138
/*
139
 * Switch the console driver to polling mode if on is non-zero, or
140
 * back to interrupt driven mode if on is zero.
141
 * cons_pollc() should be used only for kernel deugger.
142
 */
143
void
144
cons_pollc(int on)
145
{
146

    
147
        ASSERT(consdev != NULL);
148
        consdev->cnpollc(consdev->dev, on);
149
}
150

    
151
/*
152
 * Console character output routine.
153
 */
154
void
155
cons_putc(int c)
156
{
157

    
158
        ASSERT(consdev != NULL);
159
        if (c) {
160
                consdev->cnputc(consdev->dev, c);
161
                if (c == '\n')
162
                        consdev->cnputc(consdev->dev, '\r');
163
        }
164
}
165

    
166
void
167
cons_puts(char *str)
168
{
169

    
170
        ASSERT(consdev != NULL);
171

    
172
        consdev->cnpollc(consdev->dev, 1);
173
        while (*str) {
174
                consdev->cnputc(consdev->dev, *str);
175
                if (*str == '\n')
176
                        consdev->cnputc(consdev->dev, '\r');
177
                str++;
178
        }
179
        consdev->cnpollc(consdev->dev, 0);
180
}
181

    
182
void
183
cons_attach(struct consdev *cdev, int diag)
184
{
185

    
186
        if (consdev != NULL)
187
                return;
188
        consdev = cdev;
189

    
190
        /*
191
         * Set console port as diag port.
192
         */
193
        if (diag)
194
                dbgctl(DBGC_SETDIAG, &cons_diag_ops);
195
}
196

    
197
int
198
cons_init(struct driver *self)
199
{
200

    
201
        consdev = NULL;
202
        device_create(self, "console", D_CHR|D_TTY);
203
        return 0;
204
}