141480Smckusick /* 241480Smckusick * Copyright (c) 1988 University of Utah. 341480Smckusick * Copyright (c) 1990 The Regents of the University of California. 441480Smckusick * All rights reserved. 541480Smckusick * 641480Smckusick * This code is derived from software contributed to Berkeley by 741480Smckusick * the Systems Programming Group of the University of Utah Computer 841480Smckusick * Science Department. 941480Smckusick * 1041480Smckusick * %sccs.include.redist.c% 1141480Smckusick * 1253923Shibler * from: Utah $Hdr: hil.c 1.38 92/01/21$ 1341480Smckusick * 14*55070Spendry * @(#)hil.c 7.13 (Berkeley) 07/12/92 1541480Smckusick */ 1641480Smckusick 1745788Sbostic #include "sys/param.h" 1845788Sbostic #include "sys/conf.h" 1949132Skarels #include "sys/proc.h" 2045788Sbostic #include "sys/user.h" 2145788Sbostic #include "sys/ioctl.h" 2245788Sbostic #include "sys/file.h" 2345788Sbostic #include "sys/tty.h" 2445788Sbostic #include "sys/systm.h" 2545788Sbostic #include "sys/uio.h" 2645788Sbostic #include "sys/kernel.h" 2741480Smckusick 2841480Smckusick #include "hilreg.h" 2941480Smckusick #include "hilioctl.h" 3041480Smckusick #include "hilvar.h" 3141480Smckusick #include "kbdmap.h" 3241480Smckusick 3349132Skarels #include "machine/cpu.h" 3441480Smckusick 3545788Sbostic #include "vm/vm_param.h" 3645788Sbostic #include "vm/vm_map.h" 3745788Sbostic #include "vm/vm_kern.h" 3845788Sbostic #include "vm/vm_page.h" 3945788Sbostic #include "vm/vm_pager.h" 4045750Smckusick 4153923Shibler #ifdef hp300 4253923Shibler #define NHIL 1 /* XXX */ 4353923Shibler #else 4453923Shibler #include "hil.h" 4553923Shibler #endif 4653923Shibler 4753923Shibler struct hilloop hilloop[NHIL]; 4841480Smckusick struct _hilbell default_bell = { BELLDUR, BELLFREQ }; 4953923Shibler #ifdef hp800 5053923Shibler int hilspl; 5153923Shibler #endif 5241480Smckusick 5341480Smckusick #ifdef DEBUG 5441480Smckusick int hildebug = 0; 5541480Smckusick #define HDB_FOLLOW 0x01 5641480Smckusick #define HDB_MMAP 0x02 5741480Smckusick #define HDB_MASK 0x04 5841480Smckusick #define HDB_CONFIG 0x08 5941480Smckusick #define HDB_KEYBOARD 0x10 6041480Smckusick #define HDB_IDMODULE 0x20 6141480Smckusick #define HDB_EVENTS 0x80 6241480Smckusick #endif 6341480Smckusick 6442360Smckusick /* symbolic sleep message strings */ 6542360Smckusick char hilin[] = "hilin"; 6642360Smckusick 6753923Shibler hilsoftinit(unit, hilbase) 6853923Shibler int unit; 6953923Shibler struct hil_dev *hilbase; 7041480Smckusick { 7153923Shibler register struct hilloop *hilp = &hilloop[unit]; 7241480Smckusick register int i; 7341480Smckusick 7453923Shibler #ifdef DEBUG 7553923Shibler if (hildebug & HDB_FOLLOW) 7653923Shibler printf("hilsoftinit(%d, %x)\n", unit, hilbase); 7753923Shibler #endif 7841480Smckusick /* 7941480Smckusick * Initialize loop information 8041480Smckusick */ 8153923Shibler hilp->hl_addr = hilbase; 8241480Smckusick hilp->hl_cmdending = FALSE; 8341480Smckusick hilp->hl_actdev = hilp->hl_cmddev = 0; 8441480Smckusick hilp->hl_cmddone = FALSE; 8541480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 8641480Smckusick hilp->hl_pollbp = hilp->hl_pollbuf; 8741480Smckusick hilp->hl_kbddev = 0; 8841480Smckusick hilp->hl_kbdlang = KBD_DEFAULT; 8941480Smckusick hilp->hl_kbdflags = 0; 9041480Smckusick /* 9141480Smckusick * Clear all queues and device associations with queues 9241480Smckusick */ 9341480Smckusick for (i = 0; i < NHILQ; i++) { 9441480Smckusick hilp->hl_queue[i].hq_eventqueue = NULL; 9541480Smckusick hilp->hl_queue[i].hq_procp = NULL; 9641480Smckusick hilp->hl_queue[i].hq_devmask = 0; 9741480Smckusick } 9841480Smckusick for (i = 0; i < NHILD; i++) 9941480Smckusick hilp->hl_device[i].hd_qmask = 0; 10041480Smckusick hilp->hl_device[HILLOOPDEV].hd_flags = (HIL_ALIVE|HIL_PSEUDO); 10153923Shibler } 10253923Shibler 10353923Shibler hilinit(unit, hilbase) 10453923Shibler int unit; 10553923Shibler struct hil_dev *hilbase; 10653923Shibler { 10753923Shibler register struct hilloop *hilp = &hilloop[unit]; 10853923Shibler #ifdef DEBUG 10953923Shibler if (hildebug & HDB_FOLLOW) 11053923Shibler printf("hilinit(%d, %x)\n", unit, hilbase); 11153923Shibler #endif 11241480Smckusick /* 11353923Shibler * Initialize software (if not already done). 11453923Shibler */ 11553923Shibler if ((hilp->hl_device[HILLOOPDEV].hd_flags & HIL_ALIVE) == 0) 11653923Shibler hilsoftinit(unit, hilbase); 11753923Shibler /* 11853923Shibler * Initialize hardware. 11941480Smckusick * Reset the loop hardware, and collect keyboard/id info 12041480Smckusick */ 12141480Smckusick hilreset(hilp); 12253923Shibler hilinfo(unit); 12353923Shibler kbdenable(unit); 12441480Smckusick } 12541480Smckusick 12649132Skarels /* ARGSUSED */ 12749132Skarels hilopen(dev, flags, mode, p) 12841480Smckusick dev_t dev; 12949132Skarels int flags, mode; 13049132Skarels struct proc *p; 13141480Smckusick { 13253923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 13341480Smckusick register struct hilloopdev *dptr; 13441480Smckusick u_char device = HILUNIT(dev); 13541480Smckusick 13641480Smckusick #ifdef DEBUG 13741480Smckusick if (hildebug & HDB_FOLLOW) 13853923Shibler printf("hilopen(%d): loop %x device %x\n", 13953923Shibler p->p_pid, HILLOOP(dev), device); 14041480Smckusick #endif 14141480Smckusick 14241480Smckusick if ((hilp->hl_device[HILLOOPDEV].hd_flags & HIL_ALIVE) == 0) 14341480Smckusick return(ENXIO); 14441480Smckusick 14541480Smckusick dptr = &hilp->hl_device[device]; 14641480Smckusick if ((dptr->hd_flags & HIL_ALIVE) == 0) 14741480Smckusick return(ENODEV); 14841480Smckusick 14941480Smckusick /* 15041480Smckusick * Pseudo-devices cannot be read, nothing more to do. 15141480Smckusick */ 15241480Smckusick if (dptr->hd_flags & HIL_PSEUDO) 15341480Smckusick return(0); 15441480Smckusick 15541480Smckusick /* 15641480Smckusick * Open semantics: 15741480Smckusick * 1. Open devices have only one of HIL_READIN/HIL_QUEUEIN. 15841480Smckusick * 2. HPUX processes always get read syscall interface and 15941480Smckusick * must have exclusive use of the device. 16041480Smckusick * 3. BSD processes default to shared queue interface. 16141480Smckusick * Multiple processes can open the device. 16241480Smckusick */ 16343316Smckusick if (p->p_flag & SHPUX) { 16441480Smckusick if (dptr->hd_flags & (HIL_READIN|HIL_QUEUEIN)) 16541480Smckusick return(EBUSY); 16641480Smckusick dptr->hd_flags |= HIL_READIN; 16741480Smckusick } else { 16841480Smckusick if (dptr->hd_flags & HIL_READIN) 16941480Smckusick return(EBUSY); 17041480Smckusick dptr->hd_flags |= HIL_QUEUEIN; 17141480Smckusick } 17249947Smckusick if (flags & FNONBLOCK) 17341480Smckusick dptr->hd_flags |= HIL_NOBLOCK; 17441480Smckusick /* 17541480Smckusick * It is safe to flush the read buffer as we are guarenteed 17641480Smckusick * that no one else is using it. 17741480Smckusick */ 17841480Smckusick ndflush(&dptr->hd_queue, dptr->hd_queue.c_cc); 17941480Smckusick 18041480Smckusick send_hil_cmd(hilp->hl_addr, HIL_INTON, NULL, 0, NULL); 18141480Smckusick /* 18241480Smckusick * Opened the keyboard, put in raw mode. 18341480Smckusick */ 18441480Smckusick (void) splhil(); 18541480Smckusick if (device == hilp->hl_kbddev) { 18641480Smckusick u_char mask = 0; 18741480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &mask, 1, NULL); 18841480Smckusick hilp->hl_kbdflags |= KBD_RAW; 18941480Smckusick #ifdef DEBUG 19041480Smckusick if (hildebug & HDB_KEYBOARD) 19141480Smckusick printf("hilopen: keyboard %d raw\n", hilp->hl_kbddev); 19241480Smckusick #endif 19341480Smckusick } 19441480Smckusick (void) spl0(); 19541480Smckusick return (0); 19641480Smckusick } 19741480Smckusick 19841480Smckusick /* ARGSUSED */ 19952532Skarels hilclose(dev, flags, mode, p) 20041480Smckusick dev_t dev; 20152532Skarels struct proc *p; 20241480Smckusick { 20353923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 20441480Smckusick register struct hilloopdev *dptr; 20541480Smckusick register int i; 20641480Smckusick u_char device = HILUNIT(dev); 20741480Smckusick char mask, lpctrl; 20841480Smckusick 20941480Smckusick #ifdef DEBUG 21041480Smckusick if (hildebug & HDB_FOLLOW) 21143316Smckusick printf("hilclose(%d): device %x\n", p->p_pid, device); 21241480Smckusick #endif 21341480Smckusick 21441480Smckusick dptr = &hilp->hl_device[device]; 21541480Smckusick if (device && (dptr->hd_flags & HIL_PSEUDO)) 21641480Smckusick return (0); 21741480Smckusick 21852532Skarels if (p && (p->p_flag & SHPUX) == 0) { 21941480Smckusick /* 22041480Smckusick * If this is the loop device, 22141480Smckusick * free up all queues belonging to this process. 22241480Smckusick */ 22341480Smckusick if (device == 0) { 22441480Smckusick for (i = 0; i < NHILQ; i++) 22543316Smckusick if (hilp->hl_queue[i].hq_procp == p) 22653923Shibler (void) hilqfree(hilp, i); 22741480Smckusick } else { 22841480Smckusick mask = ~hildevmask(device); 22941480Smckusick (void) splhil(); 23041480Smckusick for (i = 0; i < NHILQ; i++) 23143316Smckusick if (hilp->hl_queue[i].hq_procp == p) { 23241480Smckusick dptr->hd_qmask &= ~hilqmask(i); 23341480Smckusick hilp->hl_queue[i].hq_devmask &= mask; 23441480Smckusick } 23541480Smckusick (void) spl0(); 23641480Smckusick } 23741480Smckusick } 23841480Smckusick /* 23941480Smckusick * Always flush the read buffer 24041480Smckusick */ 24141480Smckusick dptr->hd_flags &= ~(HIL_QUEUEIN|HIL_READIN|HIL_NOBLOCK); 24241480Smckusick ndflush(&dptr->hd_queue, dptr->hd_queue.c_cc); 24341480Smckusick /* 24441480Smckusick * Set keyboard back to cooked mode when closed. 24541480Smckusick */ 24641480Smckusick (void) splhil(); 24741480Smckusick if (device && device == hilp->hl_kbddev) { 24841480Smckusick mask = 1 << (hilp->hl_kbddev - 1); 24941480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &mask, 1, NULL); 25041480Smckusick hilp->hl_kbdflags &= ~(KBD_RAW|KBD_AR1|KBD_AR2); 25141480Smckusick /* 25241480Smckusick * XXX: We have had trouble with keyboards remaining raw 25341480Smckusick * after close due to the LPC_KBDCOOK bit getting cleared 25441480Smckusick * somewhere along the line. Hence we check and reset 25541480Smckusick * LPCTRL if necessary. 25641480Smckusick */ 25741480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &lpctrl); 25841480Smckusick if ((lpctrl & LPC_KBDCOOK) == 0) { 25941480Smckusick printf("hilclose: bad LPCTRL %x, reset to %x\n", 26041480Smckusick lpctrl, lpctrl|LPC_KBDCOOK); 26141480Smckusick lpctrl |= LPC_KBDCOOK; 26241480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITELPCTRL, 26341480Smckusick &lpctrl, 1, NULL); 26441480Smckusick } 26541480Smckusick #ifdef DEBUG 26641480Smckusick if (hildebug & HDB_KEYBOARD) 26741480Smckusick printf("hilclose: keyboard %d cooked\n", 26841480Smckusick hilp->hl_kbddev); 26941480Smckusick #endif 27053923Shibler kbdenable(HILLOOP(dev)); 27141480Smckusick } 27241480Smckusick (void) spl0(); 27341480Smckusick return (0); 27441480Smckusick } 27541480Smckusick 27641480Smckusick /* 27741480Smckusick * Read interface to HIL device. 27841480Smckusick */ 27941480Smckusick hilread(dev, uio) 28041480Smckusick dev_t dev; 28141480Smckusick register struct uio *uio; 28241480Smckusick { 28353923Shibler struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 28441480Smckusick register struct hilloopdev *dptr; 28541480Smckusick register int cc; 28641480Smckusick u_char device = HILUNIT(dev); 28741480Smckusick char buf[HILBUFSIZE]; 28841480Smckusick int error; 28941480Smckusick 29041480Smckusick #if 0 29141480Smckusick /* 29241480Smckusick * XXX: Don't do this since HP-UX doesn't. 29341480Smckusick * 29441480Smckusick * Check device number. 29541480Smckusick * This check is necessary since loop can reconfigure. 29641480Smckusick */ 29741480Smckusick if (device > hilp->hl_maxdev) 29841480Smckusick return(ENODEV); 29941480Smckusick #endif 30041480Smckusick 30141480Smckusick dptr = &hilp->hl_device[device]; 30241480Smckusick if ((dptr->hd_flags & HIL_READIN) == 0) 30341480Smckusick return(ENODEV); 30441480Smckusick 30541480Smckusick (void) splhil(); 30641480Smckusick while (dptr->hd_queue.c_cc == 0) { 30741480Smckusick if (dptr->hd_flags & HIL_NOBLOCK) { 30841480Smckusick spl0(); 30941480Smckusick return(EWOULDBLOCK); 31041480Smckusick } 31141480Smckusick dptr->hd_flags |= HIL_ASLEEP; 31242360Smckusick if (error = tsleep((caddr_t)dptr, TTIPRI | PCATCH, hilin, 0)) { 31342360Smckusick (void) spl0(); 31442360Smckusick return (error); 31542360Smckusick } 31641480Smckusick } 31741480Smckusick (void) spl0(); 31841480Smckusick 31941480Smckusick error = 0; 32041480Smckusick while (uio->uio_resid > 0 && error == 0) { 32141480Smckusick cc = hilq_to_b(&dptr->hd_queue, buf, 322*55070Spendry min(uio->uio_resid, HILBUFSIZE)); 32341480Smckusick if (cc <= 0) 32441480Smckusick break; 32541480Smckusick error = uiomove(buf, cc, uio); 32641480Smckusick } 32741480Smckusick return(error); 32841480Smckusick } 32941480Smckusick 33049132Skarels hilioctl(dev, cmd, data, flag, p) 33141480Smckusick dev_t dev; 33241480Smckusick caddr_t data; 33349132Skarels struct proc *p; 33441480Smckusick { 33553923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 33641480Smckusick char device = HILUNIT(dev); 33741480Smckusick struct hilloopdev *dptr; 33841480Smckusick register int i; 33941480Smckusick u_char hold; 34041480Smckusick int error; 34141480Smckusick 34241480Smckusick #ifdef DEBUG 34341480Smckusick if (hildebug & HDB_FOLLOW) 34441480Smckusick printf("hilioctl(%d): dev %x cmd %x\n", 34543316Smckusick p->p_pid, device, cmd); 34641480Smckusick #endif 34741480Smckusick 34841480Smckusick dptr = &hilp->hl_device[device]; 34941480Smckusick if ((dptr->hd_flags & HIL_ALIVE) == 0) 35041480Smckusick return (ENODEV); 35141480Smckusick 35241480Smckusick /* 35341480Smckusick * Don't allow hardware ioctls on virtual devices. 35441480Smckusick * Note that though these are the BSD names, they have the same 35541480Smckusick * values as the HP-UX equivalents so we catch them as well. 35641480Smckusick */ 35741480Smckusick if (dptr->hd_flags & HIL_PSEUDO) { 35841480Smckusick switch (cmd) { 35941480Smckusick case HILIOCSC: 36041480Smckusick case HILIOCID: 36153923Shibler case OHILIOCID: 36241480Smckusick case HILIOCRN: 36341480Smckusick case HILIOCRS: 36441480Smckusick case HILIOCED: 36541480Smckusick return(ENODEV); 36641480Smckusick 36741480Smckusick /* 36841480Smckusick * XXX: should also return ENODEV but HP-UX compat 36941480Smckusick * breaks if we do. They work ok right now because 37041480Smckusick * we only recognize one keyboard on the loop. This 37141480Smckusick * will have to change if we remove that restriction. 37241480Smckusick */ 37341480Smckusick case HILIOCAROFF: 37441480Smckusick case HILIOCAR1: 37541480Smckusick case HILIOCAR2: 37641480Smckusick break; 37741480Smckusick 37841480Smckusick default: 37941480Smckusick break; 38041480Smckusick } 38141480Smckusick } 38241480Smckusick 38341480Smckusick #ifdef HPUXCOMPAT 38443316Smckusick if (p->p_flag & SHPUX) 38541480Smckusick return(hpuxhilioctl(dev, cmd, data, flag)); 38641480Smckusick #endif 38741480Smckusick 38841480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 38941480Smckusick bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE); 39041480Smckusick hilp->hl_cmddev = device; 39141480Smckusick error = 0; 39241480Smckusick switch (cmd) { 39341480Smckusick 39441480Smckusick case HILIOCSBP: 39541480Smckusick /* Send four data bytes to the tone gererator. */ 39641480Smckusick send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 39741480Smckusick /* Send the trigger beeper command to the 8042. */ 39841480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 39941480Smckusick break; 40041480Smckusick 40141480Smckusick case HILIOCRRT: 40241480Smckusick /* Transfer the real time to the 8042 data buffer */ 40341480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 40441480Smckusick /* Read each byte of the real time */ 40541480Smckusick for (i = 0; i < 5; i++) { 40641480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 40741480Smckusick 0, &hold); 40841480Smckusick data[4-i] = hold; 40941480Smckusick } 41041480Smckusick break; 41141480Smckusick 41241480Smckusick case HILIOCRT: 41341480Smckusick for (i = 0; i < 4; i++) { 41441480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 41541480Smckusick NULL, 0, &hold); 41641480Smckusick data[i] = hold; 41741480Smckusick } 41841480Smckusick break; 41941480Smckusick 42041480Smckusick case HILIOCID: 42153923Shibler case OHILIOCID: 42241480Smckusick case HILIOCSC: 42341480Smckusick case HILIOCRN: 42441480Smckusick case HILIOCRS: 42541480Smckusick case HILIOCED: 42641480Smckusick send_hildev_cmd(hilp, device, (cmd & 0xFF)); 42741480Smckusick bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 42841480Smckusick break; 42941480Smckusick 43041480Smckusick case HILIOCAROFF: 43141480Smckusick case HILIOCAR1: 43241480Smckusick case HILIOCAR2: 43341480Smckusick if (hilp->hl_kbddev) { 43441480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 43541480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 43641480Smckusick hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 43741480Smckusick if (cmd == HILIOCAR1) 43841480Smckusick hilp->hl_kbdflags |= KBD_AR1; 43941480Smckusick else if (cmd == HILIOCAR2) 44041480Smckusick hilp->hl_kbdflags |= KBD_AR2; 44141480Smckusick } 44241480Smckusick break; 44341480Smckusick 44441480Smckusick case HILIOCBEEP: 44541480Smckusick hilbeep(hilp, (struct _hilbell *)data); 44641480Smckusick break; 44741480Smckusick 44841480Smckusick case FIONBIO: 44941480Smckusick dptr = &hilp->hl_device[device]; 45041480Smckusick if (*(int *)data) 45141480Smckusick dptr->hd_flags |= HIL_NOBLOCK; 45241480Smckusick else 45341480Smckusick dptr->hd_flags &= ~HIL_NOBLOCK; 45441480Smckusick break; 45541480Smckusick 45641480Smckusick /* 45741480Smckusick * FIOASYNC must be present for FIONBIO above to work! 45841480Smckusick * (See fcntl in kern_descrip.c). 45941480Smckusick */ 46041480Smckusick case FIOASYNC: 46141480Smckusick break; 46241480Smckusick 46341480Smckusick case HILIOCALLOCQ: 46453923Shibler error = hilqalloc(hilp, (struct hilqinfo *)data); 46541480Smckusick break; 46641480Smckusick 46741480Smckusick case HILIOCFREEQ: 46853923Shibler error = hilqfree(hilp, ((struct hilqinfo *)data)->qid); 46941480Smckusick break; 47041480Smckusick 47141480Smckusick case HILIOCMAPQ: 47253923Shibler error = hilqmap(hilp, *(int *)data, device); 47341480Smckusick break; 47441480Smckusick 47541480Smckusick case HILIOCUNMAPQ: 47653923Shibler error = hilqunmap(hilp, *(int *)data, device); 47741480Smckusick break; 47841480Smckusick 47941480Smckusick case HILIOCHPUX: 48041480Smckusick dptr = &hilp->hl_device[device]; 48141480Smckusick dptr->hd_flags |= HIL_READIN; 48241480Smckusick dptr->hd_flags &= ~HIL_QUEUEIN; 48341480Smckusick break; 48441480Smckusick 48541480Smckusick case HILIOCRESET: 48641480Smckusick hilreset(hilp); 48741480Smckusick break; 48841480Smckusick 48941480Smckusick #ifdef DEBUG 49041480Smckusick case HILIOCTEST: 49141480Smckusick hildebug = *(int *) data; 49241480Smckusick break; 49341480Smckusick #endif 49441480Smckusick 49541480Smckusick default: 49641480Smckusick error = EINVAL; 49741480Smckusick break; 49841480Smckusick 49941480Smckusick } 50041480Smckusick hilp->hl_cmddev = 0; 50141480Smckusick return(error); 50241480Smckusick } 50341480Smckusick 50441480Smckusick #ifdef HPUXCOMPAT 50541480Smckusick /* ARGSUSED */ 50641480Smckusick hpuxhilioctl(dev, cmd, data, flag) 50741480Smckusick dev_t dev; 50841480Smckusick caddr_t data; 50941480Smckusick { 51053923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 51141480Smckusick char device = HILUNIT(dev); 51241480Smckusick struct hilloopdev *dptr; 51341480Smckusick register int i; 51441480Smckusick u_char hold; 51541480Smckusick 51641480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 51741480Smckusick bzero((caddr_t)hilp->hl_cmdbuf, HILBUFSIZE); 51841480Smckusick hilp->hl_cmddev = device; 51941480Smckusick switch (cmd) { 52041480Smckusick 52141480Smckusick case HILSC: 52241480Smckusick case HILID: 52341480Smckusick case HILRN: 52441480Smckusick case HILRS: 52541480Smckusick case HILED: 52641480Smckusick case HILP1: 52741480Smckusick case HILP2: 52841480Smckusick case HILP3: 52941480Smckusick case HILP4: 53041480Smckusick case HILP5: 53141480Smckusick case HILP6: 53241480Smckusick case HILP7: 53341480Smckusick case HILP: 53441480Smckusick case HILA1: 53541480Smckusick case HILA2: 53641480Smckusick case HILA3: 53741480Smckusick case HILA4: 53841480Smckusick case HILA5: 53941480Smckusick case HILA6: 54041480Smckusick case HILA7: 54141480Smckusick case HILA: 54241480Smckusick send_hildev_cmd(hilp, device, (cmd & 0xFF)); 54341480Smckusick bcopy(hilp->hl_cmdbuf, data, hilp->hl_cmdbp-hilp->hl_cmdbuf); 54441480Smckusick break; 54541480Smckusick 54641480Smckusick case HILDKR: 54741480Smckusick case HILER1: 54841480Smckusick case HILER2: 54941480Smckusick if (hilp->hl_kbddev) { 55041480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 55141480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, (cmd & 0xFF)); 55241480Smckusick hilp->hl_kbdflags &= ~(KBD_AR1|KBD_AR2); 55341480Smckusick if (cmd == HILIOCAR1) 55441480Smckusick hilp->hl_kbdflags |= KBD_AR1; 55541480Smckusick else if (cmd == HILIOCAR2) 55641480Smckusick hilp->hl_kbdflags |= KBD_AR2; 55741480Smckusick } 55841480Smckusick break; 55941480Smckusick 56041480Smckusick case EFTSBP: 56141480Smckusick /* Send four data bytes to the tone gererator. */ 56241480Smckusick send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 56341480Smckusick /* Send the trigger beeper command to the 8042. */ 56441480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 56541480Smckusick break; 56641480Smckusick 56741480Smckusick case EFTRRT: 56841480Smckusick /* Transfer the real time to the 8042 data buffer */ 56941480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, NULL); 57041480Smckusick /* Read each byte of the real time */ 57141480Smckusick for (i = 0; i < 5; i++) { 57241480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READTIME + i, NULL, 57341480Smckusick 0, &hold); 57441480Smckusick data[4-i] = hold; 57541480Smckusick } 57641480Smckusick break; 57741480Smckusick 57841480Smckusick case EFTRT: 57941480Smckusick for (i = 0; i < 4; i++) { 58041480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF) + i, 58141480Smckusick NULL, 0, &hold); 58241480Smckusick data[i] = hold; 58341480Smckusick } 58441480Smckusick break; 58541480Smckusick 58641480Smckusick case EFTRLC: 58741480Smckusick case EFTRCC: 58841480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), NULL, 0, &hold); 58941480Smckusick *data = hold; 59041480Smckusick break; 59141480Smckusick 59241480Smckusick case EFTSRPG: 59341480Smckusick case EFTSRD: 59441480Smckusick case EFTSRR: 59541480Smckusick send_hil_cmd(hilp->hl_addr, (cmd & 0xFF), data, 1, NULL); 59641480Smckusick break; 59741480Smckusick 59841480Smckusick case EFTSBI: 59953923Shibler #ifdef hp800 60053923Shibler /* XXX big magic */ 60153923Shibler hold = 7 - (*(u_char *)data >> 5); 60253923Shibler *(int *)data = 0x84069008 | (hold << 8); 60353923Shibler send_hil_cmd(hilp->hl_addr, HIL_STARTCMD, data, 4, NULL); 60453923Shibler send_hil_cmd(hilp->hl_addr, 0xC4, NULL, 0, NULL); 60553923Shibler break; 60653923Shibler #else 60741480Smckusick hilbeep(hilp, (struct _hilbell *)data); 60853923Shibler #endif 60941480Smckusick break; 61041480Smckusick 61141480Smckusick case FIONBIO: 61241480Smckusick dptr = &hilp->hl_device[device]; 61341480Smckusick if (*(int *)data) 61441480Smckusick dptr->hd_flags |= HIL_NOBLOCK; 61541480Smckusick else 61641480Smckusick dptr->hd_flags &= ~HIL_NOBLOCK; 61741480Smckusick break; 61841480Smckusick 61941480Smckusick case FIOASYNC: 62041480Smckusick break; 62141480Smckusick 62241480Smckusick default: 62341480Smckusick hilp->hl_cmddev = 0; 62441480Smckusick return(EINVAL); 62541480Smckusick } 62641480Smckusick hilp->hl_cmddev = 0; 62741480Smckusick return(0); 62841480Smckusick } 62941480Smckusick #endif 63041480Smckusick 63141480Smckusick /* ARGSUSED */ 63241480Smckusick hilmap(dev, off, prot) 63341480Smckusick dev_t dev; 63441480Smckusick register int off; 63541480Smckusick { 63641480Smckusick } 63741480Smckusick 63841480Smckusick /*ARGSUSED*/ 63949132Skarels hilselect(dev, rw, p) 64041480Smckusick dev_t dev; 64149132Skarels struct proc *p; 64241480Smckusick { 64353923Shibler register struct hilloop *hilp = &hilloop[HILLOOP(dev)]; 64441480Smckusick register struct hilloopdev *dptr; 64541480Smckusick register struct hiliqueue *qp; 64641480Smckusick register int mask; 64741480Smckusick int s, device; 64841480Smckusick 64941480Smckusick if (rw == FWRITE) 65041480Smckusick return (1); 65141480Smckusick device = HILUNIT(dev); 65241480Smckusick 65341480Smckusick /* 65441480Smckusick * Read interface. 65541480Smckusick * Return 1 if there is something in the queue, 0 ow. 65641480Smckusick */ 65741480Smckusick dptr = &hilp->hl_device[device]; 65841480Smckusick if (dptr->hd_flags & HIL_READIN) { 65941480Smckusick s = splhil(); 66041480Smckusick if (dptr->hd_queue.c_cc) { 66141480Smckusick splx(s); 66241480Smckusick return (1); 66341480Smckusick } 66452533Smckusick selrecord(p, &dptr->hd_selr); 66541480Smckusick splx(s); 66641480Smckusick return (0); 66741480Smckusick } 66841480Smckusick 66941480Smckusick /* 67041480Smckusick * Make sure device is alive and real (or the loop device). 67141480Smckusick * Note that we do not do this for the read interface. 67241480Smckusick * This is primarily to be consistant with HP-UX. 67341480Smckusick */ 67441480Smckusick if (device && (dptr->hd_flags & (HIL_ALIVE|HIL_PSEUDO)) != HIL_ALIVE) 67541480Smckusick return (1); 67641480Smckusick 67741480Smckusick /* 67841480Smckusick * Select on loop device is special. 67941480Smckusick * Check to see if there are any data for any loop device 68041480Smckusick * provided it is associated with a queue belonging to this user. 68141480Smckusick */ 68241480Smckusick if (device == 0) 68341480Smckusick mask = -1; 68441480Smckusick else 68541480Smckusick mask = hildevmask(device); 68641480Smckusick /* 68741480Smckusick * Must check everybody with interrupts blocked to prevent races. 68841480Smckusick */ 68941480Smckusick s = splhil(); 69041480Smckusick for (qp = hilp->hl_queue; qp < &hilp->hl_queue[NHILQ]; qp++) 69143316Smckusick if (qp->hq_procp == p && (mask & qp->hq_devmask) && 69241480Smckusick qp->hq_eventqueue->hil_evqueue.head != 69341480Smckusick qp->hq_eventqueue->hil_evqueue.tail) { 69441480Smckusick splx(s); 69541480Smckusick return (1); 69641480Smckusick } 69741480Smckusick 69852533Smckusick selrecord(p, &dptr->hd_selr); 69941480Smckusick splx(s); 70041480Smckusick return (0); 70141480Smckusick } 70241480Smckusick 70353923Shibler /*ARGSUSED*/ 70453923Shibler hilint(unit) 70541480Smckusick { 70653923Shibler #ifdef hp300 70753923Shibler struct hilloop *hilp = &hilloop[0]; /* XXX how do we know on 300? */ 70853923Shibler #else 70953923Shibler struct hilloop *hilp = &hilloop[unit]; 71053923Shibler #endif 71141480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 71241480Smckusick u_char c, stat; 71341480Smckusick 71453923Shibler stat = READHILSTAT(hildevice); 71553923Shibler c = READHILDATA(hildevice); /* clears interrupt */ 71653923Shibler hil_process_int(hilp, stat, c); 71741480Smckusick } 71841480Smckusick 71941480Smckusick #include "ite.h" 72041480Smckusick 72153923Shibler hil_process_int(hilp, stat, c) 72253923Shibler register struct hilloop *hilp; 72341480Smckusick register u_char stat, c; 72441480Smckusick { 72541480Smckusick #ifdef DEBUG 72641480Smckusick if (hildebug & HDB_EVENTS) 72741480Smckusick printf("hilint: %x %x\n", stat, c); 72841480Smckusick #endif 72941480Smckusick 73041480Smckusick /* the shift enables the compiler to generate a jump table */ 73141480Smckusick switch ((stat>>HIL_SSHIFT) & HIL_SMASK) { 73241480Smckusick 73341480Smckusick #if NITE > 0 73441480Smckusick case HIL_KEY: 73541480Smckusick case HIL_SHIFT: 73641480Smckusick case HIL_CTRL: 73741480Smckusick case HIL_CTRLSHIFT: 73841480Smckusick itefilter(stat, c); 73941480Smckusick return; 74041480Smckusick #endif 74141480Smckusick 74241480Smckusick case HIL_STATUS: /* The status info. */ 74341480Smckusick if (c & HIL_ERROR) { 74441480Smckusick hilp->hl_cmddone = TRUE; 74541480Smckusick if (c == HIL_RECONFIG) 74641480Smckusick hilconfig(hilp); 74741480Smckusick break; 74841480Smckusick } 74941480Smckusick if (c & HIL_COMMAND) { 75041480Smckusick if (c & HIL_POLLDATA) /* End of data */ 75141480Smckusick hilevent(hilp); 75241480Smckusick else /* End of command */ 75341480Smckusick hilp->hl_cmdending = TRUE; 75441480Smckusick hilp->hl_actdev = 0; 75541480Smckusick } else { 75641480Smckusick if (c & HIL_POLLDATA) { /* Start of polled data */ 75741480Smckusick if (hilp->hl_actdev != 0) 75841480Smckusick hilevent(hilp); 75941480Smckusick hilp->hl_actdev = (c & HIL_DEVMASK); 76041480Smckusick hilp->hl_pollbp = hilp->hl_pollbuf; 76141480Smckusick } else { /* Start of command */ 76241480Smckusick if (hilp->hl_cmddev == (c & HIL_DEVMASK)) { 76341480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 76441480Smckusick hilp->hl_actdev = 0; 76541480Smckusick } 76641480Smckusick } 76741480Smckusick } 76841480Smckusick return; 76941480Smckusick 77041480Smckusick case HIL_DATA: 77141480Smckusick if (hilp->hl_actdev != 0) /* Collecting poll data */ 77241480Smckusick *hilp->hl_pollbp++ = c; 77341480Smckusick else if (hilp->hl_cmddev != 0) /* Collecting cmd data */ 77441480Smckusick if (hilp->hl_cmdending) { 77541480Smckusick hilp->hl_cmddone = TRUE; 77641480Smckusick hilp->hl_cmdending = FALSE; 77741480Smckusick } else 77841480Smckusick *hilp->hl_cmdbp++ = c; 77941480Smckusick return; 78041480Smckusick 78141480Smckusick case 0: /* force full jump table */ 78241480Smckusick default: 78341480Smckusick return; 78441480Smckusick } 78541480Smckusick } 78641480Smckusick 78741480Smckusick #if defined(DEBUG) && !defined(PANICBUTTON) 78841480Smckusick #define PANICBUTTON 78941480Smckusick #endif 79041480Smckusick 79141480Smckusick /* 79241480Smckusick * Optimized macro to compute: 79341480Smckusick * eq->head == (eq->tail + 1) % eq->size 79441480Smckusick * i.e. has tail caught up with head. We do this because 32 bit long 79541480Smckusick * remaidering is expensive (a function call with our compiler). 79641480Smckusick */ 79741480Smckusick #define HQFULL(eq) (((eq)->head?(eq)->head:(eq)->size) == (eq)->tail+1) 79841480Smckusick #define HQVALID(eq) \ 79941480Smckusick ((eq)->size == HEVQSIZE && (eq)->tail >= 0 && (eq)->tail < HEVQSIZE) 80041480Smckusick 80141480Smckusick hilevent(hilp) 80241480Smckusick struct hilloop *hilp; 80341480Smckusick { 80441480Smckusick register struct hilloopdev *dptr = &hilp->hl_device[hilp->hl_actdev]; 80541480Smckusick register int len, mask, qnum; 80641480Smckusick register u_char *cp, *pp; 80741480Smckusick register HILQ *hq; 80841480Smckusick struct timeval ourtime; 80941480Smckusick hil_packet *proto; 81041480Smckusick int s, len0; 81141480Smckusick long tenths; 81241480Smckusick 81341480Smckusick #ifdef PANICBUTTON 81441480Smckusick static int first; 81541480Smckusick extern int panicbutton; 81641480Smckusick 81741480Smckusick cp = hilp->hl_pollbuf; 81841480Smckusick if (panicbutton && (*cp & HIL_KBDDATA)) { 81941480Smckusick if (*++cp == 0x4E) 82041480Smckusick first = 1; 82141480Smckusick else if (first && *cp == 0x46 && !panicstr) 82241480Smckusick panic("are we having fun yet?"); 82341480Smckusick else 82441480Smckusick first = 0; 82541480Smckusick } 82641480Smckusick #endif 82741480Smckusick #ifdef DEBUG 82841480Smckusick if (hildebug & HDB_EVENTS) { 82941480Smckusick printf("hilevent: dev %d pollbuf: ", hilp->hl_actdev); 83041480Smckusick printhilpollbuf(hilp); 83141480Smckusick printf("\n"); 83241480Smckusick } 83341480Smckusick #endif 83441480Smckusick 83541480Smckusick /* 83641480Smckusick * Note that HIL_READIN effectively "shuts off" any queues 83741480Smckusick * that may have been in use at the time of an HILIOCHPUX call. 83841480Smckusick */ 83941480Smckusick if (dptr->hd_flags & HIL_READIN) { 84041480Smckusick hpuxhilevent(hilp, dptr); 84141480Smckusick return; 84241480Smckusick } 84341480Smckusick 84441480Smckusick /* 84541480Smckusick * If this device isn't on any queue or there are no data 84641480Smckusick * in the packet (can this happen?) do nothing. 84741480Smckusick */ 84841480Smckusick if (dptr->hd_qmask == 0 || 84941480Smckusick (len0 = hilp->hl_pollbp - hilp->hl_pollbuf) <= 0) 85041480Smckusick return; 85141480Smckusick 85241480Smckusick /* 85341480Smckusick * Everybody gets the same time stamp 85441480Smckusick */ 85541480Smckusick s = splclock(); 85641480Smckusick ourtime = time; 85741480Smckusick splx(s); 85841480Smckusick tenths = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 85941480Smckusick 86041480Smckusick proto = NULL; 86141480Smckusick mask = dptr->hd_qmask; 86241480Smckusick for (qnum = 0; mask; qnum++) { 86341480Smckusick if ((mask & hilqmask(qnum)) == 0) 86441480Smckusick continue; 86541480Smckusick mask &= ~hilqmask(qnum); 86641480Smckusick hq = hilp->hl_queue[qnum].hq_eventqueue; 86741480Smckusick 86841480Smckusick /* 86941480Smckusick * Ensure that queue fields that we rely on are valid 87041480Smckusick * and that there is space in the queue. If either 87141480Smckusick * test fails, we just skip this queue. 87241480Smckusick */ 87341480Smckusick if (!HQVALID(&hq->hil_evqueue) || HQFULL(&hq->hil_evqueue)) 87441480Smckusick continue; 87541480Smckusick 87641480Smckusick /* 87741480Smckusick * Copy data to queue. 87841480Smckusick * If this is the first queue we construct the packet 87941480Smckusick * with length, timestamp and poll buffer data. 88041480Smckusick * For second and sucessive packets we just duplicate 88141480Smckusick * the first packet. 88241480Smckusick */ 88341480Smckusick pp = (u_char *) &hq->hil_event[hq->hil_evqueue.tail]; 88441480Smckusick if (proto == NULL) { 88541480Smckusick proto = (hil_packet *)pp; 88641480Smckusick cp = hilp->hl_pollbuf; 88741480Smckusick len = len0; 88841480Smckusick *pp++ = len + 6; 88941480Smckusick *pp++ = hilp->hl_actdev; 89041480Smckusick *(long *)pp = tenths; 89141480Smckusick pp += sizeof(long); 89241480Smckusick do *pp++ = *cp++; while (--len); 89341480Smckusick } else 89441480Smckusick *(hil_packet *)pp = *proto; 89541480Smckusick 89641480Smckusick if (++hq->hil_evqueue.tail == hq->hil_evqueue.size) 89741480Smckusick hq->hil_evqueue.tail = 0; 89841480Smckusick } 89941480Smckusick 90041480Smckusick /* 90141480Smckusick * Wake up anyone selecting on this device or the loop itself 90241480Smckusick */ 90352533Smckusick selwakeup(&dptr->hd_selr); 90441480Smckusick dptr = &hilp->hl_device[HILLOOPDEV]; 90552533Smckusick selwakeup(&dptr->hd_selr); 90641480Smckusick } 90741480Smckusick 90841480Smckusick #undef HQFULL 90941480Smckusick 91041480Smckusick hpuxhilevent(hilp, dptr) 91141480Smckusick register struct hilloop *hilp; 91241480Smckusick register struct hilloopdev *dptr; 91341480Smckusick { 91441480Smckusick register int len; 91541480Smckusick struct timeval ourtime; 91641480Smckusick long tstamp; 91741480Smckusick int s; 91841480Smckusick 91941480Smckusick /* 92041480Smckusick * Everybody gets the same time stamp 92141480Smckusick */ 92241480Smckusick s = splclock(); 92341480Smckusick ourtime = time; 92441480Smckusick splx(s); 92541480Smckusick tstamp = (ourtime.tv_sec * 100) + (ourtime.tv_usec / 10000); 92641480Smckusick 92741480Smckusick /* 92841480Smckusick * Each packet that goes into the buffer must be preceded by the 92941480Smckusick * number of bytes in the packet, and the timestamp of the packet. 93041480Smckusick * This adds 5 bytes to the packet size. Make sure there is enough 93141480Smckusick * room in the buffer for it, and if not, toss the packet. 93241480Smckusick */ 93341480Smckusick len = hilp->hl_pollbp - hilp->hl_pollbuf; 93441480Smckusick if (dptr->hd_queue.c_cc <= (HILMAXCLIST - (len+5))) { 93541480Smckusick putc(len+5, &dptr->hd_queue); 93641480Smckusick (void) b_to_q((char *)&tstamp, sizeof tstamp, &dptr->hd_queue); 93741480Smckusick (void) b_to_q((char *)hilp->hl_pollbuf, len, &dptr->hd_queue); 93841480Smckusick } 93941480Smckusick 94041480Smckusick /* 94141480Smckusick * Wake up any one blocked on a read or select 94241480Smckusick */ 94341480Smckusick if (dptr->hd_flags & HIL_ASLEEP) { 94441480Smckusick dptr->hd_flags &= ~HIL_ASLEEP; 94541480Smckusick wakeup((caddr_t)dptr); 94641480Smckusick } 94752533Smckusick selwakeup(&dptr->hd_selr); 94841480Smckusick } 94941480Smckusick 95041480Smckusick /* 95141480Smckusick * Shared queue manipulation routines 95241480Smckusick */ 95341480Smckusick 95453923Shibler hilqalloc(hilp, qip) 95553923Shibler register struct hilloop *hilp; 95641480Smckusick struct hilqinfo *qip; 95741480Smckusick { 95849132Skarels struct proc *p = curproc; /* XXX */ 95941480Smckusick 96041480Smckusick #ifdef DEBUG 96141480Smckusick if (hildebug & HDB_FOLLOW) 96245750Smckusick printf("hilqalloc(%d): addr %x\n", p->p_pid, qip->addr); 96341480Smckusick #endif 96441480Smckusick return(EINVAL); 96541480Smckusick } 96641480Smckusick 96753923Shibler hilqfree(hilp, qnum) 96841480Smckusick register int qnum; 96941480Smckusick { 97049132Skarels struct proc *p = curproc; /* XXX */ 97141480Smckusick 97241480Smckusick #ifdef DEBUG 97341480Smckusick if (hildebug & HDB_FOLLOW) 97445750Smckusick printf("hilqfree(%d): qnum %d\n", p->p_pid, qnum); 97541480Smckusick #endif 97641480Smckusick return(EINVAL); 97741480Smckusick } 97841480Smckusick 97953923Shibler hilqmap(hilp, qnum, device) 98053923Shibler register struct hilloop *hilp; 98141480Smckusick register int qnum, device; 98241480Smckusick { 98349132Skarels struct proc *p = curproc; /* XXX */ 98441480Smckusick register struct hilloopdev *dptr = &hilp->hl_device[device]; 98541480Smckusick int s; 98641480Smckusick 98741480Smckusick #ifdef DEBUG 98841480Smckusick if (hildebug & HDB_FOLLOW) 98941480Smckusick printf("hilqmap(%d): qnum %d device %x\n", 99043316Smckusick p->p_pid, qnum, device); 99141480Smckusick #endif 99243316Smckusick if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 99341480Smckusick return(EINVAL); 99441480Smckusick if ((dptr->hd_flags & HIL_QUEUEIN) == 0) 99541480Smckusick return(EINVAL); 99649132Skarels if (dptr->hd_qmask && p->p_ucred->cr_uid && 99749132Skarels p->p_ucred->cr_uid != dptr->hd_uid) 99841480Smckusick return(EPERM); 99941480Smckusick 100041480Smckusick hilp->hl_queue[qnum].hq_devmask |= hildevmask(device); 100141480Smckusick if (dptr->hd_qmask == 0) 100249132Skarels dptr->hd_uid = p->p_ucred->cr_uid; 100341480Smckusick s = splhil(); 100441480Smckusick dptr->hd_qmask |= hilqmask(qnum); 100541480Smckusick splx(s); 100641480Smckusick #ifdef DEBUG 100741480Smckusick if (hildebug & HDB_MASK) 100841480Smckusick printf("hilqmap(%d): devmask %x qmask %x\n", 100943316Smckusick p->p_pid, hilp->hl_queue[qnum].hq_devmask, 101041480Smckusick dptr->hd_qmask); 101141480Smckusick #endif 101241480Smckusick return(0); 101341480Smckusick } 101441480Smckusick 101553923Shibler hilqunmap(hilp, qnum, device) 101653923Shibler register struct hilloop *hilp; 101741480Smckusick register int qnum, device; 101841480Smckusick { 101949132Skarels struct proc *p = curproc; /* XXX */ 102041480Smckusick int s; 102141480Smckusick 102241480Smckusick #ifdef DEBUG 102341480Smckusick if (hildebug & HDB_FOLLOW) 102441480Smckusick printf("hilqunmap(%d): qnum %d device %x\n", 102543316Smckusick p->p_pid, qnum, device); 102641480Smckusick #endif 102741480Smckusick 102843316Smckusick if (qnum >= NHILQ || hilp->hl_queue[qnum].hq_procp != p) 102941480Smckusick return(EINVAL); 103041480Smckusick 103141480Smckusick hilp->hl_queue[qnum].hq_devmask &= ~hildevmask(device); 103241480Smckusick s = splhil(); 103341480Smckusick hilp->hl_device[device].hd_qmask &= ~hilqmask(qnum); 103441480Smckusick splx(s); 103541480Smckusick #ifdef DEBUG 103641480Smckusick if (hildebug & HDB_MASK) 103741480Smckusick printf("hilqunmap(%d): devmask %x qmask %x\n", 103843316Smckusick p->p_pid, hilp->hl_queue[qnum].hq_devmask, 103941480Smckusick hilp->hl_device[device].hd_qmask); 104041480Smckusick #endif 104141480Smckusick return(0); 104241480Smckusick } 104341480Smckusick 104441480Smckusick /* 104541480Smckusick * Cooked keyboard functions for ite driver. 104641480Smckusick * There is only one "cooked" ITE keyboard (the first keyboard found) 104741480Smckusick * per loop. There may be other keyboards, but they will always be "raw". 104841480Smckusick */ 104941480Smckusick 105053923Shibler kbdbell(unit) 105153923Shibler int unit; 105241480Smckusick { 105353923Shibler struct hilloop *hilp = &hilloop[unit]; 105441480Smckusick 105541480Smckusick hilbeep(hilp, &default_bell); 105641480Smckusick } 105741480Smckusick 105853923Shibler kbdenable(unit) 105953923Shibler int unit; 106041480Smckusick { 106153923Shibler struct hilloop *hilp = &hilloop[unit]; 106241480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 106341480Smckusick char db; 106441480Smckusick 106541480Smckusick /* Set the autorepeat rate register */ 106641480Smckusick db = ar_format(KBD_ARR); 106741480Smckusick send_hil_cmd(hildevice, HIL_SETARR, &db, 1, NULL); 106841480Smckusick 106941480Smckusick /* Set the autorepeat delay register */ 107041480Smckusick db = ar_format(KBD_ARD); 107141480Smckusick send_hil_cmd(hildevice, HIL_SETARD, &db, 1, NULL); 107241480Smckusick 107341480Smckusick /* Enable interrupts */ 107441480Smckusick send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 107541480Smckusick } 107641480Smckusick 107753923Shibler kbddisable(unit) 107853923Shibler int unit; 107941480Smckusick { 108041480Smckusick } 108141480Smckusick 108241480Smckusick /* 108341480Smckusick * XXX: read keyboard directly and return code. 108441480Smckusick * Used by console getchar routine. Could really screw up anybody 108541480Smckusick * reading from the keyboard in the normal, interrupt driven fashion. 108641480Smckusick */ 108753923Shibler kbdgetc(unit, statp) 108853923Shibler int unit, *statp; 108941480Smckusick { 109053923Shibler struct hilloop *hilp = &hilloop[unit]; 109141480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 109241480Smckusick register int c, stat; 109341480Smckusick int s; 109441480Smckusick 109541480Smckusick s = splhil(); 109653923Shibler while (((stat = READHILSTAT(hildevice)) & HIL_DATA_RDY) == 0) 109741480Smckusick ; 109853923Shibler c = READHILDATA(hildevice); 109941480Smckusick splx(s); 110041480Smckusick *statp = stat; 110141480Smckusick return(c); 110241480Smckusick } 110341480Smckusick 110441480Smckusick /* 110541480Smckusick * Recoginize and clear keyboard generated NMIs. 110641480Smckusick * Returns 1 if it was ours, 0 otherwise. Note that we cannot use 110741480Smckusick * send_hil_cmd() to issue the clear NMI command as that would actually 110841480Smckusick * lower the priority to splimp() and it doesn't wait for the completion 110941480Smckusick * of the command. Either of these conditions could result in the 111041480Smckusick * interrupt reoccuring. Note that we issue the CNMT command twice. 111141480Smckusick * This seems to be needed, once is not always enough!?! 111241480Smckusick */ 111353923Shibler kbdnmi(unit) 111453923Shibler int unit; 111541480Smckusick { 111653923Shibler #ifdef hp300 111753923Shibler struct hilloop *hilp = &hilloop[0]; /* XXX how do we know on 300? */ 111853923Shibler #else 111953923Shibler struct hilloop *hilp = &hilloop[unit]; 112053923Shibler #endif 112153923Shibler #ifdef hp300 112241480Smckusick if ((*KBDNMISTAT & KBDNMI) == 0) 112341480Smckusick return(0); 112453923Shibler #endif 112541480Smckusick HILWAIT(hilp->hl_addr); 112653923Shibler WRITEHILCMD(hilp->hl_addr, HIL_CNMT); 112741480Smckusick HILWAIT(hilp->hl_addr); 112853923Shibler WRITEHILCMD(hilp->hl_addr, HIL_CNMT); 112941480Smckusick HILWAIT(hilp->hl_addr); 113041480Smckusick return(1); 113141480Smckusick } 113241480Smckusick 113341480Smckusick #define HILSECURITY 0x33 113441480Smckusick #define HILIDENTIFY 0x03 113541480Smckusick #define HILSCBIT 0x04 113641480Smckusick 113741480Smckusick /* 113841480Smckusick * Called at boot time to print out info about interesting devices 113941480Smckusick */ 114053923Shibler hilinfo(unit) 114153923Shibler int unit; 114241480Smckusick { 114353923Shibler register struct hilloop *hilp = &hilloop[unit]; 114441480Smckusick register int id, len; 114541480Smckusick register struct kbdmap *km; 114641480Smckusick 114741480Smckusick /* 114841480Smckusick * Keyboard info. 114941480Smckusick */ 115041480Smckusick if (hilp->hl_kbddev) { 115141480Smckusick printf("hil%d: ", hilp->hl_kbddev); 115241480Smckusick for (km = kbd_map; km->kbd_code; km++) 115341480Smckusick if (km->kbd_code == hilp->hl_kbdlang) { 115441480Smckusick printf("%s ", km->kbd_desc); 115541480Smckusick break; 115641480Smckusick } 115741480Smckusick printf("keyboard\n"); 115841480Smckusick } 115941480Smckusick /* 116041480Smckusick * ID module. 116141480Smckusick * Attempt to locate the first ID module and print out its 116241480Smckusick * security code. Is this a good idea?? 116341480Smckusick */ 116441480Smckusick id = hiliddev(hilp); 116541480Smckusick if (id) { 116641480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 116741480Smckusick hilp->hl_cmddev = id; 116841480Smckusick send_hildev_cmd(hilp, id, HILSECURITY); 116941480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 117041480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 117141480Smckusick hilp->hl_cmddev = 0; 117241480Smckusick printf("hil%d: security code", id); 117341480Smckusick for (id = 0; id < len; id++) 117441480Smckusick printf(" %x", hilp->hl_cmdbuf[id]); 117541480Smckusick while (id++ < 16) 117641480Smckusick printf(" 0"); 117741480Smckusick printf("\n"); 117841480Smckusick } 117941480Smckusick } 118041480Smckusick 118141480Smckusick #define HILAR1 0x3E 118241480Smckusick #define HILAR2 0x3F 118341480Smckusick 118441480Smckusick /* 118541480Smckusick * Called after the loop has reconfigured. Here we need to: 118641480Smckusick * - determine how many devices are on the loop 118741480Smckusick * (some may have been added or removed) 118841480Smckusick * - locate the ITE keyboard (if any) and ensure 118941480Smckusick * that it is in the proper state (raw or cooked) 119041480Smckusick * and is set to use the proper language mapping table 119141480Smckusick * - ensure all other keyboards are raw 119241480Smckusick * Note that our device state is now potentially invalid as 119341480Smckusick * devices may no longer be where they were. What we should 119441480Smckusick * do here is either track where the devices went and move 119541480Smckusick * state around accordingly or, more simply, just mark all 119641480Smckusick * devices as HIL_DERROR and don't allow any further use until 119741480Smckusick * they are closed. This is a little too brutal for my tastes, 119841480Smckusick * we prefer to just assume people won't move things around. 119941480Smckusick */ 120041480Smckusick hilconfig(hilp) 120141480Smckusick register struct hilloop *hilp; 120241480Smckusick { 120341480Smckusick u_char db; 120441480Smckusick int s; 120541480Smckusick 120641480Smckusick s = splhil(); 120741480Smckusick #ifdef DEBUG 120841480Smckusick if (hildebug & HDB_CONFIG) { 120941480Smckusick printf("hilconfig: reconfigured: "); 121041480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 121141480Smckusick printf("LPSTAT %x, ", db); 121241480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPCTRL, NULL, 0, &db); 121341480Smckusick printf("LPCTRL %x, ", db); 121441480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 121541480Smckusick printf("KBDSADR %x\n", db); 121641480Smckusick hilreport(hilp); 121741480Smckusick } 121841480Smckusick #endif 121941480Smckusick /* 122041480Smckusick * Determine how many devices are on the loop. 122141480Smckusick * Mark those as alive and real, all others as dead. 122241480Smckusick */ 122341480Smckusick db = 0; 122441480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READLPSTAT, NULL, 0, &db); 122541480Smckusick hilp->hl_maxdev = db & LPS_DEVMASK; 122653923Shibler #ifdef DEBUG 122753923Shibler if (hildebug & HDB_CONFIG) 122853923Shibler printf("hilconfig: %d devices found\n", hilp->hl_maxdev); 122953923Shibler #endif 123041480Smckusick for (db = 1; db < NHILD; db++) { 123141480Smckusick if (db <= hilp->hl_maxdev) 123241480Smckusick hilp->hl_device[db].hd_flags |= HIL_ALIVE; 123341480Smckusick else 123441480Smckusick hilp->hl_device[db].hd_flags &= ~HIL_ALIVE; 123541480Smckusick hilp->hl_device[db].hd_flags &= ~HIL_PSEUDO; 123641480Smckusick } 123741480Smckusick #ifdef DEBUG 123841480Smckusick if (hildebug & (HDB_CONFIG|HDB_KEYBOARD)) 123941480Smckusick printf("hilconfig: max device %d\n", hilp->hl_maxdev); 124041480Smckusick #endif 124141480Smckusick if (hilp->hl_maxdev == 0) { 124241480Smckusick hilp->hl_kbddev = 0; 124341480Smckusick splx(s); 124441480Smckusick return; 124541480Smckusick } 124641480Smckusick /* 124741480Smckusick * Find out where the keyboards are and record the ITE keyboard 124841480Smckusick * (first one found). If no keyboards found, we are all done. 124941480Smckusick */ 125041480Smckusick db = 0; 125141480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDSADR, NULL, 0, &db); 125241480Smckusick #ifdef DEBUG 125341480Smckusick if (hildebug & HDB_KEYBOARD) 125441480Smckusick printf("hilconfig: keyboard: KBDSADR %x, old %d, new %d\n", 125541480Smckusick db, hilp->hl_kbddev, ffs((int)db)); 125641480Smckusick #endif 125741480Smckusick hilp->hl_kbddev = ffs((int)db); 125841480Smckusick if (hilp->hl_kbddev == 0) { 125941480Smckusick splx(s); 126041480Smckusick return; 126141480Smckusick } 126241480Smckusick /* 126341480Smckusick * Determine if the keyboard should be cooked or raw and configure it. 126441480Smckusick */ 126541480Smckusick db = (hilp->hl_kbdflags & KBD_RAW) ? 0 : 1 << (hilp->hl_kbddev - 1); 126641480Smckusick send_hil_cmd(hilp->hl_addr, HIL_WRITEKBDSADR, &db, 1, NULL); 126741480Smckusick /* 126841480Smckusick * Re-enable autorepeat in raw mode, cooked mode AR is not affected. 126941480Smckusick */ 127041480Smckusick if (hilp->hl_kbdflags & (KBD_AR1|KBD_AR2)) { 127141480Smckusick db = (hilp->hl_kbdflags & KBD_AR1) ? HILAR1 : HILAR2; 127241480Smckusick hilp->hl_cmddev = hilp->hl_kbddev; 127341480Smckusick send_hildev_cmd(hilp, hilp->hl_kbddev, db); 127441480Smckusick hilp->hl_cmddev = 0; 127541480Smckusick } 127641480Smckusick /* 127741480Smckusick * Determine the keyboard language configuration, but don't 127841480Smckusick * override a user-specified setting. 127941480Smckusick */ 128041480Smckusick db = 0; 128141480Smckusick send_hil_cmd(hilp->hl_addr, HIL_READKBDLANG, NULL, 0, &db); 128241480Smckusick #ifdef DEBUG 128341480Smckusick if (hildebug & HDB_KEYBOARD) 128441480Smckusick printf("hilconfig: language: old %x new %x\n", 128541480Smckusick hilp->hl_kbdlang, db); 128641480Smckusick #endif 128741480Smckusick if (hilp->hl_kbdlang != KBD_SPECIAL) { 128841480Smckusick struct kbdmap *km; 128941480Smckusick 129041480Smckusick for (km = kbd_map; km->kbd_code; km++) 129141480Smckusick if (km->kbd_code == db) { 129241480Smckusick hilp->hl_kbdlang = db; 129341480Smckusick /* XXX */ 129441480Smckusick kbd_keymap = km->kbd_keymap; 129541480Smckusick kbd_shiftmap = km->kbd_shiftmap; 129641480Smckusick kbd_ctrlmap = km->kbd_ctrlmap; 129741480Smckusick kbd_ctrlshiftmap = km->kbd_ctrlshiftmap; 129841480Smckusick kbd_stringmap = km->kbd_stringmap; 129941480Smckusick } 130041480Smckusick } 130141480Smckusick splx(s); 130241480Smckusick } 130341480Smckusick 130441480Smckusick hilreset(hilp) 130541480Smckusick struct hilloop *hilp; 130641480Smckusick { 130741480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 130841480Smckusick u_char db; 130941480Smckusick 131053923Shibler #ifdef DEBUG 131153923Shibler if (hildebug & HDB_FOLLOW) 131253923Shibler printf("hilreset(%x)\n", hilp); 131353923Shibler #endif 131441480Smckusick /* 131541480Smckusick * Initialize the loop: reconfigure, don't report errors, 131641480Smckusick * cook keyboards, and enable autopolling. 131741480Smckusick */ 131841480Smckusick db = LPC_RECONF | LPC_KBDCOOK | LPC_NOERROR | LPC_AUTOPOLL; 131941480Smckusick send_hil_cmd(hildevice, HIL_WRITELPCTRL, &db, 1, NULL); 132041480Smckusick /* 132141480Smckusick * Delay one second for reconfiguration and then read the the 132241480Smckusick * data register to clear the interrupt (if the loop reconfigured). 132341480Smckusick */ 132441480Smckusick DELAY(1000000); 132553923Shibler if (READHILSTAT(hildevice) & HIL_DATA_RDY) 132653923Shibler db = READHILDATA(hildevice); 132741480Smckusick /* 132841480Smckusick * The HIL loop may have reconfigured. If so we proceed on, 132941480Smckusick * if not we loop until a successful reconfiguration is reported 133041480Smckusick * back to us. The HIL loop will continue to attempt forever. 133141480Smckusick * Probably not very smart. 133241480Smckusick */ 133341480Smckusick do { 133441480Smckusick send_hil_cmd(hildevice, HIL_READLPSTAT, NULL, 0, &db); 133541480Smckusick } while ((db & (LPS_CONFFAIL|LPS_CONFGOOD)) == 0); 133641480Smckusick /* 133741480Smckusick * At this point, the loop should have reconfigured. 133841480Smckusick * The reconfiguration interrupt has already called hilconfig() 133943411Shibler * so the keyboard has been determined. 134041480Smckusick */ 134141480Smckusick send_hil_cmd(hildevice, HIL_INTON, NULL, 0, NULL); 134241480Smckusick } 134341480Smckusick 134441480Smckusick hilbeep(hilp, bp) 134541480Smckusick struct hilloop *hilp; 134641480Smckusick register struct _hilbell *bp; 134741480Smckusick { 134841480Smckusick u_char buf[2]; 134941480Smckusick 135041480Smckusick buf[0] = ~((bp->duration - 10) / 10); 135141480Smckusick buf[1] = bp->frequency; 135241480Smckusick send_hil_cmd(hilp->hl_addr, HIL_SETTONE, buf, 2, NULL); 135341480Smckusick } 135441480Smckusick 135541480Smckusick /* 135641480Smckusick * Locate and return the address of the first ID module, 0 if none present. 135741480Smckusick */ 135841480Smckusick hiliddev(hilp) 135941480Smckusick register struct hilloop *hilp; 136041480Smckusick { 136141480Smckusick register int i, len; 136241480Smckusick 136341480Smckusick #ifdef DEBUG 136441480Smckusick if (hildebug & HDB_IDMODULE) 136553923Shibler printf("hiliddev(%x): max %d, looking for idmodule...", 136653923Shibler hilp, hilp->hl_maxdev); 136741480Smckusick #endif 136841480Smckusick for (i = 1; i <= hilp->hl_maxdev; i++) { 136941480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 137041480Smckusick hilp->hl_cmddev = i; 137141480Smckusick send_hildev_cmd(hilp, i, HILIDENTIFY); 137241480Smckusick /* 137341480Smckusick * XXX: the final condition checks to ensure that the 137441480Smckusick * device ID byte is in the range of the ID module (0x30-0x3F) 137541480Smckusick */ 137641480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 137741480Smckusick if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT) && 137841480Smckusick (hilp->hl_cmdbuf[0] & 0xF0) == 0x30) { 137941480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 138041480Smckusick hilp->hl_cmddev = i; 138141480Smckusick send_hildev_cmd(hilp, i, HILSECURITY); 138241480Smckusick break; 138341480Smckusick } 138441480Smckusick } 138541480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 138641480Smckusick hilp->hl_cmddev = 0; 138741480Smckusick #ifdef DEBUG 138841480Smckusick if (hildebug & HDB_IDMODULE) 138941480Smckusick if (i <= hilp->hl_maxdev) 139041480Smckusick printf("found at %d\n", i); 139141480Smckusick else 139241480Smckusick printf("not found\n"); 139341480Smckusick #endif 139441480Smckusick return(i <= hilp->hl_maxdev ? i : 0); 139541480Smckusick } 139641480Smckusick 139753923Shibler #ifdef HPUXCOMPAT 139841480Smckusick /* 139953923Shibler * XXX map devno as expected by HP-UX 140053923Shibler */ 140153923Shibler hildevno(dev) 140253923Shibler dev_t dev; 140353923Shibler { 140453923Shibler int newdev; 140553923Shibler 140653923Shibler newdev = 24 << 24; 140753923Shibler #ifdef HILCOMPAT 140853923Shibler /* 140953923Shibler * XXX compat check 141053923Shibler * Don't convert old style specfiles already in correct format 141153923Shibler */ 141253923Shibler if (minor(dev) && (dev & 0xF) == 0) 141353923Shibler newdev |= minor(dev); 141453923Shibler else 141553923Shibler #endif 141653923Shibler newdev |= (HILLOOP(dev) << 8) | (HILUNIT(dev) << 4); 141753923Shibler return(newdev); 141853923Shibler } 141953923Shibler #endif 142053923Shibler 142153923Shibler /* 142241480Smckusick * Low level routines which actually talk to the 8042 chip. 142341480Smckusick */ 142441480Smckusick 142541480Smckusick /* 142641480Smckusick * Send a command to the 8042 with zero or more bytes of data. 142741480Smckusick * If rdata is non-null, wait for and return a byte of data. 142841480Smckusick * We run at splimp() to make the transaction as atomic as 142941480Smckusick * possible without blocking the clock (is this necessary?) 143041480Smckusick */ 143141480Smckusick send_hil_cmd(hildevice, cmd, data, dlen, rdata) 143241480Smckusick register struct hil_dev *hildevice; 143341480Smckusick u_char cmd, *data, dlen; 143441480Smckusick u_char *rdata; 143541480Smckusick { 143641480Smckusick u_char status; 143741480Smckusick int s = splimp(); 143841480Smckusick 143941480Smckusick HILWAIT(hildevice); 144053923Shibler WRITEHILCMD(hildevice, cmd); 144141480Smckusick while (dlen--) { 144241480Smckusick HILWAIT(hildevice); 144353923Shibler WRITEHILDATA(hildevice, *data++); 144441480Smckusick } 144541480Smckusick if (rdata) { 144641480Smckusick do { 144741480Smckusick HILDATAWAIT(hildevice); 144853923Shibler status = READHILSTAT(hildevice); 144953923Shibler *rdata = READHILDATA(hildevice); 145041480Smckusick } while (((status >> HIL_SSHIFT) & HIL_SMASK) != HIL_68K); 145141480Smckusick } 145241480Smckusick splx(s); 145341480Smckusick } 145441480Smckusick 145541480Smckusick /* 145641480Smckusick * Send a command to a device on the loop. 145741480Smckusick * Since only one command can be active on the loop at any time, 145841480Smckusick * we must ensure that we are not interrupted during this process. 145941480Smckusick * Hence we mask interrupts to prevent potential access from most 146041480Smckusick * interrupt routines and turn off auto-polling to disable the 146141480Smckusick * internally generated poll commands. 146241480Smckusick * 146341480Smckusick * splhigh is extremely conservative but insures atomic operation, 146441480Smckusick * splimp (clock only interrupts) seems to be good enough in practice. 146541480Smckusick */ 146641480Smckusick send_hildev_cmd(hilp, device, cmd) 146741480Smckusick register struct hilloop *hilp; 146841480Smckusick char device, cmd; 146941480Smckusick { 147041480Smckusick register struct hil_dev *hildevice = hilp->hl_addr; 147141480Smckusick u_char status, c; 147241480Smckusick int s = splimp(); 147341480Smckusick 147441480Smckusick polloff(hildevice); 147541480Smckusick 147641480Smckusick /* 147741480Smckusick * Transfer the command and device info to the chip 147841480Smckusick */ 147941480Smckusick HILWAIT(hildevice); 148053923Shibler WRITEHILCMD(hildevice, HIL_STARTCMD); 148141480Smckusick HILWAIT(hildevice); 148253923Shibler WRITEHILDATA(hildevice, 8 + device); 148341480Smckusick HILWAIT(hildevice); 148453923Shibler WRITEHILDATA(hildevice, cmd); 148541480Smckusick HILWAIT(hildevice); 148653923Shibler WRITEHILDATA(hildevice, HIL_TIMEOUT); 148741480Smckusick /* 148841480Smckusick * Trigger the command and wait for completion 148941480Smckusick */ 149041480Smckusick HILWAIT(hildevice); 149153923Shibler WRITEHILCMD(hildevice, HIL_TRIGGER); 149241480Smckusick hilp->hl_cmddone = FALSE; 149341480Smckusick do { 149441480Smckusick HILDATAWAIT(hildevice); 149553923Shibler status = READHILSTAT(hildevice); 149653923Shibler c = READHILDATA(hildevice); 149753923Shibler hil_process_int(hilp, status, c); 149841480Smckusick } while (!hilp->hl_cmddone); 149941480Smckusick 150041480Smckusick pollon(hildevice); 150141480Smckusick splx(s); 150241480Smckusick } 150341480Smckusick 150441480Smckusick /* 150541480Smckusick * Turn auto-polling off and on. 150641480Smckusick * Also disables and enable auto-repeat. Why? 150741480Smckusick */ 150841480Smckusick polloff(hildevice) 150941480Smckusick register struct hil_dev *hildevice; 151041480Smckusick { 151141480Smckusick register char db; 151241480Smckusick 151341480Smckusick /* 151441480Smckusick * Turn off auto repeat 151541480Smckusick */ 151641480Smckusick HILWAIT(hildevice); 151753923Shibler WRITEHILCMD(hildevice, HIL_SETARR); 151841480Smckusick HILWAIT(hildevice); 151953923Shibler WRITEHILDATA(hildevice, 0); 152041480Smckusick /* 152141480Smckusick * Turn off auto-polling 152241480Smckusick */ 152341480Smckusick HILWAIT(hildevice); 152453923Shibler WRITEHILCMD(hildevice, HIL_READLPCTRL); 152541480Smckusick HILDATAWAIT(hildevice); 152653923Shibler db = READHILDATA(hildevice); 152741480Smckusick db &= ~LPC_AUTOPOLL; 152841480Smckusick HILWAIT(hildevice); 152953923Shibler WRITEHILCMD(hildevice, HIL_WRITELPCTRL); 153041480Smckusick HILWAIT(hildevice); 153153923Shibler WRITEHILDATA(hildevice, db); 153241480Smckusick /* 153341480Smckusick * Must wait til polling is really stopped 153441480Smckusick */ 153541480Smckusick do { 153641480Smckusick HILWAIT(hildevice); 153753923Shibler WRITEHILCMD(hildevice, HIL_READBUSY); 153841480Smckusick HILDATAWAIT(hildevice); 153953923Shibler db = READHILDATA(hildevice); 154041480Smckusick } while (db & BSY_LOOPBUSY); 154141480Smckusick } 154241480Smckusick 154341480Smckusick pollon(hildevice) 154441480Smckusick register struct hil_dev *hildevice; 154541480Smckusick { 154641480Smckusick register char db; 154741480Smckusick 154841480Smckusick /* 154941480Smckusick * Turn on auto polling 155041480Smckusick */ 155141480Smckusick HILWAIT(hildevice); 155253923Shibler WRITEHILCMD(hildevice, HIL_READLPCTRL); 155341480Smckusick HILDATAWAIT(hildevice); 155453923Shibler db = READHILDATA(hildevice); 155541480Smckusick db |= LPC_AUTOPOLL; 155641480Smckusick HILWAIT(hildevice); 155753923Shibler WRITEHILCMD(hildevice, HIL_WRITELPCTRL); 155841480Smckusick HILWAIT(hildevice); 155953923Shibler WRITEHILDATA(hildevice, db); 156041480Smckusick /* 156141480Smckusick * Turn on auto repeat 156241480Smckusick */ 156341480Smckusick HILWAIT(hildevice); 156453923Shibler WRITEHILCMD(hildevice, HIL_SETARR); 156541480Smckusick HILWAIT(hildevice); 156653923Shibler WRITEHILDATA(hildevice, ar_format(KBD_ARR)); 156741480Smckusick } 156841480Smckusick 156941480Smckusick #ifdef DEBUG 157041480Smckusick printhilpollbuf(hilp) 157141480Smckusick register struct hilloop *hilp; 157241480Smckusick { 157341480Smckusick register u_char *cp; 157441480Smckusick register int i, len; 157541480Smckusick 157641480Smckusick cp = hilp->hl_pollbuf; 157741480Smckusick len = hilp->hl_pollbp - cp; 157841480Smckusick for (i = 0; i < len; i++) 157941480Smckusick printf("%x ", hilp->hl_pollbuf[i]); 158041480Smckusick printf("\n"); 158141480Smckusick } 158241480Smckusick 158341480Smckusick printhilcmdbuf(hilp) 158441480Smckusick register struct hilloop *hilp; 158541480Smckusick { 158641480Smckusick register u_char *cp; 158741480Smckusick register int i, len; 158841480Smckusick 158941480Smckusick cp = hilp->hl_cmdbuf; 159041480Smckusick len = hilp->hl_cmdbp - cp; 159141480Smckusick for (i = 0; i < len; i++) 159241480Smckusick printf("%x ", hilp->hl_cmdbuf[i]); 159341480Smckusick printf("\n"); 159441480Smckusick } 159541480Smckusick 159641480Smckusick hilreport(hilp) 159741480Smckusick register struct hilloop *hilp; 159841480Smckusick { 159941480Smckusick register int i, len; 160041480Smckusick int s = splhil(); 160141480Smckusick 160241480Smckusick for (i = 1; i <= hilp->hl_maxdev; i++) { 160341480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 160441480Smckusick hilp->hl_cmddev = i; 160541480Smckusick send_hildev_cmd(hilp, i, HILIDENTIFY); 160641480Smckusick printf("hil%d: id: ", i); 160741480Smckusick printhilcmdbuf(hilp); 160841480Smckusick len = hilp->hl_cmdbp - hilp->hl_cmdbuf; 160941480Smckusick if (len > 1 && (hilp->hl_cmdbuf[1] & HILSCBIT)) { 161041480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 161141480Smckusick hilp->hl_cmddev = i; 161241480Smckusick send_hildev_cmd(hilp, i, HILSECURITY); 161341480Smckusick printf("hil%d: sc: ", i); 161441480Smckusick printhilcmdbuf(hilp); 161541480Smckusick } 161641480Smckusick } 161741480Smckusick hilp->hl_cmdbp = hilp->hl_cmdbuf; 161841480Smckusick hilp->hl_cmddev = 0; 161941480Smckusick splx(s); 162041480Smckusick } 162141480Smckusick #endif 1622