1 /* 2 * Copyright (c) 1992 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 7 * 8 * %sccs.include.redist.c% 9 * 10 * from: $Hdr: kb.c,v 4.300 91/06/09 06:42:44 root Rel41 $ SONY 11 * 12 * @(#)kb.c 7.1 (Berkeley) 06/04/92 13 */ 14 15 #include "kb.h" 16 17 #if NKB > 0 18 #include "../include/fix_machine_type.h" 19 20 #include "param.h" 21 #include "proc.h" 22 #include "user.h" 23 #include "ioctl.h" 24 #include "buf.h" 25 #include "systm.h" 26 #include "map.h" 27 #include "uio.h" 28 #include "kernel.h" 29 30 #include "../iop/keyboard.h" 31 #include "../iop/kbreg.h" 32 33 #ifdef CPU_SINGLE 34 #include "tty.h" 35 #include "clist.h" 36 #include "../sio/scc.h" 37 #include "../hbdev/hbvar.h" 38 #define iop_device hb_device 39 #define ii_alive hi_alive 40 #else 41 #include "../iop/iopvar.h" 42 #endif 43 44 int kbprobe(), kbattach(); 45 extern Key_table key_table[]; 46 extern Key_table default_table[]; 47 extern int country; 48 49 #ifdef CPU_SINGLE 50 struct hb_device *kbinfo[NKB]; 51 struct hb_driver kbdriver = 52 { kbprobe, 0, kbattach, 0, 0, "kb", kbinfo, "mc", 0, 0 }; 53 extern Key_table *key_table_addr; 54 #endif 55 56 #ifdef CPU_DOUBLE 57 struct iop_device *kbinfo[NKB]; 58 struct iop_driver kbdriver = 59 { kbprobe, 0, kbattach, 0, "kb", kbinfo }; 60 #endif 61 62 char kb_busy; 63 64 /*ARGSUSED*/ 65 kbprobe(ii) 66 struct iop_device *ii; 67 { 68 69 return (kb_probe(ii)); 70 } 71 72 /*ARGSUSED*/ 73 kbattach(ii) 74 struct iop_device *ii; 75 { 76 77 kb_attach(ii); 78 } 79 80 /*ARGSUSED*/ 81 kbopen(dev, flag) 82 dev_t dev; 83 int flag; 84 { 85 register int unit; 86 register struct iop_device *ii; 87 88 if ((unit = minor(dev)) >= NKB || (ii = kbinfo[unit]) == 0 || 89 ii->ii_alive == 0) 90 return (ENXIO); 91 if (kb_busy) 92 return (EBUSY); 93 kb_busy = 1; 94 return (kb_open()); 95 } 96 97 /*ARGSUSED*/ 98 kbclose(dev, flag) 99 dev_t dev; 100 int flag; 101 { 102 kb_close(); 103 kb_busy = 0; 104 } 105 106 #ifdef KBDEBUG 107 /*ARGSUSED*/ 108 kbread(dev, uio) 109 dev_t dev; 110 struct uio *uio; 111 { 112 int error = 0; 113 114 while (uio->uio_resid > 0) 115 if (error = kb_read(uio)) 116 break; 117 return (error); 118 } 119 #endif /* KBDEBUG */ 120 121 /*ARGSUSED*/ 122 kbwrite(dev, uio) 123 dev_t dev; 124 struct uio *uio; 125 { 126 int error = 0; 127 128 while (uio->uio_resid > 0) 129 if (error = kb_write(uio)) 130 break; 131 132 return (error); 133 } 134 135 /*ARGSUSED*/ 136 kbioctl(dev, cmd, data, flag) 137 dev_t dev; 138 caddr_t data; 139 { 140 int error = 0; 141 142 switch (cmd) { 143 144 case KBIOCBELL: 145 error = kb_ctrl(KIOCBELL, (int *)data); 146 break; 147 148 case KBIOCREPT: 149 error = kb_ctrl(KIOCREPT, 0); 150 break; 151 152 case KBIOCNRPT: 153 error = kb_ctrl(KIOCNRPT, 0); 154 break; 155 156 case KBIOCSETLOCK: 157 error = kb_ctrl(KIOCSETLOCK, (int *)data); 158 break; 159 160 case KBIOCSETTBL: 161 error = kbchange((Key_tab_info *)data); 162 break; 163 164 case KBIOCGETCNUM: 165 error = kb_ctrl(KIOCGETCNUM, (int *)data); 166 break; 167 168 case KBIOCSETCNUM: 169 error = kb_ctrl(KIOCSETCNUM, (int *)data); 170 break; 171 172 case KBIOCGETSTAT: 173 error = kb_ctrl(KIOCGETSTAT, (int *)data); 174 break; 175 176 case KBIOCSETSTAT: 177 error = kb_ctrl(KIOCSETSTAT, (int *)data); 178 break; 179 180 default: 181 return (EIO); 182 } 183 return (error); 184 } 185 186 /*ARGSUSED*/ 187 kbselect(dev, flag) 188 dev_t dev; 189 int flag; 190 { 191 192 } 193 194 kbchange(argp) 195 Key_tab_info *argp; 196 { 197 int keynumber; 198 199 keynumber = ((Key_tab_info *)argp)->key_number; 200 if (keynumber < 0 || keynumber > N_KEY) 201 return (EINVAL); 202 203 key_table[keynumber] = argp->key_num_table; 204 return (kb_ctrl(KIOCCHTBL, (Key_table *)key_table)); 205 } 206 207 /* 208 * Machine dependent functions 209 * 210 * kb_probe() 211 * kb_attach() 212 * kb_open() 213 * kb_close() 214 * kb_write() 215 * kb_ctrl() 216 */ 217 218 #ifdef CPU_SINGLE 219 extern int tty00_is_console; 220 extern Key_table *key_table_addr; 221 #define KBPRI (PZERO+1) 222 223 kb_probe(hi) 224 struct hb_device *hi; 225 { 226 227 return (1); 228 } 229 230 kb_attach(hi) 231 struct hb_device *hi; 232 { 233 234 kbd_init(); 235 kbd_ioctl(0, KIOCSETCNUM, &country); 236 } 237 238 kb_open() 239 { 240 241 #ifndef news700 242 if (tty00_is_console) 243 kbm_open(SCC_KEYBOARD); 244 #endif 245 return (0); 246 } 247 248 kb_close() 249 { 250 251 #ifndef news700 252 if (tty00_is_console) 253 kbm_close(SCC_KEYBOARD); 254 #endif 255 return (0); 256 } 257 258 #ifdef KB_DEBUG 259 kb_read(uio) 260 struct uio *uio; 261 { 262 int n; 263 char buf[32]; 264 265 return (uiomove((caddr_t)buf, n, UIO_READ, uio)); 266 n = kbd_read_raw(SCC_KEYBOARD, buf, min(uio->uio_resid, sizeof (buf))); 267 if (n == 0) 268 return (0); 269 return (uiomove((caddr_t)buf, n, UIO_READ, uio)); 270 } 271 #endif /* KB_DEBUG */ 272 273 kb_write(uio) 274 struct uio *uio; 275 { 276 int n, error; 277 char buf[32]; 278 279 n = min(sizeof(buf), uio->uio_resid); 280 if (error = uiomove((caddr_t)buf, n, UIO_WRITE, uio)) 281 return (error); 282 kbd_write(SCC_KEYBOARD, buf, n); 283 return (0); 284 } 285 286 kb_ctrl(func, arg) 287 int func; 288 int *arg; 289 { 290 291 return (kbd_ioctl(0, func, arg)); 292 } 293 #endif /* CPU_SINGLE */ 294 295 #ifdef IPC_MRX 296 #include "../ipc/newsipc.h" 297 #include "../mrx/h/kbms.h" 298 299 #ifdef news1800 300 #define ipc_phys(x) (caddr_t)((int)(x) & ~0x80000000) 301 #endif 302 #ifdef news3800 303 #define ipc_phys(x) (caddr_t)(K0_TT0(x)) 304 #endif 305 306 int port_kboutput, port_kboutput_iop, port_kbctrl, port_kbctrl_iop; 307 308 kb_probe(ii) 309 struct iop_device *ii; 310 { 311 312 port_kboutput_iop = object_query("kbd_output"); 313 port_kbctrl_iop = object_query("kbd_io"); 314 if (port_kboutput_iop <= 0 || port_kbctrl_iop <= 0) 315 return (0); 316 port_kboutput = port_create("@kboutput", NULL, 0); 317 port_kbctrl = port_create("@kbctrl", NULL, 0); 318 return (1); 319 } 320 321 kb_attach(ii) 322 struct iop_device *ii; 323 { 324 325 (void) kb_ctrl(KIOCCHTBL, (Key_table *)key_table); 326 (void) kb_ctrl(KIOCSETCNUM, &country); 327 } 328 329 kb_open() 330 { 331 332 return (0); 333 } 334 335 kb_close() 336 { 337 338 return (0); 339 } 340 341 #ifdef KB_DEBUG 342 kb_read(uio) 343 struct uio *uio; 344 { 345 char *addr; 346 int len; 347 int error; 348 349 len = uio->uio_resid; 350 msg_send(port_kbinput_iop, port_kbinput, &len, sizeof(len), 0); 351 msg_recv(port_kbinput, NULL, &addr, &len, 0); 352 error = uiomove(addr, len, UIO_READ, uio); 353 msg_free(port_kbinput); 354 return (error); 355 } 356 #endif /* KB_DEBUG */ 357 358 kb_write(uio) 359 struct uio *uio; 360 { 361 int len; 362 int error; 363 char buf[MAX_CIO]; 364 365 len = min(MAX_CIO, uio->uio_resid); 366 if (error = uiomove(buf, len, UIO_WRITE, uio)) 367 return (error); 368 msg_send(port_kboutput_iop, port_kboutput, buf, len, 0); 369 msg_recv(port_kboutput, NULL, NULL, NULL, 0); 370 msg_free(port_kboutput); 371 return (0); 372 } 373 374 kb_ctrl(func, arg) 375 int func; 376 int *arg; 377 { 378 struct kb_ctrl_req req; 379 int *reply, result; 380 static int tmp; 381 382 if (func == KIOCCHTBL || func == KIOCOYATBL) 383 req.kb_arg = (int)ipc_phys(arg); 384 else if (arg == NULL) 385 req.kb_arg = (int)&tmp; 386 else 387 req.kb_arg = *arg; 388 req.kb_func = func; 389 msg_send(port_kbctrl_iop, port_kbctrl, &req, sizeof(req), 0); 390 msg_recv(port_kbctrl, NULL, &reply, NULL, 0); 391 result = *reply; 392 msg_free(port_kbctrl); 393 switch (func) { 394 395 case KIOCGETCNUM: 396 case KIOCGETSTAT: 397 if (arg) 398 *(int *)arg = result; 399 } 400 return (0); 401 } 402 #endif /* IPC_MRX */ 403 #endif /* NKB > 0 */ 404