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