Initial import of binutils 2.22 on the new vendor branch
[dragonfly.git] / sys / dev / misc / kbd / kbdsw.c
1 /*
2  * (MPSAFE)
3  *
4  * Copyright (c) 2010 The DragonFly Project.  All rights reserved.
5  *
6  * This code is derived from software contributed to The DragonFly Project
7  * by Matthew Dillon <dillon@backplane.com>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  * 3. Neither the name of The DragonFly Project nor the names of its
20  *    contributors may be used to endorse or promote products derived
21  *    from this software without specific, prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
27  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36
37 #include "opt_kbd.h"
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/malloc.h>
43 #include <sys/conf.h>
44 #include <sys/proc.h>
45 #include <sys/tty.h>
46 #include <sys/event.h>
47 #include <sys/vnode.h>
48 #include <sys/uio.h>
49 #include <sys/thread.h>
50 #include <sys/thread2.h>
51
52 #include <machine/console.h>
53
54 #include "kbdreg.h"
55
56 int
57 sw_probe(keyboard_switch_t *sw, int unit, void *arg, int flags)
58 {
59         int error;
60
61         error = (*sw->probe)(unit, arg, flags);
62         return (error);
63 }
64
65 int
66 sw_init(keyboard_switch_t *sw, int unit, keyboard_t **kbdpp,
67         void *arg, int flags)
68 {
69         int error;
70
71         error = (*sw->init)(unit, kbdpp, arg, flags);
72         return (error);
73 }
74
75 int
76 kbd_term(keyboard_t *kbd)
77 {
78         int error;
79
80         KBD_ALWAYS_LOCK(kbd);
81         error = (*kbdsw[kbd->kb_index]->term)(kbd);
82         if (error)
83                 KBD_ALWAYS_UNLOCK(kbd);
84         /* kbd structure is stale if error is 0 */
85         return (error);
86 }
87
88 int
89 kbd_intr(keyboard_t *kbd, void *arg)
90 {
91         int error;
92         KBD_LOCK_DECLARE;
93
94         KBD_LOCK(kbd);
95         error = (*kbdsw[kbd->kb_index]->intr)(kbd, arg);
96         KBD_UNLOCK(kbd);
97
98         return (error);
99 }
100
101 int
102 kbd_test_if(keyboard_t *kbd)
103 {
104         int error;
105         KBD_LOCK_DECLARE;
106
107         KBD_LOCK(kbd);
108         error = (*kbdsw[kbd->kb_index]->test_if)(kbd);
109         KBD_UNLOCK(kbd);
110
111         return (error);
112 }
113
114 int
115 kbd_enable(keyboard_t *kbd)
116 {
117         int error;
118         KBD_LOCK_DECLARE;
119
120         KBD_LOCK(kbd);
121         error = (*kbdsw[kbd->kb_index]->enable)(kbd);
122         KBD_UNLOCK(kbd);
123
124         return (error);
125 }
126
127 int
128 kbd_disable(keyboard_t *kbd)
129 {
130         int error;
131         KBD_LOCK_DECLARE;
132
133         KBD_LOCK(kbd);
134         error = (*kbdsw[kbd->kb_index]->disable)(kbd);
135         KBD_UNLOCK(kbd);
136
137         return (error);
138 }
139
140 int
141 kbd_read(keyboard_t *kbd, int wait)
142 {
143         int error;
144         KBD_LOCK_DECLARE;
145
146         KBD_LOCK(kbd);
147         error = (*kbdsw[kbd->kb_index]->read)(kbd, wait);
148         KBD_UNLOCK(kbd);
149
150         return (error);
151 }
152
153 int
154 kbd_check(keyboard_t *kbd)
155 {
156         int error;
157         KBD_LOCK_DECLARE;
158
159         KBD_LOCK(kbd);
160         error = (*kbdsw[kbd->kb_index]->check)(kbd);
161         KBD_UNLOCK(kbd);
162
163         return (error);
164 }
165
166 u_int
167 kbd_read_char(keyboard_t *kbd, int wait)
168 {
169         int error;
170         KBD_LOCK_DECLARE;
171
172         KBD_LOCK(kbd);
173         error = (*kbdsw[kbd->kb_index]->read_char)(kbd, wait);
174         KBD_UNLOCK(kbd);
175
176         return (error);
177 }
178
179 int
180 kbd_check_char(keyboard_t *kbd)
181 {
182         int error;
183         KBD_LOCK_DECLARE;
184
185         KBD_LOCK(kbd);
186         error = (*kbdsw[kbd->kb_index]->check_char)(kbd);
187         KBD_UNLOCK(kbd);
188
189         return (error);
190 }
191
192 int
193 kbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t data)
194 {
195         int error;
196         KBD_LOCK_DECLARE;
197
198         if (kbd) {
199                 KBD_LOCK(kbd);
200                 error = (*kbdsw[kbd->kb_index]->ioctl)(kbd, cmd, data);
201                 KBD_UNLOCK(kbd);
202         } else {
203                 error = ENODEV;
204         }
205         return (error);
206 }
207
208 int
209 kbd_lock(keyboard_t *kbd, int xlock)
210 {
211         int error;
212         KBD_LOCK_DECLARE;
213
214         KBD_LOCK(kbd);
215         error = (*kbdsw[kbd->kb_index]->lock)(kbd, xlock);
216         KBD_UNLOCK(kbd);
217
218         return (error);
219 }
220
221 void
222 kbd_clear_state(keyboard_t *kbd)
223 {
224         KBD_LOCK_DECLARE;
225
226         KBD_LOCK(kbd);
227         (*kbdsw[kbd->kb_index]->clear_state)(kbd);
228         KBD_UNLOCK(kbd);
229 }
230
231 int
232 kbd_get_state(keyboard_t *kbd, void *buf, size_t len)
233 {
234         int error;
235         KBD_LOCK_DECLARE;
236
237         KBD_LOCK(kbd);
238         error = (*kbdsw[kbd->kb_index]->get_state)(kbd, buf, len);
239         KBD_UNLOCK(kbd);
240
241         return (error);
242 }
243
244 int
245 kbd_set_state(keyboard_t *kbd, void *buf, size_t len)
246 {
247         int error;
248         KBD_LOCK_DECLARE;
249
250         KBD_LOCK(kbd);
251         error = (*kbdsw[kbd->kb_index]->set_state)(kbd, buf, len);
252         KBD_UNLOCK(kbd);
253
254         return (error);
255 }
256
257 u_char *
258 kbd_get_fkeystr(keyboard_t *kbd, int fkey, size_t *len)
259 {
260         KBD_LOCK_DECLARE;
261         u_char *retstr;
262
263         KBD_LOCK(kbd);
264         retstr = (*kbdsw[kbd->kb_index]->get_fkeystr)(kbd, fkey, len);
265         KBD_UNLOCK(kbd);
266
267         return (retstr);
268 }
269
270 /*
271  * Polling mode set by debugger, we cannot lock!
272  */
273 int
274 kbd_poll(keyboard_t *kbd, int on)
275 {
276         int error;
277
278         if (!on)
279                 KBD_UNPOLL(kbd);
280         error = (*kbdsw[kbd->kb_index]->poll)(kbd, on);
281         if (on)
282                 KBD_POLL(kbd);
283
284         return (error);
285 }
286
287 void
288 kbd_diag(keyboard_t *kbd, int level)
289 {
290         KBD_LOCK_DECLARE;
291
292         KBD_LOCK(kbd);
293         (*kbdsw[kbd->kb_index]->diag)(kbd, level);
294         KBD_UNLOCK(kbd);
295 }