nckernel
0.1
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
x86
driver
keyboard
src
keyboard.c
Go to the documentation of this file.
1
#include <
slibc.h
>
2
#include <
sys/types.h
>
3
#include <
sys/io.h
>
4
#include <
stdio.h
>
5
#include <
stdlib.h
>
6
#include <
errno.h
>
7
#include <
stddef.h
>
8
#include <
stdarg.h
>
9
#include <
stropts.h
>
10
#include <
fcntl.h
>
11
#include <
stdint.h
>
12
#include <
unistd.h
>
13
#include <
string.h
>
14
15
#include <
object.h
>
16
#include <
list.h
>
17
#include <
vfs.h
>
18
#include <
device.h
>
19
#include <
keyboard.h
>
20
#include <
interrupt.h
>
21
#include <
isr.h
>
22
23
#include <
debug.h
>
24
25
#define SIZE_OF_QUEUE 64
26
27
static
struct
{
28
unsigned
short
buffer
[
SIZE_OF_QUEUE
];
29
off_t
write_offset
;
30
off_t
read_offset
;
31
}
s_info
= {
32
.
buffer
= { 0, },
33
.write_offset = 0,
34
.read_offset = 0,
35
};
36
37
struct
info
{
38
};
39
40
off_t
keyboard_lseek
(
struct
ninfo
*
ninfo
,
struct
nctx
*ctx,
off_t
off,
int
whence)
41
{
42
switch
(whence) {
43
case
SEEK_SET
:
44
break
;
45
case
SEEK_CUR
:
46
off += ctx->
offset
;
47
break
;
48
case
SEEK_END
:
49
off += ninfo->
size
;
50
break
;
51
default
:
52
return
-
EINVAL
;
53
}
54
55
if
(off < 0 || off >= ninfo->
size
) {
56
return
-
EINVAL
;
57
}
58
59
ctx->
offset
= off;
60
return
off;
61
}
62
63
int
keyboard_read
(
struct
ninfo
*
ninfo
,
struct
nctx
*ctx,
void
*buf,
size_t
size)
64
{
65
int
i;
66
char
*out = (
char
*)buf;
67
68
for
(i = 0;
s_info
.read_offset !=
s_info
.write_offset && i < size; i++) {
69
*out = (char)(
s_info
.
buffer
[
s_info
.read_offset] & 0x00FF);
70
s_info
.read_offset = (
s_info
.read_offset + 1) %
SIZE_OF_QUEUE
;
71
}
72
73
return
i;
74
}
75
76
int
keyboard_write
(
struct
ninfo
*
ninfo
,
struct
nctx
*ctx,
77
const
void
*buf,
size_t
size)
78
{
79
return
-
EPERM
;
80
}
81
82
int
keyboard_ioctl
(
struct
ninfo
*
ninfo
,
struct
nctx
*ctx,
int
request,
va_list
ap)
83
{
84
return
-
ENOSYS
;
85
}
86
87
int
keyboard_open
(
struct
ninfo
*
ninfo
,
struct
nctx
*ctx)
88
{
89
struct
info
*
info
;
90
91
info =
malloc
(
sizeof
(*info));
92
if
(!info) {
93
return
-
ENOMEM
;
94
}
95
96
memset
(info, 0,
sizeof
(*info));
97
98
ctx->
offset
= 0;
99
ctx->
priv
= info;
100
101
return
0;
102
}
103
104
int
keyboard_close
(
struct
ninfo
*
ninfo
,
struct
nctx
*ctx)
105
{
106
free
(ctx->
priv
);
107
ctx->
priv
=
NULL
;
108
return
0;
109
}
110
111
static
struct
ninfo_ops
keyboard_ops = {
112
.
lseek
=
keyboard_lseek
,
113
.read =
keyboard_read
,
114
.write =
keyboard_write
,
115
.ioctl =
keyboard_ioctl
,
116
.open =
keyboard_open
,
117
.close =
keyboard_close
,
118
};
119
120
static
int
keyboard_handler(
int
sub_irq,
void
*
info
,
void
*data)
121
{
122
static
int
idx = 0;
123
unsigned
short
ch;
/* status | scancode */
124
125
ch =
inb
(0x64);
126
ch = (ch << 8) |
inb
(0x60);
127
128
dbg_printf
(
"[%d] keyboard: %d, %p, %d, %d\n"
, idx++, sub_irq, info, ch);
129
130
s_info
.
buffer
[
s_info
.write_offset] = ch;
131
s_info
.write_offset = (
s_info
.write_offset + 1) %
SIZE_OF_QUEUE
;
132
if
(
s_info
.write_offset ==
s_info
.read_offset) {
133
/* Discard old input */
134
s_info
.read_offset = (
s_info
.read_offset + 1) %
SIZE_OF_QUEUE
;
135
}
136
137
return
0;
138
}
139
140
int
keyboard_init
(
void
)
141
{
142
struct
ninfo
*parent;
143
struct
ninfo
*
ninfo
;
144
int
ret;
145
146
ret =
register_irq
(
IRQ_NR_KEYBOARD
,
NORMAL_PRIORITY
, keyboard_handler,
NULL
);
147
if
(ret < 0) {
148
return
ret;
149
}
150
151
parent =
vfs_get_ninfo
(
NULL
,
NULL
,
"/dev"
);
152
if
(!parent) {
153
unregister_irq
(
IRQ_NR_KEYBOARD
, keyboard_handler,
NULL
);
154
return
-
EFAULT
;
155
}
156
157
ninfo =
vfs_new_dev_ninfo
(
NULL
, parent,
158
"input"
,
DEVICE_VIDEO80x25
, &keyboard_ops);
159
if
(!ninfo) {
160
unregister_irq
(
IRQ_NR_KEYBOARD
, keyboard_handler,
NULL
);
161
return
-
EFAULT
;
162
}
163
164
ninfo->
size
= 0;
165
166
return
0;
167
}
168
169
/* End of a file */
Generated on Thu Nov 7 2013 02:45:25 for nckernel by
1.8.4