153887Smckusick /* 253887Smckusick * Copyright (c) 1992 The Regents of the University of California. 353887Smckusick * All rights reserved. 453887Smckusick * 553887Smckusick * This code is derived from software contributed to Berkeley by 653887Smckusick * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc. 753887Smckusick * 853887Smckusick * %sccs.include.redist.c% 953887Smckusick * 1053887Smckusick * from: $Hdr: kb.c,v 4.300 91/06/09 06:42:44 root Rel41 $ SONY 1153887Smckusick * 12*57183Sutashiro * @(#)kb.c 7.2 (Berkeley) 12/17/92 1353887Smckusick */ 1453887Smckusick 1553887Smckusick #include "kb.h" 1653887Smckusick 1753887Smckusick #if NKB > 0 18*57183Sutashiro #include <machine/fix_machine_type.h> 1953887Smckusick 20*57183Sutashiro #include <sys/param.h> 21*57183Sutashiro #include <sys/proc.h> 22*57183Sutashiro #include <sys/user.h> 23*57183Sutashiro #include <sys/ioctl.h> 24*57183Sutashiro #include <sys/buf.h> 25*57183Sutashiro #include <sys/systm.h> 26*57183Sutashiro #include <sys/map.h> 27*57183Sutashiro #include <sys/uio.h> 28*57183Sutashiro #include <sys/kernel.h> 2953887Smckusick 30*57183Sutashiro #include <news3400/iop/keyboard.h> 31*57183Sutashiro #include <news3400/iop/kbreg.h> 3253887Smckusick 3353887Smckusick #ifdef CPU_SINGLE 34*57183Sutashiro #include <sys/tty.h> 35*57183Sutashiro #include <sys/clist.h> 36*57183Sutashiro #include <news3400/sio/scc.h> 37*57183Sutashiro #include <news3400/hbdev/hbvar.h> 3853887Smckusick #define iop_device hb_device 3953887Smckusick #define ii_alive hi_alive 4053887Smckusick #else 4153887Smckusick #include "../iop/iopvar.h" 4253887Smckusick #endif 4353887Smckusick 4453887Smckusick int kbprobe(), kbattach(); 4553887Smckusick extern Key_table key_table[]; 4653887Smckusick extern Key_table default_table[]; 4753887Smckusick extern int country; 4853887Smckusick 4953887Smckusick #ifdef CPU_SINGLE 5053887Smckusick struct hb_device *kbinfo[NKB]; 5153887Smckusick struct hb_driver kbdriver = 5253887Smckusick { kbprobe, 0, kbattach, 0, 0, "kb", kbinfo, "mc", 0, 0 }; 5353887Smckusick extern Key_table *key_table_addr; 5453887Smckusick #endif 5553887Smckusick 5653887Smckusick #ifdef CPU_DOUBLE 5753887Smckusick struct iop_device *kbinfo[NKB]; 5853887Smckusick struct iop_driver kbdriver = 5953887Smckusick { kbprobe, 0, kbattach, 0, "kb", kbinfo }; 6053887Smckusick #endif 6153887Smckusick 6253887Smckusick char kb_busy; 6353887Smckusick 6453887Smckusick /*ARGSUSED*/ 6553887Smckusick kbprobe(ii) 6653887Smckusick struct iop_device *ii; 6753887Smckusick { 6853887Smckusick 6953887Smckusick return (kb_probe(ii)); 7053887Smckusick } 7153887Smckusick 7253887Smckusick /*ARGSUSED*/ 7353887Smckusick kbattach(ii) 7453887Smckusick struct iop_device *ii; 7553887Smckusick { 7653887Smckusick 7753887Smckusick kb_attach(ii); 7853887Smckusick } 7953887Smckusick 8053887Smckusick /*ARGSUSED*/ 8153887Smckusick kbopen(dev, flag) 8253887Smckusick dev_t dev; 8353887Smckusick int flag; 8453887Smckusick { 8553887Smckusick register int unit; 8653887Smckusick register struct iop_device *ii; 8753887Smckusick 8853887Smckusick if ((unit = minor(dev)) >= NKB || (ii = kbinfo[unit]) == 0 || 8953887Smckusick ii->ii_alive == 0) 9053887Smckusick return (ENXIO); 9153887Smckusick if (kb_busy) 9253887Smckusick return (EBUSY); 9353887Smckusick kb_busy = 1; 9453887Smckusick return (kb_open()); 9553887Smckusick } 9653887Smckusick 9753887Smckusick /*ARGSUSED*/ 9853887Smckusick kbclose(dev, flag) 9953887Smckusick dev_t dev; 10053887Smckusick int flag; 10153887Smckusick { 10253887Smckusick kb_close(); 10353887Smckusick kb_busy = 0; 10453887Smckusick } 10553887Smckusick 10653887Smckusick #ifdef KBDEBUG 10753887Smckusick /*ARGSUSED*/ 10853887Smckusick kbread(dev, uio) 10953887Smckusick dev_t dev; 11053887Smckusick struct uio *uio; 11153887Smckusick { 11253887Smckusick int error = 0; 11353887Smckusick 11453887Smckusick while (uio->uio_resid > 0) 11553887Smckusick if (error = kb_read(uio)) 11653887Smckusick break; 11753887Smckusick return (error); 11853887Smckusick } 11953887Smckusick #endif /* KBDEBUG */ 12053887Smckusick 12153887Smckusick /*ARGSUSED*/ 12253887Smckusick kbwrite(dev, uio) 12353887Smckusick dev_t dev; 12453887Smckusick struct uio *uio; 12553887Smckusick { 12653887Smckusick int error = 0; 12753887Smckusick 12853887Smckusick while (uio->uio_resid > 0) 12953887Smckusick if (error = kb_write(uio)) 13053887Smckusick break; 13153887Smckusick 13253887Smckusick return (error); 13353887Smckusick } 13453887Smckusick 13553887Smckusick /*ARGSUSED*/ 13653887Smckusick kbioctl(dev, cmd, data, flag) 13753887Smckusick dev_t dev; 13853887Smckusick caddr_t data; 13953887Smckusick { 14053887Smckusick int error = 0; 14153887Smckusick 14253887Smckusick switch (cmd) { 14353887Smckusick 14453887Smckusick case KBIOCBELL: 14553887Smckusick error = kb_ctrl(KIOCBELL, (int *)data); 14653887Smckusick break; 14753887Smckusick 14853887Smckusick case KBIOCREPT: 14953887Smckusick error = kb_ctrl(KIOCREPT, 0); 15053887Smckusick break; 15153887Smckusick 15253887Smckusick case KBIOCNRPT: 15353887Smckusick error = kb_ctrl(KIOCNRPT, 0); 15453887Smckusick break; 15553887Smckusick 15653887Smckusick case KBIOCSETLOCK: 15753887Smckusick error = kb_ctrl(KIOCSETLOCK, (int *)data); 15853887Smckusick break; 15953887Smckusick 16053887Smckusick case KBIOCSETTBL: 16153887Smckusick error = kbchange((Key_tab_info *)data); 16253887Smckusick break; 16353887Smckusick 16453887Smckusick case KBIOCGETCNUM: 16553887Smckusick error = kb_ctrl(KIOCGETCNUM, (int *)data); 16653887Smckusick break; 16753887Smckusick 16853887Smckusick case KBIOCSETCNUM: 16953887Smckusick error = kb_ctrl(KIOCSETCNUM, (int *)data); 17053887Smckusick break; 17153887Smckusick 17253887Smckusick case KBIOCGETSTAT: 17353887Smckusick error = kb_ctrl(KIOCGETSTAT, (int *)data); 17453887Smckusick break; 17553887Smckusick 17653887Smckusick case KBIOCSETSTAT: 17753887Smckusick error = kb_ctrl(KIOCSETSTAT, (int *)data); 17853887Smckusick break; 17953887Smckusick 18053887Smckusick default: 18153887Smckusick return (EIO); 18253887Smckusick } 18353887Smckusick return (error); 18453887Smckusick } 18553887Smckusick 18653887Smckusick /*ARGSUSED*/ 18753887Smckusick kbselect(dev, flag) 18853887Smckusick dev_t dev; 18953887Smckusick int flag; 19053887Smckusick { 19153887Smckusick 19253887Smckusick } 19353887Smckusick 19453887Smckusick kbchange(argp) 19553887Smckusick Key_tab_info *argp; 19653887Smckusick { 19753887Smckusick int keynumber; 19853887Smckusick 19953887Smckusick keynumber = ((Key_tab_info *)argp)->key_number; 20053887Smckusick if (keynumber < 0 || keynumber > N_KEY) 20153887Smckusick return (EINVAL); 20253887Smckusick 20353887Smckusick key_table[keynumber] = argp->key_num_table; 20453887Smckusick return (kb_ctrl(KIOCCHTBL, (Key_table *)key_table)); 20553887Smckusick } 20653887Smckusick 20753887Smckusick /* 20853887Smckusick * Machine dependent functions 20953887Smckusick * 21053887Smckusick * kb_probe() 21153887Smckusick * kb_attach() 21253887Smckusick * kb_open() 21353887Smckusick * kb_close() 21453887Smckusick * kb_write() 21553887Smckusick * kb_ctrl() 21653887Smckusick */ 21753887Smckusick 21853887Smckusick #ifdef CPU_SINGLE 21953887Smckusick extern int tty00_is_console; 22053887Smckusick extern Key_table *key_table_addr; 22153887Smckusick #define KBPRI (PZERO+1) 22253887Smckusick 22353887Smckusick kb_probe(hi) 22453887Smckusick struct hb_device *hi; 22553887Smckusick { 22653887Smckusick 22753887Smckusick return (1); 22853887Smckusick } 22953887Smckusick 23053887Smckusick kb_attach(hi) 23153887Smckusick struct hb_device *hi; 23253887Smckusick { 23353887Smckusick 23453887Smckusick kbd_init(); 23553887Smckusick kbd_ioctl(0, KIOCSETCNUM, &country); 23653887Smckusick } 23753887Smckusick 23853887Smckusick kb_open() 23953887Smckusick { 24053887Smckusick 24153887Smckusick #ifndef news700 24253887Smckusick if (tty00_is_console) 24353887Smckusick kbm_open(SCC_KEYBOARD); 24453887Smckusick #endif 24553887Smckusick return (0); 24653887Smckusick } 24753887Smckusick 24853887Smckusick kb_close() 24953887Smckusick { 25053887Smckusick 25153887Smckusick #ifndef news700 25253887Smckusick if (tty00_is_console) 25353887Smckusick kbm_close(SCC_KEYBOARD); 25453887Smckusick #endif 25553887Smckusick return (0); 25653887Smckusick } 25753887Smckusick 25853887Smckusick #ifdef KB_DEBUG 25953887Smckusick kb_read(uio) 26053887Smckusick struct uio *uio; 26153887Smckusick { 26253887Smckusick int n; 26353887Smckusick char buf[32]; 26453887Smckusick 26553887Smckusick return (uiomove((caddr_t)buf, n, UIO_READ, uio)); 26653887Smckusick n = kbd_read_raw(SCC_KEYBOARD, buf, min(uio->uio_resid, sizeof (buf))); 26753887Smckusick if (n == 0) 26853887Smckusick return (0); 26953887Smckusick return (uiomove((caddr_t)buf, n, UIO_READ, uio)); 27053887Smckusick } 27153887Smckusick #endif /* KB_DEBUG */ 27253887Smckusick 27353887Smckusick kb_write(uio) 27453887Smckusick struct uio *uio; 27553887Smckusick { 27653887Smckusick int n, error; 27753887Smckusick char buf[32]; 27853887Smckusick 27953887Smckusick n = min(sizeof(buf), uio->uio_resid); 28053887Smckusick if (error = uiomove((caddr_t)buf, n, UIO_WRITE, uio)) 28153887Smckusick return (error); 28253887Smckusick kbd_write(SCC_KEYBOARD, buf, n); 28353887Smckusick return (0); 28453887Smckusick } 28553887Smckusick 28653887Smckusick kb_ctrl(func, arg) 28753887Smckusick int func; 28853887Smckusick int *arg; 28953887Smckusick { 29053887Smckusick 29153887Smckusick return (kbd_ioctl(0, func, arg)); 29253887Smckusick } 29353887Smckusick #endif /* CPU_SINGLE */ 29453887Smckusick 29553887Smckusick #ifdef IPC_MRX 29653887Smckusick #include "../ipc/newsipc.h" 29753887Smckusick #include "../mrx/h/kbms.h" 29853887Smckusick 29953887Smckusick #ifdef news1800 30053887Smckusick #define ipc_phys(x) (caddr_t)((int)(x) & ~0x80000000) 30153887Smckusick #endif 30253887Smckusick #ifdef news3800 30353887Smckusick #define ipc_phys(x) (caddr_t)(K0_TT0(x)) 30453887Smckusick #endif 30553887Smckusick 30653887Smckusick int port_kboutput, port_kboutput_iop, port_kbctrl, port_kbctrl_iop; 30753887Smckusick 30853887Smckusick kb_probe(ii) 30953887Smckusick struct iop_device *ii; 31053887Smckusick { 31153887Smckusick 31253887Smckusick port_kboutput_iop = object_query("kbd_output"); 31353887Smckusick port_kbctrl_iop = object_query("kbd_io"); 31453887Smckusick if (port_kboutput_iop <= 0 || port_kbctrl_iop <= 0) 31553887Smckusick return (0); 31653887Smckusick port_kboutput = port_create("@kboutput", NULL, 0); 31753887Smckusick port_kbctrl = port_create("@kbctrl", NULL, 0); 31853887Smckusick return (1); 31953887Smckusick } 32053887Smckusick 32153887Smckusick kb_attach(ii) 32253887Smckusick struct iop_device *ii; 32353887Smckusick { 32453887Smckusick 32553887Smckusick (void) kb_ctrl(KIOCCHTBL, (Key_table *)key_table); 32653887Smckusick (void) kb_ctrl(KIOCSETCNUM, &country); 32753887Smckusick } 32853887Smckusick 32953887Smckusick kb_open() 33053887Smckusick { 33153887Smckusick 33253887Smckusick return (0); 33353887Smckusick } 33453887Smckusick 33553887Smckusick kb_close() 33653887Smckusick { 33753887Smckusick 33853887Smckusick return (0); 33953887Smckusick } 34053887Smckusick 34153887Smckusick #ifdef KB_DEBUG 34253887Smckusick kb_read(uio) 34353887Smckusick struct uio *uio; 34453887Smckusick { 34553887Smckusick char *addr; 34653887Smckusick int len; 34753887Smckusick int error; 34853887Smckusick 34953887Smckusick len = uio->uio_resid; 35053887Smckusick msg_send(port_kbinput_iop, port_kbinput, &len, sizeof(len), 0); 35153887Smckusick msg_recv(port_kbinput, NULL, &addr, &len, 0); 35253887Smckusick error = uiomove(addr, len, UIO_READ, uio); 35353887Smckusick msg_free(port_kbinput); 35453887Smckusick return (error); 35553887Smckusick } 35653887Smckusick #endif /* KB_DEBUG */ 35753887Smckusick 35853887Smckusick kb_write(uio) 35953887Smckusick struct uio *uio; 36053887Smckusick { 36153887Smckusick int len; 36253887Smckusick int error; 36353887Smckusick char buf[MAX_CIO]; 36453887Smckusick 36553887Smckusick len = min(MAX_CIO, uio->uio_resid); 36653887Smckusick if (error = uiomove(buf, len, UIO_WRITE, uio)) 36753887Smckusick return (error); 36853887Smckusick msg_send(port_kboutput_iop, port_kboutput, buf, len, 0); 36953887Smckusick msg_recv(port_kboutput, NULL, NULL, NULL, 0); 37053887Smckusick msg_free(port_kboutput); 37153887Smckusick return (0); 37253887Smckusick } 37353887Smckusick 37453887Smckusick kb_ctrl(func, arg) 37553887Smckusick int func; 37653887Smckusick int *arg; 37753887Smckusick { 37853887Smckusick struct kb_ctrl_req req; 37953887Smckusick int *reply, result; 38053887Smckusick static int tmp; 38153887Smckusick 38253887Smckusick if (func == KIOCCHTBL || func == KIOCOYATBL) 38353887Smckusick req.kb_arg = (int)ipc_phys(arg); 38453887Smckusick else if (arg == NULL) 38553887Smckusick req.kb_arg = (int)&tmp; 38653887Smckusick else 38753887Smckusick req.kb_arg = *arg; 38853887Smckusick req.kb_func = func; 38953887Smckusick msg_send(port_kbctrl_iop, port_kbctrl, &req, sizeof(req), 0); 39053887Smckusick msg_recv(port_kbctrl, NULL, &reply, NULL, 0); 39153887Smckusick result = *reply; 39253887Smckusick msg_free(port_kbctrl); 39353887Smckusick switch (func) { 39453887Smckusick 39553887Smckusick case KIOCGETCNUM: 39653887Smckusick case KIOCGETSTAT: 39753887Smckusick if (arg) 39853887Smckusick *(int *)arg = result; 39953887Smckusick } 40053887Smckusick return (0); 40153887Smckusick } 40253887Smckusick #endif /* IPC_MRX */ 40353887Smckusick #endif /* NKB > 0 */ 404