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 } 296