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