Project

General

Profile

Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (4.9 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
 * serial.c - machine independent driver for serial port.
32
 */
33

    
34
#include <driver.h>
35
#include <sys/ioctl.h>
36
#include <tty.h>
37
#include <cons.h>
38
#include <serial.h>
39

    
40
/* #define DEBUG_SERIAL 1 */
41

    
42
#ifdef DEBUG_SERIAL
43
#define DPRINTF(a) printf a
44
#else
45
#define DPRINTF(a)
46
#endif
47

    
48
struct serial_softc {
49
        device_t        dev;                /* device object */
50
        struct tty        tty;                /* tty structure */
51
        struct serial_port *port;        /* port setting */
52
        struct serial_ops  *ops;        /* h/w operation */
53
};
54

    
55
/* Forward functions */
56
static int        serial_init(struct driver *);
57
static int        serial_read(device_t, char *, size_t *, int);
58
static int        serial_write(device_t, char *, size_t *, int);
59
static int        serial_ioctl(device_t, u_long, void *);
60

    
61
static int        serial_cngetc(device_t);
62
static void        serial_cnputc(device_t, int);
63
static void        serial_cnpollc(device_t, int);
64

    
65

    
66
static struct devops serial_devops = {
67
        /* open */        no_open,
68
        /* close */        no_close,
69
        /* read */        serial_read,
70
        /* write */        serial_write,
71
        /* ioctl */        serial_ioctl,
72
        /* devctl */        no_devctl,
73
};
74

    
75
struct driver serial_driver = {
76
        /* name */        "serial",
77
        /* devops */        &serial_devops,
78
        /* devsz */        sizeof(struct serial_softc),
79
        /* flags */        0,
80
        /* probe */        NULL,
81
        /* init */        serial_init,
82
        /* unload */        NULL,
83
};
84

    
85
static struct consdev serial_consdev = {
86
        /* dev */        NODEV,
87
        /* devops */        &serial_devops,
88
        /* cngetc */        serial_cngetc,
89
        /* cnputc */        serial_cnputc,
90
        /* cnpollc */        serial_cnpollc,
91
};
92

    
93

    
94
static int
95
serial_read(device_t dev, char *buf, size_t *nbyte, int blkno)
96
{
97
        struct serial_softc *sc = device_private(dev);
98

    
99
        return tty_read(&sc->tty, buf, nbyte);
100
}
101

    
102
static int
103
serial_write(device_t dev, char *buf, size_t *nbyte, int blkno)
104
{
105
        struct serial_softc *sc = device_private(dev);
106

    
107
        return tty_write(&sc->tty, buf, nbyte);
108
}
109

    
110
static int
111
serial_ioctl(device_t dev, u_long cmd, void *arg)
112
{
113
        struct serial_softc *sc = device_private(dev);
114

    
115
        return tty_ioctl(&sc->tty, cmd, arg);
116
}
117

    
118
/*
119
 * Start TTY output operation.
120
 */
121
static void
122
serial_start(struct tty *tp)
123
{
124
        struct serial_softc *sc = device_private(tp->t_dev);
125
        struct serial_port *port = sc->port;
126
        int c;
127

    
128
        while ((c = tty_getc(&tp->t_outq)) >= 0)
129
                sc->ops->xmt_char(port, c);
130
}
131

    
132
/*
133
 * Output completed.
134
 */
135
void
136
serial_xmt_done(struct serial_port *port)
137
{
138

    
139
        tty_done(port->tty);
140
}
141

    
142
/*
143
 * Character input.
144
 */
145
void
146
serial_rcv_char(struct serial_port *port, char c)
147
{
148

    
149
        tty_input(c, port->tty);
150
}
151

    
152
static int
153
serial_cngetc(device_t dev)
154
{
155
        struct serial_softc *sc = device_private(dev);
156
        struct serial_port *port = sc->port;
157

    
158
        return sc->ops->rcv_char(port);
159
}
160

    
161
static void
162
serial_cnputc(device_t dev, int c)
163
{
164
        struct serial_softc *sc = device_private(dev);
165
        struct serial_port *port = sc->port;
166

    
167
        sc->ops->xmt_char(port, c);
168
}
169

    
170
static void
171
serial_cnpollc(device_t dev, int on)
172
{
173
        struct serial_softc *sc = device_private(dev);
174
        struct serial_port *port = sc->port;
175

    
176
        sc->ops->set_poll(port, on);
177
}
178

    
179
void
180
serial_attach(struct serial_ops *ops, struct serial_port *port)
181
{
182
        struct serial_softc *sc;
183
        device_t dev;
184
        int diag = 0;
185

    
186
        dev = device_create(&serial_driver, "tty", D_CHR|D_TTY);
187

    
188
        sc = device_private(dev);
189
        sc->dev = dev;
190
        sc->ops = ops;
191
        sc->port = port;
192

    
193
        tty_attach(&sc->tty);
194
        sc->tty.t_dev = dev;
195
        sc->tty.t_oproc = serial_start;
196

    
197
        /* Start device */
198
        port->tty = &sc->tty;
199
        ops->start(port);
200

    
201
#ifdef CONFIG_DIAG_SERIAL
202
        diag = 1;
203
#endif
204
        serial_consdev.dev = dev;
205
        cons_attach(&serial_consdev, diag);
206
}
207

    
208
static int
209
serial_init(struct driver *self)
210
{
211

    
212
        return 0;
213
}